aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Haberland <stefan.haberland@de.ibm.com>2015-10-15 07:54:39 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-11-03 08:40:46 -0500
commit251afd69e3328653bae4a8ca09700971ca4000c5 (patch)
treec1a3ba142c40d225d238e2ae28ada7b146e230e9
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>
-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)
4435 private = (struct dasd_eckd_private *) device->private; 4435 private = (struct dasd_eckd_private *) device->private;
4436 4436
4437 /* Read Configuration Data */ 4437 /* Read Configuration Data */
4438 dasd_eckd_read_conf(device); 4438 rc = dasd_eckd_read_conf(device);
4439 if (rc) {
4440 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
4441 "Read configuration data failed, rc=%d", rc);
4442 goto out_err;
4443 }
4439 4444
4440 dasd_eckd_get_uid(device, &temp_uid); 4445 dasd_eckd_get_uid(device, &temp_uid);
4441 /* Generate device unique id */ 4446 /* Generate device unique id */
@@ -4451,13 +4456,18 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
4451 /* register lcu with alias handling, enable PAV if this is a new lcu */ 4456 /* register lcu with alias handling, enable PAV if this is a new lcu */
4452 rc = dasd_alias_make_device_known_to_lcu(device); 4457 rc = dasd_alias_make_device_known_to_lcu(device);
4453 if (rc) 4458 if (rc)
4454 return rc; 4459 goto out_err;
4455 4460
4456 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr_flags); 4461 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr_flags);
4457 dasd_eckd_validate_server(device, cqr_flags); 4462 dasd_eckd_validate_server(device, cqr_flags);
4458 4463
4459 /* RE-Read Configuration Data */ 4464 /* RE-Read Configuration Data */
4460 dasd_eckd_read_conf(device); 4465 rc = dasd_eckd_read_conf(device);
4466 if (rc) {
4467 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
4468 "Read configuration data failed, rc=%d", rc);
4469 goto out_err2;
4470 }
4461 4471
4462 /* Read Feature Codes */ 4472 /* Read Feature Codes */
4463 dasd_eckd_read_features(device); 4473 dasd_eckd_read_features(device);
@@ -4468,7 +4478,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
4468 if (rc) { 4478 if (rc) {
4469 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, 4479 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
4470 "Read device characteristic failed, rc=%d", rc); 4480 "Read device characteristic failed, rc=%d", rc);
4471 goto out_err; 4481 goto out_err2;
4472 } 4482 }
4473 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 4483 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
4474 memcpy(&private->rdc_data, &temp_rdc_data, sizeof(temp_rdc_data)); 4484 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)
4479 4489
4480 return 0; 4490 return 0;
4481 4491
4492out_err2:
4493 dasd_alias_disconnect_device_from_lcu(device);
4482out_err: 4494out_err:
4483 return -1; 4495 return -1;
4484} 4496}