[S390] dasd: support DIAG access for read-only devices
authorStefan Weinhuber <wein@de.ibm.com>
Mon, 7 Dec 2009 11:51:48 +0000 (12:51 +0100)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>
Mon, 7 Dec 2009 11:51:34 +0000 (12:51 +0100)
When a DASD device is used with the DIAG discipline, the DIAG
initialization will indicate success or error with a respective
return code. So far we have interpreted a return code of 4 as error,
but it actually means that the initialization was successful, but
the device is read-only. To allow read-only devices to be used with
DIAG we need to accept a return code of 4 as success.

Re-initialization of the DIAG access is also part of the DIAG error
recovery. If we find that the access mode of a device has been
changed from writable to read-only while the device was in use,
we print an error message.

Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/block/dasd_diag.c

index 4e49b4a6c880dce04d2599982846143050f40e61..8174ec92176954864696ead10b799b6a42238fd9 100644 (file)
@@ -145,6 +145,15 @@ dasd_diag_erp(struct dasd_device *device)
 
        mdsk_term_io(device);
        rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
+       if (rc == 4) {
+               if (!(device->features & DASD_FEATURE_READONLY)) {
+                       dev_warn(&device->cdev->dev,
+                                "The access mode of a DIAG device changed"
+                                " to read-only");
+                       device->features |= DASD_FEATURE_READONLY;
+               }
+               rc = 0;
+       }
        if (rc)
                dev_warn(&device->cdev->dev, "DIAG ERP failed with "
                            "rc=%d\n", rc);
@@ -433,16 +442,20 @@ dasd_diag_check_device(struct dasd_device *device)
        for (sb = 512; sb < bsize; sb = sb << 1)
                block->s2b_shift++;
        rc = mdsk_init_io(device, block->bp_block, 0, NULL);
-       if (rc) {
+       if (rc && (rc != 4)) {
                dev_warn(&device->cdev->dev, "DIAG initialization "
                        "failed with rc=%d\n", rc);
                rc = -EIO;
        } else {
+               if (rc == 4)
+                       device->features |= DASD_FEATURE_READONLY;
                dev_info(&device->cdev->dev,
-                        "New DASD with %ld byte/block, total size %ld KB\n",
+                        "New DASD with %ld byte/block, total size %ld KB%s\n",
                         (unsigned long) block->bp_block,
                         (unsigned long) (block->blocks <<
-                                         block->s2b_shift) >> 1);
+                                         block->s2b_shift) >> 1,
+                        (rc == 4) ? ", read-only device" : "");
+               rc = 0;
        }
 out_label:
        free_page((long) label);