summaryrefslogtreecommitdiff
path: root/drivers/s390/block
diff options
context:
space:
mode:
authorStefan Haberland <stefan.haberland@de.ibm.com>2015-10-15 13:54:39 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-11-03 14:40:46 +0100
commit251afd69e3328653bae4a8ca09700971ca4000c5 (patch)
treec1a3ba142c40d225d238e2ae28ada7b146e230e9 /drivers/s390/block
parentc7c0c9deb0a4b0715d2c09438420437b86f387c4 (diff)
s390/dasd: fix invalid PAV assignment after suspend/resume
For a valid PAV assignment the DASD driver needs to notice possibly changed configuration data. Thus the failing of read configuration data should also fail the device restore to prevent invalid PAV assignment. The failed device may get restored after additional paths get available later on. If the restore fails after the device was added to the lcu alias handling it needs to be removed from the alias handling before exiting the restore function. Reviewed-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Stefan Haberland <stefan.haberland@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.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index e53b895a4d0f..3d929abb52c7 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -4435,7 +4435,12 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
private = (struct dasd_eckd_private *) device->private;
/* Read Configuration Data */
- dasd_eckd_read_conf(device);
+ rc = dasd_eckd_read_conf(device);
+ if (rc) {
+ DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+ "Read configuration data failed, rc=%d", rc);
+ goto out_err;
+ }
dasd_eckd_get_uid(device, &temp_uid);
/* Generate device unique id */
@@ -4451,13 +4456,18 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
/* register lcu with alias handling, enable PAV if this is a new lcu */
rc = dasd_alias_make_device_known_to_lcu(device);
if (rc)
- return rc;
+ goto out_err;
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr_flags);
dasd_eckd_validate_server(device, cqr_flags);
/* RE-Read Configuration Data */
- dasd_eckd_read_conf(device);
+ rc = dasd_eckd_read_conf(device);
+ if (rc) {
+ DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
+ "Read configuration data failed, rc=%d", rc);
+ goto out_err2;
+ }
/* Read Feature Codes */
dasd_eckd_read_features(device);
@@ -4468,7 +4478,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
if (rc) {
DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
"Read device characteristic failed, rc=%d", rc);
- goto out_err;
+ goto out_err2;
}
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
memcpy(&private->rdc_data, &temp_rdc_data, sizeof(temp_rdc_data));
@@ -4479,6 +4489,8 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
return 0;
+out_err2:
+ dasd_alias_disconnect_device_from_lcu(device);
out_err:
return -1;
}