From 91978465b1e5f89025cd43cd2102943160ec6dee Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Mon, 30 Aug 2010 10:55:09 +0200 Subject: [SCSI] zfcp: Reorder registration of initial SCSI device Make sure that the rport registration did complete and then register SCSI device directly. Otherwise the unit_enqueue would race with the call to zfcp_scsi_queue_unit_register. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_aux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 96fa1f53639..68df57157d4 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -73,13 +73,14 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) if (!port) goto out_port; + flush_work(&port->rport_work); unit = zfcp_unit_enqueue(port, lun); if (IS_ERR(unit)) goto out_unit; zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL); zfcp_erp_wait(adapter); - flush_work(&unit->scsi_work); + zfcp_scsi_scan(unit); out_unit: put_device(&port->dev); -- cgit v1.2.3-18-g5258 From 57c237731b92fadc7d44824276313ec330b1989b Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:39:51 +0200 Subject: [SCSI] zfcp: Add zfcp private struct as SCSI device driver data Add a new data structure zfcp_scsi_dev that holds zfcp private data for each SCSI device. Use scsi_transport_reserve_device to let the SCSI midlayer automatically allocate this with each SCSI device. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_aux.c | 3 +++ drivers/s390/scsi/zfcp_def.h | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 68df57157d4..5c4b874591e 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -159,6 +159,9 @@ static int __init zfcp_module_init(void) fc_attach_transport(&zfcp_transport_functions); if (!zfcp_data.scsi_transport_template) goto out_transport; + scsi_transport_reserve_device(zfcp_data.scsi_transport_template, + sizeof(struct zfcp_scsi_dev)); + retval = misc_register(&zfcp_cfdc_misc); if (retval) { diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index e1c6b6e05a7..d31158c0de9 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -233,6 +233,45 @@ struct zfcp_unit { struct work_struct scsi_work; }; +/** + * struct zfcp_scsi_dev - zfcp data per SCSI device + * @status: zfcp internal status flags + * @lun_handle: handle from "open lun" for issuing FSF requests + * @erp_action: zfcp erp data for opening and recovering this LUN + * @erp_counter: zfcp erp counter for this LUN + * @latencies: FSF channel and fabric latencies + * @port: zfcp_port where this LUN belongs to + */ +struct zfcp_scsi_dev { + atomic_t status; + u32 lun_handle; + struct zfcp_erp_action erp_action; + atomic_t erp_counter; + struct zfcp_latencies latencies; + struct zfcp_port *port; +}; + +/** + * sdev_to_zfcp - Access zfcp LUN data for SCSI device + * @sdev: scsi_device where to get the zfcp_scsi_dev pointer + */ +static inline struct zfcp_scsi_dev *sdev_to_zfcp(struct scsi_device *sdev) +{ + return scsi_transport_device_data(sdev); +} + +/** + * zfcp_scsi_dev_lun - Return SCSI device LUN as 64 bit FCP LUN + * @sdev: SCSI device where to get the LUN from + */ +static inline u64 zfcp_scsi_dev_lun(struct scsi_device *sdev) +{ + u64 fcp_lun; + + int_to_scsilun(sdev->lun, (struct scsi_lun *)&fcp_lun); + return fcp_lun; +} + /** * struct zfcp_fsf_req - basic FSF request structure * @list: list of FSF requests -- cgit v1.2.3-18-g5258 From 1daa4eb50fa5cd4c8f9c55452606e786fd42053b Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:39:52 +0200 Subject: [SCSI] zfcp: Move code for managing zfcp_unit devices to new file Move the code for managing zfcp_unit devices to the new file zfcp_unit.c. This is in preparation for the change that zfcp_unit will only track the LUNs configured via unit_add, other data will be moved from zfcp_unit to the new struct zfcp_scsi_dev. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/Makefile | 5 +- drivers/s390/scsi/zfcp_aux.c | 122 +------------------- drivers/s390/scsi/zfcp_ext.h | 13 ++- drivers/s390/scsi/zfcp_scsi.c | 41 +------ drivers/s390/scsi/zfcp_sysfs.c | 56 ++------- drivers/s390/scsi/zfcp_unit.c | 255 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 279 insertions(+), 213 deletions(-) create mode 100644 drivers/s390/scsi/zfcp_unit.c (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index cb301cc6178..c454ffebb63 100644 --- a/drivers/s390/scsi/Makefile +++ b/drivers/s390/scsi/Makefile @@ -2,7 +2,8 @@ # Makefile for the S/390 specific device drivers # -zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \ - zfcp_fsf.o zfcp_dbf.o zfcp_sysfs.o zfcp_fc.o zfcp_cfdc.o +zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_cfdc.o zfcp_dbf.o zfcp_erp.o \ + zfcp_fc.o zfcp_fsf.o zfcp_qdio.o zfcp_scsi.o zfcp_sysfs.o \ + zfcp_unit.o obj-$(CONFIG_ZFCP) += zfcp.o diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 5c4b874591e..044fb22718d 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -56,7 +56,6 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) struct ccw_device *cdev; struct zfcp_adapter *adapter; struct zfcp_port *port; - struct zfcp_unit *unit; cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); if (!cdev) @@ -72,18 +71,11 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) port = zfcp_get_port_by_wwpn(adapter, wwpn); if (!port) goto out_port; - flush_work(&port->rport_work); - unit = zfcp_unit_enqueue(port, lun); - if (IS_ERR(unit)) - goto out_unit; - - zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL); - zfcp_erp_wait(adapter); - zfcp_scsi_scan(unit); -out_unit: + zfcp_unit_add(port, lun); put_device(&port->dev); + out_port: zfcp_ccw_adapter_put(adapter); out_ccw_device: @@ -214,30 +206,6 @@ static void __exit zfcp_module_exit(void) module_exit(zfcp_module_exit); -/** - * zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN - * @port: pointer to port to search for unit - * @fcp_lun: FCP LUN to search for - * - * Returns: pointer to zfcp_unit or NULL - */ -struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun) -{ - unsigned long flags; - struct zfcp_unit *unit; - - read_lock_irqsave(&port->unit_list_lock, flags); - list_for_each_entry(unit, &port->unit_list, list) - if (unit->fcp_lun == fcp_lun) { - if (!get_device(&unit->dev)) - unit = NULL; - read_unlock_irqrestore(&port->unit_list_lock, flags); - return unit; - } - read_unlock_irqrestore(&port->unit_list_lock, flags); - return NULL; -} - /** * zfcp_get_port_by_wwpn - find port in port list of adapter by wwpn * @adapter: pointer to adapter to search for port @@ -263,92 +231,6 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter, return NULL; } -/** - * zfcp_unit_release - dequeue unit - * @dev: pointer to device - * - * waits until all work is done on unit and removes it then from the unit->list - * of the associated port. - */ -static void zfcp_unit_release(struct device *dev) -{ - struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev); - - put_device(&unit->port->dev); - kfree(unit); -} - -/** - * zfcp_unit_enqueue - enqueue unit to unit list of a port. - * @port: pointer to port where unit is added - * @fcp_lun: FCP LUN of unit to be enqueued - * Returns: pointer to enqueued unit on success, ERR_PTR on error - * - * Sets up some unit internal structures and creates sysfs entry. - */ -struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun) -{ - struct zfcp_unit *unit; - int retval = -ENOMEM; - - get_device(&port->dev); - - unit = zfcp_get_unit_by_lun(port, fcp_lun); - if (unit) { - put_device(&unit->dev); - retval = -EEXIST; - goto err_out; - } - - unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL); - if (!unit) - goto err_out; - - unit->port = port; - unit->fcp_lun = fcp_lun; - unit->dev.parent = &port->dev; - unit->dev.release = zfcp_unit_release; - - if (dev_set_name(&unit->dev, "0x%016llx", - (unsigned long long) fcp_lun)) { - kfree(unit); - goto err_out; - } - retval = -EINVAL; - - INIT_WORK(&unit->scsi_work, zfcp_scsi_scan_work); - - spin_lock_init(&unit->latencies.lock); - unit->latencies.write.channel.min = 0xFFFFFFFF; - unit->latencies.write.fabric.min = 0xFFFFFFFF; - unit->latencies.read.channel.min = 0xFFFFFFFF; - unit->latencies.read.fabric.min = 0xFFFFFFFF; - unit->latencies.cmd.channel.min = 0xFFFFFFFF; - unit->latencies.cmd.fabric.min = 0xFFFFFFFF; - - if (device_register(&unit->dev)) { - put_device(&unit->dev); - goto err_out; - } - - if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs)) - goto err_out_put; - - write_lock_irq(&port->unit_list_lock); - list_add_tail(&unit->list, &port->unit_list); - write_unlock_irq(&port->unit_list_lock); - - atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status); - - return unit; - -err_out_put: - device_unregister(&unit->dev); -err_out: - put_device(&port->dev); - return ERR_PTR(retval); -} - static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter) { adapter->pool.erp_req = diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 3b93239c6f6..5c3966eaca5 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -15,12 +15,10 @@ #include "zfcp_fc.h" /* zfcp_aux.c */ -extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64); extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64); extern struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *); extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32, u32); -extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64); extern void zfcp_sg_free_table(struct scatterlist *, int); extern int zfcp_sg_setup_table(struct scatterlist *, int); extern void zfcp_device_unregister(struct device *, @@ -163,8 +161,6 @@ extern void zfcp_scsi_rport_work(struct work_struct *); extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *); extern void zfcp_scsi_schedule_rport_block(struct zfcp_port *); extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *); -extern void zfcp_scsi_scan(struct zfcp_unit *); -extern void zfcp_scsi_scan_work(struct work_struct *); extern void zfcp_scsi_set_prot(struct zfcp_adapter *); extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int); @@ -175,4 +171,13 @@ extern struct attribute_group zfcp_sysfs_port_attrs; extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; extern struct device_attribute *zfcp_sysfs_shost_attrs[]; +/* zfcp_unit.c */ +extern int zfcp_unit_add(struct zfcp_port *, u64); +extern int zfcp_unit_remove(struct zfcp_port *, u64); +extern struct zfcp_unit *zfcp_unit_find(struct zfcp_port *, u64); +extern struct scsi_device *zfcp_unit_sdev(struct zfcp_unit *unit); +extern void zfcp_unit_scsi_scan(struct zfcp_unit *); +extern void zfcp_unit_queue_scsi_scan(struct zfcp_port *); +extern unsigned int zfcp_unit_sdev_status(struct zfcp_unit *); + #endif /* ZFCP_EXT_H */ diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index cb000c9833b..03837797c45 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -144,7 +144,7 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter, list_for_each_entry(port, &adapter->port_list, list) { if (!port->rport || (id != port->rport->scsi_target_id)) continue; - unit = zfcp_get_unit_by_lun(port, lun); + unit = zfcp_unit_find(port, lun); if (unit) break; } @@ -534,20 +534,6 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport) } } -static void zfcp_scsi_queue_unit_register(struct zfcp_port *port) -{ - struct zfcp_unit *unit; - - read_lock_irq(&port->unit_list_lock); - list_for_each_entry(unit, &port->unit_list, list) { - get_device(&unit->dev); - if (scsi_queue_work(port->adapter->scsi_host, - &unit->scsi_work) <= 0) - put_device(&unit->dev); - } - read_unlock_irq(&port->unit_list_lock); -} - static void zfcp_scsi_rport_register(struct zfcp_port *port) { struct fc_rport_identifiers ids; @@ -574,7 +560,7 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port) port->rport = rport; port->starget_id = rport->scsi_target_id; - zfcp_scsi_queue_unit_register(port); + zfcp_unit_queue_scsi_scan(port); } static void zfcp_scsi_rport_block(struct zfcp_port *port) @@ -637,29 +623,6 @@ void zfcp_scsi_rport_work(struct work_struct *work) put_device(&port->dev); } -/** - * zfcp_scsi_scan - Register LUN with SCSI midlayer - * @unit: The LUN/unit to register - */ -void zfcp_scsi_scan(struct zfcp_unit *unit) -{ - struct fc_rport *rport = unit->port->rport; - - if (rport && rport->port_state == FC_PORTSTATE_ONLINE) - scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, - scsilun_to_int((struct scsi_lun *) - &unit->fcp_lun), 0); -} - -void zfcp_scsi_scan_work(struct work_struct *work) -{ - struct zfcp_unit *unit = container_of(work, struct zfcp_unit, - scsi_work); - - zfcp_scsi_scan(unit); - put_device(&unit->dev); -} - /** * zfcp_scsi_set_prot - Configure DIF/DIX support in scsi_host * @adapter: The adapter where to configure DIF/DIX for the SCSI host diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index b4561c86e23..56c46e09d2d 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -257,28 +257,15 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, const char *buf, size_t count) { struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); - struct zfcp_unit *unit; u64 fcp_lun; - int retval = -EINVAL; - - if (!(port && get_device(&port->dev))) - return -EBUSY; if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) - goto out; + return -EINVAL; - unit = zfcp_unit_enqueue(port, fcp_lun); - if (IS_ERR(unit)) - goto out; - else - retval = 0; + if (zfcp_unit_add(port, fcp_lun)) + return -EINVAL; - zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); - zfcp_erp_wait(unit->port->adapter); - zfcp_scsi_scan(unit); -out: - put_device(&port->dev); - return retval ? retval : (ssize_t) count; + return count; } static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store); @@ -287,42 +274,15 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, const char *buf, size_t count) { struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); - struct zfcp_unit *unit; u64 fcp_lun; - int retval = -EINVAL; - struct scsi_device *sdev; - - if (!(port && get_device(&port->dev))) - return -EBUSY; if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) - goto out; - - unit = zfcp_get_unit_by_lun(port, fcp_lun); - if (!unit) - goto out; - else - retval = 0; + return -EINVAL; - sdev = scsi_device_lookup(port->adapter->scsi_host, 0, - port->starget_id, - scsilun_to_int((struct scsi_lun *)&fcp_lun)); - if (sdev) { - scsi_remove_device(sdev); - scsi_device_put(sdev); - } + if (zfcp_unit_remove(port, fcp_lun)) + return -EINVAL; - write_lock_irq(&port->unit_list_lock); - list_del(&unit->list); - write_unlock_irq(&port->unit_list_lock); - - put_device(&unit->dev); - - zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); - zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); -out: - put_device(&port->dev); - return retval ? retval : (ssize_t) count; + return count; } static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c new file mode 100644 index 00000000000..e210c41ee38 --- /dev/null +++ b/drivers/s390/scsi/zfcp_unit.c @@ -0,0 +1,255 @@ +/* + * zfcp device driver + * + * Tracking of manually configured LUNs and helper functions to + * register the LUNs with the SCSI midlayer. + * + * Copyright IBM Corporation 2010 + */ + +#include "zfcp_def.h" +#include "zfcp_ext.h" + +/** + * zfcp_unit_scsi_scan - Register LUN with SCSI midlayer + * @unit: The zfcp LUN/unit to register + * + * When the SCSI midlayer is not allowed to automatically scan and + * attach SCSI devices, zfcp has to register the single devices with + * the SCSI midlayer. + */ +void zfcp_unit_scsi_scan(struct zfcp_unit *unit) +{ + struct fc_rport *rport = unit->port->rport; + unsigned int lun; + + lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun); + + if (rport && rport->port_state == FC_PORTSTATE_ONLINE) + scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, lun, 1); +} + +static void zfcp_unit_scsi_scan_work(struct work_struct *work) +{ + struct zfcp_unit *unit = container_of(work, struct zfcp_unit, + scsi_work); + + zfcp_unit_scsi_scan(unit); + put_device(&unit->dev); +} + +/** + * zfcp_unit_queue_scsi_scan - Register configured units on port + * @port: The zfcp_port where to register units + * + * After opening a port, all units configured on this port have to be + * registered with the SCSI midlayer. This function should be called + * after calling fc_remote_port_add, so that the fc_rport is already + * ONLINE and the call to scsi_scan_target runs the same way as the + * call in the FC transport class. + */ +void zfcp_unit_queue_scsi_scan(struct zfcp_port *port) +{ + struct zfcp_unit *unit; + + read_lock_irq(&port->unit_list_lock); + list_for_each_entry(unit, &port->unit_list, list) { + get_device(&unit->dev); + if (scsi_queue_work(port->adapter->scsi_host, + &unit->scsi_work) <= 0) + put_device(&unit->dev); + } + read_unlock_irq(&port->unit_list_lock); +} + +static struct zfcp_unit *_zfcp_unit_find(struct zfcp_port *port, u64 fcp_lun) +{ + struct zfcp_unit *unit; + + list_for_each_entry(unit, &port->unit_list, list) + if (unit->fcp_lun == fcp_lun) { + get_device(&unit->dev); + return unit; + } + + return NULL; +} + +/** + * zfcp_unit_find - Find and return zfcp_unit with specified FCP LUN + * @port: zfcp_port where to look for the unit + * @fcp_lun: 64 Bit FCP LUN used to identify the zfcp_unit + * + * If zfcp_unit is found, a reference is acquired that has to be + * released later. + * + * Returns: Pointer to the zfcp_unit, or NULL if there is no zfcp_unit + * with the specified FCP LUN. + */ +struct zfcp_unit *zfcp_unit_find(struct zfcp_port *port, u64 fcp_lun) +{ + struct zfcp_unit *unit; + + read_lock_irq(&port->unit_list_lock); + unit = _zfcp_unit_find(port, fcp_lun); + read_unlock_irq(&port->unit_list_lock); + return unit; +} + +/** + * zfcp_unit_release - Drop reference to zfcp_port and free memory of zfcp_unit. + * @dev: pointer to device in zfcp_unit + */ +static void zfcp_unit_release(struct device *dev) +{ + struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev); + + put_device(&unit->port->dev); + kfree(unit); +} + +/** + * zfcp_unit_enqueue - enqueue unit to unit list of a port. + * @port: pointer to port where unit is added + * @fcp_lun: FCP LUN of unit to be enqueued + * Returns: 0 success + * + * Sets up some unit internal structures and creates sysfs entry. + */ +int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun) +{ + struct zfcp_unit *unit; + + unit = zfcp_unit_find(port, fcp_lun); + if (unit) { + put_device(&unit->dev); + return -EEXIST; + } + + unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL); + if (!unit) + return -ENOMEM; + + unit->port = port; + unit->fcp_lun = fcp_lun; + unit->dev.parent = &port->dev; + unit->dev.release = zfcp_unit_release; + unit->latencies.write.channel.min = 0xFFFFFFFF; + unit->latencies.write.fabric.min = 0xFFFFFFFF; + unit->latencies.read.channel.min = 0xFFFFFFFF; + unit->latencies.read.fabric.min = 0xFFFFFFFF; + unit->latencies.cmd.channel.min = 0xFFFFFFFF; + unit->latencies.cmd.fabric.min = 0xFFFFFFFF; + INIT_WORK(&unit->scsi_work, zfcp_unit_scsi_scan_work); + spin_lock_init(&unit->latencies.lock); + + if (dev_set_name(&unit->dev, "0x%016llx", + (unsigned long long) fcp_lun)) { + kfree(unit); + return -ENOMEM; + } + + if (device_register(&unit->dev)) { + put_device(&unit->dev); + return -ENOMEM; + } + + if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs)) { + device_unregister(&unit->dev); + return -EINVAL; + } + + get_device(&port->dev); + + write_lock_irq(&port->unit_list_lock); + list_add_tail(&unit->list, &port->unit_list); + write_unlock_irq(&port->unit_list_lock); + + atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status); + zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); + zfcp_erp_wait(unit->port->adapter); + zfcp_unit_scsi_scan(unit); + + return 0; +} + +/** + * zfcp_unit_sdev - Return SCSI device for zfcp_unit + * @unit: The zfcp_unit where to get the SCSI device for + * + * Returns: scsi_device pointer on success, NULL if there is no SCSI + * device for this zfcp_unit + * + * On success, the caller also holds a reference to the SCSI device + * that must be released with scsi_device_put. + */ +struct scsi_device *zfcp_unit_sdev(struct zfcp_unit *unit) +{ + struct Scsi_Host *shost; + struct zfcp_port *port; + unsigned int lun; + + lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun); + port = unit->port; + shost = port->adapter->scsi_host; + return scsi_device_lookup(shost, 0, port->starget_id, lun); +} + +/** + * zfcp_unit_sdev_status - Return zfcp LUN status for SCSI device + * @unit: The unit to lookup the SCSI device for + * + * Returns the zfcp LUN status field of the SCSI device if the SCSI device + * for the zfcp_unit exists, 0 otherwise. + */ +unsigned int zfcp_unit_sdev_status(struct zfcp_unit *unit) +{ + unsigned int status = 0; + struct scsi_device *sdev; + struct zfcp_scsi_dev *zfcp_sdev; + + sdev = zfcp_unit_sdev(unit); + if (sdev) { + zfcp_sdev = sdev_to_zfcp(sdev); + status = atomic_read(&zfcp_sdev->status); + scsi_device_put(sdev); + } + + return status; +} + +/** + * zfcp_unit_remove - Remove entry from list of configured units + * @port: The port where to remove the unit from the configuration + * @fcp_lun: The 64 bit LUN of the unit to remove + * + * Returns: -EINVAL if a unit with the specified LUN does not exist, + * 0 on success. + */ +int zfcp_unit_remove(struct zfcp_port *port, u64 fcp_lun) +{ + struct zfcp_unit *unit; + struct scsi_device *sdev; + + write_lock_irq(&port->unit_list_lock); + unit = _zfcp_unit_find(port, fcp_lun); + if (unit) + list_del(&unit->list); + write_unlock_irq(&port->unit_list_lock); + + if (!unit) + return -EINVAL; + + sdev = zfcp_unit_sdev(unit); + if (sdev) { + scsi_remove_device(sdev); + scsi_device_put(sdev); + } + + put_device(&unit->dev); + + zfcp_erp_unit_shutdown(unit, 0, "unrem_1", NULL); + zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); + + return 0; +} -- cgit v1.2.3-18-g5258 From e4b9857fe628b453983cac89473a11a76a1f5786 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:39:53 +0200 Subject: [SCSI] zfcp: Remove ZFCP_SYSFS_FAILED macro and implement fcp_lun_show without macro These sysfs attributes will require different functions. Implement them without using macros, so that the open coded functions can be changed later. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_sysfs.c | 121 ++++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 44 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 56c46e09d2d..6b43bc46bf9 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -82,49 +82,73 @@ ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_readonly, "%d\n", (atomic_read(&unit->status) & ZFCP_STATUS_UNIT_READONLY) != 0); -#define ZFCP_SYSFS_FAILED(_feat_def, _feat, _adapter, _mod_id, _reopen_id) \ -static ssize_t zfcp_sysfs_##_feat##_failed_show(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct _feat_def *_feat = container_of(dev, struct _feat_def, dev); \ - \ - if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_ERP_FAILED) \ - return sprintf(buf, "1\n"); \ - else \ - return sprintf(buf, "0\n"); \ -} \ -static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev, \ - struct device_attribute *attr,\ - const char *buf, size_t count)\ -{ \ - struct _feat_def *_feat = container_of(dev, struct _feat_def, dev); \ - unsigned long val; \ - int retval = 0; \ - \ - if (!(_feat && get_device(&_feat->dev))) \ - return -EBUSY; \ - \ - if (strict_strtoul(buf, 0, &val) || val != 0) { \ - retval = -EINVAL; \ - goto out; \ - } \ - \ - zfcp_erp_modify_##_feat##_status(_feat, _mod_id, NULL, \ - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);\ - zfcp_erp_##_feat##_reopen(_feat, ZFCP_STATUS_COMMON_ERP_FAILED, \ - _reopen_id, NULL); \ - zfcp_erp_wait(_adapter); \ -out: \ - put_device(&_feat->dev); \ - return retval ? retval : (ssize_t) count; \ -} \ -static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \ - zfcp_sysfs_##_feat##_failed_show, \ - zfcp_sysfs_##_feat##_failed_store); +static ssize_t zfcp_sysfs_port_failed_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); -ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, "sypfai1", "sypfai2"); -ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, "syufai1", "syufai2"); + if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) + return sprintf(buf, "1\n"); + + return sprintf(buf, "0\n"); +} + +static ssize_t zfcp_sysfs_port_failed_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); + unsigned long val; + + if (strict_strtoul(buf, 0, &val) || val != 0) + return -EINVAL; + + zfcp_erp_modify_port_status(port, "sypfai1", NULL, + ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); + zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2", + NULL); + zfcp_erp_wait(port->adapter); + + return count; +} +static ZFCP_DEV_ATTR(port, failed, S_IWUSR | S_IRUGO, + zfcp_sysfs_port_failed_show, + zfcp_sysfs_port_failed_store); + +static ssize_t zfcp_sysfs_unit_failed_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev); + + if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_ERP_FAILED) + return sprintf(buf, "1\n"); + + return sprintf(buf, "0\n"); +} + +static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev); + unsigned long val; + + if (strict_strtoul(buf, 0, &val) || val != 0) + return -EINVAL; + + zfcp_erp_modify_unit_status(unit, "syufai1", NULL, + ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); + zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, + "syufai2", NULL); + zfcp_erp_wait(unit->port->adapter); + + return count; +} +static ZFCP_DEV_ATTR(unit, failed, S_IWUSR | S_IRUGO, + zfcp_sysfs_unit_failed_show, + zfcp_sysfs_unit_failed_store); static ssize_t zfcp_sysfs_adapter_failed_show(struct device *dev, struct device_attribute *attr, @@ -394,8 +418,17 @@ ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", dev_name(&unit->port->adapter->ccw_device->dev)); ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", (unsigned long long) unit->port->wwpn); -ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", - (unsigned long long) unit->fcp_lun); + +static ssize_t zfcp_sysfs_scsi_fcp_lun_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct zfcp_unit *unit = sdev->hostdata; + + return sprintf(buf, "0x%016llx\n", (unsigned long long) unit->fcp_lun); +} +static DEVICE_ATTR(fcp_lun, S_IRUGO, zfcp_sysfs_scsi_fcp_lun_show, NULL); struct device_attribute *zfcp_sysfs_sdev_attrs[] = { &dev_attr_fcp_lun, -- cgit v1.2.3-18-g5258 From fdbd1c5e27dabfa950d4b0f52a20069aeaf67b9d Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:39:54 +0200 Subject: [SCSI] zfcp: Allow running unit/LUN shutdown without acquiring reference With the change for the LUN data to be part of the scsi_device, the slave_destroy callback will be the final call to the zfcp_erp_unit_shutdown function. The erp tries to acquire a reference to run the action asynchronously and fail, if it cannot get the reference. But calling scsi_device_get from slave_destroy will fail, because the scsi_device is already in the state SDEV_DEL. Introduce a new call into the zfcp erp to solve this: The function zfcp_erp_unit_shutdown_wait will close the LUN and wait for the erp to finish without acquiring an additional reference. The wait allows to omit the reference; the caller waiting for the erp to finish already has a reference that holds the struct in place. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_erp.c | 98 ++++++++++++++++++++++++++++---------------- drivers/s390/scsi/zfcp_ext.h | 1 + 2 files changed, 63 insertions(+), 36 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 160b432c907..50514b4c873 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -21,6 +21,7 @@ enum zfcp_erp_act_flags { ZFCP_STATUS_ERP_DISMISSING = 0x00100000, ZFCP_STATUS_ERP_DISMISSED = 0x00200000, ZFCP_STATUS_ERP_LOWMEM = 0x00400000, + ZFCP_STATUS_ERP_NO_REF = 0x00800000, }; enum zfcp_erp_steps { @@ -169,22 +170,22 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, return need; } -static struct zfcp_erp_action *zfcp_erp_setup_act(int need, +static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, struct zfcp_adapter *adapter, struct zfcp_port *port, struct zfcp_unit *unit) { struct zfcp_erp_action *erp_action; - u32 status = 0; switch (need) { case ZFCP_ERP_ACTION_REOPEN_UNIT: - if (!get_device(&unit->dev)) - return NULL; + if (!(act_status & ZFCP_STATUS_ERP_NO_REF)) + if (!get_device(&unit->dev)) + return NULL; atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); erp_action = &unit->erp_action; if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING)) - status = ZFCP_STATUS_ERP_CLOSE_ONLY; + act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; break; case ZFCP_ERP_ACTION_REOPEN_PORT: @@ -195,7 +196,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); erp_action = &port->erp_action; if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) - status = ZFCP_STATUS_ERP_CLOSE_ONLY; + act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; break; case ZFCP_ERP_ACTION_REOPEN_ADAPTER: @@ -205,7 +206,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, erp_action = &adapter->erp_action; if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_RUNNING)) - status = ZFCP_STATUS_ERP_CLOSE_ONLY; + act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; break; default: @@ -217,14 +218,15 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, erp_action->port = port; erp_action->unit = unit; erp_action->action = need; - erp_action->status = status; + erp_action->status = act_status; return erp_action; } static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, struct zfcp_port *port, - struct zfcp_unit *unit, char *id, void *ref) + struct zfcp_unit *unit, char *id, void *ref, + u32 act_status) { int retval = 1, need; struct zfcp_erp_action *act = NULL; @@ -236,10 +238,10 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, if (!need) goto out; - atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status); - act = zfcp_erp_setup_act(need, adapter, port, unit); + act = zfcp_erp_setup_act(need, act_status, adapter, port, unit); if (!act) goto out; + atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status); ++adapter->erp_total_count; list_add_tail(&act->list, &adapter->erp_ready_head); wake_up(&adapter->erp_ready_wq); @@ -262,7 +264,7 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, return -EIO; } return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, - adapter, NULL, NULL, id, ref); + adapter, NULL, NULL, id, ref, 0); } /** @@ -285,7 +287,7 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, zfcp_erp_adapter_failed(adapter, "erareo1", NULL); else zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter, - NULL, NULL, id, ref); + NULL, NULL, id, ref, 0); write_unlock_irqrestore(&adapter->erp_lock, flags); } @@ -317,20 +319,6 @@ void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id, zfcp_erp_port_reopen(port, clear | flags, id, ref); } -/** - * zfcp_erp_unit_shutdown - Shutdown unit - * @unit: Unit to shut down. - * @clear: Status flags to clear. - * @id: Id for debug trace event. - * @ref: Reference for debug trace event. - */ -void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, char *id, - void *ref) -{ - int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; - zfcp_erp_unit_reopen(unit, clear | flags, id, ref); -} - static void zfcp_erp_port_block(struct zfcp_port *port, int clear) { zfcp_erp_modify_port_status(port, "erpblk1", NULL, @@ -348,7 +336,7 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, return; zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, - port->adapter, port, NULL, id, ref); + port->adapter, port, NULL, id, ref, 0); } /** @@ -381,7 +369,7 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, } return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT, - port->adapter, port, NULL, id, ref); + port->adapter, port, NULL, id, ref, 0); } /** @@ -412,7 +400,7 @@ static void zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask) } static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id, - void *ref) + void *ref, u32 act_status) { struct zfcp_adapter *adapter = unit->port->adapter; @@ -422,7 +410,7 @@ static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id, return; zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT, - adapter, unit->port, unit, id, ref); + adapter, unit->port, unit, id, ref, act_status); } /** @@ -439,8 +427,45 @@ void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id, struct zfcp_adapter *adapter = port->adapter; write_lock_irqsave(&adapter->erp_lock, flags); - _zfcp_erp_unit_reopen(unit, clear, id, ref); + _zfcp_erp_unit_reopen(unit, clear, id, ref, 0); + write_unlock_irqrestore(&adapter->erp_lock, flags); +} + +/** + * zfcp_erp_unit_shutdown - Shutdown unit + * @unit: Unit to shut down. + * @clear: Status flags to clear. + * @id: Id for debug trace event. + * @ref: Reference for debug trace event. + */ +void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, char *id, + void *ref) +{ + int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; + zfcp_erp_unit_reopen(unit, clear | flags, id, ref); +} + +/** + * zfcp_erp_unit_shutdown_wait - Shutdown unit and wait for erp completion + * @unit: Unit to shut down. + * @id: Id for debug trace event. + * + * Do not acquire a reference for the unit when creating the ERP + * action. It is safe, because this function waits for the ERP to + * complete first. + */ +void zfcp_erp_unit_shutdown_wait(struct zfcp_unit *unit, char *id) +{ + unsigned long flags; + struct zfcp_port *port = unit->port; + struct zfcp_adapter *adapter = port->adapter; + int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; + + write_lock_irqsave(&adapter->erp_lock, flags); + _zfcp_erp_unit_reopen(unit, clear, id, NULL, ZFCP_STATUS_ERP_NO_REF); write_unlock_irqrestore(&adapter->erp_lock, flags); + + zfcp_erp_wait(adapter); } static int status_change_set(unsigned long mask, atomic_t *status) @@ -566,7 +591,7 @@ static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, read_lock(&port->unit_list_lock); list_for_each_entry(unit, &port->unit_list, list) - _zfcp_erp_unit_reopen(unit, clear, id, ref); + _zfcp_erp_unit_reopen(unit, clear, id, ref, 0); read_unlock(&port->unit_list_lock); } @@ -583,7 +608,7 @@ static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) _zfcp_erp_port_reopen(act->port, 0, "ersff_3", NULL); break; case ZFCP_ERP_ACTION_REOPEN_UNIT: - _zfcp_erp_unit_reopen(act->unit, 0, "ersff_4", NULL); + _zfcp_erp_unit_reopen(act->unit, 0, "ersff_4", NULL, 0); break; } } @@ -1143,7 +1168,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret) if (zfcp_erp_strat_change_det(&unit->status, erp_status)) { _zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, - "ersscg3", NULL); + "ersscg3", NULL, 0); return ZFCP_ERP_EXIT; } break; @@ -1191,7 +1216,8 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) switch (act->action) { case ZFCP_ERP_ACTION_REOPEN_UNIT: - put_device(&unit->dev); + if (!(act->status & ZFCP_STATUS_ERP_NO_REF)) + put_device(&unit->dev); break; case ZFCP_ERP_ACTION_REOPEN_PORT: diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 5c3966eaca5..3c90604076e 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -80,6 +80,7 @@ extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, char *, void *, u32, int); extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, char *, void *); extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, char *, void *); +extern void zfcp_erp_unit_shutdown_wait(struct zfcp_unit *, char *); extern void zfcp_erp_unit_failed(struct zfcp_unit *, char *, void *); extern int zfcp_erp_thread_setup(struct zfcp_adapter *); extern void zfcp_erp_thread_kill(struct zfcp_adapter *); -- cgit v1.2.3-18-g5258 From b62a8d9b45b971a67a0f8413338c230e3117dff5 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:39:55 +0200 Subject: [SCSI] zfcp: Use SCSI device data zfcp_scsi_dev instead of zfcp_unit This is the large change to switch from using the data in zfcp_unit to zfcp_scsi_dev. Keeping everything working requires doing the switch in one piece. To ensure that no code keeps using the data in zfcp_unit, this patch also removes the data from zfcp_unit that is now being replaced with zfcp_scsi_dev. For zfcp, the scsi_device together with zfcp_scsi_dev exist from the call of slave_alloc to the call of slave_destroy. The data in zfcp_scsi_dev is initialized in zfcp_scsi_slave_alloc and the LUN is opened; the final shutdown for the LUN is run from slave_destroy. Where the scsi_device or zfcp_scsi_dev is needed, the pointer to the scsi_device is passed as function argument and inside the function converted to the pointer to zfcp_scsi_dev; this avoids back and forth conversion betweeen scsi_device and zfcp_scsi_dev. While changing the function arguments from zfcp_unit to scsi_device, the functions names are renamed form "unit" to "lun". This is to have a seperation between zfcp_scsi_dev/LUN and the zfcp_unit; only code referring to the remaining configuration information in zfcp_unit struct uses "unit". Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_dbf.c | 28 ++-- drivers/s390/scsi/zfcp_dbf.h | 12 +- drivers/s390/scsi/zfcp_def.h | 34 ++-- drivers/s390/scsi/zfcp_erp.c | 369 ++++++++++++++++++++++------------------- drivers/s390/scsi/zfcp_ext.h | 32 ++-- drivers/s390/scsi/zfcp_fsf.c | 279 +++++++++++++++---------------- drivers/s390/scsi/zfcp_scsi.c | 114 ++++++------- drivers/s390/scsi/zfcp_sysfs.c | 66 +++++--- drivers/s390/scsi/zfcp_unit.c | 11 -- 9 files changed, 480 insertions(+), 465 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index a86117b0d6e..2224caa8b92 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -482,7 +482,7 @@ static int zfcp_dbf_rec_view_format(debug_info_t *id, struct debug_view *view, zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun); zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as); zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps); - zfcp_dbf_out(&p, "unit_status", "0x%08x", r->u.trigger.us); + zfcp_dbf_out(&p, "lun_status", "0x%08x", r->u.trigger.ls); break; case ZFCP_REC_DBF_ID_ACTION: zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action); @@ -600,19 +600,20 @@ void zfcp_dbf_rec_port(char *id, void *ref, struct zfcp_port *port) } /** - * zfcp_dbf_rec_unit - trace event for unit state change + * zfcp_dbf_rec_lun - trace event for LUN state change * @id: identifier for trigger of state change * @ref: additional reference (e.g. request) - * @unit: unit + * @sdev: SCSI device */ -void zfcp_dbf_rec_unit(char *id, void *ref, struct zfcp_unit *unit) +void zfcp_dbf_rec_lun(char *id, void *ref, struct scsi_device *sdev) { - struct zfcp_port *port = unit->port; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + struct zfcp_port *port = zfcp_sdev->port; struct zfcp_dbf *dbf = port->adapter->dbf; - zfcp_dbf_rec_target(id, ref, dbf, &unit->status, - &unit->erp_counter, port->wwpn, port->d_id, - unit->fcp_lun); + zfcp_dbf_rec_target(id, ref, dbf, &zfcp_sdev->status, + &zfcp_sdev->erp_counter, port->wwpn, port->d_id, + zfcp_scsi_dev_lun(sdev)); } /** @@ -624,11 +625,11 @@ void zfcp_dbf_rec_unit(char *id, void *ref, struct zfcp_unit *unit) * @action: address of error recovery action struct * @adapter: adapter * @port: port - * @unit: unit + * @sdev: SCSI device */ void zfcp_dbf_rec_trigger(char *id2, void *ref, u8 want, u8 need, void *action, struct zfcp_adapter *adapter, struct zfcp_port *port, - struct zfcp_unit *unit) + struct scsi_device *sdev) { struct zfcp_dbf *dbf = adapter->dbf; struct zfcp_dbf_rec_record *r = &dbf->rec_buf; @@ -647,9 +648,10 @@ void zfcp_dbf_rec_trigger(char *id2, void *ref, u8 want, u8 need, void *action, r->u.trigger.ps = atomic_read(&port->status); r->u.trigger.wwpn = port->wwpn; } - if (unit) - r->u.trigger.us = atomic_read(&unit->status); - r->u.trigger.fcp_lun = unit ? unit->fcp_lun : ZFCP_DBF_INVALID_LUN; + if (sdev) + r->u.trigger.ls = atomic_read(&sdev_to_zfcp(sdev)->status); + r->u.trigger.fcp_lun = sdev ? zfcp_scsi_dev_lun(sdev) : + ZFCP_DBF_INVALID_LUN; debug_event(dbf->rec, action ? 1 : 4, r, sizeof(*r)); spin_unlock_irqrestore(&dbf->rec_lock, flags); } diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index 2bcc3403126..6a48c197b45 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h @@ -60,7 +60,7 @@ struct zfcp_dbf_rec_record_trigger { u8 need; u32 as; u32 ps; - u32 us; + u32 ls; u64 ref; u64 action; u64 wwpn; @@ -350,16 +350,16 @@ void zfcp_dbf_scsi_abort(const char *tag, struct zfcp_dbf *dbf, /** * zfcp_dbf_scsi_devreset - trace event for Logical Unit or Target Reset * @tag: tag indicating success or failure of reset operation + * @scmnd: SCSI command which caused this error recovery * @flag: indicates type of reset (Target Reset, Logical Unit Reset) - * @unit: unit that needs reset - * @scsi_cmnd: SCSI command which caused this error recovery */ static inline -void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, - struct scsi_cmnd *scsi_cmnd) +void zfcp_dbf_scsi_devreset(const char *tag, struct scsi_cmnd *scmnd, u8 flag) { + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device); + zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1, - unit->port->adapter->dbf, scsi_cmnd, NULL, 0); + zfcp_sdev->port->adapter->dbf, scmnd, NULL, 0); } #endif /* ZFCP_DBF_H */ diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index d31158c0de9..6dfae7091aa 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -85,8 +85,8 @@ struct zfcp_reqlist; #define ZFCP_STATUS_PORT_LINK_TEST 0x00000002 /* logical unit status */ -#define ZFCP_STATUS_UNIT_SHARED 0x00000004 -#define ZFCP_STATUS_UNIT_READONLY 0x00000008 +#define ZFCP_STATUS_LUN_SHARED 0x00000004 +#define ZFCP_STATUS_LUN_READONLY 0x00000008 /* FSF request status (this does not have a common part) */ #define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002 @@ -118,7 +118,7 @@ struct zfcp_erp_action { int action; /* requested action code */ struct zfcp_adapter *adapter; /* device which should be recovered */ struct zfcp_port *port; - struct zfcp_unit *unit; + struct scsi_device *sdev; u32 status; /* recovery status */ u32 step; /* active step of this erp action */ unsigned long fsf_req_id; @@ -219,17 +219,23 @@ struct zfcp_port { unsigned int starget_id; }; +/** + * struct zfcp_unit - LUN configured via zfcp sysfs + * @dev: struct device for sysfs representation and reference counting + * @list: entry in LUN/unit list per zfcp_port + * @port: reference to zfcp_port where this LUN is configured + * @fcp_lun: 64 bit LUN value + * @scsi_work: for running scsi_scan_target + * + * This is the representation of a LUN that has been configured for + * usage. The main data here is the 64 bit LUN value, data for + * running I/O and recovery is in struct zfcp_scsi_dev. + */ struct zfcp_unit { - struct device dev; - struct list_head list; /* list of logical units */ - struct zfcp_port *port; /* remote port of unit */ - atomic_t status; /* status of this logical unit */ - u64 fcp_lun; /* own FCP_LUN */ - u32 handle; /* handle assigned by FSF */ - struct scsi_device *device; /* scsi device struct pointer */ - struct zfcp_erp_action erp_action; /* pending error recovery */ - atomic_t erp_counter; - struct zfcp_latencies latencies; + struct device dev; + struct list_head list; + struct zfcp_port *port; + u64 fcp_lun; struct work_struct scsi_work; }; @@ -288,7 +294,6 @@ static inline u64 zfcp_scsi_dev_lun(struct scsi_device *sdev) * @erp_action: reference to erp action if request issued on behalf of ERP * @pool: reference to memory pool if used for this request * @issued: time when request was send (STCK) - * @unit: reference to unit if this request is a SCSI request * @handler: handler which should be called to process response */ struct zfcp_fsf_req { @@ -306,7 +311,6 @@ struct zfcp_fsf_req { struct zfcp_erp_action *erp_action; mempool_t *pool; unsigned long long issued; - struct zfcp_unit *unit; void (*handler)(struct zfcp_fsf_req *); }; diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 50514b4c873..734fc838931 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -30,12 +30,12 @@ enum zfcp_erp_steps { ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, ZFCP_ERP_STEP_PORT_OPENING = 0x0800, - ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000, - ZFCP_ERP_STEP_UNIT_OPENING = 0x2000, + ZFCP_ERP_STEP_LUN_CLOSING = 0x1000, + ZFCP_ERP_STEP_LUN_OPENING = 0x2000, }; enum zfcp_erp_act_type { - ZFCP_ERP_ACTION_REOPEN_UNIT = 1, + ZFCP_ERP_ACTION_REOPEN_LUN = 1, ZFCP_ERP_ACTION_REOPEN_PORT = 2, ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3, ZFCP_ERP_ACTION_REOPEN_ADAPTER = 4, @@ -89,24 +89,24 @@ static void zfcp_erp_action_dismiss(struct zfcp_erp_action *act) zfcp_erp_action_ready(act); } -static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) +static void zfcp_erp_action_dismiss_lun(struct scsi_device *sdev) { - if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_ERP_INUSE) - zfcp_erp_action_dismiss(&unit->erp_action); + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + + if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_INUSE) + zfcp_erp_action_dismiss(&zfcp_sdev->erp_action); } static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) { - struct zfcp_unit *unit; + struct scsi_device *sdev; if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) zfcp_erp_action_dismiss(&port->erp_action); - else { - read_lock(&port->unit_list_lock); - list_for_each_entry(unit, &port->unit_list, list) - zfcp_erp_action_dismiss_unit(unit); - read_unlock(&port->unit_list_lock); - } + else + shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + zfcp_erp_action_dismiss_lun(sdev); } static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) @@ -125,15 +125,17 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, struct zfcp_port *port, - struct zfcp_unit *unit) + struct scsi_device *sdev) { int need = want; - int u_status, p_status, a_status; + int l_status, p_status, a_status; + struct zfcp_scsi_dev *zfcp_sdev; switch (want) { - case ZFCP_ERP_ACTION_REOPEN_UNIT: - u_status = atomic_read(&unit->status); - if (u_status & ZFCP_STATUS_COMMON_ERP_INUSE) + case ZFCP_ERP_ACTION_REOPEN_LUN: + zfcp_sdev = sdev_to_zfcp(sdev); + l_status = atomic_read(&zfcp_sdev->status); + if (l_status & ZFCP_STATUS_COMMON_ERP_INUSE) return 0; p_status = atomic_read(&port->status); if (!(p_status & ZFCP_STATUS_COMMON_RUNNING) || @@ -173,18 +175,22 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, struct zfcp_adapter *adapter, struct zfcp_port *port, - struct zfcp_unit *unit) + struct scsi_device *sdev) { struct zfcp_erp_action *erp_action; + struct zfcp_scsi_dev *zfcp_sdev; switch (need) { - case ZFCP_ERP_ACTION_REOPEN_UNIT: + case ZFCP_ERP_ACTION_REOPEN_LUN: + zfcp_sdev = sdev_to_zfcp(sdev); if (!(act_status & ZFCP_STATUS_ERP_NO_REF)) - if (!get_device(&unit->dev)) + if (scsi_device_get(sdev)) return NULL; - atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); - erp_action = &unit->erp_action; - if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING)) + atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, + &zfcp_sdev->status); + erp_action = &zfcp_sdev->erp_action; + if (!(atomic_read(&zfcp_sdev->status) & + ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; break; @@ -216,7 +222,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, memset(erp_action, 0, sizeof(struct zfcp_erp_action)); erp_action->adapter = adapter; erp_action->port = port; - erp_action->unit = unit; + erp_action->sdev = sdev; erp_action->action = need; erp_action->status = act_status; @@ -225,8 +231,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, struct zfcp_port *port, - struct zfcp_unit *unit, char *id, void *ref, - u32 act_status) + struct scsi_device *sdev, + char *id, void *ref, u32 act_status) { int retval = 1, need; struct zfcp_erp_action *act = NULL; @@ -234,11 +240,11 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, if (!adapter->erp_thread) return -EIO; - need = zfcp_erp_required_act(want, adapter, port, unit); + need = zfcp_erp_required_act(want, adapter, port, sdev); if (!need) goto out; - act = zfcp_erp_setup_act(need, act_status, adapter, port, unit); + act = zfcp_erp_setup_act(need, act_status, adapter, port, sdev); if (!act) goto out; atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status); @@ -248,7 +254,7 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, zfcp_dbf_rec_thread("eracte1", adapter->dbf); retval = 0; out: - zfcp_dbf_rec_trigger(id, ref, want, need, act, adapter, port, unit); + zfcp_dbf_rec_trigger(id, ref, want, need, act, adapter, port, sdev); return retval; } @@ -392,77 +398,81 @@ int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref) return retval; } -static void zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask) +static void zfcp_erp_lun_block(struct scsi_device *sdev, int clear_mask) { - zfcp_erp_modify_unit_status(unit, "erublk1", NULL, - ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, - ZFCP_CLEAR); + zfcp_erp_modify_lun_status(sdev, "erlblk1", NULL, + ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, + ZFCP_CLEAR); } -static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id, - void *ref, u32 act_status) +static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id, + void *ref, u32 act_status) { - struct zfcp_adapter *adapter = unit->port->adapter; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; - zfcp_erp_unit_block(unit, clear); + zfcp_erp_lun_block(sdev, clear); - if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_ERP_FAILED) + if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) return; - zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT, - adapter, unit->port, unit, id, ref, act_status); + zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_LUN, adapter, + zfcp_sdev->port, sdev, id, ref, act_status); } /** - * zfcp_erp_unit_reopen - initiate reopen of a unit - * @unit: unit to be reopened - * @clear_mask: specifies flags in unit status to be cleared + * zfcp_erp_lun_reopen - initiate reopen of a LUN + * @sdev: SCSI device / LUN to be reopened + * @clear_mask: specifies flags in LUN status to be cleared * Return: 0 on success, < 0 on error */ -void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id, - void *ref) +void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id, + void *ref) { unsigned long flags; - struct zfcp_port *port = unit->port; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + struct zfcp_port *port = zfcp_sdev->port; struct zfcp_adapter *adapter = port->adapter; write_lock_irqsave(&adapter->erp_lock, flags); - _zfcp_erp_unit_reopen(unit, clear, id, ref, 0); + _zfcp_erp_lun_reopen(sdev, clear, id, ref, 0); write_unlock_irqrestore(&adapter->erp_lock, flags); } /** - * zfcp_erp_unit_shutdown - Shutdown unit - * @unit: Unit to shut down. + * zfcp_erp_lun_shutdown - Shutdown LUN + * @sdev: SCSI device / LUN to shut down. * @clear: Status flags to clear. * @id: Id for debug trace event. * @ref: Reference for debug trace event. */ -void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, char *id, - void *ref) +void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *id, + void *ref) { int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; - zfcp_erp_unit_reopen(unit, clear | flags, id, ref); + zfcp_erp_lun_reopen(sdev, clear | flags, id, ref); } /** - * zfcp_erp_unit_shutdown_wait - Shutdown unit and wait for erp completion - * @unit: Unit to shut down. + * zfcp_erp_lun_shutdown_wait - Shutdown LUN and wait for erp completion + * @sdev: SCSI device / LUN to shut down. * @id: Id for debug trace event. * - * Do not acquire a reference for the unit when creating the ERP + * Do not acquire a reference for the LUN when creating the ERP * action. It is safe, because this function waits for the ERP to - * complete first. + * complete first. This allows to shutdown the LUN, even when the SCSI + * device is in the state SDEV_DEL when scsi_device_get will fail. */ -void zfcp_erp_unit_shutdown_wait(struct zfcp_unit *unit, char *id) +void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, char *id) { unsigned long flags; - struct zfcp_port *port = unit->port; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + struct zfcp_port *port = zfcp_sdev->port; struct zfcp_adapter *adapter = port->adapter; int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; write_lock_irqsave(&adapter->erp_lock, flags); - _zfcp_erp_unit_reopen(unit, clear, id, NULL, ZFCP_STATUS_ERP_NO_REF); + _zfcp_erp_lun_reopen(sdev, clear, id, NULL, ZFCP_STATUS_ERP_NO_REF); write_unlock_irqrestore(&adapter->erp_lock, flags); zfcp_erp_wait(adapter); @@ -492,11 +502,13 @@ static void zfcp_erp_port_unblock(struct zfcp_port *port) atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status); } -static void zfcp_erp_unit_unblock(struct zfcp_unit *unit) +static void zfcp_erp_lun_unblock(struct scsi_device *sdev) { - if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status)) - zfcp_dbf_rec_unit("eruubl1", NULL, unit); - atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status); + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + + if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &zfcp_sdev->status)) + zfcp_dbf_rec_lun("erlubl1", NULL, sdev); + atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &zfcp_sdev->status); } static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) @@ -584,15 +596,14 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, read_unlock(&adapter->port_list_lock); } -static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, - char *id, void *ref) +static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear, + char *id, void *ref) { - struct zfcp_unit *unit; + struct scsi_device *sdev; - read_lock(&port->unit_list_lock); - list_for_each_entry(unit, &port->unit_list, list) - _zfcp_erp_unit_reopen(unit, clear, id, ref, 0); - read_unlock(&port->unit_list_lock); + shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + _zfcp_erp_lun_reopen(sdev, clear, id, ref, 0); } static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) @@ -607,8 +618,8 @@ static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) case ZFCP_ERP_ACTION_REOPEN_PORT: _zfcp_erp_port_reopen(act->port, 0, "ersff_3", NULL); break; - case ZFCP_ERP_ACTION_REOPEN_UNIT: - _zfcp_erp_unit_reopen(act->unit, 0, "ersff_4", NULL, 0); + case ZFCP_ERP_ACTION_REOPEN_LUN: + _zfcp_erp_lun_reopen(act->sdev, 0, "ersff_4", NULL, 0); break; } } @@ -623,7 +634,7 @@ static void zfcp_erp_strategy_followup_success(struct zfcp_erp_action *act) _zfcp_erp_port_reopen(act->port, 0, "ersfs_2", NULL); break; case ZFCP_ERP_ACTION_REOPEN_PORT: - _zfcp_erp_unit_reopen_all(act->port, 0, "ersfs_3", NULL); + _zfcp_erp_lun_reopen_all(act->port, 0, "ersfs_3", NULL); break; } } @@ -767,7 +778,7 @@ static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act) zfcp_fsf_req_dismiss_all(adapter); adapter->fsf_req_seq_no = 0; zfcp_fc_wka_ports_force_offline(adapter->gs); - /* all ports and units are closed */ + /* all ports and LUNs are closed */ zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL, ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); @@ -958,82 +969,86 @@ close_init_done: return zfcp_erp_port_strategy_open_common(erp_action); } -static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) +static void zfcp_erp_lun_strategy_clearstati(struct scsi_device *sdev) { + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | - ZFCP_STATUS_UNIT_SHARED | - ZFCP_STATUS_UNIT_READONLY, - &unit->status); + ZFCP_STATUS_LUN_SHARED | ZFCP_STATUS_LUN_READONLY, + &zfcp_sdev->status); } -static int zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action) +static int zfcp_erp_lun_strategy_close(struct zfcp_erp_action *erp_action) { - int retval = zfcp_fsf_close_unit(erp_action); + int retval = zfcp_fsf_close_lun(erp_action); if (retval == -ENOMEM) return ZFCP_ERP_NOMEM; - erp_action->step = ZFCP_ERP_STEP_UNIT_CLOSING; + erp_action->step = ZFCP_ERP_STEP_LUN_CLOSING; if (retval) return ZFCP_ERP_FAILED; return ZFCP_ERP_CONTINUES; } -static int zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action) +static int zfcp_erp_lun_strategy_open(struct zfcp_erp_action *erp_action) { - int retval = zfcp_fsf_open_unit(erp_action); + int retval = zfcp_fsf_open_lun(erp_action); if (retval == -ENOMEM) return ZFCP_ERP_NOMEM; - erp_action->step = ZFCP_ERP_STEP_UNIT_OPENING; + erp_action->step = ZFCP_ERP_STEP_LUN_OPENING; if (retval) return ZFCP_ERP_FAILED; return ZFCP_ERP_CONTINUES; } -static int zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action) +static int zfcp_erp_lun_strategy(struct zfcp_erp_action *erp_action) { - struct zfcp_unit *unit = erp_action->unit; + struct scsi_device *sdev = erp_action->sdev; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); switch (erp_action->step) { case ZFCP_ERP_STEP_UNINITIALIZED: - zfcp_erp_unit_strategy_clearstati(unit); - if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_OPEN) - return zfcp_erp_unit_strategy_close(erp_action); + zfcp_erp_lun_strategy_clearstati(sdev); + if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) + return zfcp_erp_lun_strategy_close(erp_action); /* already closed, fall through */ - case ZFCP_ERP_STEP_UNIT_CLOSING: - if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_OPEN) + case ZFCP_ERP_STEP_LUN_CLOSING: + if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) return ZFCP_ERP_FAILED; if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) return ZFCP_ERP_EXIT; - return zfcp_erp_unit_strategy_open(erp_action); + return zfcp_erp_lun_strategy_open(erp_action); - case ZFCP_ERP_STEP_UNIT_OPENING: - if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_OPEN) + case ZFCP_ERP_STEP_LUN_OPENING: + if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) return ZFCP_ERP_SUCCEEDED; } return ZFCP_ERP_FAILED; } -static int zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) +static int zfcp_erp_strategy_check_lun(struct scsi_device *sdev, int result) { + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + switch (result) { case ZFCP_ERP_SUCCEEDED : - atomic_set(&unit->erp_counter, 0); - zfcp_erp_unit_unblock(unit); + atomic_set(&zfcp_sdev->erp_counter, 0); + zfcp_erp_lun_unblock(sdev); break; case ZFCP_ERP_FAILED : - atomic_inc(&unit->erp_counter); - if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS) { - dev_err(&unit->port->adapter->ccw_device->dev, - "ERP failed for unit 0x%016Lx on " + atomic_inc(&zfcp_sdev->erp_counter); + if (atomic_read(&zfcp_sdev->erp_counter) > ZFCP_MAX_ERPS) { + dev_err(&zfcp_sdev->port->adapter->ccw_device->dev, + "ERP failed for LUN 0x%016Lx on " "port 0x%016Lx\n", - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn); - zfcp_erp_unit_failed(unit, "erusck1", NULL); + (unsigned long long)zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + zfcp_erp_lun_failed(sdev, "ersckl1", NULL); } break; } - if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { - zfcp_erp_unit_block(unit, 0); + if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { + zfcp_erp_lun_block(sdev, 0); result = ZFCP_ERP_EXIT; } return result; @@ -1101,12 +1116,12 @@ static int zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, { struct zfcp_adapter *adapter = erp_action->adapter; struct zfcp_port *port = erp_action->port; - struct zfcp_unit *unit = erp_action->unit; + struct scsi_device *sdev = erp_action->sdev; switch (erp_action->action) { - case ZFCP_ERP_ACTION_REOPEN_UNIT: - result = zfcp_erp_strategy_check_unit(unit, result); + case ZFCP_ERP_ACTION_REOPEN_LUN: + result = zfcp_erp_strategy_check_lun(sdev, result); break; case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: @@ -1141,7 +1156,8 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret) int action = act->action; struct zfcp_adapter *adapter = act->adapter; struct zfcp_port *port = act->port; - struct zfcp_unit *unit = act->unit; + struct scsi_device *sdev = act->sdev; + struct zfcp_scsi_dev *zfcp_sdev; u32 erp_status = act->status; switch (action) { @@ -1164,11 +1180,12 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret) } break; - case ZFCP_ERP_ACTION_REOPEN_UNIT: - if (zfcp_erp_strat_change_det(&unit->status, erp_status)) { - _zfcp_erp_unit_reopen(unit, - ZFCP_STATUS_COMMON_ERP_FAILED, - "ersscg3", NULL, 0); + case ZFCP_ERP_ACTION_REOPEN_LUN: + zfcp_sdev = sdev_to_zfcp(sdev); + if (zfcp_erp_strat_change_det(&zfcp_sdev->status, erp_status)) { + _zfcp_erp_lun_reopen(sdev, + ZFCP_STATUS_COMMON_ERP_FAILED, + "ersscg3", NULL, 0); return ZFCP_ERP_EXIT; } break; @@ -1179,6 +1196,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret) static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) { struct zfcp_adapter *adapter = erp_action->adapter; + struct zfcp_scsi_dev *zfcp_sdev; adapter->erp_total_count--; if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) { @@ -1190,9 +1208,10 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) zfcp_dbf_rec_action("eractd1", erp_action); switch (erp_action->action) { - case ZFCP_ERP_ACTION_REOPEN_UNIT: + case ZFCP_ERP_ACTION_REOPEN_LUN: + zfcp_sdev = sdev_to_zfcp(erp_action->sdev); atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE, - &erp_action->unit->status); + &zfcp_sdev->status); break; case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: @@ -1212,12 +1231,12 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) { struct zfcp_adapter *adapter = act->adapter; struct zfcp_port *port = act->port; - struct zfcp_unit *unit = act->unit; + struct scsi_device *sdev = act->sdev; switch (act->action) { - case ZFCP_ERP_ACTION_REOPEN_UNIT: + case ZFCP_ERP_ACTION_REOPEN_LUN: if (!(act->status & ZFCP_STATUS_ERP_NO_REF)) - put_device(&unit->dev); + scsi_device_put(sdev); break; case ZFCP_ERP_ACTION_REOPEN_PORT: @@ -1248,8 +1267,8 @@ static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) return zfcp_erp_port_forced_strategy(erp_action); case ZFCP_ERP_ACTION_REOPEN_PORT: return zfcp_erp_port_strategy(erp_action); - case ZFCP_ERP_ACTION_REOPEN_UNIT: - return zfcp_erp_unit_strategy(erp_action); + case ZFCP_ERP_ACTION_REOPEN_LUN: + return zfcp_erp_lun_strategy(erp_action); } return ZFCP_ERP_FAILED; } @@ -1426,15 +1445,15 @@ void zfcp_erp_port_failed(struct zfcp_port *port, char *id, void *ref) } /** - * zfcp_erp_unit_failed - Set unit status to failed. - * @unit: Failed unit. + * zfcp_erp_lun_failed - Set LUN status to failed. + * @sdev: Failed SCSI device / LUN * @id: Event id for debug trace. * @ref: Reference for debug trace. */ -void zfcp_erp_unit_failed(struct zfcp_unit *unit, char *id, void *ref) +void zfcp_erp_lun_failed(struct scsi_device *sdev, char *id, void *ref) { - zfcp_erp_modify_unit_status(unit, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); + zfcp_erp_modify_lun_status(sdev, id, ref, + ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); } /** @@ -1456,7 +1475,7 @@ void zfcp_erp_wait(struct zfcp_adapter *adapter) * @mask: status bits to change * @set_or_clear: ZFCP_SET or ZFCP_CLEAR * - * Changes in common status bits are propagated to attached ports and units. + * Changes in common status bits are propagated to attached ports and LUNs. */ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id, void *ref, u32 mask, int set_or_clear) @@ -1494,13 +1513,12 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id, * @mask: status bits to change * @set_or_clear: ZFCP_SET or ZFCP_CLEAR * - * Changes in common status bits are propagated to attached units. + * Changes in common status bits are propagated to attached LUNs. */ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref, u32 mask, int set_or_clear) { - struct zfcp_unit *unit; - unsigned long flags; + struct scsi_device *sdev; u32 common_mask = mask & ZFCP_COMMON_FLAGS; if (set_or_clear == ZFCP_SET) { @@ -1515,36 +1533,37 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref, atomic_set(&port->erp_counter, 0); } - if (common_mask) { - read_lock_irqsave(&port->unit_list_lock, flags); - list_for_each_entry(unit, &port->unit_list, list) - zfcp_erp_modify_unit_status(unit, id, ref, common_mask, - set_or_clear); - read_unlock_irqrestore(&port->unit_list_lock, flags); - } + if (common_mask) + shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + zfcp_erp_modify_lun_status(sdev, id, ref, + common_mask, + set_or_clear); } /** - * zfcp_erp_modify_unit_status - change unit status bits - * @unit: unit to change the status bits + * zfcp_erp_modify_lun_status - change LUN status bits + * @sdev: SCSI device / LUN where to change the status bits * @id: id for the debug trace * @ref: reference for the debug trace * @mask: status bits to change * @set_or_clear: ZFCP_SET or ZFCP_CLEAR */ -void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, char *id, void *ref, - u32 mask, int set_or_clear) +void zfcp_erp_modify_lun_status(struct scsi_device *sdev, char *id, void *ref, + u32 mask, int set_or_clear) { + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + if (set_or_clear == ZFCP_SET) { - if (status_change_set(mask, &unit->status)) - zfcp_dbf_rec_unit(id, ref, unit); - atomic_set_mask(mask, &unit->status); + if (status_change_set(mask, &zfcp_sdev->status)) + zfcp_dbf_rec_lun(id, ref, sdev); + atomic_set_mask(mask, &zfcp_sdev->status); } else { - if (status_change_clear(mask, &unit->status)) - zfcp_dbf_rec_unit(id, ref, unit); - atomic_clear_mask(mask, &unit->status); + if (status_change_clear(mask, &zfcp_sdev->status)) + zfcp_dbf_rec_lun(id, ref, sdev); + atomic_clear_mask(mask, &zfcp_sdev->status); if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) { - atomic_set(&unit->erp_counter, 0); + atomic_set(&zfcp_sdev->erp_counter, 0); } } } @@ -1563,16 +1582,16 @@ void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref) } /** - * zfcp_erp_unit_boxed - Mark unit as "boxed" and start ERP - * @port: The "boxed" unit. + * zfcp_erp_lun_boxed - Mark LUN as "boxed" and start ERP + * @sdev: The "boxed" SCSI device / LUN. * @id: The debug trace id. - * @id: Reference for the debug trace. + * @ref: Reference for the debug trace. */ -void zfcp_erp_unit_boxed(struct zfcp_unit *unit, char *id, void *ref) +void zfcp_erp_lun_boxed(struct scsi_device *sdev, char *id, void *ref) { - zfcp_erp_modify_unit_status(unit, id, ref, - ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); - zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); + zfcp_erp_modify_lun_status(sdev, id, ref, + ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); + zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); } /** @@ -1582,7 +1601,7 @@ void zfcp_erp_unit_boxed(struct zfcp_unit *unit, char *id, void *ref) * @ref: reference for debug trace * * Since the adapter has denied access, stop using the port and the - * attached units. + * attached LUNs. */ void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref) { @@ -1592,44 +1611,44 @@ void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref) } /** - * zfcp_erp_unit_access_denied - Adapter denied access to unit. - * @unit: unit where access has been denied + * zfcp_erp_lun_access_denied - Adapter denied access to LUN. + * @sdev: SCSI device / LUN where access has been denied * @id: id for debug trace * @ref: reference for debug trace * - * Since the adapter has denied access, stop using the unit. + * Since the adapter has denied access, stop using the LUN. */ -void zfcp_erp_unit_access_denied(struct zfcp_unit *unit, char *id, void *ref) +void zfcp_erp_lun_access_denied(struct scsi_device *sdev, char *id, void *ref) { - zfcp_erp_modify_unit_status(unit, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); + zfcp_erp_modify_lun_status(sdev, id, ref, + ZFCP_STATUS_COMMON_ERP_FAILED | + ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); } -static void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, char *id, - void *ref) +static void zfcp_erp_lun_access_changed(struct scsi_device *sdev, char *id, + void *ref) { - int status = atomic_read(&unit->status); + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + int status = atomic_read(&zfcp_sdev->status); + if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | ZFCP_STATUS_COMMON_ACCESS_BOXED))) return; - zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); + zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); } static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id, void *ref) { - struct zfcp_unit *unit; - unsigned long flags; + struct scsi_device *sdev; int status = atomic_read(&port->status); if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | ZFCP_STATUS_COMMON_ACCESS_BOXED))) { - read_lock_irqsave(&port->unit_list_lock, flags); - list_for_each_entry(unit, &port->unit_list, list) - zfcp_erp_unit_access_changed(unit, id, ref); - read_unlock_irqrestore(&port->unit_list_lock, flags); + shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + zfcp_erp_lun_access_changed(sdev, id, ref); return; } diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 3c90604076e..80714679f5d 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -42,10 +42,10 @@ extern void zfcp_dbf_rec_thread(char *, struct zfcp_dbf *); extern void zfcp_dbf_rec_thread_lock(char *, struct zfcp_dbf *); extern void zfcp_dbf_rec_adapter(char *, void *, struct zfcp_dbf *); extern void zfcp_dbf_rec_port(char *, void *, struct zfcp_port *); -extern void zfcp_dbf_rec_unit(char *, void *, struct zfcp_unit *); +extern void zfcp_dbf_rec_lun(char *, void *, struct scsi_device *); extern void zfcp_dbf_rec_trigger(char *, void *, u8, u8, void *, struct zfcp_adapter *, struct zfcp_port *, - struct zfcp_unit *); + struct scsi_device *); extern void zfcp_dbf_rec_action(char *, struct zfcp_erp_action *); extern void _zfcp_dbf_hba_fsf_response(const char *, int, struct zfcp_fsf_req *, struct zfcp_dbf *); @@ -76,20 +76,20 @@ extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *, void *); extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *, void *); extern void zfcp_erp_port_failed(struct zfcp_port *, char *, void *); -extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, char *, void *, u32, - int); -extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, char *, void *); -extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, char *, void *); -extern void zfcp_erp_unit_shutdown_wait(struct zfcp_unit *, char *); -extern void zfcp_erp_unit_failed(struct zfcp_unit *, char *, void *); +extern void zfcp_erp_modify_lun_status(struct scsi_device *, char *, void *, + u32, int); +extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *, void *); +extern void zfcp_erp_lun_shutdown(struct scsi_device *, int, char *, void *); +extern void zfcp_erp_lun_shutdown_wait(struct scsi_device *, char *); +extern void zfcp_erp_lun_failed(struct scsi_device *, char *, void *); extern int zfcp_erp_thread_setup(struct zfcp_adapter *); extern void zfcp_erp_thread_kill(struct zfcp_adapter *); extern void zfcp_erp_wait(struct zfcp_adapter *); extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long); extern void zfcp_erp_port_boxed(struct zfcp_port *, char *, void *); -extern void zfcp_erp_unit_boxed(struct zfcp_unit *, char *, void *); +extern void zfcp_erp_lun_boxed(struct scsi_device *, char *, void *); extern void zfcp_erp_port_access_denied(struct zfcp_port *, char *, void *); -extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, char *, void *); +extern void zfcp_erp_lun_access_denied(struct scsi_device *, char *, void *); extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *, void *); extern void zfcp_erp_timeout_handler(unsigned long); @@ -117,8 +117,8 @@ extern int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *); extern int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *); extern int zfcp_fsf_close_port(struct zfcp_erp_action *); extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *); -extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); -extern int zfcp_fsf_close_unit(struct zfcp_erp_action *); +extern int zfcp_fsf_open_lun(struct zfcp_erp_action *); +extern int zfcp_fsf_close_lun(struct zfcp_erp_action *); extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *); extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *, struct fsf_qtcb_bottom_config *); @@ -134,12 +134,10 @@ extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *, mempool_t *, unsigned int); extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32, struct zfcp_fsf_ct_els *, unsigned int); -extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *, - struct scsi_cmnd *); +extern int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *); extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); -extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8); -extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long, - struct zfcp_unit *); +extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *, u8); +extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *); extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int); /* zfcp_qdio.c */ diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 9d1d7d1842c..2fbd80257bc 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -86,17 +86,19 @@ static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req, req->status |= ZFCP_STATUS_FSFREQ_ERROR; } -static void zfcp_fsf_access_denied_unit(struct zfcp_fsf_req *req, - struct zfcp_unit *unit) +static void zfcp_fsf_access_denied_lun(struct zfcp_fsf_req *req, + struct scsi_device *sdev) { + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + struct fsf_qtcb_header *header = &req->qtcb->header; dev_warn(&req->adapter->ccw_device->dev, - "Access denied to unit 0x%016Lx on port 0x%016Lx\n", - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn); + "Access denied to LUN 0x%016Lx on port 0x%016Lx\n", + (unsigned long long)zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]); zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]); - zfcp_erp_unit_access_denied(unit, "fsuad_1", req); + zfcp_erp_lun_access_denied(sdev, "fsadl_1", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; } @@ -811,7 +813,8 @@ out: static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req) { - struct zfcp_unit *unit = req->data; + struct scsi_device *sdev = req->data; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); union fsf_status_qual *fsq = &req->qtcb->header.fsf_status_qual; if (req->status & ZFCP_STATUS_FSFREQ_ERROR) @@ -820,14 +823,15 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req) switch (req->qtcb->header.fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: if (fsq->word[0] == fsq->word[1]) { - zfcp_erp_adapter_reopen(unit->port->adapter, 0, + zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fsafch1", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; } break; case FSF_LUN_HANDLE_NOT_VALID: if (fsq->word[0] == fsq->word[1]) { - zfcp_erp_port_reopen(unit->port, 0, "fsafch2", req); + zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fsafch2", + req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; } break; @@ -835,17 +839,17 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req) req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED; break; case FSF_PORT_BOXED: - zfcp_erp_port_boxed(unit->port, "fsafch3", req); + zfcp_erp_port_boxed(zfcp_sdev->port, "fsafch3", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_BOXED: - zfcp_erp_unit_boxed(unit, "fsafch4", req); + zfcp_erp_lun_boxed(sdev, "fsafch4", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ADAPTER_STATUS_AVAILABLE: switch (fsq->word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - zfcp_fc_test_link(unit->port); + zfcp_fc_test_link(zfcp_sdev->port); /* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -859,17 +863,18 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req) } /** - * zfcp_fsf_abort_fcp_command - abort running SCSI command - * @old_req_id: unsigned long - * @unit: pointer to struct zfcp_unit + * zfcp_fsf_abort_fcp_cmnd - abort running SCSI command + * @scmnd: The SCSI command to abort * Returns: pointer to struct zfcp_fsf_req */ -struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, - struct zfcp_unit *unit) +struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd) { struct zfcp_fsf_req *req = NULL; - struct zfcp_qdio *qdio = unit->port->adapter->qdio; + struct scsi_device *sdev = scmnd->device; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio; + unsigned long old_req_id = (unsigned long) scmnd->host_scribble; spin_lock_bh(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) @@ -882,16 +887,16 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, goto out; } - if (unlikely(!(atomic_read(&unit->status) & + if (unlikely(!(atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_UNBLOCKED))) goto out_error_free; zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); - req->data = unit; + req->data = zfcp_sdev; req->handler = zfcp_fsf_abort_fcp_command_handler; - req->qtcb->header.lun_handle = unit->handle; - req->qtcb->header.port_handle = unit->port->handle; + req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; + req->qtcb->header.port_handle = zfcp_sdev->port->handle; req->qtcb->bottom.support.req_handle = (u64) old_req_id; zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); @@ -1666,7 +1671,7 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) { struct zfcp_port *port = req->data; struct fsf_qtcb_header *header = &req->qtcb->header; - struct zfcp_unit *unit; + struct scsi_device *sdev; if (req->status & ZFCP_STATUS_FSFREQ_ERROR) return; @@ -1683,11 +1688,10 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) /* can't use generic zfcp_erp_modify_port_status because * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); - read_lock(&port->unit_list_lock); - list_for_each_entry(unit, &port->unit_list, list) - atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, - &unit->status); - read_unlock(&port->unit_list_lock); + shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, + &sdev_to_zfcp(sdev)->status); zfcp_erp_port_boxed(port, "fscpph2", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -1705,11 +1709,10 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); - read_lock(&port->unit_list_lock); - list_for_each_entry(unit, &port->unit_list, list) - atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, - &unit->status); - read_unlock(&port->unit_list_lock); + shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, + &sdev_to_zfcp(sdev)->status); break; } } @@ -1758,10 +1761,11 @@ out: return retval; } -static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) +static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) { struct zfcp_adapter *adapter = req->adapter; - struct zfcp_unit *unit = req->data; + struct scsi_device *sdev = req->data; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct fsf_qtcb_header *header = &req->qtcb->header; struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support; struct fsf_queue_designator *queue_designator = @@ -1773,24 +1777,24 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | ZFCP_STATUS_COMMON_ACCESS_BOXED | - ZFCP_STATUS_UNIT_SHARED | - ZFCP_STATUS_UNIT_READONLY, - &unit->status); + ZFCP_STATUS_LUN_SHARED | + ZFCP_STATUS_LUN_READONLY, + &zfcp_sdev->status); switch (header->fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(unit->port->adapter, 0, "fsouh_1", req); + zfcp_erp_adapter_reopen(adapter, 0, "fsouh_1", req); /* fall through */ case FSF_LUN_ALREADY_OPEN: break; case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_unit(req, unit); - atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); - atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); + zfcp_fsf_access_denied_lun(req, sdev); + atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); + atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); break; case FSF_PORT_BOXED: - zfcp_erp_port_boxed(unit->port, "fsouh_2", req); + zfcp_erp_port_boxed(zfcp_sdev->port, "fsouh_2", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_SHARING_VIOLATION: @@ -1798,25 +1802,25 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) dev_warn(&adapter->ccw_device->dev, "LUN 0x%Lx on port 0x%Lx is already in " "use by CSS%d, MIF Image ID %x\n", - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn, + (unsigned long long)zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn, queue_designator->cssid, queue_designator->hla); else zfcp_act_eval_err(adapter, header->fsf_status_qual.word[2]); - zfcp_erp_unit_access_denied(unit, "fsouh_3", req); - atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); - atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); + zfcp_erp_lun_access_denied(sdev, "fsolh_3", req); + atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); + atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED: dev_warn(&adapter->ccw_device->dev, "No handle is available for LUN " "0x%016Lx on port 0x%016Lx\n", - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn); - zfcp_erp_unit_failed(unit, "fsouh_4", req); + (unsigned long long)zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + zfcp_erp_lun_failed(sdev, "fsolh_4", req); /* fall through */ case FSF_INVALID_COMMAND_OPTION: req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -1824,7 +1828,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) case FSF_ADAPTER_STATUS_AVAILABLE: switch (header->fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - zfcp_fc_test_link(unit->port); + zfcp_fc_test_link(zfcp_sdev->port); /* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -1833,8 +1837,8 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) break; case FSF_GOOD: - unit->handle = header->lun_handle; - atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); + zfcp_sdev->lun_handle = header->lun_handle; + atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &zfcp_sdev->status); if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE) && (adapter->adapter_features & FSF_FEATURE_LUN_SHARING) && @@ -1845,39 +1849,39 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) FSF_UNIT_ACCESS_OUTBOUND_TRANSFER); if (!exclusive) - atomic_set_mask(ZFCP_STATUS_UNIT_SHARED, - &unit->status); + atomic_set_mask(ZFCP_STATUS_LUN_SHARED, + &zfcp_sdev->status); if (!readwrite) { - atomic_set_mask(ZFCP_STATUS_UNIT_READONLY, - &unit->status); + atomic_set_mask(ZFCP_STATUS_LUN_READONLY, + &zfcp_sdev->status); dev_info(&adapter->ccw_device->dev, "SCSI device at LUN 0x%016Lx on port " "0x%016Lx opened read-only\n", - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn); + (unsigned long long)zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); } if (exclusive && !readwrite) { dev_err(&adapter->ccw_device->dev, "Exclusive read-only access not " - "supported (unit 0x%016Lx, " + "supported (LUN 0x%016Lx, " "port 0x%016Lx)\n", - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn); - zfcp_erp_unit_failed(unit, "fsouh_5", req); + (unsigned long long)zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + zfcp_erp_lun_failed(sdev, "fsolh_5", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; - zfcp_erp_unit_shutdown(unit, 0, "fsouh_6", req); + zfcp_erp_lun_shutdown(sdev, 0, "fsolh_6", req); } else if (!exclusive && readwrite) { dev_err(&adapter->ccw_device->dev, "Shared read-write access not " - "supported (unit 0x%016Lx, port " + "supported (LUN 0x%016Lx, port " "0x%016Lx)\n", - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn); - zfcp_erp_unit_failed(unit, "fsouh_7", req); + (unsigned long long)zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + zfcp_erp_lun_failed(sdev, "fsolh_7", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; - zfcp_erp_unit_shutdown(unit, 0, "fsouh_8", req); + zfcp_erp_lun_shutdown(sdev, 0, "fsolh_8", req); } } break; @@ -1885,11 +1889,11 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) } /** - * zfcp_fsf_open_unit - open unit + * zfcp_fsf_open_lun - open LUN * @erp_action: pointer to struct zfcp_erp_action * Returns: 0 on success, error otherwise */ -int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) +int zfcp_fsf_open_lun(struct zfcp_erp_action *erp_action) { struct zfcp_adapter *adapter = erp_action->adapter; struct zfcp_qdio *qdio = adapter->qdio; @@ -1913,9 +1917,9 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->qtcb->header.port_handle = erp_action->port->handle; - req->qtcb->bottom.support.fcp_lun = erp_action->unit->fcp_lun; - req->handler = zfcp_fsf_open_unit_handler; - req->data = erp_action->unit; + req->qtcb->bottom.support.fcp_lun = zfcp_scsi_dev_lun(erp_action->sdev); + req->handler = zfcp_fsf_open_lun_handler; + req->data = erp_action->sdev; req->erp_action = erp_action; erp_action->fsf_req_id = req->req_id; @@ -1933,30 +1937,32 @@ out: return retval; } -static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req) +static void zfcp_fsf_close_lun_handler(struct zfcp_fsf_req *req) { - struct zfcp_unit *unit = req->data; + struct scsi_device *sdev = req->data; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); if (req->status & ZFCP_STATUS_FSFREQ_ERROR) return; switch (req->qtcb->header.fsf_status) { case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(unit->port->adapter, 0, "fscuh_1", req); + zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1", + req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_HANDLE_NOT_VALID: - zfcp_erp_port_reopen(unit->port, 0, "fscuh_2", req); + zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fscuh_2", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: - zfcp_erp_port_boxed(unit->port, "fscuh_3", req); + zfcp_erp_port_boxed(zfcp_sdev->port, "fscuh_3", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ADAPTER_STATUS_AVAILABLE: switch (req->qtcb->header.fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - zfcp_fc_test_link(unit->port); + zfcp_fc_test_link(zfcp_sdev->port); /* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -1964,19 +1970,20 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req) } break; case FSF_GOOD: - atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); + atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &zfcp_sdev->status); break; } } /** - * zfcp_fsf_close_unit - close zfcp unit - * @erp_action: pointer to struct zfcp_unit + * zfcp_fsf_close_LUN - close LUN + * @erp_action: pointer to erp_action triggering the "close LUN" * Returns: 0 on success, error otherwise */ -int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) +int zfcp_fsf_close_lun(struct zfcp_erp_action *erp_action) { struct zfcp_qdio *qdio = erp_action->adapter->qdio; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(erp_action->sdev); struct zfcp_fsf_req *req; int retval = -EIO; @@ -1997,9 +2004,9 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->qtcb->header.port_handle = erp_action->port->handle; - req->qtcb->header.lun_handle = erp_action->unit->handle; - req->handler = zfcp_fsf_close_unit_handler; - req->data = erp_action->unit; + req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; + req->handler = zfcp_fsf_close_lun_handler; + req->data = erp_action->sdev; req->erp_action = erp_action; erp_action->fsf_req_id = req->req_id; @@ -2025,7 +2032,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) { struct fsf_qual_latency_info *lat_in; struct latency_cont *lat = NULL; - struct zfcp_unit *unit = req->unit; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scsi->device); struct zfcp_blk_drv_data blktrc; int ticks = req->adapter->timer_ticks; @@ -2048,24 +2055,24 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) case FSF_DATADIR_DIF_READ_STRIP: case FSF_DATADIR_DIF_READ_CONVERT: case FSF_DATADIR_READ: - lat = &unit->latencies.read; + lat = &zfcp_sdev->latencies.read; break; case FSF_DATADIR_DIF_WRITE_INSERT: case FSF_DATADIR_DIF_WRITE_CONVERT: case FSF_DATADIR_WRITE: - lat = &unit->latencies.write; + lat = &zfcp_sdev->latencies.write; break; case FSF_DATADIR_CMND: - lat = &unit->latencies.cmd; + lat = &zfcp_sdev->latencies.cmd; break; } if (lat) { - spin_lock(&unit->latencies.lock); + spin_lock(&zfcp_sdev->latencies.lock); zfcp_fsf_update_lat(&lat->channel, lat_in->channel_lat); zfcp_fsf_update_lat(&lat->fabric, lat_in->fabric_lat); lat->counter++; - spin_unlock(&unit->latencies.lock); + spin_unlock(&zfcp_sdev->latencies.lock); } } @@ -2141,68 +2148,66 @@ static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req) static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req) { - struct zfcp_unit *unit; + struct scsi_cmnd *scmnd = req->data; + struct scsi_device *sdev = scmnd->device; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct fsf_qtcb_header *header = &req->qtcb->header; - if (unlikely(req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)) - unit = req->data; - else - unit = req->unit; - if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) goto skip_fsfstatus; switch (header->fsf_status) { case FSF_HANDLE_MISMATCH: case FSF_PORT_HANDLE_NOT_VALID: - zfcp_erp_adapter_reopen(unit->port->adapter, 0, "fssfch1", req); + zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fssfch1", + req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_FCPLUN_NOT_VALID: case FSF_LUN_HANDLE_NOT_VALID: - zfcp_erp_port_reopen(unit->port, 0, "fssfch2", req); + zfcp_erp_port_reopen(zfcp_sdev->port, 0, "fssfch2", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: zfcp_fsf_class_not_supp(req); break; case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_unit(req, unit); + zfcp_fsf_access_denied_lun(req, sdev); break; case FSF_DIRECTION_INDICATOR_NOT_VALID: dev_err(&req->adapter->ccw_device->dev, - "Incorrect direction %d, unit 0x%016Lx on port " + "Incorrect direction %d, LUN 0x%016Lx on port " "0x%016Lx closed\n", req->qtcb->bottom.io.data_direction, - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn); - zfcp_erp_adapter_shutdown(unit->port->adapter, 0, "fssfch3", - req); + (unsigned long long)zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0, + "fssfch3", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_CMND_LENGTH_NOT_VALID: dev_err(&req->adapter->ccw_device->dev, - "Incorrect CDB length %d, unit 0x%016Lx on " + "Incorrect CDB length %d, LUN 0x%016Lx on " "port 0x%016Lx closed\n", req->qtcb->bottom.io.fcp_cmnd_length, - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn); - zfcp_erp_adapter_shutdown(unit->port->adapter, 0, "fssfch4", - req); + (unsigned long long)zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + zfcp_erp_adapter_shutdown(zfcp_sdev->port->adapter, 0, + "fssfch4", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: - zfcp_erp_port_boxed(unit->port, "fssfch5", req); + zfcp_erp_port_boxed(zfcp_sdev->port, "fssfch5", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_BOXED: - zfcp_erp_unit_boxed(unit, "fssfch6", req); + zfcp_erp_lun_boxed(sdev, "fssfch6", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ADAPTER_STATUS_AVAILABLE: if (header->fsf_status_qual.word[0] == FSF_SQ_INVOKE_LINK_TEST_PROCEDURE) - zfcp_fc_test_link(unit->port); + zfcp_fc_test_link(zfcp_sdev->port); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } @@ -2211,8 +2216,6 @@ skip_fsfstatus: zfcp_fsf_send_fcp_ctm_handler(req); else { zfcp_fsf_send_fcp_command_task_handler(req); - req->unit = NULL; - put_device(&unit->dev); } } @@ -2255,22 +2258,22 @@ static int zfcp_fsf_set_data_dir(struct scsi_cmnd *scsi_cmnd, u32 *data_dir) } /** - * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) - * @unit: unit where command is sent to + * zfcp_fsf_fcp_cmnd - initiate an FCP command (for a SCSI command) * @scsi_cmnd: scsi command to be sent */ -int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, - struct scsi_cmnd *scsi_cmnd) +int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) { struct zfcp_fsf_req *req; struct fcp_cmnd *fcp_cmnd; unsigned int sbtype = SBAL_FLAGS0_TYPE_READ; int real_bytes, retval = -EIO, dix_bytes = 0; - struct zfcp_adapter *adapter = unit->port->adapter; + struct scsi_device *sdev = scsi_cmnd->device; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; struct zfcp_qdio *qdio = adapter->qdio; struct fsf_qtcb_bottom_io *io; - if (unlikely(!(atomic_read(&unit->status) & + if (unlikely(!(atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_UNBLOCKED))) return -EBUSY; @@ -2295,11 +2298,10 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, io = &req->qtcb->bottom.io; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - req->unit = unit; req->data = scsi_cmnd; req->handler = zfcp_fsf_send_fcp_command_handler; - req->qtcb->header.lun_handle = unit->handle; - req->qtcb->header.port_handle = unit->port->handle; + req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; + req->qtcb->header.port_handle = zfcp_sdev->port->handle; io->service_class = FSF_CLASS_3; io->fcp_cmnd_length = FCP_CMND_LEN; @@ -2310,8 +2312,6 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, zfcp_fsf_set_data_dir(scsi_cmnd, &io->data_direction); - get_device(&unit->dev); - fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd); @@ -2338,7 +2338,6 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, goto out; failed_scsi_cmnd: - put_device(&unit->dev); zfcp_fsf_req_free(req); scsi_cmnd->host_scribble = NULL; out: @@ -2347,18 +2346,20 @@ out: } /** - * zfcp_fsf_send_fcp_ctm - send SCSI task management command - * @unit: pointer to struct zfcp_unit + * zfcp_fsf_fcp_task_mgmt - send SCSI task management command + * @scmnd: SCSI command to send the task management command for * @tm_flags: unsigned byte for task management flags * Returns: on success pointer to struct fsf_req, NULL otherwise */ -struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) +struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd, + u8 tm_flags) { struct zfcp_fsf_req *req = NULL; struct fcp_cmnd *fcp_cmnd; - struct zfcp_qdio *qdio = unit->port->adapter->qdio; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device); + struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio; - if (unlikely(!(atomic_read(&unit->status) & + if (unlikely(!(atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_UNBLOCKED))) return NULL; @@ -2376,10 +2377,10 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) } req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; - req->data = unit; + req->data = scmnd; req->handler = zfcp_fsf_send_fcp_command_handler; - req->qtcb->header.lun_handle = unit->handle; - req->qtcb->header.port_handle = unit->port->handle; + req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; + req->qtcb->header.port_handle = zfcp_sdev->port->handle; req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; req->qtcb->bottom.io.service_class = FSF_CLASS_3; req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN; @@ -2387,7 +2388,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; - zfcp_fc_fcp_tm(fcp_cmnd, unit->device, tm_flags); + zfcp_fc_fcp_tm(fcp_cmnd, scmnd->device, tm_flags); zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); if (!zfcp_fsf_req_send(req)) diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 03837797c45..bc7217b8898 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -49,11 +49,12 @@ static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, return sdev->queue_depth; } -static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) +static void zfcp_scsi_slave_destroy(struct scsi_device *sdev) { - struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; - unit->device = NULL; - put_device(&unit->dev); + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + + zfcp_erp_lun_shutdown_wait(sdev, "scssd_1"); + put_device(&zfcp_sdev->port->dev); } static int zfcp_scsi_slave_configure(struct scsi_device *sdp) @@ -78,23 +79,16 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, void (*done) (struct scsi_cmnd *)) { - struct zfcp_unit *unit; - struct zfcp_adapter *adapter; - int status, scsi_result, ret; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); + struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device)); + int status, scsi_result, ret; /* reset the status for this request */ scpnt->result = 0; scpnt->host_scribble = NULL; scpnt->scsi_done = done; - /* - * figure out adapter and target device - * (stored there by zfcp_scsi_slave_alloc) - */ - adapter = (struct zfcp_adapter *) scpnt->device->host->hostdata[0]; - unit = scpnt->device->hostdata; - scsi_result = fc_remote_port_chkready(rport); if (unlikely(scsi_result)) { scpnt->result = scsi_result; @@ -103,11 +97,11 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, return 0; } - status = atomic_read(&unit->status); + status = atomic_read(&zfcp_sdev->status); if (unlikely(status & ZFCP_STATUS_COMMON_ERP_FAILED) && - !(atomic_read(&unit->port->status) & + !(atomic_read(&zfcp_sdev->port->status) & ZFCP_STATUS_COMMON_ERP_FAILED)) { - /* only unit access denied, but port is good + /* only LUN access denied, but port is good * not covered by FC transport, have to fail here */ zfcp_scsi_command_fail(scpnt, DID_ERROR); return 0; @@ -115,8 +109,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) { /* This could be either - * open unit pending: this is temporary, will result in - * open unit or ERP_FAILED, so retry command + * open LUN pending: this is temporary, will result in + * open LUN or ERP_FAILED, so retry command * call to rport_delete pending: mimic retry from * fc_remote_port_chkready until rport is BLOCKED */ @@ -124,7 +118,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, return 0; } - ret = zfcp_fsf_send_fcp_command_task(unit, scpnt); + ret = zfcp_fsf_fcp_cmnd(scpnt); if (unlikely(ret == -EBUSY)) return SCSI_MLQUEUE_DEVICE_BUSY; else if (unlikely(ret < 0)) @@ -133,45 +127,42 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, return ret; } -static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter, - unsigned int id, u64 lun) +static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) { - unsigned long flags; + struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); + struct zfcp_adapter *adapter = + (struct zfcp_adapter *) sdev->host->hostdata[0]; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct zfcp_port *port; - struct zfcp_unit *unit = NULL; + struct zfcp_unit *unit; - read_lock_irqsave(&adapter->port_list_lock, flags); - list_for_each_entry(port, &adapter->port_list, list) { - if (!port->rport || (id != port->rport->scsi_target_id)) - continue; - unit = zfcp_unit_find(port, lun); - if (unit) - break; - } - read_unlock_irqrestore(&adapter->port_list_lock, flags); + port = zfcp_get_port_by_wwpn(adapter, rport->port_name); + if (!port) + return -ENXIO; - return unit; -} + unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev)); + if (unit) + put_device(&unit->dev); + else { + put_device(&port->dev); + return -ENXIO; + } -static int zfcp_scsi_slave_alloc(struct scsi_device *sdp) -{ - struct zfcp_adapter *adapter; - struct zfcp_unit *unit; - u64 lun; + zfcp_sdev->port = port; + zfcp_sdev->latencies.write.channel.min = 0xFFFFFFFF; + zfcp_sdev->latencies.write.fabric.min = 0xFFFFFFFF; + zfcp_sdev->latencies.read.channel.min = 0xFFFFFFFF; + zfcp_sdev->latencies.read.fabric.min = 0xFFFFFFFF; + zfcp_sdev->latencies.cmd.channel.min = 0xFFFFFFFF; + zfcp_sdev->latencies.cmd.fabric.min = 0xFFFFFFFF; + spin_lock_init(&zfcp_sdev->latencies.lock); - adapter = (struct zfcp_adapter *) sdp->host->hostdata[0]; - if (!adapter) - goto out; + zfcp_erp_modify_lun_status(sdev, "scsla_0", NULL, + ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); + zfcp_erp_lun_reopen(sdev, 0, "scsla_1", NULL); + zfcp_erp_wait(port->adapter); - int_to_scsilun(sdp->lun, (struct scsi_lun *)&lun); - unit = zfcp_unit_lookup(adapter, sdp->id, lun); - if (unit) { - sdp->hostdata = unit; - unit->device = sdp; - return 0; - } -out: - return -ENXIO; + return 0; } static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) @@ -179,7 +170,6 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) struct Scsi_Host *scsi_host = scpnt->device->host; struct zfcp_adapter *adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; - struct zfcp_unit *unit = scpnt->device->hostdata; struct zfcp_fsf_req *old_req, *abrt_req; unsigned long flags; unsigned long old_reqid = (unsigned long) scpnt->host_scribble; @@ -203,7 +193,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) write_unlock_irqrestore(&adapter->abort_lock, flags); while (retry--) { - abrt_req = zfcp_fsf_abort_fcp_command(old_reqid, unit); + abrt_req = zfcp_fsf_abort_fcp_cmnd(scpnt); if (abrt_req) break; @@ -238,14 +228,14 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) { - struct zfcp_unit *unit = scpnt->device->hostdata; - struct zfcp_adapter *adapter = unit->port->adapter; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); + struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; struct zfcp_fsf_req *fsf_req = NULL; int retval = SUCCESS, ret; int retry = 3; while (retry--) { - fsf_req = zfcp_fsf_send_fcp_ctm(unit, tm_flags); + fsf_req = zfcp_fsf_fcp_task_mgmt(scpnt, tm_flags); if (fsf_req) break; @@ -256,7 +246,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_RUNNING)) { - zfcp_dbf_scsi_devreset("nres", tm_flags, unit, scpnt); + zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags); return SUCCESS; } } @@ -266,10 +256,10 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) wait_for_completion(&fsf_req->completion); if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { - zfcp_dbf_scsi_devreset("fail", tm_flags, unit, scpnt); + zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags); retval = FAILED; } else - zfcp_dbf_scsi_devreset("okay", tm_flags, unit, scpnt); + zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags); zfcp_fsf_req_free(fsf_req); return retval; @@ -287,8 +277,8 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) { - struct zfcp_unit *unit = scpnt->device->hostdata; - struct zfcp_adapter *adapter = unit->port->adapter; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); + struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; int ret; zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt); diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 6b43bc46bf9..4f59356b07b 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -68,19 +68,19 @@ ZFCP_DEFINE_ATTR(zfcp_port, port, access_denied, "%d\n", ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0); ZFCP_DEFINE_ATTR(zfcp_unit, unit, status, "0x%08x\n", - atomic_read(&unit->status)); + zfcp_unit_sdev_status(unit)); ZFCP_DEFINE_ATTR(zfcp_unit, unit, in_recovery, "%d\n", - (atomic_read(&unit->status) & + (zfcp_unit_sdev_status(unit) & ZFCP_STATUS_COMMON_ERP_INUSE) != 0); ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_denied, "%d\n", - (atomic_read(&unit->status) & + (zfcp_unit_sdev_status(unit) & ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0); ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_shared, "%d\n", - (atomic_read(&unit->status) & - ZFCP_STATUS_UNIT_SHARED) != 0); + (zfcp_unit_sdev_status(unit) & + ZFCP_STATUS_LUN_SHARED) != 0); ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_readonly, "%d\n", - (atomic_read(&unit->status) & - ZFCP_STATUS_UNIT_READONLY) != 0); + (zfcp_unit_sdev_status(unit) & + ZFCP_STATUS_LUN_READONLY) != 0); static ssize_t zfcp_sysfs_port_failed_show(struct device *dev, struct device_attribute *attr, @@ -121,11 +121,17 @@ static ssize_t zfcp_sysfs_unit_failed_show(struct device *dev, char *buf) { struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev); + struct scsi_device *sdev; + unsigned int status, failed = 1; + + sdev = zfcp_unit_sdev(unit); + if (sdev) { + status = atomic_read(&sdev_to_zfcp(sdev)->status); + failed = status & ZFCP_STATUS_COMMON_ERP_FAILED ? 1 : 0; + scsi_device_put(sdev); + } - if (atomic_read(&unit->status) & ZFCP_STATUS_COMMON_ERP_FAILED) - return sprintf(buf, "1\n"); - - return sprintf(buf, "0\n"); + return sprintf(buf, "%d\n", failed); } static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev, @@ -134,15 +140,21 @@ static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev, { struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev); unsigned long val; + struct scsi_device *sdev; if (strict_strtoul(buf, 0, &val) || val != 0) return -EINVAL; - zfcp_erp_modify_unit_status(unit, "syufai1", NULL, - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); - zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, - "syufai2", NULL); - zfcp_erp_wait(unit->port->adapter); + sdev = zfcp_unit_sdev(unit); + if (sdev) { + zfcp_erp_modify_lun_status(sdev, "syufai1", NULL, + ZFCP_STATUS_COMMON_RUNNING, + ZFCP_SET); + zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, + "syufai2", NULL); + zfcp_erp_wait(unit->port->adapter); + } else + zfcp_unit_scsi_scan(unit); return count; } @@ -347,9 +359,9 @@ zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \ struct device_attribute *attr, \ char *buf) { \ struct scsi_device *sdev = to_scsi_device(dev); \ - struct zfcp_unit *unit = sdev->hostdata; \ - struct zfcp_latencies *lat = &unit->latencies; \ - struct zfcp_adapter *adapter = unit->port->adapter; \ + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \ + struct zfcp_latencies *lat = &zfcp_sdev->latencies; \ + struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; \ unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \ \ spin_lock_bh(&lat->lock); \ @@ -378,8 +390,8 @@ zfcp_sysfs_unit_##_name##_latency_store(struct device *dev, \ const char *buf, size_t count) \ { \ struct scsi_device *sdev = to_scsi_device(dev); \ - struct zfcp_unit *unit = sdev->hostdata; \ - struct zfcp_latencies *lat = &unit->latencies; \ + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \ + struct zfcp_latencies *lat = &zfcp_sdev->latencies; \ unsigned long flags; \ \ spin_lock_irqsave(&lat->lock, flags); \ @@ -407,26 +419,26 @@ static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, \ struct device_attribute *attr,\ char *buf) \ { \ - struct scsi_device *sdev = to_scsi_device(dev); \ - struct zfcp_unit *unit = sdev->hostdata; \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \ + struct zfcp_port *port = zfcp_sdev->port; \ \ return sprintf(buf, _format, _value); \ } \ static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL); ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", - dev_name(&unit->port->adapter->ccw_device->dev)); + dev_name(&port->adapter->ccw_device->dev)); ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", - (unsigned long long) unit->port->wwpn); + (unsigned long long) port->wwpn); static ssize_t zfcp_sysfs_scsi_fcp_lun_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_device *sdev = to_scsi_device(dev); - struct zfcp_unit *unit = sdev->hostdata; - return sprintf(buf, "0x%016llx\n", (unsigned long long) unit->fcp_lun); + return sprintf(buf, "0x%016llx\n", zfcp_scsi_dev_lun(sdev)); } static DEVICE_ATTR(fcp_lun, S_IRUGO, zfcp_sysfs_scsi_fcp_lun_show, NULL); diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c index e210c41ee38..1119c535a66 100644 --- a/drivers/s390/scsi/zfcp_unit.c +++ b/drivers/s390/scsi/zfcp_unit.c @@ -134,14 +134,7 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun) unit->fcp_lun = fcp_lun; unit->dev.parent = &port->dev; unit->dev.release = zfcp_unit_release; - unit->latencies.write.channel.min = 0xFFFFFFFF; - unit->latencies.write.fabric.min = 0xFFFFFFFF; - unit->latencies.read.channel.min = 0xFFFFFFFF; - unit->latencies.read.fabric.min = 0xFFFFFFFF; - unit->latencies.cmd.channel.min = 0xFFFFFFFF; - unit->latencies.cmd.fabric.min = 0xFFFFFFFF; INIT_WORK(&unit->scsi_work, zfcp_unit_scsi_scan_work); - spin_lock_init(&unit->latencies.lock); if (dev_set_name(&unit->dev, "0x%016llx", (unsigned long long) fcp_lun)) { @@ -165,9 +158,6 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun) list_add_tail(&unit->list, &port->unit_list); write_unlock_irq(&port->unit_list_lock); - atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status); - zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); - zfcp_erp_wait(unit->port->adapter); zfcp_unit_scsi_scan(unit); return 0; @@ -248,7 +238,6 @@ int zfcp_unit_remove(struct zfcp_port *port, u64 fcp_lun) put_device(&unit->dev); - zfcp_erp_unit_shutdown(unit, 0, "unrem_1", NULL); zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); return 0; -- cgit v1.2.3-18-g5258 From f8210e34887e1feb977a9b6b8caa086855af40c9 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:39:56 +0200 Subject: [SCSI] zfcp: Allow midlayer to scan for LUNs when running in NPIV mode Enable the LUN scanning mechanism in the SCSI midlayer: - Do not set the disable_target_scan bit in the FC transport class. - Set max_lun to 0xFFFFFFFF to allow the midlayer scan to include the two-level hierachical LUNs (like 0x40XX40XX00000000, but in SCSI midlayer LUN format). - Set max_id to a high value to allow triggering the SCSI device rescan from sysfs. When running in NPIV mode, zfcp accepts all LUNs in slave_attach. When running in non-NPIV mode, the list of zfcp_unit structs determines which SCSI devices are allowed on the current system. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_scsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index bc7217b8898..1e8d0cc7e1d 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -143,7 +143,8 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) unit = zfcp_unit_find(port, zfcp_scsi_dev_lun(sdev)); if (unit) put_device(&unit->dev); - else { + + if (!unit && !(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) { put_device(&port->dev); return -ENXIO; } @@ -309,8 +310,8 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) } /* tell the SCSI stack some characteristics of this adapter */ - adapter->scsi_host->max_id = 1; - adapter->scsi_host->max_lun = 1; + adapter->scsi_host->max_id = 511; + adapter->scsi_host->max_lun = 0xFFFFFFFF; adapter->scsi_host->max_channel = 0; adapter->scsi_host->unique_id = dev_id.devno; adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */ @@ -687,7 +688,6 @@ struct fc_function_template zfcp_transport_functions = { .show_host_port_type = 1, .show_host_speed = 1, .show_host_port_id = 1, - .disable_target_scan = 1, .dd_bsg_size = sizeof(struct zfcp_fsf_ct_els), }; -- cgit v1.2.3-18-g5258 From 44a24cb3731495336d77f3a955a7004997270dfd Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:39:57 +0200 Subject: [SCSI] zfcp: Change spin_lock_bh to spin_lock_irq to fix lockdep warning With the change to use the data on the SCSI device, iterating through all LUNs/scsi_devices takes the SCSI host_lock. This triggers warnings from the lock dependency checker: ========================================================= [ INFO: possible irq lock inversion dependency detected ] 2.6.34.1 #97 --------------------------------------------------------- chchp/3224 just changed the state of lock: (&(shost->host_lock)->rlock){-.-...}, at: [<00000000003a73f4>] __scsi_iterate_devices+0x38/0xbc but this lock took another, HARDIRQ-unsafe lock in the past: (&(&qdio->req_q_lock)->rlock){+.-...} and interrupts could create inverse lock ordering between them. other info that might help us debug this: [ 24.972394] 2 locks held by chchp/3224: #0: (&(sch->lock)->rlock){-.-...}, at: [<0000000000401efa>] do_IRQ+0xb2/0x1e4 #1: (&adapter->port_list_lock){.-....}, at: [<0000000000490302>] zfcp_erp_modify_adapter_status+0x9e/0x16c [...] ========================================================= [ INFO: possible irq lock inversion dependency detected ] 2.6.34.1 #98 --------------------------------------------------------- chchp/3235 just changed the state of lock: (&(shost->host_lock)->rlock){-.-...}, at: [<00000000003a73f4>] __scsi_iterate_devices+0x38/0xbc but this lock took another, HARDIRQ-unsafe lock in the past: (&(&qdio->stat_lock)->rlock){+.-...} and interrupts could create inverse lock ordering between them. other info that might help us debug this: 2 locks held by chchp/3235: #0: (&(sch->lock)->rlock){-.-...}, at: [<0000000000401efa>] do_IRQ+0xb2/0x1e4 #1: (&adapter->port_list_lock){.-.-..}, at: [<00000000004902f6>] zfcp_erp_modify_adapter_status+0x9e/0x16c [...] To stop this warning, change the request queue lock to disable irqs, not only softirq. The changes are required only outside of the critical "send fcp command" path. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fsf.c | 72 +++++++++++++++++++++---------------------- drivers/s390/scsi/zfcp_qdio.c | 18 ++++++----- 2 files changed, 46 insertions(+), 44 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 2fbd80257bc..48aa16a40d9 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -773,7 +773,7 @@ int zfcp_fsf_status_read(struct zfcp_qdio *qdio) struct fsf_status_read_buffer *sr_buf; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -807,7 +807,7 @@ failed_buf: zfcp_fsf_req_free(req); zfcp_dbf_hba_fsf_unsol("fail", adapter->dbf, NULL); out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -876,7 +876,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd) struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio; unsigned long old_req_id = (unsigned long) scmnd->host_scribble; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_ABORT_FCP_CMND, @@ -907,7 +907,7 @@ out_error_free: zfcp_fsf_req_free(req); req = NULL; out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return req; } @@ -1046,7 +1046,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, struct zfcp_fsf_req *req; int ret = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1078,7 +1078,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, failed_send: zfcp_fsf_req_free(req); out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return ret; } @@ -1142,7 +1142,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, struct zfcp_qdio *qdio = adapter->qdio; int ret = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1178,7 +1178,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, failed_send: zfcp_fsf_req_free(req); out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return ret; } @@ -1188,7 +1188,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) struct zfcp_qdio *qdio = erp_action->adapter->qdio; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1220,7 +1220,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) erp_action->fsf_req_id = 0; } out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1230,7 +1230,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio, struct zfcp_fsf_req *req = NULL; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out_unlock; @@ -1256,7 +1256,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio, zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(req); - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); if (!retval) wait_for_completion(&req->completion); @@ -1264,7 +1264,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio, return retval; out_unlock: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1282,7 +1282,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) if (!(qdio->adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) return -EOPNOTSUPP; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1309,7 +1309,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) erp_action->fsf_req_id = 0; } out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1328,7 +1328,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio, if (!(qdio->adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) return -EOPNOTSUPP; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out_unlock; @@ -1348,7 +1348,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio, req->handler = zfcp_fsf_exchange_port_data_handler; zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(req); - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); if (!retval) wait_for_completion(&req->completion); @@ -1358,7 +1358,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio, return retval; out_unlock: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1442,7 +1442,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1473,7 +1473,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) put_device(&port->dev); } out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1510,7 +1510,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1539,7 +1539,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) erp_action->fsf_req_id = 0; } out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1585,7 +1585,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1610,7 +1610,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) if (retval) zfcp_fsf_req_free(req); out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1638,7 +1638,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1663,7 +1663,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) if (retval) zfcp_fsf_req_free(req); out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1728,7 +1728,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1757,7 +1757,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) erp_action->fsf_req_id = 0; } out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1900,7 +1900,7 @@ int zfcp_fsf_open_lun(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -1933,7 +1933,7 @@ int zfcp_fsf_open_lun(struct zfcp_erp_action *erp_action) erp_action->fsf_req_id = 0; } out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -1987,7 +1987,7 @@ int zfcp_fsf_close_lun(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -2017,7 +2017,7 @@ int zfcp_fsf_close_lun(struct zfcp_erp_action *erp_action) erp_action->fsf_req_id = 0; } out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return retval; } @@ -2363,7 +2363,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd, ZFCP_STATUS_COMMON_UNBLOCKED))) return NULL; - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -2397,7 +2397,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd, zfcp_fsf_req_free(req); req = NULL; out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return req; } @@ -2433,7 +2433,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, return ERR_PTR(-EINVAL); } - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (zfcp_qdio_sbal_get(qdio)) goto out; @@ -2460,7 +2460,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(req); out: - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); if (!retval) { wait_for_completion(&req->completion); diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index b2635759721..60e6e5714eb 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -60,13 +60,11 @@ static inline void zfcp_qdio_account(struct zfcp_qdio *qdio) unsigned long long now, span; int used; - spin_lock(&qdio->stat_lock); now = get_clock_monotonic(); span = (now - qdio->req_q_time) >> 12; used = QDIO_MAX_BUFFERS_PER_Q - atomic_read(&qdio->req_q_free); qdio->req_q_util += used * span; qdio->req_q_time = now; - spin_unlock(&qdio->stat_lock); } static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, @@ -84,7 +82,9 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, /* cleanup all SBALs being program-owned now */ zfcp_qdio_zero_sbals(qdio->req_q, idx, count); + spin_lock_irq(&qdio->stat_lock); zfcp_qdio_account(qdio); + spin_unlock_irq(&qdio->stat_lock); atomic_add(count, &qdio->req_q_free); wake_up(&qdio->req_q_wq); } @@ -201,11 +201,11 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) { - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); if (atomic_read(&qdio->req_q_free) || !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) return 1; - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); return 0; } @@ -223,7 +223,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio) { long ret; - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); ret = wait_event_interruptible_timeout(qdio->req_q_wq, zfcp_qdio_sbal_check(qdio), 5 * HZ); @@ -239,7 +239,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio) zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1", NULL); } - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); return -EIO; } @@ -254,7 +254,9 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) int retval; u8 sbal_number = q_req->sbal_number; + spin_lock(&qdio->stat_lock); zfcp_qdio_account(qdio); + spin_unlock(&qdio->stat_lock); retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, q_req->sbal_first, sbal_number); @@ -328,9 +330,9 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio) return; /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ - spin_lock_bh(&qdio->req_q_lock); + spin_lock_irq(&qdio->req_q_lock); atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); - spin_unlock_bh(&qdio->req_q_lock); + spin_unlock_irq(&qdio->req_q_lock); wake_up(&qdio->req_q_wq); -- cgit v1.2.3-18-g5258 From c61b536c97f225a74cf430716fdb243dfafe9d48 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:39:58 +0200 Subject: [SCSI] zfcp: Reorder FCP I/O and task management handler functions Instead of calling the same handler for both, I/O and task management commands, use different handlers that call a function for the common part. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fsf.c | 147 +++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 75 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 48aa16a40d9..2b9dfea9f25 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -2080,73 +2080,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) sizeof(blktrc)); } -static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) -{ - struct scsi_cmnd *scpnt; - struct fcp_resp_with_ext *fcp_rsp; - unsigned long flags; - - read_lock_irqsave(&req->adapter->abort_lock, flags); - - scpnt = req->data; - if (unlikely(!scpnt)) { - read_unlock_irqrestore(&req->adapter->abort_lock, flags); - return; - } - - if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { - set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); - goto skip_fsfstatus; - } - - switch (req->qtcb->header.fsf_status) { - case FSF_INCONSISTENT_PROT_DATA: - case FSF_INVALID_PROT_PARM: - set_host_byte(scpnt, DID_ERROR); - goto skip_fsfstatus; - case FSF_BLOCK_GUARD_CHECK_FAILURE: - zfcp_scsi_dif_sense_error(scpnt, 0x1); - goto skip_fsfstatus; - case FSF_APP_TAG_CHECK_FAILURE: - zfcp_scsi_dif_sense_error(scpnt, 0x2); - goto skip_fsfstatus; - case FSF_REF_TAG_CHECK_FAILURE: - zfcp_scsi_dif_sense_error(scpnt, 0x3); - goto skip_fsfstatus; - } - fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; - zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt); - -skip_fsfstatus: - zfcp_fsf_req_trace(req, scpnt); - zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req); - - scpnt->host_scribble = NULL; - (scpnt->scsi_done) (scpnt); - /* - * We must hold this lock until scsi_done has been called. - * Otherwise we may call scsi_done after abort regarding this - * command has completed. - * Note: scsi_done must not block! - */ - read_unlock_irqrestore(&req->adapter->abort_lock, flags); -} - -static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req) -{ - struct fcp_resp_with_ext *fcp_rsp; - struct fcp_resp_rsp_info *rsp_info; - - fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; - rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; - - if ((rsp_info->rsp_code != FCP_TMF_CMPL) || - (req->status & ZFCP_STATUS_FSFREQ_ERROR)) - req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; -} - - -static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req) +static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req) { struct scsi_cmnd *scmnd = req->data; struct scsi_device *sdev = scmnd->device; @@ -2154,7 +2088,7 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req) struct fsf_qtcb_header *header = &req->qtcb->header; if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) - goto skip_fsfstatus; + return; switch (header->fsf_status) { case FSF_HANDLE_MISMATCH: @@ -2211,12 +2145,60 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req) req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; } -skip_fsfstatus: - if (req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) - zfcp_fsf_send_fcp_ctm_handler(req); - else { - zfcp_fsf_send_fcp_command_task_handler(req); +} + +static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) +{ + struct scsi_cmnd *scpnt; + struct fcp_resp_with_ext *fcp_rsp; + unsigned long flags; + + zfcp_fsf_fcp_handler_common(req); + + read_lock_irqsave(&req->adapter->abort_lock, flags); + + scpnt = req->data; + if (unlikely(!scpnt)) { + read_unlock_irqrestore(&req->adapter->abort_lock, flags); + return; } + + if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { + set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); + goto skip_fsfstatus; + } + + switch (req->qtcb->header.fsf_status) { + case FSF_INCONSISTENT_PROT_DATA: + case FSF_INVALID_PROT_PARM: + set_host_byte(scpnt, DID_ERROR); + goto skip_fsfstatus; + case FSF_BLOCK_GUARD_CHECK_FAILURE: + zfcp_scsi_dif_sense_error(scpnt, 0x1); + goto skip_fsfstatus; + case FSF_APP_TAG_CHECK_FAILURE: + zfcp_scsi_dif_sense_error(scpnt, 0x2); + goto skip_fsfstatus; + case FSF_REF_TAG_CHECK_FAILURE: + zfcp_scsi_dif_sense_error(scpnt, 0x3); + goto skip_fsfstatus; + } + fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; + zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt); + +skip_fsfstatus: + zfcp_fsf_req_trace(req, scpnt); + zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req); + + scpnt->host_scribble = NULL; + (scpnt->scsi_done) (scpnt); + /* + * We must hold this lock until scsi_done has been called. + * Otherwise we may call scsi_done after abort regarding this + * command has completed. + * Note: scsi_done must not block! + */ + read_unlock_irqrestore(&req->adapter->abort_lock, flags); } static int zfcp_fsf_set_data_dir(struct scsi_cmnd *scsi_cmnd, u32 *data_dir) @@ -2299,7 +2281,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) io = &req->qtcb->bottom.io; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->data = scsi_cmnd; - req->handler = zfcp_fsf_send_fcp_command_handler; + req->handler = zfcp_fsf_fcp_cmnd_handler; req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; req->qtcb->header.port_handle = zfcp_sdev->port->handle; io->service_class = FSF_CLASS_3; @@ -2345,6 +2327,21 @@ out: return retval; } +static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req) +{ + struct fcp_resp_with_ext *fcp_rsp; + struct fcp_resp_rsp_info *rsp_info; + + zfcp_fsf_fcp_handler_common(req); + + fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; + rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; + + if ((rsp_info->rsp_code != FCP_TMF_CMPL) || + (req->status & ZFCP_STATUS_FSFREQ_ERROR)) + req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; +} + /** * zfcp_fsf_fcp_task_mgmt - send SCSI task management command * @scmnd: SCSI command to send the task management command for @@ -2378,7 +2375,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd, req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; req->data = scmnd; - req->handler = zfcp_fsf_send_fcp_command_handler; + req->handler = zfcp_fsf_fcp_task_mgmt_handler; req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; req->qtcb->header.port_handle = zfcp_sdev->port->handle; req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; -- cgit v1.2.3-18-g5258 From a1ca48319a9aa1c5b57ce142f538e76050bb8972 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:39:59 +0200 Subject: [SCSI] zfcp: Move ACL/CFDC code to zfcp_cfdc.c Move the code evaluating the ACL/CFDC specific errors to the file zfcp_cfdc.c. With this change, all code related to the old access control feature is kept in one file, not split across zfcp_erp.c and zfcp_fsf.c. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_cfdc.c | 186 +++++++++++++++++++++++++++++++++++++++++- drivers/s390/scsi/zfcp_erp.c | 82 ------------------- drivers/s390/scsi/zfcp_ext.h | 12 ++- drivers/s390/scsi/zfcp_fsf.c | 129 ++++------------------------- 4 files changed, 207 insertions(+), 202 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index fcbd2b756da..f952b89b108 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -2,9 +2,10 @@ * zfcp device driver * * Userspace interface for accessing the - * Access Control Lists / Control File Data Channel + * Access Control Lists / Control File Data Channel; + * handling of response code and states for ports and LUNs. * - * Copyright IBM Corporation 2008, 2009 + * Copyright IBM Corporation 2008, 2010 */ #define KMSG_COMPONENT "zfcp" @@ -260,3 +261,184 @@ struct miscdevice zfcp_cfdc_misc = { .name = "zfcp_cfdc", .fops = &zfcp_cfdc_fops, }; + +/** + * zfcp_cfdc_adapter_access_changed - Process change in adapter ACT + * @adapter: Adapter where the Access Control Table (ACT) changed + * + * After a change in the adapter ACT, check if access to any + * previously denied resources is now possible. + */ +void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter) +{ + unsigned long flags; + struct zfcp_port *port; + struct scsi_device *sdev; + struct zfcp_scsi_dev *zfcp_sdev; + int status; + + if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) + return; + + read_lock_irqsave(&adapter->port_list_lock, flags); + list_for_each_entry(port, &adapter->port_list, list) { + status = atomic_read(&port->status); + if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) || + (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) + zfcp_erp_port_reopen(port, + ZFCP_STATUS_COMMON_ERP_FAILED, + "cfaac_1", NULL); + } + read_unlock_irqrestore(&adapter->port_list_lock, flags); + + shost_for_each_device(sdev, port->adapter->scsi_host) { + zfcp_sdev = sdev_to_zfcp(sdev); + status = atomic_read(&zfcp_sdev->status); + if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) || + (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) + zfcp_erp_lun_reopen(sdev, + ZFCP_STATUS_COMMON_ERP_FAILED, + "cfaac_2", NULL); + } +} + +static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) +{ + u16 subtable = table >> 16; + u16 rule = table & 0xffff; + const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" }; + + if (subtable && subtable < ARRAY_SIZE(act_type)) + dev_warn(&adapter->ccw_device->dev, + "Access denied according to ACT rule type %s, " + "rule %d\n", act_type[subtable], rule); +} + +/** + * zfcp_cfdc_port_denied - Process "access denied" for port + * @port: The port where the acces has been denied + * @qual: The FSF status qualifier for the access denied FSF status + */ +void zfcp_cfdc_port_denied(struct zfcp_port *port, + union fsf_status_qual *qual) +{ + dev_warn(&port->adapter->ccw_device->dev, + "Access denied to port 0x%016Lx\n", + (unsigned long long)port->wwpn); + + zfcp_act_eval_err(port->adapter, qual->halfword[0]); + zfcp_act_eval_err(port->adapter, qual->halfword[1]); + zfcp_erp_modify_port_status(port, "cfadp_1", NULL, + ZFCP_STATUS_COMMON_ERP_FAILED | + ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); +} + +/** + * zfcp_cfdc_lun_denied - Process "access denied" for LUN + * @sdev: The SCSI device / LUN where the access has been denied + * @qual: The FSF status qualifier for the access denied FSF status + */ +void zfcp_cfdc_lun_denied(struct scsi_device *sdev, + union fsf_status_qual *qual) +{ + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + + dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev, + "Access denied to LUN 0x%016Lx on port 0x%016Lx\n", + zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]); + zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]); + zfcp_erp_modify_lun_status(sdev, "cfadl_1", NULL, + ZFCP_STATUS_COMMON_ERP_FAILED | + ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); + + atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); + atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); +} + +/** + * zfcp_cfdc_lun_shrng_vltn - Evaluate LUN sharing violation status + * @sdev: The LUN / SCSI device where sharing violation occurred + * @qual: The FSF status qualifier from the LUN sharing violation + */ +void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *sdev, + union fsf_status_qual *qual) +{ + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + + if (qual->word[0]) + dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev, + "LUN 0x%Lx on port 0x%Lx is already in " + "use by CSS%d, MIF Image ID %x\n", + zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn, + qual->fsf_queue_designator.cssid, + qual->fsf_queue_designator.hla); + else + zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]); + + zfcp_erp_modify_lun_status(sdev, "fsosh_3", NULL, + ZFCP_STATUS_COMMON_ERP_FAILED | + ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); + atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); + atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); +} + +/** + * zfcp_cfdc_open_lun_eval - Eval access ctrl. status for successful "open lun" + * @sdev: The SCSI device / LUN where to evaluate the status + * @bottom: The qtcb bottom with the status from the "open lun" + * + * Returns: 0 if LUN is usable, -EACCES if the access control table + * reports an unsupported configuration. + */ +int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev, + struct fsf_qtcb_bottom_support *bottom) +{ + int shared, rw; + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; + + if ((adapter->connection_features & FSF_FEATURE_NPIV_MODE) || + !(adapter->adapter_features & FSF_FEATURE_LUN_SHARING) || + zfcp_ccw_priv_sch(adapter)) + return 0; + + shared = !(bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE); + rw = (bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER); + + if (shared) + atomic_set_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); + + if (!rw) { + atomic_set_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); + dev_info(&adapter->ccw_device->dev, "SCSI device at LUN " + "0x%016Lx on port 0x%016Lx opened read-only\n", + zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + } + + if (!shared && !rw) { + dev_err(&adapter->ccw_device->dev, "Exclusive read-only access " + "not supported (LUN 0x%016Lx, port 0x%016Lx)\n", + zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + zfcp_erp_lun_failed(sdev, "fsosh_5", NULL); + zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6", NULL); + return -EACCES; + } + + if (shared && rw) { + dev_err(&adapter->ccw_device->dev, + "Shared read-write access not supported " + "(LUN 0x%016Lx, port 0x%016Lx)\n", + zfcp_scsi_dev_lun(sdev), + (unsigned long long)zfcp_sdev->port->wwpn); + zfcp_erp_lun_failed(sdev, "fsosh_7", NULL); + zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8", NULL); + return -EACCES; + } + + return 0; +} diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 734fc838931..9e7d029ac7a 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -1593,85 +1593,3 @@ void zfcp_erp_lun_boxed(struct scsi_device *sdev, char *id, void *ref) ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); } - -/** - * zfcp_erp_port_access_denied - Adapter denied access to port. - * @port: port where access has been denied - * @id: id for debug trace - * @ref: reference for debug trace - * - * Since the adapter has denied access, stop using the port and the - * attached LUNs. - */ -void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref) -{ - zfcp_erp_modify_port_status(port, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); -} - -/** - * zfcp_erp_lun_access_denied - Adapter denied access to LUN. - * @sdev: SCSI device / LUN where access has been denied - * @id: id for debug trace - * @ref: reference for debug trace - * - * Since the adapter has denied access, stop using the LUN. - */ -void zfcp_erp_lun_access_denied(struct scsi_device *sdev, char *id, void *ref) -{ - zfcp_erp_modify_lun_status(sdev, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); -} - -static void zfcp_erp_lun_access_changed(struct scsi_device *sdev, char *id, - void *ref) -{ - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - int status = atomic_read(&zfcp_sdev->status); - - if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | - ZFCP_STATUS_COMMON_ACCESS_BOXED))) - return; - - zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); -} - -static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id, - void *ref) -{ - struct scsi_device *sdev; - int status = atomic_read(&port->status); - - if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | - ZFCP_STATUS_COMMON_ACCESS_BOXED))) { - shost_for_each_device(sdev, port->adapter->scsi_host) - if (sdev_to_zfcp(sdev)->port == port) - zfcp_erp_lun_access_changed(sdev, id, ref); - return; - } - - zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); -} - -/** - * zfcp_erp_adapter_access_changed - Process change in adapter ACT - * @adapter: Adapter where the Access Control Table (ACT) changed - * @id: Id for debug trace - * @ref: Reference for debug trace - */ -void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id, - void *ref) -{ - unsigned long flags; - struct zfcp_port *port; - - if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) - return; - - read_lock_irqsave(&adapter->port_list_lock, flags); - list_for_each_entry(port, &adapter->port_list, list) - zfcp_erp_port_access_changed(port, id, ref); - read_unlock_irqrestore(&adapter->port_list_lock, flags); -} diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 80714679f5d..7320132a430 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -34,6 +34,14 @@ extern void zfcp_ccw_adapter_put(struct zfcp_adapter *); /* zfcp_cfdc.c */ extern struct miscdevice zfcp_cfdc_misc; +extern void zfcp_cfdc_port_denied(struct zfcp_port *, union fsf_status_qual *); +extern void zfcp_cfdc_lun_denied(struct scsi_device *, union fsf_status_qual *); +extern void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *, + union fsf_status_qual *); +extern int zfcp_cfdc_open_lun_eval(struct scsi_device *, + struct fsf_qtcb_bottom_support *); +extern void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *); + /* zfcp_dbf.c */ extern int zfcp_dbf_adapter_register(struct zfcp_adapter *); @@ -88,10 +96,6 @@ extern void zfcp_erp_wait(struct zfcp_adapter *); extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long); extern void zfcp_erp_port_boxed(struct zfcp_port *, char *, void *); extern void zfcp_erp_lun_boxed(struct scsi_device *, char *, void *); -extern void zfcp_erp_port_access_denied(struct zfcp_port *, char *, void *); -extern void zfcp_erp_lun_access_denied(struct scsi_device *, char *, void *); -extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *, - void *); extern void zfcp_erp_timeout_handler(unsigned long); /* zfcp_fc.c */ diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 2b9dfea9f25..813c5b22565 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -61,47 +61,6 @@ static u32 fsf_qtcb_type[] = { [FSF_QTCB_UPLOAD_CONTROL_FILE] = FSF_SUPPORT_COMMAND }; -static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) -{ - u16 subtable = table >> 16; - u16 rule = table & 0xffff; - const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" }; - - if (subtable && subtable < ARRAY_SIZE(act_type)) - dev_warn(&adapter->ccw_device->dev, - "Access denied according to ACT rule type %s, " - "rule %d\n", act_type[subtable], rule); -} - -static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req, - struct zfcp_port *port) -{ - struct fsf_qtcb_header *header = &req->qtcb->header; - dev_warn(&req->adapter->ccw_device->dev, - "Access denied to port 0x%016Lx\n", - (unsigned long long)port->wwpn); - zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]); - zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]); - zfcp_erp_port_access_denied(port, "fspad_1", req); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; -} - -static void zfcp_fsf_access_denied_lun(struct zfcp_fsf_req *req, - struct scsi_device *sdev) -{ - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - - struct fsf_qtcb_header *header = &req->qtcb->header; - dev_warn(&req->adapter->ccw_device->dev, - "Access denied to LUN 0x%016Lx on port 0x%016Lx\n", - (unsigned long long)zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]); - zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]); - zfcp_erp_lun_access_denied(sdev, "fsadl_1", req); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; -} - static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req) { dev_err(&req->adapter->ccw_device->dev, "FCP device not " @@ -295,13 +254,12 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) break; case FSF_STATUS_READ_NOTIFICATION_LOST: if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED) - zfcp_erp_adapter_access_changed(adapter, "fssrh_3", - req); + zfcp_cfdc_adapter_access_changed(adapter); if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS) queue_work(adapter->work_queue, &adapter->scan_work); break; case FSF_STATUS_READ_CFDC_UPDATED: - zfcp_erp_adapter_access_changed(adapter, "fssrh_4", req); + zfcp_cfdc_adapter_access_changed(adapter); break; case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: adapter->adapter_features = sr_buf->payload.word[0]; @@ -1116,8 +1074,10 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) case FSF_RESPONSE_SIZE_TOO_LARGE: break; case FSF_ACCESS_DENIED: - if (port) - zfcp_fsf_access_denied_port(req, port); + if (port) { + zfcp_cfdc_port_denied(port, &header->fsf_status_qual); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; + } break; case FSF_SBAL_MISMATCH: /* should never occure, avoided in zfcp_fsf_send_els */ @@ -1375,7 +1335,8 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) case FSF_PORT_ALREADY_OPEN: break; case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_port(req, port); + zfcp_cfdc_port_denied(port, &header->fsf_status_qual); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: dev_warn(&req->adapter->ccw_device->dev, @@ -1682,7 +1643,7 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_port(req, port); + zfcp_cfdc_port_denied(port, &header->fsf_status_qual); break; case FSF_PORT_BOXED: /* can't use generic zfcp_erp_modify_port_status because @@ -1768,9 +1729,6 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct fsf_qtcb_header *header = &req->qtcb->header; struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support; - struct fsf_queue_designator *queue_designator = - &header->fsf_status_qual.fsf_queue_designator; - int exclusive, readwrite; if (req->status & ZFCP_STATUS_FSFREQ_ERROR) return; @@ -1789,29 +1747,15 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) case FSF_LUN_ALREADY_OPEN: break; case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_lun(req, sdev); - atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); - atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); + zfcp_cfdc_lun_denied(sdev, &header->fsf_status_qual); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: zfcp_erp_port_boxed(zfcp_sdev->port, "fsouh_2", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_SHARING_VIOLATION: - if (header->fsf_status_qual.word[0]) - dev_warn(&adapter->ccw_device->dev, - "LUN 0x%Lx on port 0x%Lx is already in " - "use by CSS%d, MIF Image ID %x\n", - (unsigned long long)zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn, - queue_designator->cssid, - queue_designator->hla); - else - zfcp_act_eval_err(adapter, - header->fsf_status_qual.word[2]); - zfcp_erp_lun_access_denied(sdev, "fsolh_3", req); - atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); - atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); + zfcp_cfdc_lun_shrng_vltn(sdev, &header->fsf_status_qual); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED: @@ -1839,51 +1783,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) case FSF_GOOD: zfcp_sdev->lun_handle = header->lun_handle; atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &zfcp_sdev->status); - - if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE) && - (adapter->adapter_features & FSF_FEATURE_LUN_SHARING) && - !zfcp_ccw_priv_sch(adapter)) { - exclusive = (bottom->lun_access_info & - FSF_UNIT_ACCESS_EXCLUSIVE); - readwrite = (bottom->lun_access_info & - FSF_UNIT_ACCESS_OUTBOUND_TRANSFER); - - if (!exclusive) - atomic_set_mask(ZFCP_STATUS_LUN_SHARED, - &zfcp_sdev->status); - - if (!readwrite) { - atomic_set_mask(ZFCP_STATUS_LUN_READONLY, - &zfcp_sdev->status); - dev_info(&adapter->ccw_device->dev, - "SCSI device at LUN 0x%016Lx on port " - "0x%016Lx opened read-only\n", - (unsigned long long)zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - } - - if (exclusive && !readwrite) { - dev_err(&adapter->ccw_device->dev, - "Exclusive read-only access not " - "supported (LUN 0x%016Lx, " - "port 0x%016Lx)\n", - (unsigned long long)zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_lun_failed(sdev, "fsolh_5", req); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; - zfcp_erp_lun_shutdown(sdev, 0, "fsolh_6", req); - } else if (!exclusive && readwrite) { - dev_err(&adapter->ccw_device->dev, - "Shared read-write access not " - "supported (LUN 0x%016Lx, port " - "0x%016Lx)\n", - (unsigned long long)zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_lun_failed(sdev, "fsolh_7", req); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; - zfcp_erp_lun_shutdown(sdev, 0, "fsolh_8", req); - } - } + zfcp_cfdc_open_lun_eval(sdev, bottom); break; } } @@ -2106,7 +2006,8 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req) zfcp_fsf_class_not_supp(req); break; case FSF_ACCESS_DENIED: - zfcp_fsf_access_denied_lun(req, sdev); + zfcp_cfdc_lun_denied(sdev, &header->fsf_status_qual); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_DIRECTION_INDICATOR_NOT_VALID: dev_err(&req->adapter->ccw_device->dev, -- cgit v1.2.3-18-g5258 From c9ff5d0315231b133a43e5af842bc01fb474f0d7 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Wed, 8 Sep 2010 14:40:00 +0200 Subject: [SCSI] zfcp: Remove duplicated code from zfcp_ccw_set_online The steps for setting the zfcp_adapter online are the same in zfcp_ccw_set_online and zfcp_ccw_activate. Remove the code duplication by calling zfcp_ccw_activate from zfcp_ccw_set_online. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_ccw.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index ce1cc7a11fb..bdf2f38e4b1 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -164,14 +164,7 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev) BUG_ON(!zfcp_reqlist_isempty(adapter->req_list)); adapter->req_no = 0; - zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL, - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); - zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, - "ccsonl2", NULL); - zfcp_erp_wait(adapter); - - flush_work(&adapter->scan_work); - + zfcp_ccw_activate(cdev); zfcp_ccw_adapter_put(adapter); return 0; } -- cgit v1.2.3-18-g5258 From edaed859e63aac174fcc3fed81886b91bb124661 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 8 Sep 2010 14:40:01 +0200 Subject: [SCSI] zfcp: Replace status modifier functions. Replace the zfcp_modify__status functions and its accompanying wrappers with dedicated status modifier functions. This eases code readability and maintenance. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_ccw.c | 8 +- drivers/s390/scsi/zfcp_cfdc.c | 22 ++-- drivers/s390/scsi/zfcp_def.h | 5 - drivers/s390/scsi/zfcp_erp.c | 258 +++++++++++++++++++---------------------- drivers/s390/scsi/zfcp_ext.h | 17 +-- drivers/s390/scsi/zfcp_fc.c | 2 +- drivers/s390/scsi/zfcp_fsf.c | 72 +++++++----- drivers/s390/scsi/zfcp_scsi.c | 3 +- drivers/s390/scsi/zfcp_sysfs.c | 10 +- 9 files changed, 189 insertions(+), 208 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index bdf2f38e4b1..0833c2b51e3 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -46,8 +46,7 @@ static int zfcp_ccw_activate(struct ccw_device *cdev) if (!adapter) return 0; - zfcp_erp_modify_adapter_status(adapter, "ccresu1", NULL, - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); + zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, "ccresu2", NULL); zfcp_erp_wait(adapter); @@ -217,9 +216,8 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event) break; case CIO_OPER: dev_info(&cdev->dev, "The FCP device is operational again\n"); - zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL, - ZFCP_STATUS_COMMON_RUNNING, - ZFCP_SET); + zfcp_erp_set_adapter_status(adapter, + ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, "ccnoti4", NULL); break; diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index f952b89b108..a56d14166c9 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -328,9 +328,9 @@ void zfcp_cfdc_port_denied(struct zfcp_port *port, zfcp_act_eval_err(port->adapter, qual->halfword[0]); zfcp_act_eval_err(port->adapter, qual->halfword[1]); - zfcp_erp_modify_port_status(port, "cfadp_1", NULL, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); + zfcp_erp_set_port_status(port, + ZFCP_STATUS_COMMON_ERP_FAILED | + ZFCP_STATUS_COMMON_ACCESS_DENIED); } /** @@ -349,9 +349,9 @@ void zfcp_cfdc_lun_denied(struct scsi_device *sdev, (unsigned long long)zfcp_sdev->port->wwpn); zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]); zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]); - zfcp_erp_modify_lun_status(sdev, "cfadl_1", NULL, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); + zfcp_erp_set_lun_status(sdev, + ZFCP_STATUS_COMMON_ERP_FAILED | + ZFCP_STATUS_COMMON_ACCESS_DENIED); atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); @@ -378,9 +378,9 @@ void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *sdev, else zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]); - zfcp_erp_modify_lun_status(sdev, "fsosh_3", NULL, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); + zfcp_erp_set_lun_status(sdev, + ZFCP_STATUS_COMMON_ERP_FAILED | + ZFCP_STATUS_COMMON_ACCESS_DENIED); atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); } @@ -424,7 +424,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev, "not supported (LUN 0x%016Lx, port 0x%016Lx)\n", zfcp_scsi_dev_lun(sdev), (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_lun_failed(sdev, "fsosh_5", NULL); + zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6", NULL); return -EACCES; } @@ -435,7 +435,7 @@ int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev, "(LUN 0x%016Lx, port 0x%016Lx)\n", zfcp_scsi_dev_lun(sdev), (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_lun_failed(sdev, "fsosh_7", NULL); + zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8", NULL); return -EACCES; } diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 6dfae7091aa..9ae1d0a6f62 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -325,9 +325,4 @@ struct zfcp_data { struct kmem_cache *adisc_cache; }; -/********************** ZFCP SPECIFIC DEFINES ********************************/ - -#define ZFCP_SET 0x00000100 -#define ZFCP_CLEAR 0x00000200 - #endif /* ZFCP_DEF_H */ diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 9e7d029ac7a..d37c7331f24 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -57,9 +57,8 @@ enum zfcp_erp_act_result { static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int mask) { - zfcp_erp_modify_adapter_status(adapter, "erablk1", NULL, - ZFCP_STATUS_COMMON_UNBLOCKED | mask, - ZFCP_CLEAR); + zfcp_erp_clear_adapter_status(adapter, + ZFCP_STATUS_COMMON_UNBLOCKED | mask); } static int zfcp_erp_action_exists(struct zfcp_erp_action *act) @@ -266,7 +265,8 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, /* ensure propagation of failed status to new devices */ if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { - zfcp_erp_adapter_failed(adapter, "erareo1", NULL); + zfcp_erp_set_adapter_status(adapter, + ZFCP_STATUS_COMMON_ERP_FAILED); return -EIO; } return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, @@ -290,7 +290,8 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, write_lock_irqsave(&adapter->erp_lock, flags); if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) - zfcp_erp_adapter_failed(adapter, "erareo1", NULL); + zfcp_erp_set_adapter_status(adapter, + ZFCP_STATUS_COMMON_ERP_FAILED); else zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter, NULL, NULL, id, ref, 0); @@ -327,9 +328,8 @@ void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id, static void zfcp_erp_port_block(struct zfcp_port *port, int clear) { - zfcp_erp_modify_port_status(port, "erpblk1", NULL, - ZFCP_STATUS_COMMON_UNBLOCKED | clear, - ZFCP_CLEAR); + zfcp_erp_clear_port_status(port, + ZFCP_STATUS_COMMON_UNBLOCKED | clear); } static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, @@ -370,7 +370,7 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { /* ensure propagation of failed status to new devices */ - zfcp_erp_port_failed(port, "erpreo1", NULL); + zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED); return -EIO; } @@ -400,9 +400,8 @@ int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref) static void zfcp_erp_lun_block(struct scsi_device *sdev, int clear_mask) { - zfcp_erp_modify_lun_status(sdev, "erlblk1", NULL, - ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, - ZFCP_CLEAR); + zfcp_erp_clear_lun_status(sdev, + ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask); } static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id, @@ -483,11 +482,6 @@ static int status_change_set(unsigned long mask, atomic_t *status) return (atomic_read(status) ^ mask) & mask; } -static int status_change_clear(unsigned long mask, atomic_t *status) -{ - return atomic_read(status) & mask; -} - static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) { if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status)) @@ -779,8 +773,7 @@ static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act) adapter->fsf_req_seq_no = 0; zfcp_fc_wka_ports_force_offline(adapter->gs); /* all ports and LUNs are closed */ - zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL, - ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); + zfcp_erp_clear_adapter_status(adapter, ZFCP_STATUS_COMMON_OPEN); atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); @@ -897,7 +890,7 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) struct zfcp_port *port = act->port; if (port->wwpn != adapter->peer_wwpn) { - zfcp_erp_port_failed(port, "eroptp1", NULL); + zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED); return ZFCP_ERP_FAILED; } port->d_id = adapter->peer_d_id; @@ -1042,7 +1035,8 @@ static int zfcp_erp_strategy_check_lun(struct scsi_device *sdev, int result) "port 0x%016Lx\n", (unsigned long long)zfcp_scsi_dev_lun(sdev), (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_lun_failed(sdev, "ersckl1", NULL); + zfcp_erp_set_lun_status(sdev, + ZFCP_STATUS_COMMON_ERP_FAILED); } break; } @@ -1072,7 +1066,8 @@ static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) dev_err(&port->adapter->ccw_device->dev, "ERP failed for remote port 0x%016Lx\n", (unsigned long long)port->wwpn); - zfcp_erp_port_failed(port, "erpsck1", NULL); + zfcp_erp_set_port_status(port, + ZFCP_STATUS_COMMON_ERP_FAILED); } break; } @@ -1099,7 +1094,8 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, dev_err(&adapter->ccw_device->dev, "ERP cannot recover an error " "on the FCP device\n"); - zfcp_erp_adapter_failed(adapter, "erasck1", NULL); + zfcp_erp_set_adapter_status(adapter, + ZFCP_STATUS_COMMON_ERP_FAILED); } break; } @@ -1421,175 +1417,159 @@ void zfcp_erp_thread_kill(struct zfcp_adapter *adapter) } /** - * zfcp_erp_adapter_failed - Set adapter status to failed. - * @adapter: Failed adapter. - * @id: Event id for debug trace. - * @ref: Reference for debug trace. + * zfcp_erp_wait - wait for completion of error recovery on an adapter + * @adapter: adapter for which to wait for completion of its error recovery */ -void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, char *id, void *ref) +void zfcp_erp_wait(struct zfcp_adapter *adapter) { - zfcp_erp_modify_adapter_status(adapter, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); + wait_event(adapter->erp_done_wqh, + !(atomic_read(&adapter->status) & + ZFCP_STATUS_ADAPTER_ERP_PENDING)); } /** - * zfcp_erp_port_failed - Set port status to failed. - * @port: Failed port. - * @id: Event id for debug trace. - * @ref: Reference for debug trace. + * zfcp_erp_set_adapter_status - set adapter status bits + * @adapter: adapter to change the status + * @mask: status bits to change + * + * Changes in common status bits are propagated to attached ports and LUNs. */ -void zfcp_erp_port_failed(struct zfcp_port *port, char *id, void *ref) +void zfcp_erp_set_adapter_status(struct zfcp_adapter *adapter, u32 mask) { - zfcp_erp_modify_port_status(port, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); -} + struct zfcp_port *port; + struct scsi_device *sdev; + unsigned long flags; + u32 common_mask = mask & ZFCP_COMMON_FLAGS; -/** - * zfcp_erp_lun_failed - Set LUN status to failed. - * @sdev: Failed SCSI device / LUN - * @id: Event id for debug trace. - * @ref: Reference for debug trace. - */ -void zfcp_erp_lun_failed(struct scsi_device *sdev, char *id, void *ref) -{ - zfcp_erp_modify_lun_status(sdev, id, ref, - ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); -} + atomic_set_mask(mask, &adapter->status); -/** - * zfcp_erp_wait - wait for completion of error recovery on an adapter - * @adapter: adapter for which to wait for completion of its error recovery - */ -void zfcp_erp_wait(struct zfcp_adapter *adapter) -{ - wait_event(adapter->erp_done_wqh, - !(atomic_read(&adapter->status) & - ZFCP_STATUS_ADAPTER_ERP_PENDING)); + if (!common_mask) + return; + + read_lock_irqsave(&adapter->port_list_lock, flags); + list_for_each_entry(port, &adapter->port_list, list) + atomic_set_mask(common_mask, &port->status); + read_unlock_irqrestore(&adapter->port_list_lock, flags); + + shost_for_each_device(sdev, adapter->scsi_host) + atomic_set_mask(common_mask, &sdev_to_zfcp(sdev)->status); } /** - * zfcp_erp_modify_adapter_status - change adapter status bits + * zfcp_erp_clear_adapter_status - clear adapter status bits * @adapter: adapter to change the status - * @id: id for the debug trace - * @ref: reference for the debug trace * @mask: status bits to change - * @set_or_clear: ZFCP_SET or ZFCP_CLEAR * * Changes in common status bits are propagated to attached ports and LUNs. */ -void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id, - void *ref, u32 mask, int set_or_clear) +void zfcp_erp_clear_adapter_status(struct zfcp_adapter *adapter, u32 mask) { struct zfcp_port *port; + struct scsi_device *sdev; unsigned long flags; u32 common_mask = mask & ZFCP_COMMON_FLAGS; + u32 clear_counter = mask & ZFCP_STATUS_COMMON_ERP_FAILED; - if (set_or_clear == ZFCP_SET) { - if (status_change_set(mask, &adapter->status)) - zfcp_dbf_rec_adapter(id, ref, adapter->dbf); - atomic_set_mask(mask, &adapter->status); - } else { - if (status_change_clear(mask, &adapter->status)) - zfcp_dbf_rec_adapter(id, ref, adapter->dbf); - atomic_clear_mask(mask, &adapter->status); - if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) - atomic_set(&adapter->erp_counter, 0); + atomic_clear_mask(mask, &adapter->status); + + if (!common_mask) + return; + + if (clear_counter) + atomic_set(&adapter->erp_counter, 0); + + read_lock_irqsave(&adapter->port_list_lock, flags); + list_for_each_entry(port, &adapter->port_list, list) { + atomic_clear_mask(common_mask, &port->status); + if (clear_counter) + atomic_set(&port->erp_counter, 0); } + read_unlock_irqrestore(&adapter->port_list_lock, flags); - if (common_mask) { - read_lock_irqsave(&adapter->port_list_lock, flags); - list_for_each_entry(port, &adapter->port_list, list) - zfcp_erp_modify_port_status(port, id, ref, common_mask, - set_or_clear); - read_unlock_irqrestore(&adapter->port_list_lock, flags); + shost_for_each_device(sdev, adapter->scsi_host) { + atomic_clear_mask(common_mask, &sdev_to_zfcp(sdev)->status); + if (clear_counter) + atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); } } /** - * zfcp_erp_modify_port_status - change port status bits - * @port: port to change the status bits - * @id: id for the debug trace - * @ref: reference for the debug trace + * zfcp_erp_set_port_status - set port status bits + * @port: port to change the status * @mask: status bits to change - * @set_or_clear: ZFCP_SET or ZFCP_CLEAR * * Changes in common status bits are propagated to attached LUNs. */ -void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref, - u32 mask, int set_or_clear) +void zfcp_erp_set_port_status(struct zfcp_port *port, u32 mask) { struct scsi_device *sdev; u32 common_mask = mask & ZFCP_COMMON_FLAGS; - if (set_or_clear == ZFCP_SET) { - if (status_change_set(mask, &port->status)) - zfcp_dbf_rec_port(id, ref, port); - atomic_set_mask(mask, &port->status); - } else { - if (status_change_clear(mask, &port->status)) - zfcp_dbf_rec_port(id, ref, port); - atomic_clear_mask(mask, &port->status); - if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) - atomic_set(&port->erp_counter, 0); - } + atomic_set_mask(mask, &port->status); - if (common_mask) - shost_for_each_device(sdev, port->adapter->scsi_host) - if (sdev_to_zfcp(sdev)->port == port) - zfcp_erp_modify_lun_status(sdev, id, ref, - common_mask, - set_or_clear); + if (!common_mask) + return; + + shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) + atomic_set_mask(common_mask, + &sdev_to_zfcp(sdev)->status); } /** - * zfcp_erp_modify_lun_status - change LUN status bits - * @sdev: SCSI device / LUN where to change the status bits - * @id: id for the debug trace - * @ref: reference for the debug trace + * zfcp_erp_clear_port_status - clear port status bits + * @port: adapter to change the status * @mask: status bits to change - * @set_or_clear: ZFCP_SET or ZFCP_CLEAR + * + * Changes in common status bits are propagated to attached LUNs. */ -void zfcp_erp_modify_lun_status(struct scsi_device *sdev, char *id, void *ref, - u32 mask, int set_or_clear) +void zfcp_erp_clear_port_status(struct zfcp_port *port, u32 mask) { - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + struct scsi_device *sdev; + u32 common_mask = mask & ZFCP_COMMON_FLAGS; + u32 clear_counter = mask & ZFCP_STATUS_COMMON_ERP_FAILED; + + atomic_clear_mask(mask, &port->status); + + if (!common_mask) + return; - if (set_or_clear == ZFCP_SET) { - if (status_change_set(mask, &zfcp_sdev->status)) - zfcp_dbf_rec_lun(id, ref, sdev); - atomic_set_mask(mask, &zfcp_sdev->status); - } else { - if (status_change_clear(mask, &zfcp_sdev->status)) - zfcp_dbf_rec_lun(id, ref, sdev); - atomic_clear_mask(mask, &zfcp_sdev->status); - if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) { - atomic_set(&zfcp_sdev->erp_counter, 0); + if (clear_counter) + atomic_set(&port->erp_counter, 0); + + shost_for_each_device(sdev, port->adapter->scsi_host) + if (sdev_to_zfcp(sdev)->port == port) { + atomic_clear_mask(common_mask, + &sdev_to_zfcp(sdev)->status); + if (clear_counter) + atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); } - } } /** - * zfcp_erp_port_boxed - Mark port as "boxed" and start ERP - * @port: The "boxed" port. - * @id: The debug trace id. - * @id: Reference for the debug trace. + * zfcp_erp_set_lun_status - set lun status bits + * @sdev: SCSI device / lun to set the status bits + * @mask: status bits to change */ -void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref) +void zfcp_erp_set_lun_status(struct scsi_device *sdev, u32 mask) { - zfcp_erp_modify_port_status(port, id, ref, - ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); - zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + + atomic_set_mask(mask, &zfcp_sdev->status); } /** - * zfcp_erp_lun_boxed - Mark LUN as "boxed" and start ERP - * @sdev: The "boxed" SCSI device / LUN. - * @id: The debug trace id. - * @ref: Reference for the debug trace. + * zfcp_erp_clear_lun_status - clear lun status bits + * @sdev: SCSi device / lun to clear the status bits + * @mask: status bits to change */ -void zfcp_erp_lun_boxed(struct scsi_device *sdev, char *id, void *ref) +void zfcp_erp_clear_lun_status(struct scsi_device *sdev, u32 mask) { - zfcp_erp_modify_lun_status(sdev, id, ref, - ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); - zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + + atomic_clear_mask(mask, &zfcp_sdev->status); + + if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) + atomic_set(&zfcp_sdev->erp_counter, 0); } + diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 7320132a430..bf8f3e51483 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -71,31 +71,26 @@ extern void _zfcp_dbf_scsi(const char *, const char *, int, struct zfcp_dbf *, unsigned long); /* zfcp_erp.c */ -extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, char *, - void *, u32, int); +extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32); +extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32); extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *, void *); extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *, void *); -extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, char *, void *); -extern void zfcp_erp_modify_port_status(struct zfcp_port *, char *, void *, u32, - int); +extern void zfcp_erp_set_port_status(struct zfcp_port *, u32); +extern void zfcp_erp_clear_port_status(struct zfcp_port *, u32); extern int zfcp_erp_port_reopen(struct zfcp_port *, int, char *, void *); extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *, void *); extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *, void *); -extern void zfcp_erp_port_failed(struct zfcp_port *, char *, void *); -extern void zfcp_erp_modify_lun_status(struct scsi_device *, char *, void *, - u32, int); +extern void zfcp_erp_set_lun_status(struct scsi_device *, u32); +extern void zfcp_erp_clear_lun_status(struct scsi_device *, u32); extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *, void *); extern void zfcp_erp_lun_shutdown(struct scsi_device *, int, char *, void *); extern void zfcp_erp_lun_shutdown_wait(struct scsi_device *, char *); -extern void zfcp_erp_lun_failed(struct scsi_device *, char *, void *); extern int zfcp_erp_thread_setup(struct zfcp_adapter *); extern void zfcp_erp_thread_kill(struct zfcp_adapter *); extern void zfcp_erp_wait(struct zfcp_adapter *); extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long); -extern void zfcp_erp_port_boxed(struct zfcp_port *, char *, void *); -extern void zfcp_erp_lun_boxed(struct scsi_device *, char *, void *); extern void zfcp_erp_timeout_handler(unsigned long); /* zfcp_fc.c */ diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 6f3ed2b9a34..86fd905df48 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -365,7 +365,7 @@ void zfcp_fc_port_did_lookup(struct work_struct *work) } if (!port->d_id) { - zfcp_erp_port_failed(port, "fcgpn_2", NULL); + zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED); goto out; } diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 813c5b22565..beaf0916cea 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -104,7 +104,7 @@ static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) read_unlock_irqrestore(&adapter->port_list_lock, flags); } -static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id, +static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, struct fsf_link_down_info *link_down) { struct zfcp_adapter *adapter = req->adapter; @@ -184,7 +184,7 @@ static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id, "the FC fabric is down\n"); } out: - zfcp_erp_adapter_failed(adapter, id, req); + zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_ERP_FAILED); } static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req) @@ -195,13 +195,13 @@ static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req) switch (sr_buf->status_subtype) { case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: - zfcp_fsf_link_down_info_eval(req, "fssrld1", ldi); + zfcp_fsf_link_down_info_eval(req, ldi); break; case FSF_STATUS_READ_SUB_FDISC_FAILED: - zfcp_fsf_link_down_info_eval(req, "fssrld2", ldi); + zfcp_fsf_link_down_info_eval(req, ldi); break; case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE: - zfcp_fsf_link_down_info_eval(req, "fssrld3", NULL); + zfcp_fsf_link_down_info_eval(req, NULL); }; } @@ -242,9 +242,8 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) dev_info(&adapter->ccw_device->dev, "The local link has been restored\n"); /* All ports should be marked as ready to run again */ - zfcp_erp_modify_adapter_status(adapter, "fssrh_1", NULL, - ZFCP_STATUS_COMMON_RUNNING, - ZFCP_SET); + zfcp_erp_set_adapter_status(adapter, + ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | ZFCP_STATUS_COMMON_ERP_FAILED, @@ -359,16 +358,14 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req) zfcp_erp_adapter_shutdown(adapter, 0, "fspse_4", req); break; case FSF_PROT_LINK_DOWN: - zfcp_fsf_link_down_info_eval(req, "fspse_5", - &psq->link_down_info); + zfcp_fsf_link_down_info_eval(req, &psq->link_down_info); /* go through reopen to flush pending requests */ zfcp_erp_adapter_reopen(adapter, 0, "fspse_6", req); break; case FSF_PROT_REEST_QUEUE: /* All ports should be marked as ready to run again */ - zfcp_erp_modify_adapter_status(adapter, "fspse_7", NULL, - ZFCP_STATUS_COMMON_RUNNING, - ZFCP_SET); + zfcp_erp_set_adapter_status(adapter, + ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | ZFCP_STATUS_COMMON_ERP_FAILED, @@ -538,7 +535,7 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); - zfcp_fsf_link_down_info_eval(req, "fsecdh2", + zfcp_fsf_link_down_info_eval(req, &qtcb->header.fsf_status_qual.link_down_info); break; default: @@ -604,7 +601,7 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) break; case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: zfcp_fsf_exchange_port_evaluate(req); - zfcp_fsf_link_down_info_eval(req, "fsepdh1", + zfcp_fsf_link_down_info_eval(req, &qtcb->header.fsf_status_qual.link_down_info); break; } @@ -797,11 +794,17 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req) req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED; break; case FSF_PORT_BOXED: - zfcp_erp_port_boxed(zfcp_sdev->port, "fsafch3", req); + zfcp_erp_set_port_status(zfcp_sdev->port, + ZFCP_STATUS_COMMON_ACCESS_BOXED); + zfcp_erp_port_reopen(zfcp_sdev->port, + ZFCP_STATUS_COMMON_ERP_FAILED, "fsafch3", + req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_BOXED: - zfcp_erp_lun_boxed(sdev, "fsafch4", req); + zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ACCESS_BOXED); + zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, + "fsafch4", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ADAPTER_STATUS_AVAILABLE: @@ -1343,7 +1346,8 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) "Not enough FCP adapter resources to open " "remote port 0x%016Lx\n", (unsigned long long)port->wwpn); - zfcp_erp_port_failed(port, "fsoph_1", req); + zfcp_erp_set_port_status(port, + ZFCP_STATUS_COMMON_ERP_FAILED); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ADAPTER_STATUS_AVAILABLE: @@ -1453,9 +1457,7 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req) case FSF_ADAPTER_STATUS_AVAILABLE: break; case FSF_GOOD: - zfcp_erp_modify_port_status(port, "fscph_2", req, - ZFCP_STATUS_COMMON_OPEN, - ZFCP_CLEAR); + zfcp_erp_clear_port_status(port, ZFCP_STATUS_COMMON_OPEN); break; } } @@ -1653,7 +1655,9 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) if (sdev_to_zfcp(sdev)->port == port) atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &sdev_to_zfcp(sdev)->status); - zfcp_erp_port_boxed(port, "fscpph2", req); + zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ACCESS_BOXED); + zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, + "fscpph2", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ADAPTER_STATUS_AVAILABLE: @@ -1751,7 +1755,11 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: - zfcp_erp_port_boxed(zfcp_sdev->port, "fsouh_2", req); + zfcp_erp_set_port_status(zfcp_sdev->port, + ZFCP_STATUS_COMMON_ACCESS_BOXED); + zfcp_erp_port_reopen(zfcp_sdev->port, + ZFCP_STATUS_COMMON_ERP_FAILED, "fsouh_2", + req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_SHARING_VIOLATION: @@ -1764,7 +1772,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) "0x%016Lx on port 0x%016Lx\n", (unsigned long long)zfcp_scsi_dev_lun(sdev), (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_lun_failed(sdev, "fsolh_4", req); + zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); /* fall through */ case FSF_INVALID_COMMAND_OPTION: req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -1856,7 +1864,11 @@ static void zfcp_fsf_close_lun_handler(struct zfcp_fsf_req *req) req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: - zfcp_erp_port_boxed(zfcp_sdev->port, "fscuh_3", req); + zfcp_erp_set_port_status(zfcp_sdev->port, + ZFCP_STATUS_COMMON_ACCESS_BOXED); + zfcp_erp_port_reopen(zfcp_sdev->port, + ZFCP_STATUS_COMMON_ERP_FAILED, "fscuh_3", + req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ADAPTER_STATUS_AVAILABLE: @@ -2032,11 +2044,17 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req) req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_PORT_BOXED: - zfcp_erp_port_boxed(zfcp_sdev->port, "fssfch5", req); + zfcp_erp_set_port_status(zfcp_sdev->port, + ZFCP_STATUS_COMMON_ACCESS_BOXED); + zfcp_erp_port_reopen(zfcp_sdev->port, + ZFCP_STATUS_COMMON_ERP_FAILED, "fssfch5", + req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_LUN_BOXED: - zfcp_erp_lun_boxed(sdev, "fssfch6", req); + zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ACCESS_BOXED); + zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, + "fssfch6", req); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; case FSF_ADAPTER_STATUS_AVAILABLE: diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 1e8d0cc7e1d..ae10883a5b2 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -158,8 +158,7 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) zfcp_sdev->latencies.cmd.fabric.min = 0xFFFFFFFF; spin_lock_init(&zfcp_sdev->latencies.lock); - zfcp_erp_modify_lun_status(sdev, "scsla_0", NULL, - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); + zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_lun_reopen(sdev, 0, "scsla_1", NULL); zfcp_erp_wait(port->adapter); diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 4f59356b07b..2f2c54f4718 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -104,8 +104,7 @@ static ssize_t zfcp_sysfs_port_failed_store(struct device *dev, if (strict_strtoul(buf, 0, &val) || val != 0) return -EINVAL; - zfcp_erp_modify_port_status(port, "sypfai1", NULL, - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); + zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "sypfai2", NULL); zfcp_erp_wait(port->adapter); @@ -147,9 +146,7 @@ static ssize_t zfcp_sysfs_unit_failed_store(struct device *dev, sdev = zfcp_unit_sdev(unit); if (sdev) { - zfcp_erp_modify_lun_status(sdev, "syufai1", NULL, - ZFCP_STATUS_COMMON_RUNNING, - ZFCP_SET); + zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED, "syufai2", NULL); zfcp_erp_wait(unit->port->adapter); @@ -199,8 +196,7 @@ static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev, goto out; } - zfcp_erp_modify_adapter_status(adapter, "syafai1", NULL, - ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); + zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, "syafai2", NULL); zfcp_erp_wait(adapter); -- cgit v1.2.3-18-g5258 From bf5eefb007e7c5498a41af2dd65d957ae9793a63 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Tue, 28 Sep 2010 10:11:06 +0200 Subject: [SCSI] zfcp: Remove scsi_cmnd->serial_number from debug traces With the change that drivers have to explicitly request the serial number for SCSI commands, this field should not be part of the zfcp traces. It is not worth the effort to request the serial number only for tracing purposes, so simply remove this field from the debug traces. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_dbf.c | 4 ---- drivers/s390/scsi/zfcp_dbf.h | 2 -- 2 files changed, 6 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 2224caa8b92..2cdd6b28ff7 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -154,7 +154,6 @@ void _zfcp_dbf_hba_fsf_response(const char *tag2, int level, scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; if (scsi_cmnd) { response->u.fcp.cmnd = (unsigned long)scsi_cmnd; - response->u.fcp.serial = scsi_cmnd->serial_number; response->u.fcp.data_dir = qtcb->bottom.io.data_direction; } @@ -330,7 +329,6 @@ static void zfcp_dbf_hba_view_response(char **p, break; zfcp_dbf_out(p, "data_direction", "0x%04x", r->u.fcp.data_dir); zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); - zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); *p += sprintf(*p, "\n"); break; @@ -881,7 +879,6 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level, } rec->scsi_result = scsi_cmnd->result; rec->scsi_cmnd = (unsigned long)scsi_cmnd; - rec->scsi_serial = scsi_cmnd->serial_number; memcpy(rec->scsi_opcode, scsi_cmnd->cmnd, min((int)scsi_cmnd->cmd_len, ZFCP_DBF_SCSI_OPCODE)); @@ -950,7 +947,6 @@ static int zfcp_dbf_scsi_view_format(debug_info_t *id, struct debug_view *view, zfcp_dbf_out(&p, "scsi_lun", "0x%08x", r->scsi_lun); zfcp_dbf_out(&p, "scsi_result", "0x%08x", r->scsi_result); zfcp_dbf_out(&p, "scsi_cmnd", "0x%0Lx", r->scsi_cmnd); - zfcp_dbf_out(&p, "scsi_serial", "0x%016Lx", r->scsi_serial); zfcp_dbf_outd(&p, "scsi_opcode", r->scsi_opcode, ZFCP_DBF_SCSI_OPCODE, 0, ZFCP_DBF_SCSI_OPCODE); zfcp_dbf_out(&p, "scsi_retries", "0x%02x", r->scsi_retries); diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index 6a48c197b45..04081b1b62b 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h @@ -110,7 +110,6 @@ struct zfcp_dbf_hba_record_response { union { struct { u64 cmnd; - u64 serial; u32 data_dir; } fcp; struct { @@ -206,7 +205,6 @@ struct zfcp_dbf_scsi_record { u32 scsi_lun; u32 scsi_result; u64 scsi_cmnd; - u64 scsi_serial; #define ZFCP_DBF_SCSI_OPCODE 16 u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE]; u8 scsi_retries; -- cgit v1.2.3-18-g5258