aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_eckd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block/dasd_eckd.c')
-rw-r--r--drivers/s390/block/dasd_eckd.c78
1 files changed, 51 insertions, 27 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 4305c23c57a4..5b1cd8d6e971 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -692,18 +692,20 @@ dasd_eckd_cdl_reclen(int recid)
692/* 692/*
693 * Generate device unique id that specifies the physical device. 693 * Generate device unique id that specifies the physical device.
694 */ 694 */
695static int dasd_eckd_generate_uid(struct dasd_device *device, 695static int dasd_eckd_generate_uid(struct dasd_device *device)
696 struct dasd_uid *uid)
697{ 696{
698 struct dasd_eckd_private *private; 697 struct dasd_eckd_private *private;
698 struct dasd_uid *uid;
699 int count; 699 int count;
700 unsigned long flags;
700 701
701 private = (struct dasd_eckd_private *) device->private; 702 private = (struct dasd_eckd_private *) device->private;
702 if (!private) 703 if (!private)
703 return -ENODEV; 704 return -ENODEV;
704 if (!private->ned || !private->gneq) 705 if (!private->ned || !private->gneq)
705 return -ENODEV; 706 return -ENODEV;
706 707 uid = &private->uid;
708 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
707 memset(uid, 0, sizeof(struct dasd_uid)); 709 memset(uid, 0, sizeof(struct dasd_uid));
708 memcpy(uid->vendor, private->ned->HDA_manufacturer, 710 memcpy(uid->vendor, private->ned->HDA_manufacturer,
709 sizeof(uid->vendor) - 1); 711 sizeof(uid->vendor) - 1);
@@ -726,9 +728,25 @@ static int dasd_eckd_generate_uid(struct dasd_device *device,
726 private->vdsneq->uit[count]); 728 private->vdsneq->uit[count]);
727 } 729 }
728 } 730 }
731 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
729 return 0; 732 return 0;
730} 733}
731 734
735static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid)
736{
737 struct dasd_eckd_private *private;
738 unsigned long flags;
739
740 if (device->private) {
741 private = (struct dasd_eckd_private *)device->private;
742 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
743 *uid = private->uid;
744 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
745 return 0;
746 }
747 return -EINVAL;
748}
749
732static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device, 750static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device,
733 void *rcd_buffer, 751 void *rcd_buffer,
734 struct ciw *ciw, __u8 lpm) 752 struct ciw *ciw, __u8 lpm)
@@ -1088,6 +1106,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1088{ 1106{
1089 struct dasd_eckd_private *private; 1107 struct dasd_eckd_private *private;
1090 struct dasd_block *block; 1108 struct dasd_block *block;
1109 struct dasd_uid temp_uid;
1091 int is_known, rc; 1110 int is_known, rc;
1092 int readonly; 1111 int readonly;
1093 1112
@@ -1124,13 +1143,13 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1124 if (rc) 1143 if (rc)
1125 goto out_err1; 1144 goto out_err1;
1126 1145
1127 /* Generate device unique id and register in devmap */ 1146 /* Generate device unique id */
1128 rc = dasd_eckd_generate_uid(device, &private->uid); 1147 rc = dasd_eckd_generate_uid(device);
1129 if (rc) 1148 if (rc)
1130 goto out_err1; 1149 goto out_err1;
1131 dasd_set_uid(device->cdev, &private->uid);
1132 1150
1133 if (private->uid.type == UA_BASE_DEVICE) { 1151 dasd_eckd_get_uid(device, &temp_uid);
1152 if (temp_uid.type == UA_BASE_DEVICE) {
1134 block = dasd_alloc_block(); 1153 block = dasd_alloc_block();
1135 if (IS_ERR(block)) { 1154 if (IS_ERR(block)) {
1136 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", 1155 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
@@ -3305,15 +3324,16 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
3305 if (rc) 3324 if (rc)
3306 goto out_err; 3325 goto out_err;
3307 3326
3308 /* Generate device unique id and register in devmap */ 3327 dasd_eckd_get_uid(device, &temp_uid);
3309 rc = dasd_eckd_generate_uid(device, &private->uid); 3328 /* Generate device unique id */
3310 dasd_get_uid(device->cdev, &temp_uid); 3329 rc = dasd_eckd_generate_uid(device);
3330 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
3311 if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0) 3331 if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0)
3312 dev_err(&device->cdev->dev, "The UID of the DASD has " 3332 dev_err(&device->cdev->dev, "The UID of the DASD has "
3313 "changed\n"); 3333 "changed\n");
3334 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
3314 if (rc) 3335 if (rc)
3315 goto out_err; 3336 goto out_err;
3316 dasd_set_uid(device->cdev, &private->uid);
3317 3337
3318 /* register lcu with alias handling, enable PAV if this is a new lcu */ 3338 /* register lcu with alias handling, enable PAV if this is a new lcu */
3319 is_known = dasd_alias_make_device_known_to_lcu(device); 3339 is_known = dasd_alias_make_device_known_to_lcu(device);
@@ -3358,42 +3378,45 @@ static int dasd_eckd_reload_device(struct dasd_device *device)
3358{ 3378{
3359 struct dasd_eckd_private *private; 3379 struct dasd_eckd_private *private;
3360 int rc, old_base; 3380 int rc, old_base;
3361 char uid[60]; 3381 char print_uid[60];
3382 struct dasd_uid uid;
3383 unsigned long flags;
3362 3384
3363 private = (struct dasd_eckd_private *) device->private; 3385 private = (struct dasd_eckd_private *) device->private;
3386
3387 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
3364 old_base = private->uid.base_unit_addr; 3388 old_base = private->uid.base_unit_addr;
3389 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
3390
3365 /* Read Configuration Data */ 3391 /* Read Configuration Data */
3366 rc = dasd_eckd_read_conf(device); 3392 rc = dasd_eckd_read_conf(device);
3367 if (rc) 3393 if (rc)
3368 goto out_err; 3394 goto out_err;
3369 3395
3370 rc = dasd_eckd_generate_uid(device, &private->uid); 3396 rc = dasd_eckd_generate_uid(device);
3371 if (rc) 3397 if (rc)
3372 goto out_err; 3398 goto out_err;
3373
3374 dasd_set_uid(device->cdev, &private->uid);
3375
3376 /* 3399 /*
3377 * update unit address configuration and 3400 * update unit address configuration and
3378 * add device to alias management 3401 * add device to alias management
3379 */ 3402 */
3380 dasd_alias_update_add_device(device); 3403 dasd_alias_update_add_device(device);
3381 3404
3382 if (old_base != private->uid.base_unit_addr) { 3405 dasd_eckd_get_uid(device, &uid);
3383 if (strlen(private->uid.vduit) > 0) 3406
3384 snprintf(uid, 60, "%s.%s.%04x.%02x.%s", 3407 if (old_base != uid.base_unit_addr) {
3385 private->uid.vendor, private->uid.serial, 3408 if (strlen(uid.vduit) > 0)
3386 private->uid.ssid, private->uid.base_unit_addr, 3409 snprintf(print_uid, sizeof(print_uid),
3387 private->uid.vduit); 3410 "%s.%s.%04x.%02x.%s", uid.vendor, uid.serial,
3411 uid.ssid, uid.base_unit_addr, uid.vduit);
3388 else 3412 else
3389 snprintf(uid, 60, "%s.%s.%04x.%02x", 3413 snprintf(print_uid, sizeof(print_uid),
3390 private->uid.vendor, private->uid.serial, 3414 "%s.%s.%04x.%02x", uid.vendor, uid.serial,
3391 private->uid.ssid, 3415 uid.ssid, uid.base_unit_addr);
3392 private->uid.base_unit_addr);
3393 3416
3394 dev_info(&device->cdev->dev, 3417 dev_info(&device->cdev->dev,
3395 "An Alias device was reassigned to a new base device " 3418 "An Alias device was reassigned to a new base device "
3396 "with UID: %s\n", uid); 3419 "with UID: %s\n", print_uid);
3397 } 3420 }
3398 return 0; 3421 return 0;
3399 3422
@@ -3455,6 +3478,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
3455 .freeze = dasd_eckd_pm_freeze, 3478 .freeze = dasd_eckd_pm_freeze,
3456 .restore = dasd_eckd_restore_device, 3479 .restore = dasd_eckd_restore_device,
3457 .reload = dasd_eckd_reload_device, 3480 .reload = dasd_eckd_reload_device,
3481 .get_uid = dasd_eckd_get_uid,
3458}; 3482};
3459 3483
3460static int __init 3484static int __init