]>
Commit | Line | Data |
---|---|---|
82094b55 AF |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: dasd_eckd: Write format record 0 is now allowed | |
3 | References: bnc#477816,LTC#52004 | |
4 | ||
5 | Description: Permission is now granted to storage subsystem to format write | |
6 | record 0 with: | |
7 | * an ID = CCHHR, where CC = physical cylinder number, | |
8 | HH = physical head number, and R = 0 | |
9 | * a key length of zero | |
10 | * a data length of eight | |
11 | * a data field containing all zeros | |
12 | ||
13 | Acked-by: John Jolly <jjolly@suse.de> | |
14 | --- | |
15 | drivers/s390/block/dasd_eckd.c | 28 +++++++++++++++++++++------- | |
16 | 1 file changed, 21 insertions(+), 7 deletions(-) | |
17 | ||
18 | Index: linux-sles11/drivers/s390/block/dasd_eckd.c | |
19 | =================================================================== | |
20 | --- linux-sles11.orig/drivers/s390/block/dasd_eckd.c | |
21 | +++ linux-sles11/drivers/s390/block/dasd_eckd.c | |
22 | @@ -1265,6 +1265,8 @@ dasd_eckd_format_device(struct dasd_devi | |
23 | int rpt, cyl, head; | |
24 | int cplength, datasize; | |
25 | int i; | |
26 | + int intensity = 0; | |
27 | + int r0_perm; | |
28 | ||
29 | private = (struct dasd_eckd_private *) device->private; | |
30 | rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize); | |
31 | @@ -1296,9 +1298,18 @@ dasd_eckd_format_device(struct dasd_devi | |
32 | * Bit 1: write home address, currently not supported | |
33 | * Bit 2: invalidate tracks | |
34 | * Bit 3: use OS/390 compatible disk layout (cdl) | |
35 | + * Bit 4: do not allow storage subsystem to modify record zero | |
36 | * Only some bit combinations do make sense. | |
37 | */ | |
38 | - switch (fdata->intensity) { | |
39 | + if (fdata->intensity & 0x10) { | |
40 | + r0_perm = 0; | |
41 | + intensity = fdata->intensity & ~0x10; | |
42 | + } else { | |
43 | + r0_perm = 1; | |
44 | + intensity = fdata->intensity; | |
45 | + } | |
46 | + | |
47 | + switch (intensity) { | |
48 | case 0x00: /* Normal format */ | |
49 | case 0x08: /* Normal format, use cdl. */ | |
50 | cplength = 2 + rpt; | |
51 | @@ -1323,7 +1334,7 @@ dasd_eckd_format_device(struct dasd_devi | |
52 | break; | |
53 | default: | |
54 | DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.", | |
55 | - fdata->intensity); | |
56 | + intensity); | |
57 | return ERR_PTR(-EINVAL); | |
58 | } | |
59 | /* Allocate the format ccw request. */ | |
60 | @@ -1335,11 +1346,14 @@ dasd_eckd_format_device(struct dasd_devi | |
61 | data = fcp->data; | |
62 | ccw = fcp->cpaddr; | |
63 | ||
64 | - switch (fdata->intensity & ~0x08) { | |
65 | + switch (intensity & ~0x08) { | |
66 | case 0x00: /* Normal format. */ | |
67 | define_extent(ccw++, (struct DE_eckd_data *) data, | |
68 | fdata->start_unit, fdata->start_unit, | |
69 | DASD_ECKD_CCW_WRITE_CKD, device); | |
70 | + /* grant subsystem permission to format R0 */ | |
71 | + if (r0_perm) | |
72 | + ((struct DE_eckd_data *)data)->ga_extended |= 0x04; | |
73 | data += sizeof(struct DE_eckd_data); | |
74 | ccw[-1].flags |= CCW_FLAG_CC; | |
75 | locate_record(ccw++, (struct LO_eckd_data *) data, | |
76 | @@ -1373,7 +1387,7 @@ dasd_eckd_format_device(struct dasd_devi | |
77 | data += sizeof(struct LO_eckd_data); | |
78 | break; | |
79 | } | |
80 | - if (fdata->intensity & 0x01) { /* write record zero */ | |
81 | + if (intensity & 0x01) { /* write record zero */ | |
82 | ect = (struct eckd_count *) data; | |
83 | data += sizeof(struct eckd_count); | |
84 | ect->cyl = cyl; | |
85 | @@ -1388,7 +1402,7 @@ dasd_eckd_format_device(struct dasd_devi | |
86 | ccw->cda = (__u32)(addr_t) ect; | |
87 | ccw++; | |
88 | } | |
89 | - if ((fdata->intensity & ~0x08) & 0x04) { /* erase track */ | |
90 | + if ((intensity & ~0x08) & 0x04) { /* erase track */ | |
91 | ect = (struct eckd_count *) data; | |
92 | data += sizeof(struct eckd_count); | |
93 | ect->cyl = cyl; | |
94 | @@ -1411,14 +1425,14 @@ dasd_eckd_format_device(struct dasd_devi | |
95 | ect->kl = 0; | |
96 | ect->dl = fdata->blksize; | |
97 | /* Check for special tracks 0-1 when formatting CDL */ | |
98 | - if ((fdata->intensity & 0x08) && | |
99 | + if ((intensity & 0x08) && | |
100 | fdata->start_unit == 0) { | |
101 | if (i < 3) { | |
102 | ect->kl = 4; | |
103 | ect->dl = sizes_trk0[i] - 4; | |
104 | } | |
105 | } | |
106 | - if ((fdata->intensity & 0x08) && | |
107 | + if ((intensity & 0x08) && | |
108 | fdata->start_unit == 1) { | |
109 | ect->kl = 44; | |
110 | ect->dl = LABEL_SIZE - 44; |