aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Baptiste Joret <joret@de.ibm.com>2009-03-26 10:23:46 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-03-26 10:24:04 -0400
commitf9a28f7bc5225af476f8d4bb669038da8801b7c4 (patch)
tree1e441451b99e6076f008568426e9e0155097cf0f
parent0000d031703c33b9ea909ad81f03762db66135e1 (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>
-rw-r--r--drivers/s390/block/dasd_eckd.c25
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;