diff options
Diffstat (limited to 'drivers/s390/block/dasd_eckd.c')
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 78 |
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) /* * Generate device unique id that specifies the physical device. */ -static int dasd_eckd_generate_uid(struct dasd_device *device, - struct dasd_uid *uid) +static int dasd_eckd_generate_uid(struct dasd_device *device) { struct dasd_eckd_private *private; + struct dasd_uid *uid; int count; + unsigned long flags; private = (struct dasd_eckd_private *) device->private; if (!private) return -ENODEV; if (!private->ned || !private->gneq) return -ENODEV; - + uid = &private->uid; + spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); memset(uid, 0, sizeof(struct dasd_uid)); memcpy(uid->vendor, private->ned->HDA_manufacturer, sizeof(uid->vendor) - 1); @@ -726,9 +728,25 @@ static int dasd_eckd_generate_uid(struct dasd_device *device, private->vdsneq->uit[count]); } } + spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); return 0; } +static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid) +{ + struct dasd_eckd_private *private; + unsigned long flags; + + if (device->private) { + private = (struct dasd_eckd_private *)device->private; + spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); + *uid = private->uid; + spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); + return 0; + } + return -EINVAL; +} + static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device, void *rcd_buffer, struct ciw *ciw, __u8 lpm) @@ -1088,6 +1106,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) { struct dasd_eckd_private *private; struct dasd_block *block; + struct dasd_uid temp_uid; int is_known, rc; int readonly; @@ -1124,13 +1143,13 @@ dasd_eckd_check_characteristics(struct dasd_device *device) if (rc) goto out_err1; - /* Generate device unique id and register in devmap */ - rc = dasd_eckd_generate_uid(device, &private->uid); + /* Generate device unique id */ + rc = dasd_eckd_generate_uid(device); if (rc) goto out_err1; - dasd_set_uid(device->cdev, &private->uid); - if (private->uid.type == UA_BASE_DEVICE) { + dasd_eckd_get_uid(device, &temp_uid); + if (temp_uid.type == UA_BASE_DEVICE) { block = dasd_alloc_block(); if (IS_ERR(block)) { DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", @@ -3305,15 +3324,16 @@ static int dasd_eckd_restore_device(struct dasd_device *device) if (rc) goto out_err; - /* Generate device unique id and register in devmap */ - rc = dasd_eckd_generate_uid(device, &private->uid); - dasd_get_uid(device->cdev, &temp_uid); + dasd_eckd_get_uid(device, &temp_uid); + /* Generate device unique id */ + rc = dasd_eckd_generate_uid(device); + spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0) dev_err(&device->cdev->dev, "The UID of the DASD has " "changed\n"); + spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); if (rc) goto out_err; - dasd_set_uid(device->cdev, &private->uid); /* register lcu with alias handling, enable PAV if this is a new lcu */ is_known = dasd_alias_make_device_known_to_lcu(device); @@ -3358,42 +3378,45 @@ static int dasd_eckd_reload_device(struct dasd_device *device) { struct dasd_eckd_private *private; int rc, old_base; - char uid[60]; + char print_uid[60]; + struct dasd_uid uid; + unsigned long flags; private = (struct dasd_eckd_private *) device->private; + + spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); old_base = private->uid.base_unit_addr; + spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); + /* Read Configuration Data */ rc = dasd_eckd_read_conf(device); if (rc) goto out_err; - rc = dasd_eckd_generate_uid(device, &private->uid); + rc = dasd_eckd_generate_uid(device); if (rc) goto out_err; - - dasd_set_uid(device->cdev, &private->uid); - /* * update unit address configuration and * add device to alias management */ dasd_alias_update_add_device(device); - if (old_base != private->uid.base_unit_addr) { - if (strlen(private->uid.vduit) > 0) - snprintf(uid, 60, "%s.%s.%04x.%02x.%s", - private->uid.vendor, private->uid.serial, - private->uid.ssid, private->uid.base_unit_addr, - private->uid.vduit); + dasd_eckd_get_uid(device, &uid); + + if (old_base != uid.base_unit_addr) { + if (strlen(uid.vduit) > 0) + snprintf(print_uid, sizeof(print_uid), + "%s.%s.%04x.%02x.%s", uid.vendor, uid.serial, + uid.ssid, uid.base_unit_addr, uid.vduit); else - snprintf(uid, 60, "%s.%s.%04x.%02x", - private->uid.vendor, private->uid.serial, - private->uid.ssid, - private->uid.base_unit_addr); + snprintf(print_uid, sizeof(print_uid), + "%s.%s.%04x.%02x", uid.vendor, uid.serial, + uid.ssid, uid.base_unit_addr); dev_info(&device->cdev->dev, "An Alias device was reassigned to a new base device " - "with UID: %s\n", uid); + "with UID: %s\n", print_uid); } return 0; @@ -3455,6 +3478,7 @@ static struct dasd_discipline dasd_eckd_discipline = { .freeze = dasd_eckd_pm_freeze, .restore = dasd_eckd_restore_device, .reload = dasd_eckd_reload_device, + .get_uid = dasd_eckd_get_uid, }; static int __init |