zfcp patches for 2.6.33 merge window
Subsystems (4)
cover zfcp patches for 2.6.33 merge window
Here is the series of zfcp patches for the 2.6.33 merge window.
The first patch adds the target reset flag to the fc_fcp.h header file to replace the private zfcp definition of this flag. The other zfcp patches include:
- rework locking and reference counting for zfcp structs
- module unloading
- use common code FC protocol definitions instead of private ones
- minor updates and cleanup
--
Christof Schmitt
PATCH 1/22 SCSI: Add target reset flag to FCP header file
From: Christof Schmitt <[email protected]>
While the target reset task management function has been deprecated in newer specs, it is still in use by SCSI FC drivers and there is no real replacement. Add the target reset flag to the FCP header file to allow usage of this definition in SCSI FC drivers.
---
include/scsi/fc/fc_fcp.h | 2 ++ 1 file changed, 2 insertions(+)
include/scsi/fc/fc_fcp.h +2 -0
@@ -83,6 +83,8 @@ struct fcp_cmnd32 {* fc_tm_flags - task management flags field. */ #define FCP_TMF_CLR_ACA 0x40/* clear ACA condition */ +#define FCP_TMF_TGT_RESET 0x20/* target reset task management, +deprecated as of FCP-3 */ #define FCP_TMF_LUN_RESET 0x10/* logical unit reset task management */ #define FCP_TMF_CLR_TASK_SET 0x04/* clear task set */ #define FCP_TMF_ABT_TASK_SET 0x02/* abort task set */
PATCH 2/22 zfcp: Replace global config_lock with local list locks
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
The global config_lock was used to protect the configuration organized in independent lists. It is not necessary to have a lock on driver level for this purpose. This patch replaces the global config_lock with a set of local list locks.
---
drivers/s390/scsi/zfcp_aux.c | 80 ++++++++++++++++------------ drivers/s390/scsi/zfcp_ccw.c | 23 ++++---- drivers/s390/scsi/zfcp_def.h | 9 +-- drivers/s390/scsi/zfcp_erp.c | 116 +++++++++++++++++++++-------------------- drivers/s390/scsi/zfcp_fc.c | 49 +++++++---------- drivers/s390/scsi/zfcp_fsf.c | 22 +++---- drivers/s390/scsi/zfcp_scsi.c | 52 ++++++++---------- drivers/s390/scsi/zfcp_sysfs.c | 48 +++++++--------- 8 files changed, 199 insertions(+), 200 deletions(-)
drivers/s390/scsi/zfcp_aux.c +46 -34
@@ -187,7 +187,6 @@ static int __init zfcp_module_init(void) goto out_gid_cache;mutex_init (&zfcp_data.config_mutex); -rwlock_init (&zfcp_data.config_lock); zfcp_data.scsi_transport_template =fc_attach_transport (&zfcp_transport_functions);
@@ -238,12 +237,18 @@ module_init(zfcp_module_init);*/ struct zfcp_unit *zfcp_get_unit_by_lun (struct zfcp_port *port,u64 fcp_lun) { +unsigned long flags;struct zfcp_unit *unit; -list_for_each_entry (unit, &port->unit_list_head, list) +read_lock_irqsave (&port->unit_list_lock, flags); +list_for_each_entry (unit, &port->unit_list, list)if ((unit->fcp_lun == fcp_lun) && - !(atomic_read (&unit->status) &ZFCP_STATUS_COMMON_REMOVE )) -return unit; + !(atomic_read (&unit->status) &ZFCP_STATUS_COMMON_REMOVE )) { +zfcp_unit_get (unit); +read_unlock_irqrestore (&port->unit_list_lock, flags); +return unit; + } +read_unlock_irqrestore (&port->unit_list_lock, flags);return NULL ; }
@@ -257,12 +262,18 @@ struct zfcp_unit *zfcp_get_unit_by_lun(sstruct zfcp_port *zfcp_get_port_by_wwpn (struct zfcp_adapter *adapter,u64 wwpn) { +unsigned long flags;struct zfcp_port *port; -list_for_each_entry (port, &adapter->port_list_head, list) +read_lock_irqsave (&adapter->port_list_lock, flags); +list_for_each_entry (port, &adapter->port_list, list)if ((port->wwpn == wwpn) && - !(atomic_read (&port->status) &ZFCP_STATUS_COMMON_REMOVE )) + !(atomic_read (&port->status) &ZFCP_STATUS_COMMON_REMOVE )) { +zfcp_port_get (port); +read_unlock_irqrestore (&adapter->port_list_lock, flags);return port; + } +read_unlock_irqrestore (&adapter->port_list_lock, flags);return NULL ; }
@@ -284,12 +295,11 @@ struct zfcp_unit *zfcp_unit_enqueue(stru {struct zfcp_unit *unit; -read_lock_irq (&zfcp_data.config_lock); -if (zfcp_get_unit_by_lun (port, fcp_lun)) { -read_unlock_irq (&zfcp_data.config_lock); + unit =zfcp_get_unit_by_lun (port, fcp_lun); +if (unit) { +zfcp_unit_put (unit);return ERR_PTR (-EINVAL ); } -read_unlock_irq (&zfcp_data.config_lock); unit =kzalloc (sizeof (struct zfcp_unit ),GFP_KERNEL );if (!unit)
@@ -335,13 +345,13 @@ struct zfcp_unit *zfcp_unit_enqueue(struzfcp_unit_get (unit); -write_lock_irq (&zfcp_data.config_lock); -list_add_tail (&unit->list, &port->unit_list_head); +write_lock_irq (&port->unit_list_lock); +list_add_tail (&unit->list, &port->unit_list); +write_unlock_irq (&port->unit_list_lock); +atomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &unit->status);atomic_set_mask (ZFCP_STATUS_COMMON_RUNNING , &unit->status); -write_unlock_irq (&zfcp_data.config_lock); -zfcp_port_get (port);return unit;
@@ -356,11 +366,11 @@ struct zfcp_unit *zfcp_unit_enqueue(stru*/ void zfcp_unit_dequeue (struct zfcp_unit *unit) { +struct zfcp_port *port = unit->port; +wait_event (unit->remove_wq,atomic_read (&unit->refcount) ==0 ); -write_lock_irq (&zfcp_data.config_lock); -list_del (&unit->list); -write_unlock_irq (&zfcp_data.config_lock); -zfcp_port_put (unit->port); +list_del (&unit->list);/* no list locking required */ +zfcp_port_put (port);sysfs_remove_group (&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs);device_unregister (&unit->sysfs_device); }
@@ -539,11 +549,13 @@ int zfcp_adapter_enqueue(struct ccw_deviif (zfcp_fc_gs_setup (adapter)) goto generic_services_failed; +rwlock_init (&adapter->port_list_lock); +INIT_LIST_HEAD (&adapter->port_list); +init_waitqueue_head (&adapter->remove_wq);init_waitqueue_head (&adapter->erp_ready_wq);init_waitqueue_head (&adapter->erp_done_wqh); -INIT_LIST_HEAD (&adapter->port_list_head);INIT_LIST_HEAD (&adapter->erp_ready_head);INIT_LIST_HEAD (&adapter->erp_running_head);
@@ -650,19 +662,20 @@ struct zfcp_port *zfcp_port_enqueue(stru {struct zfcp_port *port; -read_lock_irq (&zfcp_data.config_lock); -if (zfcp_get_port_by_wwpn (adapter, wwpn)) { -read_unlock_irq (&zfcp_data.config_lock); -return ERR_PTR (-EINVAL ); + port =zfcp_get_port_by_wwpn (adapter, wwpn); +if (port) { +zfcp_port_put (port); +return ERR_PTR (-EEXIST ); } -read_unlock_irq (&zfcp_data.config_lock); port =kzalloc (sizeof (struct zfcp_port ),GFP_KERNEL );if (!port)return ERR_PTR (-ENOMEM ); +rwlock_init (&port->unit_list_lock); +INIT_LIST_HEAD (&port->unit_list); +init_waitqueue_head (&port->remove_wq); -INIT_LIST_HEAD (&port->unit_list_head);INIT_WORK (&port->gid_pn_work, zfcp_fc_port_did_lookup);INIT_WORK (&port->test_link_work, zfcp_fc_link_test_work);INIT_WORK (&port->rport_work, zfcp_scsi_rport_work);
@@ -698,13 +711,13 @@ struct zfcp_port *zfcp_port_enqueue(struzfcp_port_get (port); -write_lock_irq (&zfcp_data.config_lock); -list_add_tail (&port->list, &adapter->port_list_head); +write_lock_irq (&adapter->port_list_lock); +list_add_tail (&port->list, &adapter->port_list); +write_unlock_irq (&adapter->port_list_lock); +atomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &port->status);atomic_set_mask (ZFCP_STATUS_COMMON_RUNNING , &port->status); -write_unlock_irq (&zfcp_data.config_lock); -zfcp_adapter_get (adapter);return port; }
@@ -715,12 +728,11 @@ struct zfcp_port *zfcp_port_enqueue(stru*/ void zfcp_port_dequeue (struct zfcp_port *port) { -write_lock_irq (&zfcp_data.config_lock); -list_del (&port->list); -write_unlock_irq (&zfcp_data.config_lock); +struct zfcp_adapter *adapter = port->adapter; + +list_del (&port->list);/* no list locking required here */ wait_event (port->remove_wq,atomic_read (&port->refcount) ==0 ); -cancel_work_sync (&port->rport_work);/* usually not necessary */ -zfcp_adapter_put (port->adapter); +zfcp_adapter_put (adapter);sysfs_remove_group (&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);device_unregister (&port->sysfs_device); }
drivers/s390/scsi/zfcp_ccw.c +12 -11
@@ -100,10 +100,11 @@ static void zfcp_ccw_remove(struct ccw_dmutex_lock (&zfcp_data.config_mutex); adapter =dev_get_drvdata (&ccw_device->dev); -if (!adapter) - goto out;mutex_unlock (&zfcp_data.config_mutex); +if (!adapter) +return ; +cancel_work_sync (&adapter->scan_work);mutex_lock (&zfcp_data.config_mutex);
@@ -111,18 +112,21 @@ static void zfcp_ccw_remove(struct ccw_d/* this also removes the scsi devices, so call it first */ zfcp_adapter_scsi_unregister (adapter); -write_lock_irq (&zfcp_data.config_lock); -list_for_each_entry_safe (port, p, &adapter->port_list_head, list) { -list_for_each_entry_safe (unit, u, &port->unit_list_head, list) { -list_move (&unit->list, &unit_remove_lh); +write_lock_irq (&adapter->port_list_lock); +list_for_each_entry_safe (port, p, &adapter->port_list, list) { +write_lock (&port->unit_list_lock); +list_for_each_entry_safe (unit, u, &port->unit_list, list) {atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , &unit->status); +list_move (&unit->list, &unit_remove_lh); } -list_move (&port->list, &port_remove_lh); +write_unlock (&port->unit_list_lock);atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , &port->status); +list_move (&port->list, &port_remove_lh); }atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , &adapter->status); -write_unlock_irq (&zfcp_data.config_lock); +write_unlock_irq (&adapter->port_list_lock); +mutex_unlock (&zfcp_data.config_mutex);list_for_each_entry_safe (port, p, &port_remove_lh, list) {list_for_each_entry_safe (unit, u, &unit_remove_lh, list)
@@ -131,9 +135,6 @@ static void zfcp_ccw_remove(struct ccw_d }wait_event (adapter->remove_wq,atomic_read (&adapter->refcount) ==0 );zfcp_adapter_dequeue (adapter); - -out: -mutex_unlock (&zfcp_data.config_mutex); }/**
drivers/s390/scsi/zfcp_def.h +4 -5
@@ -461,7 +461,8 @@ struct zfcp_adapter {u32 hardware_version;/* of FCP channel */ u16 timer_ticks;/* time int for a tick */ struct Scsi_Host *scsi_host;/* Pointer to mid-layer */ -struct list_head port_list_head;/* remote port list */ +struct list_head port_list;/* remote port list */ +rwlock_t port_list_lock;/* port list lock */ unsigned long req_no;/* unique FSF req number */ struct list_head *req_list;/* list of pending reqs */ spinlock_t req_list_lock;/* request list lock */
@@ -504,7 +505,8 @@ struct zfcp_port {wait_queue_head_t remove_wq;/* can be used to wait for refcount drop to zero */ struct zfcp_adapter *adapter;/* adapter used to access port */ -struct list_head unit_list_head;/* head of logical unit list */ +struct list_head unit_list;/* head of logical unit list */ +rwlock_t unit_list_lock;/* unit list lock */ atomic_t status;/* status of this remote port */ u64 wwnn;/* WWNN if known */ u64 wwpn;/* WWPN */
@@ -601,9 +603,6 @@ struct zfcp_fsf_req {struct zfcp_data {struct scsi_host_template scsi_host_template;struct scsi_transport_template *scsi_transport_template; -rwlock_t config_lock;/* serialises changes -to adapter/port/unit -lists */ struct mutex config_mutex;struct kmem_cache *gpn_ft_cache;struct kmem_cache *qtcb_cache;
drivers/s390/scsi/zfcp_erp.c +61 -55
272 lines not on this page · raw message
drivers/s390/scsi/zfcp_fc.c +22 -27
120 lines not on this page · raw message
drivers/s390/scsi/zfcp_fsf.c +11 -11
@@ -122,36 +122,32 @@ void zfcp_fsf_req_free(struct zfcp_fsf_rstatic void zfcp_fsf_status_read_port_closed (struct zfcp_fsf_req *req) { +unsigned long flags;struct fsf_status_read_buffer *sr_buf = req->data;struct zfcp_adapter *adapter = req->adapter;struct zfcp_port *port;int d_id = sr_buf->d_id &ZFCP_DID_MASK ; -unsigned long flags; -read_lock_irqsave (&zfcp_data.config_lock, flags); -list_for_each_entry (port, &adapter->port_list_head, list) +read_lock_irqsave (&adapter->port_list_lock, flags); +list_for_each_entry (port, &adapter->port_list, list)if (port->d_id == d_id) { -read_unlock_irqrestore (&zfcp_data.config_lock, flags);zfcp_erp_port_reopen (port,0 ,"fssrpc1" , req); -return ; +break ; } -read_unlock_irqrestore (&zfcp_data.config_lock, flags); +read_unlock_irqrestore (&adapter->port_list_lock, flags); }static void zfcp_fsf_link_down_info_eval (struct zfcp_fsf_req *req,char *id,struct fsf_link_down_info *link_down) {struct zfcp_adapter *adapter = req->adapter; -unsigned long flags;if (atomic_read (&adapter->status) &ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED )return ;atomic_set_mask (ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED , &adapter->status); -read_lock_irqsave (&zfcp_data.config_lock, flags);zfcp_scsi_schedule_rports_block (adapter); -read_unlock_irqrestore (&zfcp_data.config_lock, flags);if (!link_down) goto out;
@@ -1765,9 +1761,11 @@ static void zfcp_fsf_close_physical_port/* 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); -list_for_each_entry (unit, &port->unit_list_head, list) +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);zfcp_erp_port_boxed (port,"fscpph2" , req); req->status |=ZFCP_STATUS_FSFREQ_ERROR |ZFCP_STATUS_FSFREQ_RETRY ;
@@ -1787,9 +1785,11 @@ static void zfcp_fsf_close_physical_port* ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ atomic_clear_mask (ZFCP_STATUS_PORT_PHYS_OPEN , &port->status); -list_for_each_entry (unit, &port->unit_list_head, list) +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);break ; } }
drivers/s390/scsi/zfcp_scsi.c +23 -29
112 lines not on this page · raw message
drivers/s390/scsi/zfcp_sysfs.c +20 -28
70 lines not on this page · raw message
PATCH 3/22 zfcp: Replace local reference counting with common kref
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
Replace the local reference counting by already available mechanisms offered by kref. Where possible existing device structures were used, including the same functionality.
---
drivers/s390/scsi/zfcp_aux.c | 231 +++++++++++++++++++---------------------- drivers/s390/scsi/zfcp_ccw.c | 16 +- drivers/s390/scsi/zfcp_cfdc.c | 5 drivers/s390/scsi/zfcp_dbf.c | 2 drivers/s390/scsi/zfcp_def.h | 53 --------- drivers/s390/scsi/zfcp_erp.c | 20 +-- drivers/s390/scsi/zfcp_ext.h | 6 - drivers/s390/scsi/zfcp_fc.c | 42 ++++--- drivers/s390/scsi/zfcp_fsf.c | 12 +- drivers/s390/scsi/zfcp_scsi.c | 23 +--- drivers/s390/scsi/zfcp_sysfs.c | 46 +++----- 11 files changed, 197 insertions(+), 259 deletions(-)
drivers/s390/scsi/zfcp_aux.c +108 -123
@@ -96,13 +96,12 @@ static void __init zfcp_init_device_conf adapter =dev_get_drvdata (&ccwdev->dev);if (!adapter) goto out_unlock; -zfcp_adapter_get (adapter); +kref_get (&adapter->ref); port =zfcp_get_port_by_wwpn (adapter, wwpn);if (!port) goto out_port; -zfcp_port_get (port); unit =zfcp_unit_enqueue (port, lun);if (IS_ERR (unit)) goto out_unit;
@@ -113,11 +112,10 @@ static void __init zfcp_init_device_confflush_work (&unit->scsi_work);mutex_lock (&zfcp_data.config_mutex); -zfcp_unit_put (unit); out_unit: -zfcp_port_put (port); +put_device (&port->sysfs_device); out_port: -zfcp_adapter_put (adapter); +kref_put (&adapter->ref, zfcp_adapter_release); out_unlock:mutex_unlock (&zfcp_data.config_mutex); out_ccwdev:
@@ -244,7 +242,7 @@ struct zfcp_unit *zfcp_get_unit_by_lun(slist_for_each_entry (unit, &port->unit_list, list)if ((unit->fcp_lun == fcp_lun) && !(atomic_read (&unit->status) &ZFCP_STATUS_COMMON_REMOVE )) { -zfcp_unit_get (unit); +get_device (&unit->sysfs_device);read_unlock_irqrestore (&port->unit_list_lock, flags);return unit; }
@@ -269,7 +267,7 @@ struct zfcp_port *zfcp_get_port_by_wwpn(list_for_each_entry (port, &adapter->port_list, list)if ((port->wwpn == wwpn) && !(atomic_read (&port->status) &ZFCP_STATUS_COMMON_REMOVE )) { -zfcp_port_get (port); +get_device (&port->sysfs_device);read_unlock_irqrestore (&adapter->port_list_lock, flags);return port; }
@@ -277,9 +275,20 @@ struct zfcp_port *zfcp_get_port_by_wwpn(return NULL ; } -static void zfcp_sysfs_unit_release (struct device *dev) +/** +* 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) { -kfree (container_of(dev ,struct zfcp_unit ,sysfs_device )); + struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, + sysfs_device); + +put_device (&unit->port->sysfs_device); +kfree (unit); }/**
@@ -294,36 +303,39 @@ static void zfcp_sysfs_unit_release(strustruct zfcp_unit *zfcp_unit_enqueue (struct zfcp_port *port,u64 fcp_lun) {struct zfcp_unit *unit; +int retval = -ENOMEM ; + +get_device (&port->sysfs_device); unit =zfcp_get_unit_by_lun (port, fcp_lun);if (unit) { -zfcp_unit_put (unit); -return ERR_PTR (-EINVAL ); +put_device (&unit->sysfs_device); + retval = -EEXIST ; + goto err_out; } unit =kzalloc (sizeof (struct zfcp_unit ),GFP_KERNEL );if (!unit) -return ERR_PTR (-ENOMEM ); - -atomic_set (&unit->refcount,0 ); -init_waitqueue_head (&unit->remove_wq); -INIT_WORK (&unit->scsi_work, zfcp_scsi_scan); + goto err_out; unit->port = port; unit->fcp_lun = fcp_lun; + unit->sysfs_device.parent = &port->sysfs_device; + unit->sysfs_device.release = zfcp_unit_release;if (dev_set_name (&unit->sysfs_device,"0x%016llx" , (unsigned long long ) fcp_lun)) {kfree (unit); -return ERR_PTR (-ENOMEM ); + goto err_out; } - unit->sysfs_device.parent = &port->sysfs_device; - unit->sysfs_device.release = zfcp_sysfs_unit_release;dev_set_drvdata (&unit->sysfs_device, unit); + retval = -EINVAL ;/* mark unit unusable as long as sysfs registration is not complete */ atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , &unit->status); +INIT_WORK (&unit->scsi_work, zfcp_scsi_scan); +spin_lock_init (&unit->latencies.lock); unit->latencies.write.channel.min =0xFFFFFFFF ; unit->latencies.write.fabric.min =0xFFFFFFFF ;
@@ -334,16 +346,12 @@ struct zfcp_unit *zfcp_unit_enqueue(struif (device_register (&unit->sysfs_device)) {put_device (&unit->sysfs_device); -return ERR_PTR (-EINVAL ); + goto err_out; }if (sysfs_create_group (&unit->sysfs_device.kobj, - &zfcp_sysfs_unit_attrs)) { -device_unregister (&unit->sysfs_device); -return ERR_PTR (-EINVAL ); - } - -zfcp_unit_get (unit); + &zfcp_sysfs_unit_attrs)) + goto err_out_put;write_lock_irq (&port->unit_list_lock);list_add_tail (&unit->list, &port->unit_list);
@@ -352,27 +360,13 @@ struct zfcp_unit *zfcp_unit_enqueue(struatomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &unit->status);atomic_set_mask (ZFCP_STATUS_COMMON_RUNNING , &unit->status); -zfcp_port_get (port); -return unit; -} - -/** -* zfcp_unit_dequeue - dequeue unit -* @unit: pointer to zfcp_unit -* -* waits until all work is done on unit and removes it then from the unit->list -* of the associated port. -*/ -void zfcp_unit_dequeue (struct zfcp_unit *unit) -{ -struct zfcp_port *port = unit->port; -wait_event (unit->remove_wq,atomic_read (&unit->refcount) ==0 ); -list_del (&unit->list);/* no list locking required */ -zfcp_port_put (port); -sysfs_remove_group (&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs); +err_out_put:device_unregister (&unit->sysfs_device); +err_out: +put_device (&port->sysfs_device); +return ERR_PTR (retval); }static int zfcp_allocate_low_mem_buffers (struct zfcp_adapter *adapter)
@@ -518,41 +512,44 @@ int zfcp_adapter_enqueue(struct ccw_devi {struct zfcp_adapter *adapter; -/* -* Note: It is safe to release the list_lock, as any list changes -* are protected by the config_mutex, which must be held to get here -*/ +if (!get_device (&ccw_device->dev)) +return -ENODEV ; adapter =kzalloc (sizeof (struct zfcp_adapter ),GFP_KERNEL ); -if (!adapter) +if (!adapter) { +put_device (&ccw_device->dev);return -ENOMEM ; + } + +kref_init (&adapter->ref); ccw_device->handler =NULL ; adapter->ccw_device = ccw_device; -atomic_set (&adapter->refcount,0 ); + +INIT_WORK (&adapter->stat_work, _zfcp_status_read_scheduler); +INIT_WORK (&adapter->scan_work, _zfcp_fc_scan_ports_later);if (zfcp_qdio_setup (adapter)) - goto qdio_failed; + goto failed;if (zfcp_allocate_low_mem_buffers (adapter)) - goto low_mem_buffers_failed; + goto failed;if (zfcp_reqlist_alloc (adapter)) - goto low_mem_buffers_failed; + goto failed;if (zfcp_dbf_adapter_register (adapter)) - goto debug_register_failed; + goto failed;if (zfcp_setup_adapter_work_queue (adapter)) - goto work_queue_failed; + goto failed;if (zfcp_fc_gs_setup (adapter)) - goto generic_services_failed; + goto failed;rwlock_init (&adapter->port_list_lock);INIT_LIST_HEAD (&adapter->port_list); -init_waitqueue_head (&adapter->remove_wq);init_waitqueue_head (&adapter->erp_ready_wq);init_waitqueue_head (&adapter->erp_done_wqh);
@@ -565,10 +562,7 @@ int zfcp_adapter_enqueue(struct ccw_devirwlock_init (&adapter->abort_lock);if (zfcp_erp_thread_setup (adapter)) - goto erp_thread_failed; - -INIT_WORK (&adapter->stat_work, _zfcp_status_read_scheduler); -INIT_WORK (&adapter->scan_work, _zfcp_fc_scan_ports_later); + goto failed; adapter->service_level.seq_print = zfcp_print_sl;
@@ -579,54 +573,37 @@ int zfcp_adapter_enqueue(struct ccw_deviif (sysfs_create_group (&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs)) - goto sysfs_failed; + goto failed;atomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &adapter->status);if (!zfcp_adapter_scsi_register (adapter))return 0 ; -sysfs_failed: -zfcp_erp_thread_kill (adapter); -erp_thread_failed: -zfcp_fc_gs_destroy (adapter); -generic_services_failed: -zfcp_destroy_adapter_work_queue (adapter); -work_queue_failed: -zfcp_dbf_adapter_unregister (adapter->dbf); -debug_register_failed: -dev_set_drvdata (&ccw_device->dev,NULL ); -kfree (adapter->req_list); -low_mem_buffers_failed: -zfcp_free_low_mem_buffers (adapter); -qdio_failed: -zfcp_qdio_destroy (adapter->qdio); -kfree (adapter); +failed: +kref_put (&adapter->ref, zfcp_adapter_release);return -ENOMEM ; }/** -* zfcp_adapter_dequeue - remove the adapter from the resource list -* @adapter: pointer to struct zfcp_adapter which should be removed +* zfcp_adapter_release - remove the adapter from the resource list +* @ref: pointer to struct kref * locks: adapter list write lock is assumed to be held by caller */ -void zfcp_adapter_dequeue (struct zfcp_adapter *adapter) +void zfcp_adapter_release (struct kref *ref) { -int retval =0 ; -unsigned long flags; + struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter, + ref); +struct ccw_device *ccw_device = adapter->ccw_device;cancel_work_sync (&adapter->stat_work); +zfcp_fc_wka_ports_force_offline (adapter->gs); -sysfs_remove_group (&adapter->ccw_device->dev.kobj, - &zfcp_sysfs_adapter_attrs); -dev_set_drvdata (&adapter->ccw_device->dev,NULL ); -/* sanity check: no pending FSF requests */ -spin_lock_irqsave (&adapter->req_list_lock, flags); - retval =zfcp_reqlist_isempty (adapter); -spin_unlock_irqrestore (&adapter->req_list_lock, flags); -if (!retval) -return ; +sysfs_remove_group (&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs); + +dev_set_drvdata (&ccw_device->dev,NULL ); +dev_set_drvdata (&adapter->ccw_device->dev,NULL );zfcp_fc_gs_destroy (adapter);zfcp_erp_thread_kill (adapter);zfcp_destroy_adapter_work_queue (adapter);
@@ -637,11 +614,30 @@ void zfcp_adapter_dequeue(struct zfcp_adkfree (adapter->fc_stats);kfree (adapter->stats_reset_data);kfree (adapter); +put_device (&ccw_device->dev); +} + +/** +* zfcp_device_unregister - remove port, unit from system +* @dev: reference to device which is to be removed +* @grp: related reference to attribute group +* +* Helper function to unregister port, unit from system +*/ +void zfcp_device_unregister (struct device *dev, +const struct attribute_group *grp) +{ +sysfs_remove_group (&dev->kobj, grp); +device_unregister (dev); } -static void zfcp_sysfs_port_release (struct device *dev) +static void zfcp_port_release (struct device *dev) { -kfree (container_of(dev ,struct zfcp_port ,sysfs_device )); + struct zfcp_port *port = container_of(dev, struct zfcp_port, + sysfs_device); + +kref_put (&port->adapter->ref, zfcp_adapter_release); +kfree (port); }/**
@@ -661,21 +657,24 @@ struct zfcp_port *zfcp_port_enqueue(stru u32 status, u32 d_id) {struct zfcp_port *port; +int retval = -ENOMEM ; + +kref_get (&adapter->ref); port =zfcp_get_port_by_wwpn (adapter, wwpn);if (port) { -zfcp_port_put (port); -return ERR_PTR (-EEXIST ); +put_device (&port->sysfs_device); + retval = -EEXIST ; + goto err_out; } port =kzalloc (sizeof (struct zfcp_port ),GFP_KERNEL );if (!port) -return ERR_PTR (-ENOMEM ); + goto err_out;rwlock_init (&port->unit_list_lock);INIT_LIST_HEAD (&port->unit_list); -init_waitqueue_head (&port->remove_wq);INIT_WORK (&port->gid_pn_work, zfcp_fc_port_did_lookup);INIT_WORK (&port->test_link_work, zfcp_fc_link_test_work);INIT_WORK (&port->rport_work, zfcp_scsi_rport_work);
@@ -684,32 +683,28 @@ struct zfcp_port *zfcp_port_enqueue(stru port->d_id = d_id; port->wwpn = wwpn; port->rport_task =RPORT_NONE ; + port->sysfs_device.parent = &adapter->ccw_device->dev; + port->sysfs_device.release = zfcp_port_release;/* mark port unusable as long as sysfs registration is not complete */ atomic_set_mask (status |ZFCP_STATUS_COMMON_REMOVE , &port->status); -atomic_set (&port->refcount,0 );if (dev_set_name (&port->sysfs_device,"0x%016llx" , (unsigned long long )wwpn)) {kfree (port); -return ERR_PTR (-ENOMEM ); + goto err_out; } - port->sysfs_device.parent = &adapter->ccw_device->dev; - port->sysfs_device.release = zfcp_sysfs_port_release;dev_set_drvdata (&port->sysfs_device, port); + retval = -EINVAL ;if (device_register (&port->sysfs_device)) {put_device (&port->sysfs_device); -return ERR_PTR (-EINVAL ); + goto err_out; }if (sysfs_create_group (&port->sysfs_device.kobj, - &zfcp_sysfs_port_attrs)) { -device_unregister (&port->sysfs_device); -return ERR_PTR (-EINVAL ); - } - -zfcp_port_get (port); + &zfcp_sysfs_port_attrs)) + goto err_out_put;write_lock_irq (&adapter->port_list_lock);list_add_tail (&port->list, &adapter->port_list);
@@ -718,23 +713,13 @@ struct zfcp_port *zfcp_port_enqueue(struatomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &port->status);atomic_set_mask (ZFCP_STATUS_COMMON_RUNNING , &port->status); -zfcp_adapter_get (adapter);return port; -} -/** -* zfcp_port_dequeue - dequeues a port from the port list of the adapter -* @port: pointer to struct zfcp_port which should be removed -*/ -void zfcp_port_dequeue (struct zfcp_port *port) -{ -struct zfcp_adapter *adapter = port->adapter; - -list_del (&port->list);/* no list locking required here */ -wait_event (port->remove_wq,atomic_read (&port->refcount) ==0 ); -zfcp_adapter_put (adapter); -sysfs_remove_group (&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs); +err_out_put:device_unregister (&port->sysfs_device); +err_out: +kref_put (&adapter->ref, zfcp_adapter_release); +return ERR_PTR (retval); }/**
drivers/s390/scsi/zfcp_ccw.c +9 -7
@@ -128,13 +128,15 @@ static void zfcp_ccw_remove(struct ccw_dwrite_unlock_irq (&adapter->port_list_lock);mutex_unlock (&zfcp_data.config_mutex); -list_for_each_entry_safe (port, p, &port_remove_lh, list) { -list_for_each_entry_safe (unit, u, &unit_remove_lh, list) -zfcp_unit_dequeue (unit); -zfcp_port_dequeue (port); - } -wait_event (adapter->remove_wq,atomic_read (&adapter->refcount) ==0 ); -zfcp_adapter_dequeue (adapter); +list_for_each_entry_safe (unit, u, &unit_remove_lh, list) +zfcp_device_unregister (&unit->sysfs_device, + &zfcp_sysfs_unit_attrs); + +list_for_each_entry_safe (port, p, &port_remove_lh, list) +zfcp_device_unregister (&port->sysfs_device, + &zfcp_sysfs_port_attrs); + +kref_put (&adapter->ref, zfcp_adapter_release); }/**
drivers/s390/scsi/zfcp_cfdc.c +2 -3
@@ -98,7 +98,7 @@ static struct zfcp_adapter *zfcp_cfdc_geif (!adapter) goto out_put; -zfcp_adapter_get (adapter); +kref_get (&adapter->ref); out_put:put_device (&ccwdev->dev); out:
@@ -212,7 +212,6 @@ static long zfcp_cfdc_dev_ioctl(struct f retval = -ENXIO ; goto free_buffer; } -zfcp_adapter_get (adapter); retval =zfcp_cfdc_sg_setup (data->command, fsf_cfdc->sg, data_user->control_file);
@@ -245,7 +244,7 @@ static long zfcp_cfdc_dev_ioctl(struct f free_sg:zfcp_sg_free_table (fsf_cfdc->sg,ZFCP_CFDC_PAGES ); adapter_put: -zfcp_adapter_put (adapter); +kref_put (&adapter->ref, zfcp_adapter_release); free_buffer:kfree (data); no_mem_sense:
drivers/s390/scsi/zfcp_dbf.c +2 -0
@@ -1067,6 +1067,8 @@ err_out:*/ void zfcp_dbf_adapter_unregister (struct zfcp_dbf *dbf) { +if (!dbf) +return ;debug_unregister (dbf->scsi);debug_unregister (dbf->san);debug_unregister (dbf->hba);
drivers/s390/scsi/zfcp_def.h +1 -52
75 lines not on this page · raw message
drivers/s390/scsi/zfcp_erp.c +11 -9
@@ -174,7 +174,7 @@ static struct zfcp_erp_action *zfcp_erp_switch (need) {case ZFCP_ERP_ACTION_REOPEN_UNIT : -zfcp_unit_get (unit); +get_device (&unit->sysfs_device);atomic_set_mask (ZFCP_STATUS_COMMON_ERP_INUSE , &unit->status); erp_action = &unit->erp_action;if (!(atomic_read (&unit->status) &ZFCP_STATUS_COMMON_RUNNING ))
@@ -183,7 +183,7 @@ static struct zfcp_erp_action *zfcp_erp_case ZFCP_ERP_ACTION_REOPEN_PORT :case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED : -zfcp_port_get (port); +get_device (&port->sysfs_device);zfcp_erp_action_dismiss_port (port);atomic_set_mask (ZFCP_STATUS_COMMON_ERP_INUSE , &port->status); erp_action = &port->erp_action;
@@ -192,7 +192,7 @@ static struct zfcp_erp_action *zfcp_erp_break ;case ZFCP_ERP_ACTION_REOPEN_ADAPTER : -zfcp_adapter_get (adapter); +kref_get (&adapter->ref);zfcp_erp_action_dismiss_adapter (adapter);atomic_set_mask (ZFCP_STATUS_COMMON_ERP_INUSE , &adapter->status); erp_action = &adapter->erp_action;
@@ -1177,19 +1177,19 @@ static void zfcp_erp_action_cleanup(struswitch (act->action) {case ZFCP_ERP_ACTION_REOPEN_UNIT :if ((result ==ZFCP_ERP_SUCCEEDED ) && !unit->device) { -zfcp_unit_get (unit); +get_device (&unit->sysfs_device);if (scsi_queue_work (unit->port->adapter->scsi_host, &unit->scsi_work) <=0 ) -zfcp_unit_put (unit); +put_device (&unit->sysfs_device); } -zfcp_unit_put (unit); +put_device (&unit->sysfs_device);break ;case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED :case ZFCP_ERP_ACTION_REOPEN_PORT :if (result ==ZFCP_ERP_SUCCEEDED )zfcp_scsi_schedule_rport_register (port); -zfcp_port_put (port); +put_device (&port->sysfs_device);break ;case ZFCP_ERP_ACTION_REOPEN_ADAPTER :
@@ -1198,7 +1198,7 @@ static void zfcp_erp_action_cleanup(struschedule_work (&adapter->scan_work); }else unregister_service_level (&adapter->service_level); -zfcp_adapter_put (adapter); +kref_put (&adapter->ref, zfcp_adapter_release);break ; } }
@@ -1224,8 +1224,9 @@ static int zfcp_erp_strategy(struct zfcpunsigned long flags;struct zfcp_adapter *adapter = erp_action->adapter; -write_lock_irqsave (&adapter->erp_lock, flags); +kref_get (&adapter->ref); +write_lock_irqsave (&adapter->erp_lock, flags);zfcp_erp_strategy_check_fsfreq (erp_action);if (erp_action->status &ZFCP_STATUS_ERP_DISMISSED ) {
@@ -1282,6 +1283,7 @@ static int zfcp_erp_strategy(struct zfcpif (retval !=ZFCP_ERP_CONTINUES )zfcp_erp_action_cleanup (erp_action, retval); +kref_put (&adapter->ref, zfcp_adapter_release);return retval; }
drivers/s390/scsi/zfcp_ext.h +3 -3
@@ -15,15 +15,15 @@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 int zfcp_adapter_enqueue (struct ccw_device *); -extern void zfcp_adapter_dequeue (struct zfcp_adapter *);extern struct zfcp_port *zfcp_port_enqueue (struct zfcp_adapter *,u64 ,u32 ,u32 ); -extern void zfcp_port_dequeue (struct zfcp_port *);extern struct zfcp_unit *zfcp_unit_enqueue (struct zfcp_port *,u64 ); -extern void zfcp_unit_dequeue (struct zfcp_unit *);extern int zfcp_reqlist_isempty (struct zfcp_adapter *);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 *, +const struct attribute_group *); +extern void zfcp_adapter_release (struct kref *);/* zfcp_ccw.c */ extern int zfcp_ccw_register (void );
drivers/s390/scsi/zfcp_fc.c +25 -17
119 lines not on this page · raw message
drivers/s390/scsi/zfcp_fsf.c +6 -6
@@ -1492,7 +1492,7 @@ static void zfcp_fsf_open_port_handler(s } out: -zfcp_port_put (port); +put_device (&port->sysfs_device); }/**
@@ -1530,14 +1530,14 @@ int zfcp_fsf_open_port(struct zfcp_erp_a req->data = port; req->erp_action = erp_action; erp_action->fsf_req = req; -zfcp_port_get (port); +get_device (&port->sysfs_device);zfcp_fsf_start_erp_timer (req); retval =zfcp_fsf_req_send (req);if (retval) {zfcp_fsf_req_free (req); erp_action->fsf_req =NULL ; -zfcp_port_put (port); +put_device (&port->sysfs_device); } out:spin_unlock_bh (&qdio->req_q_lock);
@@ -2335,7 +2335,7 @@ skip_fsfstatus:else {zfcp_fsf_send_fcp_command_task_handler (req); req->unit =NULL ; -zfcp_unit_put (unit); +put_device (&unit->sysfs_device); } }
@@ -2387,7 +2387,7 @@ int zfcp_fsf_send_fcp_command_task(struc } req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; -zfcp_unit_get (unit); +get_device (&unit->sysfs_device); req->unit = unit; req->data = scsi_cmnd; req->handler = zfcp_fsf_send_fcp_command_handler;
@@ -2463,7 +2463,7 @@ int zfcp_fsf_send_fcp_command_task(struc goto out; failed_scsi_cmnd: -zfcp_unit_put (unit); +put_device (&unit->sysfs_device);zfcp_fsf_req_free (req); scsi_cmnd->host_scribble =NULL ; out:
drivers/s390/scsi/zfcp_scsi.c +11 -12
@@ -52,7 +52,7 @@ static void zfcp_scsi_slave_destroy(stru {struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; unit->device =NULL ; -zfcp_unit_put (unit); +put_device (&unit->sysfs_device); }static int zfcp_scsi_slave_configure (struct scsi_device *sdp)
@@ -335,8 +335,7 @@ void zfcp_adapter_scsi_unregister(structread_lock_irq (&adapter->port_list_lock);list_for_each_entry (port, &adapter->port_list, list) -if (port->rport) - port->rport =NULL ; + port->rport =NULL ;read_unlock_irq (&adapter->port_list_lock);fc_remove_host (shost);
@@ -356,7 +355,7 @@ zfcp_init_fc_host_stats(struct zfcp_adap fc_stats =kmalloc (sizeof (*fc_stats),GFP_KERNEL );if (!fc_stats)return NULL ; - adapter->fc_stats = fc_stats;/* freed in adater_dequeue */ + adapter->fc_stats = fc_stats;/* freed in adapter_release */ }memset (adapter->fc_stats,0 ,sizeof (*adapter->fc_stats));return adapter->fc_stats;
@@ -472,7 +471,7 @@ static void zfcp_reset_fc_host_stats(str adapter->stats_reset = jiffies/HZ ;kfree (adapter->stats_reset_data); adapter->stats_reset_data = data;/* finally freed in -adapter_dequeue */ +adapter_release */ } }
@@ -517,7 +516,7 @@ static void zfcp_scsi_terminate_rport_ioif (port) {zfcp_erp_port_reopen (port,0 ,"sctrpi1" ,NULL ); -zfcp_port_put (port); +put_device (&port->sysfs_device); } }
@@ -559,23 +558,23 @@ static void zfcp_scsi_rport_block(structvoid zfcp_scsi_schedule_rport_register (struct zfcp_port *port) { -zfcp_port_get (port); +get_device (&port->sysfs_device); port->rport_task =RPORT_ADD ;if (!queue_work (port->adapter->work_queue, &port->rport_work)) -zfcp_port_put (port); +put_device (&port->sysfs_device); }void zfcp_scsi_schedule_rport_block (struct zfcp_port *port) { -zfcp_port_get (port); +get_device (&port->sysfs_device); port->rport_task =RPORT_DEL ;if (port->rport &&queue_work (port->adapter->work_queue, &port->rport_work))return ; -zfcp_port_put (port); +put_device (&port->sysfs_device); }void zfcp_scsi_schedule_rports_block (struct zfcp_adapter *adapter)
@@ -604,7 +603,7 @@ void zfcp_scsi_rport_work(struct work_st } } -zfcp_port_put (port); +put_device (&port->sysfs_device); }
@@ -622,7 +621,7 @@ void zfcp_scsi_scan(struct work_struct *scsilun_to_int ((struct scsi_lun *) &unit->fcp_lun), 0); -zfcp_unit_put (unit); +put_device (&unit->sysfs_device); }static int zfcp_execute_fc_job (struct fc_bsg_job *job)
drivers/s390/scsi/zfcp_sysfs.c +19 -27
89 lines not on this page · raw message
PATCH 4/22 zfcp: Remove global config_mutex
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
The global config_mutex was required for the serialization of a configuration change within the zfcp driver. This global locking is now obsolete and can be removed. The requirement of serializing the access to a zfcp_adapter reference via a ccw_device is realized wth a static spinlock.
---
drivers/s390/scsi/zfcp_aux.c | 86 +++++++++++-------------- drivers/s390/scsi/zfcp_ccw.c | 138 ++++++++++++++++++++++------------------- drivers/s390/scsi/zfcp_cfdc.c | 25 ++----- drivers/s390/scsi/zfcp_def.h | 1 drivers/s390/scsi/zfcp_ext.h | 5 + drivers/s390/scsi/zfcp_fc.c | 3 drivers/s390/scsi/zfcp_sysfs.c | 132 ++++++++++++++++++++++++++++++--------- 7 files changed, 232 insertions(+), 158 deletions(-)
drivers/s390/scsi/zfcp_aux.c +40 -46
@@ -80,23 +80,21 @@ int zfcp_reqlist_isempty(struct zfcp_adastatic void __init zfcp_init_device_configure (char *busid,u64 wwpn,u64 lun) { -struct ccw_device *ccwdev; +struct ccw_device *cdev;struct zfcp_adapter *adapter;struct zfcp_port *port;struct zfcp_unit *unit; - ccwdev =get_ccwdev_by_busid (&zfcp_ccw_driver, busid); -if (!ccwdev) + cdev =get_ccwdev_by_busid (&zfcp_ccw_driver, busid); +if (!cdev)return ; -if (ccw_device_set_online (ccwdev)) - goto out_ccwdev; +if (ccw_device_set_online (cdev)) + goto out_ccw_device; -mutex_lock (&zfcp_data.config_mutex); - adapter =dev_get_drvdata (&ccwdev->dev); + adapter =zfcp_ccw_adapter_by_cdev (cdev);if (!adapter) - goto out_unlock; -kref_get (&adapter->ref); + goto out_ccw_device; port =zfcp_get_port_by_wwpn (adapter, wwpn);if (!port)
@@ -105,21 +103,17 @@ static void __init zfcp_init_device_conf unit =zfcp_unit_enqueue (port, lun);if (IS_ERR (unit)) goto out_unit; -mutex_unlock (&zfcp_data.config_mutex);zfcp_erp_unit_reopen (unit,0 ,"auidc_1" ,NULL );zfcp_erp_wait (adapter);flush_work (&unit->scsi_work); -mutex_lock (&zfcp_data.config_mutex); out_unit:put_device (&port->sysfs_device); out_port: -kref_put (&adapter->ref, zfcp_adapter_release); -out_unlock: -mutex_unlock (&zfcp_data.config_mutex); -out_ccwdev: -put_device (&ccwdev->dev); +zfcp_ccw_adapter_put (adapter); +out_ccw_device: +put_device (&cdev->dev);return ; }
@@ -184,8 +178,6 @@ static int __init zfcp_module_init(void)if (!zfcp_data.gid_pn_cache) goto out_gid_cache; -mutex_init (&zfcp_data.config_mutex); - zfcp_data.scsi_transport_template =fc_attach_transport (&zfcp_transport_functions);if (!zfcp_data.scsi_transport_template)
@@ -296,7 +288,6 @@ static void zfcp_unit_release(struct dev* @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 -* Locks: config_mutex must be held to serialize changes to the unit list * * Sets up some unit internal structures and creates sysfs entry. */
@@ -371,7 +362,6 @@ err_out:static int zfcp_allocate_low_mem_buffers (struct zfcp_adapter *adapter) { -/* must only be called with zfcp_data.config_mutex taken */ adapter->pool.erp_req =mempool_create_kmalloc_pool (1 ,sizeof (struct zfcp_fsf_req ));if (!adapter->pool.erp_req)
@@ -419,7 +409,6 @@ static int zfcp_allocate_low_mem_buffersstatic void zfcp_free_low_mem_buffers (struct zfcp_adapter *adapter) { -/* zfcp_data.config_mutex must be held */ if (adapter->pool.erp_req)mempool_destroy (adapter->pool.erp_req);if (adapter->pool.scsi_req)
@@ -501,24 +490,22 @@ static void zfcp_destroy_adapter_work_qu* zfcp_adapter_enqueue - enqueue a new adapter to the list * @ccw_device: pointer to the struct cc_device * -* Returns: 0 if a new adapter was successfully enqueued -* -ENOMEM if alloc failed +* Returns: struct zfcp_adapter* * Enqueues an adapter at the end of the adapter list in the driver data. * All adapter internal structures are set up. * Proc-fs entries are also created. -* locks: config_mutex must be held to serialize changes to the adapter list */ -int zfcp_adapter_enqueue (struct ccw_device *ccw_device) +struct zfcp_adapter *zfcp_adapter_enqueue (struct ccw_device *ccw_device) {struct zfcp_adapter *adapter;if (!get_device (&ccw_device->dev)) -return -ENODEV ; +return ERR_PTR (-ENODEV ); adapter =kzalloc (sizeof (struct zfcp_adapter ),GFP_KERNEL );if (!adapter) {put_device (&ccw_device->dev); -return -ENOMEM ; +return ERR_PTR (-ENOMEM ); }kref_init (&adapter->ref);
@@ -578,11 +565,30 @@ int zfcp_adapter_enqueue(struct ccw_deviatomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &adapter->status);if (!zfcp_adapter_scsi_register (adapter)) -return 0 ; +return adapter; failed: -kref_put (&adapter->ref, zfcp_adapter_release); -return -ENOMEM ; +zfcp_adapter_unregister (adapter); +return ERR_PTR (-ENOMEM ); +} + +void zfcp_adapter_unregister (struct zfcp_adapter *adapter) +{ +struct ccw_device *cdev = adapter->ccw_device; + +cancel_work_sync (&adapter->scan_work); +cancel_work_sync (&adapter->stat_work); +zfcp_destroy_adapter_work_queue (adapter); + +zfcp_fc_wka_ports_force_offline (adapter->gs); +zfcp_adapter_scsi_unregister (adapter); +sysfs_remove_group (&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs); + +zfcp_erp_thread_kill (adapter); +zfcp_dbf_adapter_unregister (adapter->dbf); +zfcp_qdio_destroy (adapter->qdio); + +zfcp_ccw_adapter_put (adapter);/* final put to release */ }/**
@@ -594,27 +600,16 @@ void zfcp_adapter_release(struct kref *r { struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter, ref); -struct ccw_device *ccw_device = adapter->ccw_device; - -cancel_work_sync (&adapter->stat_work); - -zfcp_fc_wka_ports_force_offline (adapter->gs); -sysfs_remove_group (&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs); - -dev_set_drvdata (&ccw_device->dev,NULL ); +struct ccw_device *cdev = adapter->ccw_device;dev_set_drvdata (&adapter->ccw_device->dev,NULL );zfcp_fc_gs_destroy (adapter); -zfcp_erp_thread_kill (adapter); -zfcp_destroy_adapter_work_queue (adapter); -zfcp_dbf_adapter_unregister (adapter->dbf);zfcp_free_low_mem_buffers (adapter); -zfcp_qdio_destroy (adapter->qdio);kfree (adapter->req_list);kfree (adapter->fc_stats);kfree (adapter->stats_reset_data);kfree (adapter); -put_device (&ccw_device->dev); +put_device (&cdev->dev); }/**
@@ -636,7 +631,7 @@ static void zfcp_port_release(struct dev struct zfcp_port *port = container_of(dev, struct zfcp_port, sysfs_device); -kref_put (&port->adapter->ref, zfcp_adapter_release); +zfcp_ccw_adapter_put (port->adapter);kfree (port); }
@@ -647,7 +642,6 @@ static void zfcp_port_release(struct dev* @status: initial status for the port * @d_id: destination id of the remote port to be enqueued * Returns: pointer to enqueued port on success, ERR_PTR on error -* Locks: config_mutex must be held to serialize changes to the port list * * All port internal structures are set up and the sysfs entry is generated. * d_id is used to enqueue ports with a well known address like the Directory
@@ -718,7 +712,7 @@ struct zfcp_port *zfcp_port_enqueue(stru err_out_put:device_unregister (&port->sysfs_device); err_out: -kref_put (&adapter->ref, zfcp_adapter_release); +zfcp_ccw_adapter_put (adapter);return ERR_PTR (retval); }
drivers/s390/scsi/zfcp_ccw.c +76 -62
288 lines not on this page · raw message
drivers/s390/scsi/zfcp_cfdc.c +10 -15
@@ -86,22 +86,17 @@ static int zfcp_cfdc_copy_to_user(void _static struct zfcp_adapter *zfcp_cfdc_get_adapter (u32 devno) {char busid[9 ]; -struct ccw_device *ccwdev; -struct zfcp_adapter *adapter =NULL ; +struct ccw_device *cdev; +struct zfcp_adapter *adapter;snprintf (busid,sizeof (busid),"0.0.%04x" , devno); - ccwdev =get_ccwdev_by_busid (&zfcp_ccw_driver, busid); -if (!ccwdev) - goto out; - - adapter =dev_get_drvdata (&ccwdev->dev); -if (!adapter) - goto out_put; - -kref_get (&adapter->ref); -out_put: -put_device (&ccwdev->dev); -out: + cdev =get_ccwdev_by_busid (&zfcp_ccw_driver, busid); +if (!cdev) +return NULL ; + + adapter =zfcp_ccw_adapter_by_cdev (cdev); + +put_device (&cdev->dev);return adapter; }
@@ -244,7 +239,7 @@ static long zfcp_cfdc_dev_ioctl(struct f free_sg:zfcp_sg_free_table (fsf_cfdc->sg,ZFCP_CFDC_PAGES ); adapter_put: -kref_put (&adapter->ref, zfcp_adapter_release); +zfcp_ccw_adapter_put (adapter); free_buffer:kfree (data); no_mem_sense:
drivers/s390/scsi/zfcp_def.h +0 -1
@@ -595,7 +595,6 @@ struct zfcp_fsf_req {struct zfcp_data {struct scsi_host_template scsi_host_template;struct scsi_transport_template *scsi_transport_template; -struct mutex config_mutex;struct kmem_cache *gpn_ft_cache;struct kmem_cache *qtcb_cache;struct kmem_cache *sr_buffer_cache;
drivers/s390/scsi/zfcp_ext.h +4 -1
@@ -14,7 +14,7 @@/* 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 int zfcp_adapter_enqueue (struct ccw_device *); +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 );
@@ -24,11 +24,14 @@ extern int zfcp_sg_setup_table(struct scextern void zfcp_device_unregister (struct device *,const struct attribute_group *);extern void zfcp_adapter_release (struct kref *); +extern void zfcp_adapter_unregister (struct zfcp_adapter *);/* zfcp_ccw.c */ extern int zfcp_ccw_register (void );extern int zfcp_ccw_priv_sch (struct zfcp_adapter *);extern struct ccw_driver zfcp_ccw_driver; +extern struct zfcp_adapter *zfcp_ccw_adapter_by_cdev (struct ccw_device *); +extern void zfcp_ccw_adapter_put (struct zfcp_adapter *);/* zfcp_cfdc.c */ extern struct miscdevice zfcp_cfdc_misc;
drivers/s390/scsi/zfcp_fc.c +0 -3
@@ -622,8 +622,6 @@ static int zfcp_fc_eval_gpn_ft(struct zfreturn -E2BIG ; } -mutex_lock (&zfcp_data.config_mutex); -/* first entry is the header */ for (x =1 ; x < max_entries && !last; x++) {if (x % (ZFCP_GPN_FT_ENTRIES +1 ))
@@ -655,7 +653,6 @@ static int zfcp_fc_eval_gpn_ft(struct zflist_for_each_entry_safe (port, tmp, &adapter->port_list, list)zfcp_fc_validate_port (port, &remove_lh);write_unlock_irqrestore (&adapter->port_list_lock, flags); -mutex_unlock (&zfcp_data.config_mutex);list_for_each_entry_safe (port, tmp, &remove_lh, list) {zfcp_erp_port_shutdown (port,0 ,"fcegpf2" ,NULL );
drivers/s390/scsi/zfcp_sysfs.c +102 -30
207 lines not on this page · raw message
PATCH 5/22 zfcp: Remove suspend callback
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
The callback for suspend is not required because it contains exactly the same functionality as the _set_offline routine does.
---
drivers/s390/scsi/zfcp_ccw.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-)
drivers/s390/scsi/zfcp_ccw.c +1 -17
@@ -37,22 +37,6 @@ void zfcp_ccw_adapter_put(struct zfcp_adspin_unlock_irqrestore (&zfcp_ccw_adapter_ref_lock, flags); } -static int zfcp_ccw_suspend (struct ccw_device *cdev) - -{ -struct zfcp_adapter *adapter =zfcp_ccw_adapter_by_cdev (cdev); - -if (!adapter) -return 0 ; - -zfcp_erp_adapter_shutdown (adapter,0 ,"ccsusp1" ,NULL ); -zfcp_erp_wait (adapter); - -zfcp_ccw_adapter_put (adapter); - -return 0 ; -} -static int zfcp_ccw_activate (struct ccw_device *cdev) {
@@ -291,7 +275,7 @@ struct ccw_driver zfcp_ccw_driver = { .set_offline = zfcp_ccw_set_offline, .notify = zfcp_ccw_notify, .shutdown = zfcp_ccw_shutdown, - .freeze = zfcp_ccw_suspend, + .freeze = zfcp_ccw_set_offline, .thaw = zfcp_ccw_activate, .restore = zfcp_ccw_activate, };
PATCH 6/22 zfcp: Access ports and units with container_of in sysfs code
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
When accessing port and unit attributes, use container_of instead of dev_get_drvdata. This eliminates some code checker warnings about aliased access of data structures.
---
drivers/s390/scsi/zfcp_aux.c | 2 -- drivers/s390/scsi/zfcp_sysfs.c | 15 ++++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-)
drivers/s390/scsi/zfcp_aux.c +0 -2
@@ -319,7 +319,6 @@ struct zfcp_unit *zfcp_unit_enqueue(strukfree (unit); goto err_out; } -dev_set_drvdata (&unit->sysfs_device, unit); retval = -EINVAL ;/* mark unit unusable as long as sysfs registration is not complete */
@@ -688,7 +687,6 @@ struct zfcp_port *zfcp_port_enqueue(strukfree (port); goto err_out; } -dev_set_drvdata (&port->sysfs_device, port); retval = -EINVAL ;if (device_register (&port->sysfs_device)) {
drivers/s390/scsi/zfcp_sysfs.c +10 -5
@@ -19,7 +19,8 @@ static ssize_t zfcp_sysfs_##_feat##_##_nstruct device_attribute *at,\ char *buf) \ { \ - struct _feat_def *_feat = dev_get_drvdata(dev); \ + struct _feat_def *_feat = container_of(dev, struct _feat_def, \ + sysfs_device); \ \return sprintf (buf, _format, _value); \ } \
@@ -86,7 +87,8 @@ static ssize_t zfcp_sysfs_##_feat##_failstruct device_attribute *attr, \ char *buf) \ { \ - struct _feat_def *_feat = dev_get_drvdata(dev); \ + struct _feat_def *_feat = container_of(dev, struct _feat_def, \ + sysfs_device); \ \if (atomic_read (&_feat->status) &ZFCP_STATUS_COMMON_ERP_FAILED ) \return sprintf (buf,"1\n" ); \
@@ -97,7 +99,8 @@ static ssize_t zfcp_sysfs_##_feat##_failstruct device_attribute *attr,\ const char *buf, size_t count)\ { \ - struct _feat_def *_feat = dev_get_drvdata(dev); \ + struct _feat_def *_feat = container_of(dev, struct _feat_def, \ + sysfs_device); \unsigned long val; \int retval =0 ; \ \
@@ -274,7 +277,8 @@ static ssize_t zfcp_sysfs_unit_add_storestruct device_attribute *attr, const char *buf, size_t count) { - struct zfcp_port *port = dev_get_drvdata(dev); + struct zfcp_port *port = container_of(dev, struct zfcp_port, + sysfs_device);struct zfcp_unit *unit;u64 fcp_lun;int retval = -EINVAL ;
@@ -305,7 +309,8 @@ static ssize_t zfcp_sysfs_unit_remove_ststruct device_attribute *attr, const char *buf, size_t count) { - struct zfcp_port *port = dev_get_drvdata(dev); + struct zfcp_port *port = container_of(dev, struct zfcp_port, + sysfs_device);struct zfcp_unit *unit;u64 fcp_lun;int retval =0 ;
PATCH 7/22 zfcp: Merge trace code for fsf requests in one function
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The latencies traced per fsf request are traced for sysfs output and for blktrace, each in one function. Simplify the tracing code by merging both tracing functions into one.
---
drivers/s390/scsi/zfcp_fsf.c | 95 ++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 55 deletions(-)
drivers/s390/scsi/zfcp_fsf.c +40 -55
@@ -2109,64 +2109,52 @@ static void zfcp_fsf_update_lat(struct f lat_rec->max =max (lat_rec->max, lat); } -static void zfcp_fsf_req_latency (struct zfcp_fsf_req *req) +static void zfcp_fsf_req_trace (struct zfcp_fsf_req *req,struct scsi_cmnd *scsi) { -struct fsf_qual_latency_info *lat_inf; -struct latency_cont *lat; +struct fsf_qual_latency_info *lat_in; +struct latency_cont *lat =NULL ;struct zfcp_unit *unit = req->unit; +struct zfcp_blk_drv_data blktrc; +int ticks = req->adapter->timer_ticks; - lat_inf = &req->qtcb->prefix.prot_status_qual.latency_info; + lat_in = &req->qtcb->prefix.prot_status_qual.latency_info; -switch (req->qtcb->bottom.io.data_direction) { -case FSF_DATADIR_READ : - lat = &unit->latencies.read; -break ; -case FSF_DATADIR_WRITE : - lat = &unit->latencies.write; -break ; -case FSF_DATADIR_CMND : - lat = &unit->latencies.cmd; -break ; -default : -return ; - } - -spin_lock (&unit->latencies.lock); -zfcp_fsf_update_lat (&lat->channel, lat_inf->channel_lat); -zfcp_fsf_update_lat (&lat->fabric, lat_inf->fabric_lat); - lat->counter++; -spin_unlock (&unit->latencies.lock); -} + blktrc.flags =0 ; + blktrc.magic =ZFCP_BLK_DRV_DATA_MAGIC ; +if (req->status &ZFCP_STATUS_FSFREQ_ERROR ) + blktrc.flags |=ZFCP_BLK_REQ_ERROR ; + blktrc.inb_usage = req->queue_req.qdio_inb_usage; + blktrc.outb_usage = req->queue_req.qdio_outb_usage; + +if (req->adapter->adapter_features &FSF_FEATURE_MEASUREMENT_DATA ) { + blktrc.flags |=ZFCP_BLK_LAT_VALID ; + blktrc.channel_lat = lat_in->channel_lat * ticks; + blktrc.fabric_lat = lat_in->fabric_lat * ticks; + +switch (req->qtcb->bottom.io.data_direction) { +case FSF_DATADIR_READ : + lat = &unit->latencies.read; +break ; +case FSF_DATADIR_WRITE : + lat = &unit->latencies.write; +break ; +case FSF_DATADIR_CMND : + lat = &unit->latencies.cmd; +break ; + } -#ifdef CONFIG_BLK_DEV_IO_TRACE -static void zfcp_fsf_trace_latency (struct zfcp_fsf_req *fsf_req) -{ -struct fsf_qual_latency_info *lat_inf; -struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; -struct request *req = scsi_cmnd->request; -struct zfcp_blk_drv_data trace; -int ticks = fsf_req->adapter->timer_ticks; - - trace.flags =0 ; - trace.magic =ZFCP_BLK_DRV_DATA_MAGIC ; -if (fsf_req->adapter->adapter_features &FSF_FEATURE_MEASUREMENT_DATA ) { - trace.flags |=ZFCP_BLK_LAT_VALID ; - lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info; - trace.channel_lat = lat_inf->channel_lat * ticks; - trace.fabric_lat = lat_inf->fabric_lat * ticks; - } -if (fsf_req->status &ZFCP_STATUS_FSFREQ_ERROR ) - trace.flags |=ZFCP_BLK_REQ_ERROR ; - trace.inb_usage = fsf_req->queue_req.qdio_inb_usage; - trace.outb_usage = fsf_req->queue_req.qdio_outb_usage; +if (lat) { +spin_lock (&unit->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); + } + } -blk_add_driver_data (req->q, req, &trace,sizeof (trace)); -} -#else -static inline void zfcp_fsf_trace_latency (struct zfcp_fsf_req *fsf_req) -{ +blk_add_driver_data (scsi->request->q, scsi->request, &blktrc, +sizeof (blktrc)); } -#endif static void zfcp_fsf_send_fcp_command_task_handler (struct zfcp_fsf_req *req) {
@@ -2199,10 +2187,7 @@ static void zfcp_fsf_send_fcp_command_ta scpnt->result |= fcp_rsp_iu->scsi_status; -if (req->adapter->adapter_features &FSF_FEATURE_MEASUREMENT_DATA ) -zfcp_fsf_req_latency (req); - -zfcp_fsf_trace_latency (req); +zfcp_fsf_req_trace (req, scpnt);if (unlikely (fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) {if (fcp_rsp_info[3 ] ==RSP_CODE_GOOD )
PATCH 8/22 zfcp: Implement module unloading
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
With the reference counting for zfcp data structures, it is now possible to implement module unloading again. Module unloading requires to free all data structures in the module exit function. This is done by unregistering zfcp from s390 cio and the SCSI midlayer first in the module exit function.
---
drivers/s390/scsi/zfcp_aux.c | 15 ++++++++++++++- drivers/s390/scsi/zfcp_ccw.c | 11 ----------- drivers/s390/scsi/zfcp_ext.h | 1 - 3 files changed, 14 insertions(+), 13 deletions(-)
drivers/s390/scsi/zfcp_aux.c +14 -1
@@ -189,7 +189,7 @@ static int __init zfcp_module_init(void) goto out_misc; } - retval =zfcp_ccw_register (); + retval =ccw_driver_register (&zfcp_ccw_driver);if (retval) {pr_err ("The zfcp device driver could not register with " "the common I/O layer\n" );
@@ -218,6 +218,19 @@ out:module_init (zfcp_module_init); +static void __exit zfcp_module_exit(void) +{ +ccw_driver_unregister (&zfcp_ccw_driver); +misc_deregister (&zfcp_cfdc_misc); +fc_release_transport (zfcp_data.scsi_transport_template); +kmem_cache_destroy (zfcp_data.gid_pn_cache); +kmem_cache_destroy (zfcp_data.sr_buffer_cache); +kmem_cache_destroy (zfcp_data.qtcb_cache); +kmem_cache_destroy (zfcp_data.gpn_ft_cache); +} + +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
drivers/s390/scsi/zfcp_ccw.c +0 -11
@@ -279,14 +279,3 @@ struct ccw_driver zfcp_ccw_driver = { .thaw = zfcp_ccw_activate, .restore = zfcp_ccw_activate, }; - -/** -* zfcp_ccw_register - ccw register function -* -* Registers the driver at the common i/o layer. This function will be called -* at module load time/system start. -*/ -int __init zfcp_ccw_register (void ) -{ -return ccw_driver_register (&zfcp_ccw_driver); -}
drivers/s390/scsi/zfcp_ext.h +0 -1
@@ -27,7 +27,6 @@ extern void zfcp_adapter_release(structextern void zfcp_adapter_unregister (struct zfcp_adapter *);/* zfcp_ccw.c */ -extern int zfcp_ccw_register (void );extern int zfcp_ccw_priv_sch (struct zfcp_adapter *);extern struct ccw_driver zfcp_ccw_driver;extern struct zfcp_adapter *zfcp_ccw_adapter_by_cdev (struct ccw_device *);
PATCH 9/22 zfcp: Remove STATUS_COMMON_REMOVE flag as it is not required anymore
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
The flag ZFCP_STATUS_COMMON_REMOVE was used to indicate that a resource is not ready to be used or about to be removed from the system. This is now better done by an improved list handling and therefore the additional indicator is not required anymore.
---
drivers/s390/scsi/zfcp_aux.c | 27 ++++----------- drivers/s390/scsi/zfcp_ccw.c | 7 ---- drivers/s390/scsi/zfcp_def.h | 1 drivers/s390/scsi/zfcp_erp.c | 6 ++- drivers/s390/scsi/zfcp_fc.c | 1 drivers/s390/scsi/zfcp_sysfs.c | 70 ++++++++++++----------------------------- 6 files changed, 34 insertions(+), 78 deletions(-)
drivers/s390/scsi/zfcp_aux.c +7 -20
@@ -245,9 +245,9 @@ struct zfcp_unit *zfcp_get_unit_by_lun(sread_lock_irqsave (&port->unit_list_lock, flags);list_for_each_entry (unit, &port->unit_list, list) -if ((unit->fcp_lun == fcp_lun) && - !(atomic_read (&unit->status) &ZFCP_STATUS_COMMON_REMOVE )) { -get_device (&unit->sysfs_device); +if (unit->fcp_lun == fcp_lun) { +if (!get_device (&unit->sysfs_device)) + unit =NULL ;read_unlock_irqrestore (&port->unit_list_lock, flags);return unit; }
@@ -270,9 +270,9 @@ struct zfcp_port *zfcp_get_port_by_wwpn(read_lock_irqsave (&adapter->port_list_lock, flags);list_for_each_entry (port, &adapter->port_list, list) -if ((port->wwpn == wwpn) && - !(atomic_read (&port->status) &ZFCP_STATUS_COMMON_REMOVE )) { -get_device (&port->sysfs_device); +if (port->wwpn == wwpn) { +if (!get_device (&port->sysfs_device)) + port =NULL ;read_unlock_irqrestore (&adapter->port_list_lock, flags);return port; }
@@ -334,9 +334,6 @@ struct zfcp_unit *zfcp_unit_enqueue(stru } retval = -EINVAL ; -/* mark unit unusable as long as sysfs registration is not complete */ -atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , &unit->status); -INIT_WORK (&unit->scsi_work, zfcp_scsi_scan);spin_lock_init (&unit->latencies.lock);
@@ -360,7 +357,6 @@ struct zfcp_unit *zfcp_unit_enqueue(strulist_add_tail (&unit->list, &port->unit_list);write_unlock_irq (&port->unit_list_lock); -atomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &unit->status);atomic_set_mask (ZFCP_STATUS_COMMON_RUNNING , &unit->status);return unit;
@@ -565,17 +561,12 @@ struct zfcp_adapter *zfcp_adapter_enqueu adapter->service_level.seq_print = zfcp_print_sl; -/* mark adapter unusable as long as sysfs registration is not complete */ -atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , &adapter->status); -dev_set_drvdata (&ccw_device->dev, adapter);if (sysfs_create_group (&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs)) goto failed; -atomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &adapter->status); -if (!zfcp_adapter_scsi_register (adapter))return adapter;
@@ -692,9 +683,6 @@ struct zfcp_port *zfcp_port_enqueue(stru port->sysfs_device.parent = &adapter->ccw_device->dev; port->sysfs_device.release = zfcp_port_release; -/* mark port unusable as long as sysfs registration is not complete */ -atomic_set_mask (status |ZFCP_STATUS_COMMON_REMOVE , &port->status); -if (dev_set_name (&port->sysfs_device,"0x%016llx" , (unsigned long long )wwpn)) {kfree (port);
@@ -715,8 +703,7 @@ struct zfcp_port *zfcp_port_enqueue(strulist_add_tail (&port->list, &adapter->port_list);write_unlock_irq (&adapter->port_list_lock); -atomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &port->status); -atomic_set_mask (ZFCP_STATUS_COMMON_RUNNING , &port->status); +atomic_set_mask (status |ZFCP_STATUS_COMMON_RUNNING , &port->status);return port;
drivers/s390/scsi/zfcp_ccw.c +1 -6
@@ -113,16 +113,11 @@ static void zfcp_ccw_remove(struct ccw_dwrite_lock_irq (&adapter->port_list_lock);list_for_each_entry_safe (port, p, &adapter->port_list, list) {write_lock (&port->unit_list_lock); -list_for_each_entry_safe (unit, u, &port->unit_list, list) { -atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , - &unit->status); +list_for_each_entry_safe (unit, u, &port->unit_list, list)list_move (&unit->list, &unit_remove_lh); - }write_unlock (&port->unit_list_lock); -atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , &port->status);list_move (&port->list, &port_remove_lh); } -atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , &adapter->status);write_unlock_irq (&adapter->port_list_lock);zfcp_ccw_adapter_put (adapter);/* put from zfcp_ccw_adapter_by_cdev */
drivers/s390/scsi/zfcp_def.h +0 -1
@@ -205,7 +205,6 @@ struct zfcp_ls_adisc {#define ZFCP_COMMON_FLAGS 0xfff00000/* common status bits */ -#define ZFCP_STATUS_COMMON_REMOVE 0x80000000#define ZFCP_STATUS_COMMON_RUNNING 0x40000000#define ZFCP_STATUS_COMMON_ERP_FAILED 0x20000000#define ZFCP_STATUS_COMMON_UNBLOCKED 0x10000000
drivers/s390/scsi/zfcp_erp.c +4 -2
@@ -174,7 +174,8 @@ static struct zfcp_erp_action *zfcp_erp_switch (need) {case ZFCP_ERP_ACTION_REOPEN_UNIT : -get_device (&unit->sysfs_device); +if (!get_device (&unit->sysfs_device)) +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 ))
@@ -183,7 +184,8 @@ static struct zfcp_erp_action *zfcp_erp_case ZFCP_ERP_ACTION_REOPEN_PORT :case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED : -get_device (&port->sysfs_device); +if (!get_device (&port->sysfs_device)) +return NULL ;zfcp_erp_action_dismiss_port (port);atomic_set_mask (ZFCP_STATUS_COMMON_ERP_INUSE , &port->status); erp_action = &port->erp_action;
drivers/s390/scsi/zfcp_fc.c +0 -1
@@ -589,7 +589,6 @@ static void zfcp_fc_validate_port(struct !list_empty(&port->unit_list))return ; -atomic_set_mask (ZFCP_STATUS_COMMON_REMOVE , &port->status);list_move_tail (&port->list, lh); }
drivers/s390/scsi/zfcp_sysfs.c +22 -48
149 lines not on this page · raw message
PATCH 10/22 zfcp: Assign scheduled work to driver queue
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
The port_scan work was scheduled to the work_queue provided by the kernel. This resulted on SMP systems to a likely situation that more than one scan_work were processed in parallel. This is not required and openes the possibility of race conditions between the removal of invalid ports and the enqueue of just scanned ports. This patch synchronizes the scan_work tasks by scheduling them to adapter local work_queue.
---
drivers/s390/scsi/zfcp_aux.c | 2 +- drivers/s390/scsi/zfcp_erp.c | 2 +- drivers/s390/scsi/zfcp_ext.h | 3 +-- drivers/s390/scsi/zfcp_fc.c | 25 +++++++++---------------- drivers/s390/scsi/zfcp_fsf.c | 2 +- drivers/s390/scsi/zfcp_sysfs.c | 7 ++++--- 6 files changed, 17 insertions(+), 24 deletions(-)
drivers/s390/scsi/zfcp_aux.c +1 -1
@@ -522,7 +522,7 @@ struct zfcp_adapter *zfcp_adapter_enqueu adapter->ccw_device = ccw_device;INIT_WORK (&adapter->stat_work, _zfcp_status_read_scheduler); -INIT_WORK (&adapter->scan_work, _zfcp_fc_scan_ports_later); +INIT_WORK (&adapter->scan_work, zfcp_fc_scan_ports);if (zfcp_qdio_setup (adapter)) goto failed;
drivers/s390/scsi/zfcp_erp.c +1 -1
@@ -1197,7 +1197,7 @@ static void zfcp_erp_action_cleanup(strucase ZFCP_ERP_ACTION_REOPEN_ADAPTER :if (result ==ZFCP_ERP_SUCCEEDED ) {register_service_level (&adapter->service_level); -schedule_work (&adapter->scan_work); +queue_work (adapter->work_queue, &adapter->scan_work); }else unregister_service_level (&adapter->service_level);kref_put (&adapter->ref, zfcp_adapter_release);
drivers/s390/scsi/zfcp_ext.h +1 -2
@@ -94,8 +94,7 @@ extern void zfcp_erp_adapter_access_chanextern void zfcp_erp_timeout_handler (unsigned long );/* zfcp_fc.c */ -extern int zfcp_fc_scan_ports (struct zfcp_adapter *); -extern void _zfcp_fc_scan_ports_later (struct work_struct *); +extern void zfcp_fc_scan_ports (struct work_struct *);extern void zfcp_fc_incoming_els (struct zfcp_fsf_req *);extern void zfcp_fc_port_did_lookup (struct work_struct *);extern void zfcp_fc_trigger_did_lookup (struct zfcp_port *);
drivers/s390/scsi/zfcp_fc.c +9 -16
@@ -184,7 +184,7 @@ static void zfcp_fc_incoming_rscn(struct range_mask = rscn_range_mask[fcp_rscn_element->addr_format];_zfcp_fc_incoming_rscn (fsf_req, range_mask, fcp_rscn_element); } -schedule_work (&fsf_req->adapter->scan_work); +queue_work (fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work); }static void zfcp_fc_incoming_wwpn (struct zfcp_fsf_req *req,u64 wwpn)
@@ -664,10 +664,12 @@ static int zfcp_fc_eval_gpn_ft(struct zf/** * zfcp_fc_scan_ports - scan remote ports and attach new ports -* @adapter: pointer to struct zfcp_adapter +* @work: reference to scheduled work */ -int zfcp_fc_scan_ports (struct zfcp_adapter *adapter) +void zfcp_fc_scan_ports (struct work_struct *work) { + struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter, + scan_work);int ret, i;struct zfcp_gpn_ft *gpn_ft;int chain, max_entries, buf_num, max_bytes;
@@ -679,17 +681,14 @@ int zfcp_fc_scan_ports(struct zfcp_adaptif (fc_host_port_type (adapter->scsi_host) !=FC_PORTTYPE_NPORT &&fc_host_port_type (adapter->scsi_host) !=FC_PORTTYPE_NPIV ) -return 0 ; +return ; - ret =zfcp_fc_wka_port_get (&adapter->gs->ds); -if (ret) -return ret; +if (zfcp_fc_wka_port_get (&adapter->gs->ds)) +return ; gpn_ft =zfcp_alloc_sg_env (buf_num); -if (!gpn_ft) { - ret = -ENOMEM ; +if (!gpn_ft) goto out; - }for (i =0 ; i <3 ; i++) { ret =zfcp_fc_send_gpn_ft (gpn_ft, adapter, max_bytes);
@@ -704,15 +703,9 @@ int zfcp_fc_scan_ports(struct zfcp_adaptzfcp_free_sg_env (gpn_ft, buf_num); out:zfcp_fc_wka_port_put (&adapter->gs->ds); -return ret; } -void _zfcp_fc_scan_ports_later (struct work_struct *work) -{ -zfcp_fc_scan_ports (container_of(work ,struct zfcp_adapter ,scan_work )); -} -struct zfcp_els_fc_job {struct zfcp_send_els els;struct fc_bsg_job *job;
drivers/s390/scsi/zfcp_fsf.c +1 -1
@@ -287,7 +287,7 @@ static void zfcp_fsf_status_read_handlerzfcp_erp_adapter_access_changed (adapter,"fssrh_3" , req);if (sr_buf->status_subtype &FSF_STATUS_READ_SUB_INCOMING_ELS ) -schedule_work (&adapter->scan_work); +queue_work (adapter->work_queue, &adapter->scan_work);break ;case FSF_STATUS_READ_CFDC_UPDATED :zfcp_erp_adapter_access_changed (adapter,"fssrh_4" , req);
drivers/s390/scsi/zfcp_sysfs.c +4 -3
@@ -184,15 +184,16 @@ static ssize_t zfcp_sysfs_port_rescan_st {struct ccw_device *cdev =to_ccwdev (dev);struct zfcp_adapter *adapter =zfcp_ccw_adapter_by_cdev (cdev); -int ret;if (!adapter)return -ENODEV ; - ret =zfcp_fc_scan_ports (adapter); +/* sync the user-space- with the kernel-invocation of scan_work */ +queue_work (adapter->work_queue, &adapter->scan_work); +flush_work (&adapter->scan_work);zfcp_ccw_adapter_put (adapter); -return ret ? ret : (ssize_t ) count; +return (ssize_t ) count; } static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL, zfcp_sysfs_port_rescan_store);
PATCH 11/22 zfcp: Dont fail SCSI commands when transitioning to blocked fc_rport
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
If an error occurs that triggers the call to fc_remote_port_delete, ideally this call would happen before any I/O is passed back to the SCSI midlayer through scsi_done. The SCSI midlayer will retry the commands and fc_remote_port_chkready will return the correct status code. But with the delay between calling scsi_done in softirq context and the call to fc_remote_port_delete from the workqueue, there is a window where zfcp returns DID_ERROR. This leads to SCSI error recovery which then leads to offline SCSI devices since all recovery actions will fail with the rport now being blocked.
In this window, zfcp has to return DID_IMM_RETRY just as the FC transport class would do in fc_remote_port_chkready for the blocked fc_rport. As soon as the fc_rport is BLOCKED, fc_remote_port_chkready will do the right thing.
Additionally, there are two more cases to catch in zfcp_scsi_queuecommand:
- After the port has been opened, the unit has to be opened. During this period I/O has to be retried. This can also be handled with DID_IMM_RETRY.
- If the access to the unit fails, but the port is good, then this single unit cannot be accessed and I/O to this unit has to fail without involving the FC transport class.
---
drivers/s390/scsi/zfcp_scsi.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/s390/scsi/zfcp_scsi.c +16 -2
@@ -112,12 +112,26 @@ static int zfcp_scsi_queuecommand(struct } status =atomic_read (&unit->status); -if (unlikely ((status &ZFCP_STATUS_COMMON_ERP_FAILED ) || - !(status &ZFCP_STATUS_COMMON_RUNNING ))) { +if (unlikely (status &ZFCP_STATUS_COMMON_ERP_FAILED ) && + !(atomic_read (&unit->port->status) & +ZFCP_STATUS_COMMON_ERP_FAILED )) { +/* only unit access denied, but port is good +* not covered by FC transport, have to fail here */ zfcp_scsi_command_fail (scpnt,DID_ERROR );return 0 ; } +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 +* call to rport_delete pending: mimic retry from +* fc_remote_port_chkready until rport is BLOCKED +*/ +zfcp_scsi_command_fail (scpnt,DID_IMM_RETRY ); +return 0 ; + } + ret =zfcp_fsf_send_fcp_command_task (unit, scpnt);if (unlikely (ret == -EBUSY ))return SCSI_MLQUEUE_DEVICE_BUSY ;
PATCH 12/22 zfcp: Update FCP protocol related code
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Use common data structures for FCP CMND, FCP RSP and related definitions and remove zfcp private definitions. Split the FCP CMND setup and FCP RSP evaluation code in seperate functions. Use inline functions to not negatively impact the I/O path.
--- drivers/s390/scsi/zfcp_dbf.c | 35 +++++++------ drivers/s390/scsi/zfcp_dbf.h | 3 - drivers/s390/scsi/zfcp_def.h | 57 --------------------- drivers/s390/scsi/zfcp_ext.h | 1 drivers/s390/scsi/zfcp_fc.h | 112 ++++++++++++++++++++++++++++++++++++++++++ drivers/s390/scsi/zfcp_fsf.c | 97 ++++++------------------------------ drivers/s390/scsi/zfcp_scsi.c | 20 +------ 7 files changed, 156 insertions(+), 169 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +19 -16
@@ -870,8 +870,9 @@ void _zfcp_dbf_scsi(const char *tag, construct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf;struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;unsigned long flags; -struct fcp_rsp_iu *fcp_rsp; -char *fcp_rsp_info =NULL , *fcp_sns_info =NULL ; +struct fcp_resp_with_ext *fcp_rsp; +struct fcp_resp_rsp_info *fcp_rsp_info =NULL ; +char *fcp_sns_info =NULL ;int offset =0 , buflen =0 ;spin_lock_irqsave (&dbf->scsi_lock, flags);
@@ -895,20 +896,22 @@ void _zfcp_dbf_scsi(const char *tag, con rec->scsi_allowed = scsi_cmnd->allowed; }if (fsf_req !=NULL ) { - fcp_rsp = (struct fcp_rsp_iu *) - &(fsf_req->qtcb->bottom.io.fcp_rsp); - fcp_rsp_info = (unsigned char *) &fcp_rsp[1 ]; - fcp_sns_info = -zfcp_get_fcp_sns_info_ptr (fcp_rsp); - - rec->rsp_validity = fcp_rsp->validity.value; - rec->rsp_scsi_status = fcp_rsp->scsi_status; - rec->rsp_resid = fcp_rsp->fcp_resid; -if (fcp_rsp->validity.bits.fcp_rsp_len_valid) - rec->rsp_code = *(fcp_rsp_info +3 ); -if (fcp_rsp->validity.bits.fcp_sns_len_valid) { - buflen =min ((int )fcp_rsp->fcp_sns_len, -ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO ); + fcp_rsp = (struct fcp_resp_with_ext *) + &(fsf_req->qtcb->bottom.io.fcp_rsp); + fcp_rsp_info = (struct fcp_resp_rsp_info *) + &fcp_rsp[1 ]; + fcp_sns_info = (char *) &fcp_rsp[1 ]; +if (fcp_rsp->resp.fr_flags &FCP_RSP_LEN_VAL ) + fcp_sns_info += fcp_rsp->ext.fr_sns_len; + + rec->rsp_validity = fcp_rsp->resp.fr_flags; + rec->rsp_scsi_status = fcp_rsp->resp.fr_status; + rec->rsp_resid = fcp_rsp->ext.fr_resid; +if (fcp_rsp->resp.fr_flags &FCP_RSP_LEN_VAL ) + rec->rsp_code = fcp_rsp_info->rsp_code; +if (fcp_rsp->resp.fr_flags &FCP_SNS_LEN_VAL ) { + buflen =min (fcp_rsp->ext.fr_sns_len, + (u32 )ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO ); rec->sns_info_len = buflen; memcpy(rec->sns_info, fcp_sns_info, min(buflen,
drivers/s390/scsi/zfcp_dbf.h +2 -1
@@ -22,6 +22,7 @@#ifndef ZFCP_DBF_H #define ZFCP_DBF_H +#include <scsi/fc/fc_fcp.h> #include "zfcp_ext.h" #include "zfcp_fsf.h" #include "zfcp_def.h"
@@ -343,7 +344,7 @@ static inlinevoid zfcp_dbf_scsi_devreset (const char *tag,u8 flag,struct zfcp_unit *unit,struct scsi_cmnd *scsi_cmnd) { -zfcp_dbf_scsi (flag ==FCP_TARGET_RESET ?"trst" :"lrst" , tag,1 , +zfcp_dbf_scsi (flag ==FCP_TMF_TGT_RESET ?"trst" :"lrst" , tag,1 , unit->port->adapter->dbf, scsi_cmnd,NULL ,0 ); }
drivers/s390/scsi/zfcp_def.h +0 -57
65 lines not on this page · raw message
drivers/s390/scsi/zfcp_ext.h +0 -1
@@ -154,7 +154,6 @@ extern void zfcp_qdio_close(struct zfcp_extern struct zfcp_data zfcp_data;extern int zfcp_adapter_scsi_register (struct zfcp_adapter *);extern void zfcp_adapter_scsi_unregister (struct zfcp_adapter *); -extern char *zfcp_get_fcp_sns_info_ptr (struct fcp_rsp_iu *);extern struct fc_function_template zfcp_transport_functions;extern void zfcp_scsi_rport_work (struct work_struct *);extern void zfcp_scsi_schedule_rport_register (struct zfcp_port *);
drivers/s390/scsi/zfcp_fc.h new file +112 -0
112 lines not on this page · raw message
drivers/s390/scsi/zfcp_fsf.c +18 -79
188 lines not on this page · raw message
drivers/s390/scsi/zfcp_scsi.c +5 -15
@@ -9,6 +9,8 @@#define KMSG_COMPONENT "zfcp"#define pr_fmt (fmt) KMSG_COMPONENT ": " fmt +#include <linux/types.h> +#include <scsi/fc/fc_fcp.h> #include <asm/atomic.h> #include "zfcp_ext.h" #include "zfcp_dbf.h"
@@ -17,18 +19,6 @@ static unsigned int default_depth = 32;module_param_named (queue_depth, default_depth, uint,0600 );MODULE_PARM_DESC (queue_depth,"Default queue depth for new SCSI devices" ); -/* Find start of Sense Information in FCP response unit*/ -char *zfcp_get_fcp_sns_info_ptr (struct fcp_rsp_iu *fcp_rsp_iu) -{ -char *fcp_sns_info_ptr; - - fcp_sns_info_ptr = (unsigned char *) &fcp_rsp_iu[1 ]; -if (fcp_rsp_iu->validity.bits.fcp_rsp_len_valid) - fcp_sns_info_ptr += fcp_rsp_iu->fcp_rsp_len; - -return fcp_sns_info_ptr; -} -static int zfcp_scsi_change_queue_depth (struct scsi_device *sdev,int depth,int reason) {
@@ -283,12 +273,12 @@ static int zfcp_task_mgmt_function(strucstatic int zfcp_scsi_eh_device_reset_handler (struct scsi_cmnd *scpnt) { -return zfcp_task_mgmt_function (scpnt,FCP_LOGICAL_UNIT_RESET ); +return zfcp_task_mgmt_function (scpnt,FCP_TMF_LUN_RESET ); }static int zfcp_scsi_eh_target_reset_handler (struct scsi_cmnd *scpnt) { -return zfcp_task_mgmt_function (scpnt,FCP_TARGET_RESET ); +return zfcp_task_mgmt_function (scpnt,FCP_TMF_TGT_RESET ); }static int zfcp_scsi_eh_host_reset_handler (struct scsi_cmnd *scpnt)
@@ -325,7 +315,7 @@ int zfcp_adapter_scsi_register(struct zf adapter->scsi_host->max_lun =1 ; adapter->scsi_host->max_channel =0 ; adapter->scsi_host->unique_id = dev_id.devno; - adapter->scsi_host->max_cmd_len =255 ; + adapter->scsi_host->max_cmd_len =16 ;/* in struct fcp_cmnd */ adapter->scsi_host->transportt = zfcp_data.scsi_transport_template; adapter->scsi_host->hostdata[0 ] = (unsigned long ) adapter;
PATCH 13/22 zfcp: Use common code definitions for FC ELS structs
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Use common code definitions for FC plogi, logo, rscn and adisc structs instead of inventing private ones. Move the private struct for issuing ELS ADISC inside zfcp to zfcp_fc header file.
---
drivers/s390/scsi/zfcp_def.h | 45 --------------- drivers/s390/scsi/zfcp_ext.h | 4 + drivers/s390/scsi/zfcp_fc.c | 129 +++++++++++++++++++++---------------------- drivers/s390/scsi/zfcp_fc.h | 17 +++++ drivers/s390/scsi/zfcp_fsf.c | 45 ++++++--------- drivers/s390/scsi/zfcp_fsf.h | 20 ------ 6 files changed, 107 insertions(+), 153 deletions(-)
drivers/s390/scsi/zfcp_def.h +0 -45
@@ -75,51 +75,6 @@#define ZFCP_DID_MASK 0x00FFFFFF -/* see fc-fs */ -#define LS_RSCN 0x61 -#define LS_LOGO 0x05 -#define LS_PLOGI 0x03 - -struct fcp_rscn_head { -u8 command; -u8 page_length;/* always 0x04 */ -u16 payload_len; -} __attribute__((packed)); - -struct fcp_rscn_element { -u8 reserved:2 ; -u8 event_qual:4 ; -u8 addr_format:2 ; -u32 nport_did:24 ; -} __attribute__((packed)); - -/* see fc-ph */ -struct fcp_logo { -u32 command; -u32 nport_did; -u64 nport_wwpn; -} __attribute__((packed)); - -/* -* FC-FS stuff -*/ -#define R_A_TOV 10/* seconds */ - -#define ZFCP_LS_RLS 0x0f -#define ZFCP_LS_ADISC 0x52 -#define ZFCP_LS_RPS 0x56 -#define ZFCP_LS_RSCN 0x61 -#define ZFCP_LS_RNID 0x78 - -struct zfcp_ls_adisc { -u8 code; -u8 field[3 ]; -u32 hard_nport_id; -u64 wwpn; -u64 wwnn; -u32 nport_id; -} __attribute__ ((packed)); -/* * FC-GS-2 stuff */
drivers/s390/scsi/zfcp_ext.h +3 -1
@@ -9,6 +9,8 @@#ifndef ZFCP_EXT_H #define ZFCP_EXT_H +#include <linux/types.h> +#include <scsi/fc/fc_els.h> #include "zfcp_def.h" /* zfcp_aux.c */
@@ -98,7 +100,7 @@ extern void zfcp_fc_scan_ports(struct woextern void zfcp_fc_incoming_els (struct zfcp_fsf_req *);extern void zfcp_fc_port_did_lookup (struct work_struct *);extern void zfcp_fc_trigger_did_lookup (struct zfcp_port *); -extern void zfcp_fc_plogi_evaluate (struct zfcp_port *,struct fsf_plogi *); +extern void zfcp_fc_plogi_evaluate (struct zfcp_port *,struct fc_els_flogi *);extern void zfcp_fc_test_link (struct zfcp_port *);extern void zfcp_fc_link_test_work (struct work_struct *);extern void zfcp_fc_wka_ports_force_offline (struct zfcp_wka_ports *);
drivers/s390/scsi/zfcp_fc.c +65 -64
230 lines not on this page · raw message
drivers/s390/scsi/zfcp_fc.h +17 -0
@@ -10,11 +10,28 @@#ifndef ZFCP_FC_H #define ZFCP_FC_H +#include <scsi/fc/fc_els.h> #include <scsi/fc/fc_fcp.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_tcq.h> /** +* struct zfcp_fc_els_adisc - everything required in zfcp for issuing ELS ADISC +* @els: data required for issuing els fsf command +* @req: scatterlist entry for ELS ADISC request +* @resp: scatterlist entry for ELS ADISC response +* @adisc_req: ELS ADISC request data +* @adisc_resp: ELS ADISC response data +*/ +struct zfcp_fc_els_adisc { +struct zfcp_send_els els; +struct scatterlist req; +struct scatterlist resp; +struct fc_els_adisc adisc_req; +struct fc_els_adisc adisc_resp; +}; + +/** * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd * @fcp: fcp_cmnd to setup * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
drivers/s390/scsi/zfcp_fsf.c +20 -25
103 lines not on this page · raw message
drivers/s390/scsi/zfcp_fsf.h +2 -18
@@ -309,22 +309,7 @@ struct fsf_qtcb_header {u8 res4[16 ]; } __attribute__ ((packed)); -struct fsf_nport_serv_param { -u8 common_serv_param[16 ]; -u64 wwpn; -u64 wwnn; -u8 class1_serv_param[16 ]; -u8 class2_serv_param[16 ]; -u8 class3_serv_param[16 ]; -u8 class4_serv_param[16 ]; -u8 vendor_version_level[16 ]; -} __attribute__ ((packed)); -#define FSF_PLOGI_MIN_LEN 112 -struct fsf_plogi { -u32 code; -struct fsf_nport_serv_param serv_param; -} __attribute__ ((packed));#define FSF_FCP_CMND_SIZE 288#define FSF_FCP_RSP_SIZE 128
@@ -377,13 +362,12 @@ struct fsf_qtcb_bottom_config {u16 timer_interval;u8 res2[8 ];u32 s_id; -struct fsf_nport_serv_param nport_serv_param; -u8 reserved_nport_serv_param[16 ]; +u8 nport_serv_param[128 ];u8 res3[8 ];u32 adapter_ports;u32 hardware_version;u8 serial_number[32 ]; -struct fsf_nport_serv_param plogi_payload; +u8 plogi_payload[112 ];struct fsf_statistics_info stat_info;u8 res4[112 ]; } __attribute__ ((packed));
PATCH 14/22 zfcp: Use common code definitions for FC CT structs
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Use common code definitions for FC GPN_FT and GID_PN instead of inventing private ones. Move the private structs still required inside zfcp to zfcp_fc header file.
---
drivers/s390/scsi/zfcp_aux.c | 13 ++-- drivers/s390/scsi/zfcp_dbf.c | 36 +++++------ drivers/s390/scsi/zfcp_def.h | 74 ----------------------- drivers/s390/scsi/zfcp_fc.c | 138 +++++++++++++++++-------------------------- drivers/s390/scsi/zfcp_fc.h | 80 ++++++++++++++++++++++++ 5 files changed, 161 insertions(+), 180 deletions(-)
drivers/s390/scsi/zfcp_aux.c +7 -6
@@ -31,6 +31,7 @@#include <linux/miscdevice.h> #include <linux/seq_file.h> #include "zfcp_ext.h" +#include "zfcp_fc.h" #define ZFCP_BUS_ID_SIZE 20
@@ -159,7 +160,7 @@ static int __init zfcp_module_init(void)int retval = -ENOMEM ; zfcp_data.gpn_ft_cache =zfcp_cache_hw_align ("zfcp_gpn" , -sizeof (struct ct_iu_gpn_ft_req )); +sizeof (struct zfcp_fc_gpn_ft_req ));if (!zfcp_data.gpn_ft_cache) goto out;
@@ -174,7 +175,7 @@ static int __init zfcp_module_init(void) goto out_sr_cache; zfcp_data.gid_pn_cache =zfcp_cache_hw_align ("zfcp_gid" , -sizeof (struct zfcp_gid_pn_data )); +sizeof (struct zfcp_fc_gid_pn ));if (!zfcp_data.gid_pn_cache) goto out_gid_cache;
@@ -407,9 +408,9 @@ static int zfcp_allocate_low_mem_buffersif (!adapter->pool.status_read_data)return -ENOMEM ; - adapter->pool.gid_pn_data = + adapter->pool.gid_pn =mempool_create_slab_pool (1 , zfcp_data.gid_pn_cache); -if (!adapter->pool.gid_pn_data) +if (!adapter->pool.gid_pn)return -ENOMEM ;return 0 ;
@@ -429,8 +430,8 @@ static void zfcp_free_low_mem_buffers(stmempool_destroy (adapter->pool.status_read_req);if (adapter->pool.status_read_data)mempool_destroy (adapter->pool.status_read_data); -if (adapter->pool.gid_pn_data) -mempool_destroy (adapter->pool.gid_pn_data); +if (adapter->pool.gid_pn) +mempool_destroy (adapter->pool.gid_pn); }/**
drivers/s390/scsi/zfcp_dbf.c +18 -18
@@ -684,7 +684,7 @@ void zfcp_dbf_san_ct_request(struct zfcpstruct zfcp_wka_port *wka_port = ct->wka_port;struct zfcp_adapter *adapter = wka_port->adapter;struct zfcp_dbf *dbf = adapter->dbf; -struct ct_hdr *hdr =sg_virt (ct->req); +struct fc_ct_hdr *hdr =sg_virt (ct->req);struct zfcp_dbf_san_record *r = &dbf->san_buf;struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req;int level =3 ;
@@ -697,17 +697,17 @@ void zfcp_dbf_san_ct_request(struct zfcp r->fsf_seqno = fsf_req->seq_no; r->s_id =fc_host_port_id (adapter->scsi_host); r->d_id = wka_port->d_id; - oct->cmd_req_code = hdr->cmd_rsp_code; - oct->revision = hdr->revision; - oct->gs_type = hdr->gs_type; - oct->gs_subtype = hdr->gs_subtype; - oct->options = hdr->options; - oct->max_res_size = hdr->max_res_size; - oct->len =min ((int )ct->req->length - (int )sizeof (struct ct_hdr ), + oct->cmd_req_code = hdr->ct_cmd; + oct->revision = hdr->ct_rev; + oct->gs_type = hdr->ct_fs_type; + oct->gs_subtype = hdr->ct_fs_subtype; + oct->options = hdr->ct_options; + oct->max_res_size = hdr->ct_mr_size; + oct->len =min ((int )ct->req->length - (int )sizeof (struct fc_ct_hdr ),ZFCP_DBF_SAN_MAX_PAYLOAD );debug_event (dbf->san, level, r,sizeof (*r));zfcp_dbf_hexdump (dbf->san, r,sizeof (*r), level, - (void *)hdr +sizeof (struct ct_hdr ), oct->len); + (void *)hdr +sizeof (struct fc_ct_hdr ), oct->len);spin_unlock_irqrestore (&dbf->san_lock, flags); }
@@ -720,7 +720,7 @@ void zfcp_dbf_san_ct_response(struct zfcstruct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;struct zfcp_wka_port *wka_port = ct->wka_port;struct zfcp_adapter *adapter = wka_port->adapter; -struct ct_hdr *hdr =sg_virt (ct->resp); +struct fc_ct_hdr *hdr =sg_virt (ct->resp);struct zfcp_dbf *dbf = adapter->dbf;struct zfcp_dbf_san_record *r = &dbf->san_buf;struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp;
@@ -734,17 +734,17 @@ void zfcp_dbf_san_ct_response(struct zfc r->fsf_seqno = fsf_req->seq_no; r->s_id = wka_port->d_id; r->d_id =fc_host_port_id (adapter->scsi_host); - rct->cmd_rsp_code = hdr->cmd_rsp_code; - rct->revision = hdr->revision; - rct->reason_code = hdr->reason_code; - rct->expl = hdr->reason_code_expl; - rct->vendor_unique = hdr->vendor_unique; - rct->max_res_size = hdr->max_res_size; - rct->len =min ((int )ct->resp->length - (int )sizeof (struct ct_hdr ), + rct->cmd_rsp_code = hdr->ct_cmd; + rct->revision = hdr->ct_rev; + rct->reason_code = hdr->ct_reason; + rct->expl = hdr->ct_explan; + rct->vendor_unique = hdr->ct_vendor; + rct->max_res_size = hdr->ct_mr_size; + rct->len =min ((int )ct->resp->length - (int )sizeof (struct fc_ct_hdr ),ZFCP_DBF_SAN_MAX_PAYLOAD );debug_event (dbf->san, level, r,sizeof (*r));zfcp_dbf_hexdump (dbf->san, r,sizeof (*r), level, - (void *)hdr +sizeof (struct ct_hdr ), rct->len); + (void *)hdr +sizeof (struct fc_ct_hdr ), rct->len);spin_unlock_irqrestore (&dbf->san_lock, flags); }
drivers/s390/scsi/zfcp_def.h +1 -73
101 lines not on this page · raw message
drivers/s390/scsi/zfcp_fc.c +55 -83
256 lines not on this page · raw message
drivers/s390/scsi/zfcp_fc.h +80 -0
89 lines not on this page · raw message
PATCH 15/22 zfcp: Move WKA port to zfcp FC code
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The well-known-address (WKA) port handling code is part of the FC code in zfcp. Move everything WKA related to the zfcp_fc files and use the common zfcp_fc prefix for structs and functions. Drop the unused key management service while renaming the struct, no request could ever reach this service in zfcp and it is obsolete anyway.
---
drivers/s390/scsi/zfcp_dbf.c | 5 ++-- drivers/s390/scsi/zfcp_def.h | 31 +------------------------- drivers/s390/scsi/zfcp_ext.h | 6 ++--- drivers/s390/scsi/zfcp_fc.c | 44 ++++++++++++++++++------------------- drivers/s390/scsi/zfcp_fc.h | 50 +++++++++++++++++++++++++++++++++++++++++++ drivers/s390/scsi/zfcp_fsf.c | 22 +++++++++--------- 6 files changed, 90 insertions(+), 68 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +3 -2
@@ -13,6 +13,7 @@#include <asm/debug.h> #include "zfcp_dbf.h" #include "zfcp_ext.h" +#include "zfcp_fc.h" static u32 dbfsize =4 ;
@@ -681,7 +682,7 @@ void zfcp_dbf_rec_action(char *id2, struvoid zfcp_dbf_san_ct_request (struct zfcp_fsf_req *fsf_req) {struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; -struct zfcp_wka_port *wka_port = ct->wka_port; +struct zfcp_fc_wka_port *wka_port = ct->wka_port;struct zfcp_adapter *adapter = wka_port->adapter;struct zfcp_dbf *dbf = adapter->dbf;struct fc_ct_hdr *hdr =sg_virt (ct->req);
@@ -718,7 +719,7 @@ void zfcp_dbf_san_ct_request(struct zfcpvoid zfcp_dbf_san_ct_response (struct zfcp_fsf_req *fsf_req) {struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; -struct zfcp_wka_port *wka_port = ct->wka_port; +struct zfcp_fc_wka_port *wka_port = ct->wka_port;struct zfcp_adapter *adapter = wka_port->adapter;struct fc_ct_hdr *hdr =sg_virt (ct->resp);struct zfcp_dbf *dbf = adapter->dbf;
drivers/s390/scsi/zfcp_def.h +2 -29
@@ -104,14 +104,6 @@#define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001#define ZFCP_STATUS_PORT_LINK_TEST 0x00000002 -/* well known address (WKA) port status*/ -enum zfcp_wka_status { -ZFCP_WKA_PORT_OFFLINE , -ZFCP_WKA_PORT_CLOSING , -ZFCP_WKA_PORT_OPENING , -ZFCP_WKA_PORT_ONLINE , -}; -/* logical unit status */ #define ZFCP_STATUS_UNIT_SHARED 0x00000004#define ZFCP_STATUS_UNIT_READONLY 0x00000008
@@ -155,7 +147,7 @@ struct zfcp_adapter_mempool {* @status: used to pass error status to calling function */ struct zfcp_send_ct { -struct zfcp_wka_port *wka_port; +struct zfcp_fc_wka_port *wka_port;struct scatterlist *req;struct scatterlist *resp;void (*handler)(unsigned long );
@@ -190,25 +182,6 @@ struct zfcp_send_els {int status; }; -struct zfcp_wka_port { -struct zfcp_adapter *adapter; -wait_queue_head_t completion_wq; -enum zfcp_wka_status status; -atomic_t refcount; -u32 d_id; -u32 handle; -struct mutex mutex; -struct delayed_work work; -}; - -struct zfcp_wka_ports { -struct zfcp_wka_port ms;/* management service */ -struct zfcp_wka_port ts;/* time service */ -struct zfcp_wka_port ds;/* directory service */ -struct zfcp_wka_port as;/* alias service */ -struct zfcp_wka_port ks;/* key distribution service */ -}; -struct zfcp_qdio_queue {struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q ];u8 first;/* index of next free bfr in queue */
@@ -309,7 +282,7 @@ struct zfcp_adapter {u32 erp_low_mem_count;/* nr of erp actions waiting for memory */ struct task_struct *erp_thread; -struct zfcp_wka_ports *gs;/* generic services */ +struct zfcp_fc_wka_ports *gs;/* generic services */ struct zfcp_dbf *dbf;/* debug traces */ struct zfcp_adapter_mempool pool;/* Adapter memory pools */ struct fc_host_statistics *fc_stats;
drivers/s390/scsi/zfcp_ext.h +3 -3
@@ -103,7 +103,7 @@ extern void zfcp_fc_trigger_did_lookup(sextern void zfcp_fc_plogi_evaluate (struct zfcp_port *,struct fc_els_flogi *);extern void zfcp_fc_test_link (struct zfcp_port *);extern void zfcp_fc_link_test_work (struct work_struct *); -extern void zfcp_fc_wka_ports_force_offline (struct zfcp_wka_ports *); +extern void zfcp_fc_wka_ports_force_offline (struct zfcp_fc_wka_ports *);extern int zfcp_fc_gs_setup (struct zfcp_adapter *);extern void zfcp_fc_gs_destroy (struct zfcp_adapter *);extern int zfcp_fc_execute_els_fc_job (struct fc_bsg_job *);
@@ -111,8 +111,8 @@ extern int zfcp_fc_execute_ct_fc_job(str/* zfcp_fsf.c */ extern int zfcp_fsf_open_port (struct zfcp_erp_action *); -extern int zfcp_fsf_open_wka_port (struct zfcp_wka_port *); -extern int zfcp_fsf_close_wka_port (struct zfcp_wka_port *); +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 *);
drivers/s390/scsi/zfcp_fc.c +21 -23
121 lines not on this page · raw message
drivers/s390/scsi/zfcp_fc.h +50 -0
56 lines not on this page · raw message
drivers/s390/scsi/zfcp_fsf.c +11 -11
@@ -1096,7 +1096,7 @@ static int zfcp_fsf_setup_ct_els(struct*/ int zfcp_fsf_send_ct (struct zfcp_send_ct *ct,mempool_t *pool) { -struct zfcp_wka_port *wka_port = ct->wka_port; +struct zfcp_fc_wka_port *wka_port = ct->wka_port;struct zfcp_qdio *qdio = wka_port->adapter->qdio;struct zfcp_fsf_req *req;int ret = -EIO ;
@@ -1610,11 +1610,11 @@ out:static void zfcp_fsf_open_wka_port_handler (struct zfcp_fsf_req *req) { -struct zfcp_wka_port *wka_port = req->data; +struct zfcp_fc_wka_port *wka_port = req->data;struct fsf_qtcb_header *header = &req->qtcb->header;if (req->status &ZFCP_STATUS_FSFREQ_ERROR ) { - wka_port->status =ZFCP_WKA_PORT_OFFLINE ; + wka_port->status =ZFCP_FC_WKA_PORT_OFFLINE ; goto out; }
@@ -1627,13 +1627,13 @@ static void zfcp_fsf_open_wka_port_handl req->status |=ZFCP_STATUS_FSFREQ_ERROR ;/* fall through */ case FSF_ACCESS_DENIED : - wka_port->status =ZFCP_WKA_PORT_OFFLINE ; + wka_port->status =ZFCP_FC_WKA_PORT_OFFLINE ;break ;case FSF_GOOD : wka_port->handle = header->port_handle;/* fall through */ case FSF_PORT_ALREADY_OPEN : - wka_port->status =ZFCP_WKA_PORT_ONLINE ; + wka_port->status =ZFCP_FC_WKA_PORT_ONLINE ; } out:wake_up (&wka_port->completion_wq);
@@ -1641,10 +1641,10 @@ out:/** * zfcp_fsf_open_wka_port - create and send open wka-port request -* @wka_port: pointer to struct zfcp_wka_port +* @wka_port: pointer to struct zfcp_fc_wka_port * Returns: 0 on success, error otherwise */ -int zfcp_fsf_open_wka_port (struct zfcp_wka_port *wka_port) +int zfcp_fsf_open_wka_port (struct zfcp_fc_wka_port *wka_port) {struct qdio_buffer_element *sbale;struct zfcp_qdio *qdio = wka_port->adapter->qdio;
@@ -1683,23 +1683,23 @@ out:static void zfcp_fsf_close_wka_port_handler (struct zfcp_fsf_req *req) { -struct zfcp_wka_port *wka_port = req->data; +struct zfcp_fc_wka_port *wka_port = req->data;if (req->qtcb->header.fsf_status ==FSF_PORT_HANDLE_NOT_VALID ) { req->status |=ZFCP_STATUS_FSFREQ_ERROR ;zfcp_erp_adapter_reopen (wka_port->adapter,0 ,"fscwph1" , req); } - wka_port->status =ZFCP_WKA_PORT_OFFLINE ; + wka_port->status =ZFCP_FC_WKA_PORT_OFFLINE ;wake_up (&wka_port->completion_wq); }/** * zfcp_fsf_close_wka_port - create and send close wka port request -* @erp_action: pointer to struct zfcp_erp_action +* @wka_port: WKA port to open * Returns: 0 on success, error otherwise */ -int zfcp_fsf_close_wka_port (struct zfcp_wka_port *wka_port) +int zfcp_fsf_close_wka_port (struct zfcp_fc_wka_port *wka_port) {struct qdio_buffer_element *sbale;struct zfcp_qdio *qdio = wka_port->adapter->qdio;
PATCH 16/22 zfcp: Remove ZFCP_DID_MASK
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Instead of assigning 4 bytes with the highest byte masked out, use a 3 byte array with the ntoh24 and h24ton helper functions, thus eliminating the need for the ZFCP_DID_MASK.
---
drivers/s390/scsi/zfcp_dbf.c | 4 ++-- drivers/s390/scsi/zfcp_def.h | 4 ---- drivers/s390/scsi/zfcp_fsf.c | 12 ++++++------ drivers/s390/scsi/zfcp_fsf.h | 15 +++++++++------ 4 files changed, 17 insertions(+), 18 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +2 -2
@@ -178,7 +178,7 @@ void _zfcp_dbf_hba_fsf_response(const chcase FSF_QTCB_SEND_ELS : send_els = (struct zfcp_send_els *)fsf_req->data; - response->u.els.d_id = qtcb->bottom.support.d_id; + response->u.els.d_id =ntoh24 (qtcb->bottom.support.d_id); response->u.els.ls_code = send_els->ls_code >>24 ;break ;
@@ -812,7 +812,7 @@ void zfcp_dbf_san_incoming_els(struct zfint length = (int )buf->length - (int )((void *)&buf->payload - (void *)buf); -zfcp_dbf_san_els ("iels" ,1 , fsf_req, buf->d_id, +zfcp_dbf_san_els ("iels" ,1 , fsf_req,ntoh24 (buf->d_id),fc_host_port_id (adapter->scsi_host), buf->payload.data[0 ], (void *)buf->payload.data, length);
drivers/s390/scsi/zfcp_def.h +0 -4
@@ -71,10 +71,6 @@/* timeout value for "default timer" for fsf requests */ #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ) -/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/ - -#define ZFCP_DID_MASK 0x00FFFFFF -/*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/ /*
drivers/s390/scsi/zfcp_fsf.c +6 -6
@@ -128,7 +128,7 @@ static void zfcp_fsf_status_read_port_clstruct fsf_status_read_buffer *sr_buf = req->data;struct zfcp_adapter *adapter = req->adapter;struct zfcp_port *port; -int d_id = sr_buf->d_id &ZFCP_DID_MASK ; +int d_id =ntoh24 (sr_buf->d_id);read_lock_irqsave (&adapter->port_list_lock, flags);list_for_each_entry (port, &adapter->port_list, list)
@@ -494,7 +494,7 @@ static int zfcp_fsf_exchange_config_evalfc_host_port_name (shost) = nsp->fl_wwpn;fc_host_node_name (shost) = nsp->fl_wwnn; -fc_host_port_id (shost) = bottom->s_id &ZFCP_DID_MASK ; +fc_host_port_id (shost) =ntoh24 (bottom->s_id);fc_host_speed (shost) = bottom->fc_link_speed;fc_host_supported_classes (shost) =FC_COS_CLASS2 |FC_COS_CLASS3 ;
@@ -506,7 +506,7 @@ static int zfcp_fsf_exchange_config_evalswitch (bottom->fc_topology) {case FSF_TOPO_P2P : - adapter->peer_d_id = bottom->peer_d_id &ZFCP_DID_MASK ; + adapter->peer_d_id =ntoh24 (bottom->peer_d_id); adapter->peer_wwpn = plogi->fl_wwpn; adapter->peer_wwnn = plogi->fl_wwnn;fc_host_port_type (shost) =FC_PORTTYPE_PTP ;
@@ -1216,7 +1216,7 @@ int zfcp_fsf_send_els(struct zfcp_send_eif (ret) goto failed_send; - req->qtcb->bottom.support.d_id = els->d_id; +hton24 (req->qtcb->bottom.support.d_id, els->d_id); req->handler = zfcp_fsf_send_els_handler; req->data = els;
@@ -1522,7 +1522,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_a sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ; req->handler = zfcp_fsf_open_port_handler; - req->qtcb->bottom.support.d_id = port->d_id; +hton24 (req->qtcb->bottom.support.d_id, port->d_id); req->data = port; req->erp_action = erp_action; erp_action->fsf_req = req;
@@ -1669,7 +1669,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_f sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ; req->handler = zfcp_fsf_open_wka_port_handler; - req->qtcb->bottom.support.d_id = wka_port->d_id; +hton24 (req->qtcb->bottom.support.d_id, wka_port->d_id); req->data = wka_port;zfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT );
drivers/s390/scsi/zfcp_fsf.h +9 -6
@@ -11,6 +11,7 @@#include <linux/pfn.h> #include <linux/scatterlist.h> +#include <scsi/libfc.h> #define FSF_QTCB_CURRENT_VERSION 0x00000001
@@ -228,7 +229,8 @@ struct fsf_status_read_buffer {u32 length;u32 res1;struct fsf_queue_designator queue_designator; -u32 d_id; +u8 res2; +u8 d_id[3 ];u32 class;u64 fcp_lun;u8 res3[24 ];
@@ -327,8 +329,8 @@ struct fsf_qtcb_bottom_io {struct fsf_qtcb_bottom_support {u32 operation_subtype; -u8 res1[12 ]; -u32 d_id; +u8 res1[13 ]; +u8 d_id[3 ];u32 option;u64 fcp_lun;u64 res2;
@@ -357,11 +359,12 @@ struct fsf_qtcb_bottom_config {u32 fc_topology;u32 fc_link_speed;u32 adapter_type; -u32 peer_d_id; +u8 res0; +u8 peer_d_id[3 ];u8 res1[2 ];u16 timer_interval; -u8 res2[8 ]; -u32 s_id; +u8 res2[9 ]; +u8 s_id[3 ];u8 nport_serv_param[128 ];u8 res3[8 ];u32 adapter_ports;
PATCH 17/22 zfcp: Simplify handling of ct and els requests
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Remove some redundancies in FC related code and trace:
- drop redundant data from SAN trace (local s_id that only changes during link down, ls_code that is already part of payload, d_id in ct response trace that is always the same as in ct request trace)
- use one common fsf struct to hold zfcp data for ct and els requests
- leverage common fsf struct for FC passthrough job data, allocate it with dd_bsg_data for passthrough requests and unify common code for ct and els passthrough request
- simplify callback handling in zfcp_fc
---
drivers/s390/scsi/zfcp_dbf.c | 56 +++------ drivers/s390/scsi/zfcp_dbf.h | 7 - drivers/s390/scsi/zfcp_def.h | 46 ------- drivers/s390/scsi/zfcp_ext.h | 12 + drivers/s390/scsi/zfcp_fc.c | 253 +++++++++++++++--------------------------- drivers/s390/scsi/zfcp_fc.h | 7 - drivers/s390/scsi/zfcp_fsf.c | 28 ++-- drivers/s390/scsi/zfcp_fsf.h | 18 ++ drivers/s390/scsi/zfcp_scsi.c | 18 -- 9 files changed, 160 insertions(+), 285 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +21 -35
@@ -179,7 +179,6 @@ void _zfcp_dbf_hba_fsf_response(const chcase FSF_QTCB_SEND_ELS : send_els = (struct zfcp_send_els *)fsf_req->data; response->u.els.d_id =ntoh24 (qtcb->bottom.support.d_id); - response->u.els.ls_code = send_els->ls_code >>24 ;break ;case FSF_QTCB_ABORT_FCP_CMND :
@@ -349,7 +348,6 @@ static void zfcp_dbf_hba_view_response(ccase FSF_QTCB_SEND_ELS :zfcp_dbf_out (p,"d_id" ,"0x%06x" , r->u.els.d_id); -zfcp_dbf_out (p,"ls_code" ,"0x%02x" , r->u.els.ls_code);break ;case FSF_QTCB_ABORT_FCP_CMND :
@@ -678,12 +676,12 @@ void zfcp_dbf_rec_action(char *id2, stru/** * zfcp_dbf_san_ct_request - trace event for issued CT request * @fsf_req: request containing issued CT data +* @d_id: destination id where ct request is sent to */ -void zfcp_dbf_san_ct_request (struct zfcp_fsf_req *fsf_req) +void zfcp_dbf_san_ct_request (struct zfcp_fsf_req *fsf_req,u32 d_id) { -struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; -struct zfcp_fc_wka_port *wka_port = ct->wka_port; -struct zfcp_adapter *adapter = wka_port->adapter; +struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data; +struct zfcp_adapter *adapter = fsf_req->adapter;struct zfcp_dbf *dbf = adapter->dbf;struct fc_ct_hdr *hdr =sg_virt (ct->req);struct zfcp_dbf_san_record *r = &dbf->san_buf;
@@ -696,8 +694,7 @@ void zfcp_dbf_san_ct_request(struct zfcpstrncpy (r->tag,"octc" ,ZFCP_DBF_TAG_SIZE ); r->fsf_reqid = fsf_req->req_id; r->fsf_seqno = fsf_req->seq_no; - r->s_id =fc_host_port_id (adapter->scsi_host); - r->d_id = wka_port->d_id; + oct->d_id = d_id; oct->cmd_req_code = hdr->ct_cmd; oct->revision = hdr->ct_rev; oct->gs_type = hdr->ct_fs_type;
@@ -718,9 +715,8 @@ void zfcp_dbf_san_ct_request(struct zfcp*/ void zfcp_dbf_san_ct_response (struct zfcp_fsf_req *fsf_req) { -struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; -struct zfcp_fc_wka_port *wka_port = ct->wka_port; -struct zfcp_adapter *adapter = wka_port->adapter; +struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data; +struct zfcp_adapter *adapter = fsf_req->adapter;struct fc_ct_hdr *hdr =sg_virt (ct->resp);struct zfcp_dbf *dbf = adapter->dbf;struct zfcp_dbf_san_record *r = &dbf->san_buf;
@@ -733,8 +729,6 @@ void zfcp_dbf_san_ct_response(struct zfcstrncpy (r->tag,"rctc" ,ZFCP_DBF_TAG_SIZE ); r->fsf_reqid = fsf_req->req_id; r->fsf_seqno = fsf_req->seq_no; - r->s_id = wka_port->d_id; - r->d_id =fc_host_port_id (adapter->scsi_host); rct->cmd_rsp_code = hdr->ct_cmd; rct->revision = hdr->ct_rev; rct->reason_code = hdr->ct_reason;
@@ -750,8 +744,8 @@ void zfcp_dbf_san_ct_response(struct zfc }static void zfcp_dbf_san_els (const char *tag,int level, -struct zfcp_fsf_req *fsf_req,u32 s_id,u32 d_id, -u8 ls_code,void *buffer,int buflen) +struct zfcp_fsf_req *fsf_req,u32 d_id, +void *buffer,int buflen) {struct zfcp_adapter *adapter = fsf_req->adapter;struct zfcp_dbf *dbf = adapter->dbf;
@@ -763,9 +757,7 @@ static void zfcp_dbf_san_els(const charstrncpy (rec->tag, tag,ZFCP_DBF_TAG_SIZE ); rec->fsf_reqid = fsf_req->req_id; rec->fsf_seqno = fsf_req->seq_no; - rec->s_id = s_id; - rec->d_id = d_id; - rec->u.els.ls_code = ls_code; + rec->u.els.d_id = d_id;debug_event (dbf->san, level, rec,sizeof (*rec));zfcp_dbf_hexdump (dbf->san, rec,sizeof (*rec), level, buffer,min (buflen,ZFCP_DBF_SAN_MAX_PAYLOAD ));
@@ -778,12 +770,11 @@ static void zfcp_dbf_san_els(const char*/ void zfcp_dbf_san_els_request (struct zfcp_fsf_req *fsf_req) { -struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; +struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data; +u32 d_id =ntoh24 (fsf_req->qtcb->bottom.support.d_id); -zfcp_dbf_san_els ("oels" ,2 , fsf_req, -fc_host_port_id (els->adapter->scsi_host), - els->d_id, *(u8 *)sg_virt (els->req), -sg_virt (els->req), els->req->length); +zfcp_dbf_san_els ("oels" ,2 , fsf_req, d_id, +sg_virt (els->req), els->req->length); }/**
@@ -792,12 +783,11 @@ void zfcp_dbf_san_els_request(struct zfc*/ void zfcp_dbf_san_els_response (struct zfcp_fsf_req *fsf_req) { -struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; +struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data; +u32 d_id =ntoh24 (fsf_req->qtcb->bottom.support.d_id); -zfcp_dbf_san_els ("rels" ,2 , fsf_req, els->d_id, -fc_host_port_id (els->adapter->scsi_host), - *(u8 *)sg_virt (els->req),sg_virt (els->resp), - els->resp->length); +zfcp_dbf_san_els ("rels" ,2 , fsf_req, d_id, +sg_virt (els->resp), els->resp->length); }/**
@@ -806,16 +796,13 @@ void zfcp_dbf_san_els_response(struct zf*/ void zfcp_dbf_san_incoming_els (struct zfcp_fsf_req *fsf_req) { -struct zfcp_adapter *adapter = fsf_req->adapter;struct fsf_status_read_buffer *buf = (struct fsf_status_read_buffer *)fsf_req->data;int length = (int )buf->length - (int )((void *)&buf->payload - (void *)buf);zfcp_dbf_san_els ("iels" ,1 , fsf_req,ntoh24 (buf->d_id), -fc_host_port_id (adapter->scsi_host), - buf->payload.data[0 ], (void *)buf->payload.data, - length); + (void *)buf->payload.data, length); } static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view,
@@ -830,11 +817,10 @@ static int zfcp_dbf_san_view_format(debuzfcp_dbf_tag (&p,"tag" , r->tag);zfcp_dbf_out (&p,"fsf_reqid" ,"0x%0Lx" , r->fsf_reqid);zfcp_dbf_out (&p,"fsf_seqno" ,"0x%08x" , r->fsf_seqno); -zfcp_dbf_out (&p,"s_id" ,"0x%06x" , r->s_id); -zfcp_dbf_out (&p,"d_id" ,"0x%06x" , r->d_id);if (strncmp (r->tag,"octc" ,ZFCP_DBF_TAG_SIZE ) ==0 ) {struct zfcp_dbf_san_record_ct_request *ct = &r->u.ct_req; +zfcp_dbf_out (&p,"d_id" ,"0x%06x" , ct->d_id);zfcp_dbf_out (&p,"cmd_req_code" ,"0x%04x" , ct->cmd_req_code);zfcp_dbf_out (&p,"revision" ,"0x%02x" , ct->revision);zfcp_dbf_out (&p,"gs_type" ,"0x%02x" , ct->gs_type);
@@ -853,7 +839,7 @@ static int zfcp_dbf_san_view_format(debu strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {struct zfcp_dbf_san_record_els *els = &r->u.els; -zfcp_dbf_out (&p,"ls_code" ,"0x%02x" , els->ls_code); +zfcp_dbf_out (&p,"d_id" ,"0x%06x" , els->d_id); }return p - out_buf; }
drivers/s390/scsi/zfcp_dbf.h +2 -5
@@ -123,7 +123,6 @@ struct zfcp_dbf_hba_record_response { } unit;struct {u32 d_id; -u8 ls_code; } els; } u; } __attribute__ ((packed));
@@ -167,6 +166,7 @@ struct zfcp_dbf_san_record_ct_request {u8 options;u16 max_res_size;u32 len; +u32 d_id; } __attribute__ ((packed));struct zfcp_dbf_san_record_ct_response {
@@ -180,16 +180,13 @@ struct zfcp_dbf_san_record_ct_response { } __attribute__ ((packed));struct zfcp_dbf_san_record_els { -u8 ls_code; -u32 len; +u32 d_id; } __attribute__ ((packed));struct zfcp_dbf_san_record {u8 tag[ZFCP_DBF_TAG_SIZE ];u64 fsf_reqid;u32 fsf_seqno; -u32 s_id; -u32 d_id;union {struct zfcp_dbf_san_record_ct_request ct_req;struct zfcp_dbf_san_record_ct_response ct_resp;
drivers/s390/scsi/zfcp_def.h +0 -46
52 lines not on this page · raw message
drivers/s390/scsi/zfcp_ext.h +7 -5
@@ -12,6 +12,7 @@#include <linux/types.h> #include <scsi/fc/fc_els.h> #include "zfcp_def.h" +#include "zfcp_fc.h" /* zfcp_aux.c */ extern struct zfcp_unit *zfcp_get_unit_by_lun (struct zfcp_port *,u64 );
@@ -55,7 +56,7 @@ extern void _zfcp_dbf_hba_fsf_unsol(cons struct fsf_status_read_buffer *);extern void zfcp_dbf_hba_qdio (struct zfcp_dbf *,unsigned int ,int ,int );extern void zfcp_dbf_hba_berr (struct zfcp_dbf *,struct zfcp_fsf_req *); -extern void zfcp_dbf_san_ct_request (struct zfcp_fsf_req *); +extern void zfcp_dbf_san_ct_request (struct zfcp_fsf_req *,u32 );extern void zfcp_dbf_san_ct_response (struct zfcp_fsf_req *);extern void zfcp_dbf_san_els_request (struct zfcp_fsf_req *);extern void zfcp_dbf_san_els_response (struct zfcp_fsf_req *);
@@ -106,8 +107,7 @@ extern void zfcp_fc_link_test_work(strucextern void zfcp_fc_wka_ports_force_offline (struct zfcp_fc_wka_ports *);extern int zfcp_fc_gs_setup (struct zfcp_adapter *);extern void zfcp_fc_gs_destroy (struct zfcp_adapter *); -extern int zfcp_fc_execute_els_fc_job (struct fc_bsg_job *); -extern int zfcp_fc_execute_ct_fc_job (struct fc_bsg_job *); +extern int zfcp_fc_exec_bsg_job (struct fc_bsg_job *);/* zfcp_fsf.c */ extern int zfcp_fsf_open_port (struct zfcp_erp_action *);
@@ -128,8 +128,10 @@ extern struct zfcp_fsf_req *zfcp_fsf_conextern void zfcp_fsf_req_dismiss_all (struct zfcp_adapter *);extern int zfcp_fsf_status_read (struct zfcp_qdio *);extern int zfcp_status_read_refill (struct zfcp_adapter *adapter); -extern int zfcp_fsf_send_ct (struct zfcp_send_ct *,mempool_t *); -extern int zfcp_fsf_send_els (struct zfcp_send_els *); +extern int zfcp_fsf_send_ct (struct zfcp_fc_wka_port *,struct zfcp_fsf_ct_els *, +mempool_t *); +extern int zfcp_fsf_send_els (struct zfcp_adapter *,u32 , +struct zfcp_fsf_ct_els *);extern int zfcp_fsf_send_fcp_command_task (struct zfcp_unit *,struct scsi_cmnd *);extern void zfcp_fsf_req_free (struct zfcp_fsf_req *);
drivers/s390/scsi/zfcp_fc.c +92 -161
397 lines not on this page · raw message
drivers/s390/scsi/zfcp_fc.h +4 -3
@@ -15,6 +15,7 @@#include <scsi/fc/fc_ns.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_tcq.h> +#include "zfcp_fsf.h" #define ZFCP_FC_CT_SIZE_PAGE (PAGE_SIZE - sizeof(struct fc_ct_hdr))#define ZFCP_FC_GPN_FT_ENT_PAGE (ZFCP_FC_CT_SIZE_PAGE \
@@ -55,7 +56,7 @@ struct zfcp_fc_gid_pn_resp {* @gid_pn_resp: GID_PN response data */ struct zfcp_fc_gid_pn { -struct zfcp_send_ct ct; +struct zfcp_fsf_ct_els ct;struct scatterlist sg_req;struct scatterlist sg_resp;struct zfcp_fc_gid_pn_req gid_pn_req;
@@ -90,7 +91,7 @@ struct zfcp_fc_gpn_ft_resp {* @sg_resp: scatter list entries for gpn_ft responses (per memory page) */ struct zfcp_fc_gpn_ft { -struct zfcp_send_ct ct; +struct zfcp_fsf_ct_els ct;struct scatterlist sg_req;struct scatterlist sg_resp[ZFCP_FC_GPN_FT_NUM_BUFS ]; };
@@ -104,7 +105,7 @@ struct zfcp_fc_gpn_ft {* @adisc_resp: ELS ADISC response data */ struct zfcp_fc_els_adisc { -struct zfcp_send_els els; +struct zfcp_fsf_ct_els els;struct scatterlist req;struct scatterlist resp;struct fc_els_adisc adisc_req;
drivers/s390/scsi/zfcp_fsf.c +13 -15
@@ -961,10 +961,10 @@ out:static void zfcp_fsf_send_ct_handler (struct zfcp_fsf_req *req) {struct zfcp_adapter *adapter = req->adapter; -struct zfcp_send_ct *send_ct = req->data; +struct zfcp_fsf_ct_els *ct = req->data;struct fsf_qtcb_header *header = &req->qtcb->header; - send_ct->status = -EINVAL ; + ct->status = -EINVAL ;if (req->status &ZFCP_STATUS_FSFREQ_ERROR ) goto skip_fsfstatus;
@@ -972,7 +972,7 @@ static void zfcp_fsf_send_ct_handler(strswitch (header->fsf_status) {case FSF_GOOD :zfcp_dbf_san_ct_response (req); - send_ct->status =0 ; + ct->status =0 ;break ;case FSF_SERVICE_CLASS_NOT_SUPPORTED :zfcp_fsf_class_not_supp (req);
@@ -1004,8 +1004,8 @@ static void zfcp_fsf_send_ct_handler(str } skip_fsfstatus: -if (send_ct->handler) - send_ct->handler (send_ct->handler_data); +if (ct->handler) + ct->handler (ct->handler_data); } static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale,
@@ -1094,9 +1094,9 @@ static int zfcp_fsf_setup_ct_els(struct* @ct: pointer to struct zfcp_send_ct with data for request * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req */ -int zfcp_fsf_send_ct (struct zfcp_send_ct *ct,mempool_t *pool) +int zfcp_fsf_send_ct (struct zfcp_fc_wka_port *wka_port, +struct zfcp_fsf_ct_els *ct,mempool_t *pool) { -struct zfcp_fc_wka_port *wka_port = ct->wka_port;struct zfcp_qdio *qdio = wka_port->adapter->qdio;struct zfcp_fsf_req *req;int ret = -EIO ;
@@ -1122,7 +1122,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct req->qtcb->header.port_handle = wka_port->handle; req->data = ct; -zfcp_dbf_san_ct_request (req); +zfcp_dbf_san_ct_request (req, wka_port->d_id); ret =zfcp_fsf_req_send (req);if (ret)
@@ -1139,7 +1139,7 @@ out:static void zfcp_fsf_send_els_handler (struct zfcp_fsf_req *req) { -struct zfcp_send_els *send_els = req->data; +struct zfcp_fsf_ct_els *send_els = req->data;struct zfcp_port *port = send_els->port;struct fsf_qtcb_header *header = &req->qtcb->header;
@@ -1159,9 +1159,6 @@ static void zfcp_fsf_send_els_handler(stcase FSF_ADAPTER_STATUS_AVAILABLE :switch (header->fsf_status_qual.word[0 ]){case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE : -if (port && (send_els->ls_code !=ELS_ADISC )) -zfcp_fc_test_link (port); -/*fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED :case FSF_SQ_RETRY_IF_POSSIBLE : req->status |=ZFCP_STATUS_FSFREQ_ERROR ;
@@ -1193,10 +1190,11 @@ skip_fsfstatus:* zfcp_fsf_send_els - initiate an ELS command (FC-FS) * @els: pointer to struct zfcp_send_els with data for the command */ -int zfcp_fsf_send_els (struct zfcp_send_els *els) +int zfcp_fsf_send_els (struct zfcp_adapter *adapter,u32 d_id, +struct zfcp_fsf_ct_els *els) {struct zfcp_fsf_req *req; -struct zfcp_qdio *qdio = els->adapter->qdio; +struct zfcp_qdio *qdio = adapter->qdio;int ret = -EIO ;spin_lock_bh (&qdio->req_q_lock);
@@ -1216,7 +1214,7 @@ int zfcp_fsf_send_els(struct zfcp_send_eif (ret) goto failed_send; -hton24 (req->qtcb->bottom.support.d_id, els->d_id); +hton24 (req->qtcb->bottom.support.d_id, d_id); req->handler = zfcp_fsf_send_els_handler; req->data = els;
drivers/s390/scsi/zfcp_fsf.h +18 -0
@@ -437,4 +437,22 @@ struct zfcp_blk_drv_data {u64 fabric_lat; } __attribute__ ((packed)); +/** +* struct zfcp_fsf_ct_els - zfcp data for ct or els request +* @req: scatter-gather list for request +* @resp: scatter-gather list for response +* @handler: handler function (called for response to the request) +* @handler_data: data passed to handler function +* @port: Optional pointer to port for zfcp internal ELS (only test link ADISC) +* @status: used to pass error status to calling function +*/ +struct zfcp_fsf_ct_els { +struct scatterlist *req; +struct scatterlist *resp; +void (*handler)(void *); +void *handler_data; +struct zfcp_port *port; +int status; +}; +#endif /* FSF_H */
drivers/s390/scsi/zfcp_scsi.c +3 -15
@@ -14,6 +14,7 @@#include <asm/atomic.h> #include "zfcp_ext.h" #include "zfcp_dbf.h" +#include "zfcp_fc.h" static unsigned int default_depth =32 ;module_param_named (queue_depth, default_depth, uint,0600 );
@@ -628,20 +629,6 @@ void zfcp_scsi_scan(struct work_struct *put_device (&unit->sysfs_device); } -static int zfcp_execute_fc_job (struct fc_bsg_job *job) -{ -switch (job->request->msgcode) { -case FC_BSG_RPT_ELS : -case FC_BSG_HST_ELS_NOLOGIN : -return zfcp_fc_execute_els_fc_job (job); -case FC_BSG_RPT_CT : -case FC_BSG_HST_CT : -return zfcp_fc_execute_ct_fc_job (job); -default : -return -EINVAL ; - } -} -struct fc_function_template zfcp_transport_functions = { .show_starget_port_id =1 , .show_starget_port_name =1 ,
@@ -662,13 +649,14 @@ struct fc_function_template zfcp_transpo .get_host_port_state = zfcp_get_host_port_state, .terminate_rport_io = zfcp_scsi_terminate_rport_io, .show_host_port_state = 1, - .bsg_request = zfcp_execute_fc_job, + .bsg_request = zfcp_fc_exec_bsg_job,/* no functions registered for following dynamic attributes but directly set by LLDD */ .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), };struct zfcp_data zfcp_data = {
PATCH 18/22 zfcp: Improve ELS ADISC handling
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Introduce kmem_cache for ELS ADISC data to guarantee the required hardware alignment and free the allocated memory in case the send failes.
---
drivers/s390/scsi/zfcp_aux.c | 8 ++++++++ drivers/s390/scsi/zfcp_def.h | 1 + drivers/s390/scsi/zfcp_fc.c | 11 ++++++++--- 3 files changed, 17 insertions(+), 3 deletions(-)
drivers/s390/scsi/zfcp_aux.c +8 -0
@@ -179,6 +179,11 @@ static int __init zfcp_module_init(void)if (!zfcp_data.gid_pn_cache) goto out_gid_cache; + zfcp_data.adisc_cache =zfcp_cache_hw_align ("zfcp_adisc" , +sizeof (struct zfcp_fc_els_adisc )); +if (!zfcp_data.adisc_cache) + goto out_adisc_cache; + zfcp_data.scsi_transport_template =fc_attach_transport (&zfcp_transport_functions);if (!zfcp_data.scsi_transport_template)
@@ -206,6 +211,8 @@ out_ccw_register: out_misc:fc_release_transport (zfcp_data.scsi_transport_template); out_transport: +kmem_cache_destroy (zfcp_data.adisc_cache); +out_adisc_cache:kmem_cache_destroy (zfcp_data.gid_pn_cache); out_gid_cache:kmem_cache_destroy (zfcp_data.sr_buffer_cache);
@@ -224,6 +231,7 @@ static void __exit zfcp_module_exit(voidccw_driver_unregister (&zfcp_ccw_driver);misc_deregister (&zfcp_cfdc_misc);fc_release_transport (zfcp_data.scsi_transport_template); +kmem_cache_destroy (zfcp_data.adisc_cache);kmem_cache_destroy (zfcp_data.gid_pn_cache);kmem_cache_destroy (zfcp_data.sr_buffer_cache);kmem_cache_destroy (zfcp_data.qtcb_cache);
drivers/s390/scsi/zfcp_def.h +1 -0
@@ -347,6 +347,7 @@ struct zfcp_data {struct kmem_cache *qtcb_cache;struct kmem_cache *sr_buffer_cache;struct kmem_cache *gid_pn_cache; +struct kmem_cache *adisc_cache; };/********************** ZFCP SPECIFIC DEFINES ********************************/
drivers/s390/scsi/zfcp_fc.c +8 -3
@@ -389,15 +389,16 @@ static void zfcp_fc_adisc_handler(void * out:atomic_clear_mask (ZFCP_STATUS_PORT_LINK_TEST , &port->status);put_device (&port->sysfs_device); -kfree (adisc); +kmem_cache_free (zfcp_data.adisc_cache, adisc); }static int zfcp_fc_adisc (struct zfcp_port *port) {struct zfcp_fc_els_adisc *adisc;struct zfcp_adapter *adapter = port->adapter; +int ret; - adisc =kzalloc (sizeof (struct zfcp_fc_els_adisc ),GFP_ATOMIC ); + adisc =kmem_cache_alloc (zfcp_data.adisc_cache,GFP_ATOMIC );if (!adisc)return -ENOMEM ;
@@ -420,7 +421,11 @@ static int zfcp_fc_adisc(struct zfcp_porhton24 (adisc->adisc_req.adisc_port_id,fc_host_port_id (adapter->scsi_host)); -return zfcp_fsf_send_els (adapter, port->d_id, &adisc->els); + ret =zfcp_fsf_send_els (adapter, port->d_id, &adisc->els); +if (ret) +kmem_cache_free (zfcp_data.adisc_cache, adisc); + +return ret; }void zfcp_fc_link_test_work (struct work_struct *work)
PATCH 19/22 zfcp: Update FSF error reporting
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The SCSI midlayer retries commands based on the remote port state and the command status reported by the driver. Returning DID_TRANSPORT_DISRUPTED is a better approach, use this for reporting FSF errors back to the SCSI midlayer. See
http://marc.info/?l=linux-scsi&m=125668044215051&w=2 as reference.
There is also no need in special treatment of ABORTED commands, so remove the ZFCP_STATUS_FSFREQ_ABORTED, the commands are then returned with DID_TRANSPORT_DISRUPTED.
Also remove the ZFCP_STATUS_FSFREQ_RETRY: It is useless, no retry is happening in the FSF layer and nobody checks the state of this flag.
---
drivers/s390/scsi/zfcp_def.h | 2 -- drivers/s390/scsi/zfcp_fsf.c | 38 +++++++++++--------------------------- 2 files changed, 11 insertions(+), 29 deletions(-)
drivers/s390/scsi/zfcp_def.h +0 -2
@@ -110,10 +110,8 @@#define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010#define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040#define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED 0x00000080 -#define ZFCP_STATUS_FSFREQ_ABORTED 0x00000100#define ZFCP_STATUS_FSFREQ_TMFUNCFAILED 0x00000200#define ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP 0x00000400 -#define ZFCP_STATUS_FSFREQ_RETRY 0x00000800#define ZFCP_STATUS_FSFREQ_DISMISSED 0x00001000/************************* STRUCTURE DEFINITIONS *****************************/
drivers/s390/scsi/zfcp_fsf.c +11 -27
@@ -315,7 +315,6 @@ static void zfcp_fsf_fsfstatus_qual_evalcase FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED :return ;case FSF_SQ_COMMAND_ABORTED : - req->status |=ZFCP_STATUS_FSFREQ_ABORTED ;break ;case FSF_SQ_NO_RECOM : dev_err(&req->adapter->ccw_device->dev,
@@ -356,8 +355,7 @@ static void zfcp_fsf_protstatus_eval(strzfcp_dbf_hba_fsf_response (req);if (req->status &ZFCP_STATUS_FSFREQ_DISMISSED ) { - req->status |=ZFCP_STATUS_FSFREQ_ERROR | -ZFCP_STATUS_FSFREQ_RETRY ;/* only for SCSI cmnds. */ + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;return ; }
@@ -375,7 +373,7 @@ static void zfcp_fsf_protstatus_eval(strcase FSF_PROT_ERROR_STATE :case FSF_PROT_SEQ_NUMB_ERROR :zfcp_erp_adapter_reopen (adapter,0 ,"fspse_2" , req); - req->status |=ZFCP_STATUS_FSFREQ_RETRY ; + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ;case FSF_PROT_UNSUPP_QTCB_TYPE : dev_err(&adapter->ccw_device->dev,
@@ -884,13 +882,11 @@ static void zfcp_fsf_abort_fcp_command_hbreak ;case FSF_PORT_BOXED :zfcp_erp_port_boxed (unit->port,"fsafch3" , req); - req->status |=ZFCP_STATUS_FSFREQ_ERROR | -ZFCP_STATUS_FSFREQ_RETRY ; + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ;case FSF_LUN_BOXED :zfcp_erp_unit_boxed (unit,"fsafch4" , req); - req->status |=ZFCP_STATUS_FSFREQ_ERROR | -ZFCP_STATUS_FSFREQ_RETRY ; + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ;case FSF_ADAPTER_STATUS_AVAILABLE :switch (fsq->word[0 ]) {
@@ -988,8 +984,7 @@ static void zfcp_fsf_send_ct_handler(strcase FSF_ACCESS_DENIED :break ;case FSF_PORT_BOXED : - req->status |=ZFCP_STATUS_FSFREQ_ERROR | -ZFCP_STATUS_FSFREQ_RETRY ; + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ;case FSF_PORT_HANDLE_NOT_VALID :zfcp_erp_adapter_reopen (adapter,0 ,"fsscth1" , req);
@@ -1761,9 +1756,7 @@ static void zfcp_fsf_close_physical_port &unit->status);read_unlock (&port->unit_list_lock);zfcp_erp_port_boxed (port,"fscpph2" , req); - req->status |=ZFCP_STATUS_FSFREQ_ERROR | -ZFCP_STATUS_FSFREQ_RETRY ; - + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ;case FSF_ADAPTER_STATUS_AVAILABLE :switch (header->fsf_status_qual.word[0 ]) {
@@ -1867,8 +1860,7 @@ static void zfcp_fsf_open_unit_handler(sbreak ;case FSF_PORT_BOXED :zfcp_erp_port_boxed (unit->port,"fsouh_2" , req); - req->status |=ZFCP_STATUS_FSFREQ_ERROR | -ZFCP_STATUS_FSFREQ_RETRY ; + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ;case FSF_LUN_SHARING_VIOLATION :if (header->fsf_status_qual.word[0 ])
@@ -2030,8 +2022,7 @@ static void zfcp_fsf_close_unit_handler(break ;case FSF_PORT_BOXED :zfcp_erp_port_boxed (unit->port,"fscuh_3" , req); - req->status |=ZFCP_STATUS_FSFREQ_ERROR | -ZFCP_STATUS_FSFREQ_RETRY ; + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ;case FSF_ADAPTER_STATUS_AVAILABLE :switch (req->qtcb->header.fsf_status_qual.word[0 ]) {
@@ -2164,13 +2155,8 @@ static void zfcp_fsf_send_fcp_command_tareturn ; } -if (unlikely (req->status &ZFCP_STATUS_FSFREQ_ABORTED )) { -set_host_byte (scpnt,DID_SOFT_ERROR ); - goto skip_fsfstatus; - } -if (unlikely (req->status &ZFCP_STATUS_FSFREQ_ERROR )) { -set_host_byte (scpnt,DID_ERROR ); +set_host_byte (scpnt,DID_TRANSPORT_DISRUPTED ); goto skip_fsfstatus; }
@@ -2266,13 +2252,11 @@ static void zfcp_fsf_send_fcp_command_habreak ;case FSF_PORT_BOXED :zfcp_erp_port_boxed (unit->port,"fssfch5" , req); - req->status |=ZFCP_STATUS_FSFREQ_ERROR | -ZFCP_STATUS_FSFREQ_RETRY ; + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ;case FSF_LUN_BOXED :zfcp_erp_unit_boxed (unit,"fssfch6" , req); - req->status |=ZFCP_STATUS_FSFREQ_ERROR | -ZFCP_STATUS_FSFREQ_RETRY ; + req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ;case FSF_ADAPTER_STATUS_AVAILABLE : if (header->fsf_status_qual.word[0] ==
PATCH 20/22 zfcp: Block scsi_eh thread for rport state BLOCKED
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
In case the SCSI error recovery starts because of a SCSI command timeout, but then something else triggers the rport to be deleted, the SCSI error recovery will run to the end and set the SCSI device offline. To prevent this, call the FC transport function fc_block_scsi_eh which waits until the rport leaves the BLOCKED state. This guarantees that communication is possible if the rport is ONLINE, or the SCSI devices will be removed if the rport state switches to NOT_PRESENT.
---
drivers/s390/scsi/zfcp_scsi.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/s390/scsi/zfcp_scsi.c +3 -0
@@ -209,6 +209,7 @@ static int zfcp_scsi_eh_abort_handler(stbreak ;zfcp_erp_wait (adapter); +fc_block_scsi_eh (scpnt);if (!(atomic_read (&adapter->status) &ZFCP_STATUS_COMMON_RUNNING )) { zfcp_dbf_scsi_abort("nres", adapter->dbf, scpnt, NULL,
@@ -248,6 +249,7 @@ static int zfcp_task_mgmt_function(strucbreak ;zfcp_erp_wait (adapter); +fc_block_scsi_eh (scpnt);if (!(atomic_read (&adapter->status) &ZFCP_STATUS_COMMON_RUNNING )) {zfcp_dbf_scsi_devreset ("nres" , tm_flags, unit, scpnt);
@@ -289,6 +291,7 @@ static int zfcp_scsi_eh_host_reset_handlzfcp_erp_adapter_reopen (adapter,0 ,"schrh_1" , scpnt);zfcp_erp_wait (adapter); +fc_block_scsi_eh (scpnt);return SUCCESS ; }
PATCH 21/22 zfcp: Activate fc4s attributes for zfcp in FC transport class
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Enable the display of supported and active fc4s for zfcp in the FC transport class. zfcp only supports FCP, so simply hard-code this information. The zfcp hbaapi already has this information hardcoded, but this would allow to switch from the coding in the zfcp hbaapi to the common FC transport attributes in the future.
---
drivers/s390/scsi/zfcp_fsf.c | 2 ++ drivers/s390/scsi/zfcp_scsi.c | 2 ++ 2 files changed, 4 insertions(+)
drivers/s390/scsi/zfcp_fsf.c +2 -0
@@ -495,6 +495,8 @@ static int zfcp_fsf_exchange_config_evalfc_host_port_id (shost) =ntoh24 (bottom->s_id);fc_host_speed (shost) = bottom->fc_link_speed;fc_host_supported_classes (shost) =FC_COS_CLASS2 |FC_COS_CLASS3 ; +fc_host_supported_fc4s (shost)[2 ] =1 ;/* FCP */ +fc_host_active_fc4s (shost)[2 ] =1 ;/* FCP */ adapter->hydra_version = bottom->adapter_type; adapter->timer_ticks = bottom->timer_interval;
drivers/s390/scsi/zfcp_scsi.c +2 -0
@@ -643,6 +643,7 @@ struct fc_function_template zfcp_transpo .show_host_port_name = 1, .show_host_permanent_port_name = 1, .show_host_supported_classes = 1, + .show_host_supported_fc4s = 1, .show_host_supported_speeds = 1, .show_host_maxframe_size = 1, .show_host_serial_number = 1,
@@ -652,6 +653,7 @@ struct fc_function_template zfcp_transpo .get_host_port_state = zfcp_get_host_port_state, .terminate_rport_io = zfcp_scsi_terminate_rport_io, .show_host_port_state = 1, + .show_host_active_fc4s = 1, .bsg_request = zfcp_fc_exec_bsg_job,/* no functions registered for following dynamic attributes but directly set by LLDD */
PATCH 22/22 zfcp: Remove flag ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The flag ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP is never set and hence can be removed. This is a leftover from the time when zfcp had to decide whether the target supports a "logical unit reset" or not. Nowadays, the SCSI midlayer calls the eh_device_reset_handler or the eh_target_reset_handler and zfcp simply maps this to a "logical unit reset" or a "target reset".
---
drivers/s390/scsi/zfcp_def.h | 1 - drivers/s390/scsi/zfcp_scsi.c | 3 --- 2 files changed, 4 deletions(-)
drivers/s390/scsi/zfcp_def.h +0 -1
@@ -111,7 +111,6 @@#define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040#define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED 0x00000080#define ZFCP_STATUS_FSFREQ_TMFUNCFAILED 0x00000200 -#define ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP 0x00000400#define ZFCP_STATUS_FSFREQ_DISMISSED 0x00001000/************************* STRUCTURE DEFINITIONS *****************************/
drivers/s390/scsi/zfcp_scsi.c +0 -3
@@ -264,9 +264,6 @@ static int zfcp_task_mgmt_function(strucif (fsf_req->status &ZFCP_STATUS_FSFREQ_TMFUNCFAILED ) {zfcp_dbf_scsi_devreset ("fail" , tm_flags, unit, scpnt); retval =FAILED ; - }else if (fsf_req->status &ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP ) { -zfcp_dbf_scsi_devreset ("nsup" , tm_flags, unit, scpnt); - retval =FAILED ; }else zfcp_dbf_scsi_devreset ("okay" , tm_flags, unit, scpnt);