diff options
author | Jean-Baptiste Joret <joret@de.ibm.com> | 2009-03-26 10:23:46 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-03-26 10:24:04 -0400 |
commit | f9a28f7bc5225af476f8d4bb669038da8801b7c4 (patch) | |
tree | 1e441451b99e6076f008568426e9e0155097cf0f /drivers/s390/block | |
parent | 0000d031703c33b9ea909ad81f03762db66135e1 (diff) |
[S390] dasd_eckd / Write format R0 is now allowed BB
Permission is now granted to the subsystem to format write R0 with:
* an ID = CCHHR, where CC = physical cylinder number,
HH = physical head number, and R = 0
* a key length of zero
* a data length of eight
* a data field containing all zeros
Signed-off-by: Jean-Baptiste Joret <joret@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block')
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index bdb87998f364..0eb5e5888c42 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1265,6 +1265,8 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
1265 | int rpt, cyl, head; | 1265 | int rpt, cyl, head; |
1266 | int cplength, datasize; | 1266 | int cplength, datasize; |
1267 | int i; | 1267 | int i; |
1268 | int intensity = 0; | ||
1269 | int r0_perm; | ||
1268 | 1270 | ||
1269 | private = (struct dasd_eckd_private *) device->private; | 1271 | private = (struct dasd_eckd_private *) device->private; |
1270 | rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize); | 1272 | rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize); |
@@ -1296,9 +1298,17 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
1296 | * Bit 1: write home address, currently not supported | 1298 | * Bit 1: write home address, currently not supported |
1297 | * Bit 2: invalidate tracks | 1299 | * Bit 2: invalidate tracks |
1298 | * Bit 3: use OS/390 compatible disk layout (cdl) | 1300 | * Bit 3: use OS/390 compatible disk layout (cdl) |
1301 | * Bit 4: do not allow storage subsystem to modify record zero | ||
1299 | * Only some bit combinations do make sense. | 1302 | * Only some bit combinations do make sense. |
1300 | */ | 1303 | */ |
1301 | switch (fdata->intensity) { | 1304 | if (fdata->intensity & 0x10) { |
1305 | r0_perm = 0; | ||
1306 | intensity = fdata->intensity & ~0x10; | ||
1307 | } else { | ||
1308 | r0_perm = 1; | ||
1309 | intensity = fdata->intensity; | ||
1310 | } | ||
1311 | switch (intensity) { | ||
1302 | case 0x00: /* Normal format */ | 1312 | case 0x00: /* Normal format */ |
1303 | case 0x08: /* Normal format, use cdl. */ | 1313 | case 0x08: /* Normal format, use cdl. */ |
1304 | cplength = 2 + rpt; | 1314 | cplength = 2 + rpt; |
@@ -1335,11 +1345,14 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
1335 | data = fcp->data; | 1345 | data = fcp->data; |
1336 | ccw = fcp->cpaddr; | 1346 | ccw = fcp->cpaddr; |
1337 | 1347 | ||
1338 | switch (fdata->intensity & ~0x08) { | 1348 | switch (intensity & ~0x08) { |
1339 | case 0x00: /* Normal format. */ | 1349 | case 0x00: /* Normal format. */ |
1340 | define_extent(ccw++, (struct DE_eckd_data *) data, | 1350 | define_extent(ccw++, (struct DE_eckd_data *) data, |
1341 | fdata->start_unit, fdata->start_unit, | 1351 | fdata->start_unit, fdata->start_unit, |
1342 | DASD_ECKD_CCW_WRITE_CKD, device); | 1352 | DASD_ECKD_CCW_WRITE_CKD, device); |
1353 | /* grant subsystem permission to format R0 */ | ||
1354 | if (r0_perm) | ||
1355 | ((struct DE_eckd_data *)data)->ga_extended |= 0x04; | ||
1343 | data += sizeof(struct DE_eckd_data); | 1356 | data += sizeof(struct DE_eckd_data); |
1344 | ccw[-1].flags |= CCW_FLAG_CC; | 1357 | ccw[-1].flags |= CCW_FLAG_CC; |
1345 | locate_record(ccw++, (struct LO_eckd_data *) data, | 1358 | locate_record(ccw++, (struct LO_eckd_data *) data, |
@@ -1373,7 +1386,7 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
1373 | data += sizeof(struct LO_eckd_data); | 1386 | data += sizeof(struct LO_eckd_data); |
1374 | break; | 1387 | break; |
1375 | } | 1388 | } |
1376 | if (fdata->intensity & 0x01) { /* write record zero */ | 1389 | if (intensity & 0x01) { /* write record zero */ |
1377 | ect = (struct eckd_count *) data; | 1390 | ect = (struct eckd_count *) data; |
1378 | data += sizeof(struct eckd_count); | 1391 | data += sizeof(struct eckd_count); |
1379 | ect->cyl = cyl; | 1392 | ect->cyl = cyl; |
@@ -1388,7 +1401,7 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
1388 | ccw->cda = (__u32)(addr_t) ect; | 1401 | ccw->cda = (__u32)(addr_t) ect; |
1389 | ccw++; | 1402 | ccw++; |
1390 | } | 1403 | } |
1391 | if ((fdata->intensity & ~0x08) & 0x04) { /* erase track */ | 1404 | if ((intensity & ~0x08) & 0x04) { /* erase track */ |
1392 | ect = (struct eckd_count *) data; | 1405 | ect = (struct eckd_count *) data; |
1393 | data += sizeof(struct eckd_count); | 1406 | data += sizeof(struct eckd_count); |
1394 | ect->cyl = cyl; | 1407 | ect->cyl = cyl; |
@@ -1411,14 +1424,14 @@ dasd_eckd_format_device(struct dasd_device * device, | |||
1411 | ect->kl = 0; | 1424 | ect->kl = 0; |
1412 | ect->dl = fdata->blksize; | 1425 | ect->dl = fdata->blksize; |
1413 | /* Check for special tracks 0-1 when formatting CDL */ | 1426 | /* Check for special tracks 0-1 when formatting CDL */ |
1414 | if ((fdata->intensity & 0x08) && | 1427 | if ((intensity & 0x08) && |
1415 | fdata->start_unit == 0) { | 1428 | fdata->start_unit == 0) { |
1416 | if (i < 3) { | 1429 | if (i < 3) { |
1417 | ect->kl = 4; | 1430 | ect->kl = 4; |
1418 | ect->dl = sizes_trk0[i] - 4; | 1431 | ect->dl = sizes_trk0[i] - 4; |
1419 | } | 1432 | } |
1420 | } | 1433 | } |
1421 | if ((fdata->intensity & 0x08) && | 1434 | if ((intensity & 0x08) && |
1422 | fdata->start_unit == 1) { | 1435 | fdata->start_unit == 1) { |
1423 | ect->kl = 44; | 1436 | ect->kl = 44; |
1424 | ect->dl = LABEL_SIZE - 44; | 1437 | ect->dl = LABEL_SIZE - 44; |