diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
| -rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 9cf30d124b9e..01f927ae61b5 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -4,7 +4,7 @@ * * Module interface and handling of zfcp data structures. * - * Copyright IBM Corp. 2002, 2017 + * Copyright IBM Corp. 2002, 2020 */ /* @@ -25,10 +25,10 @@ * Martin Petermann * Sven Schuetz * Steffen Maier + * Benjamin Block */ -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "zfcp: " fmt #include <linux/seq_file.h> #include <linux/slab.h> @@ -36,10 +36,11 @@ #include "zfcp_ext.h" #include "zfcp_fc.h" #include "zfcp_reqlist.h" +#include "zfcp_diag.h" #define ZFCP_BUS_ID_SIZE 20 -MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com"); +MODULE_AUTHOR("IBM Corporation"); MODULE_DESCRIPTION("FCP HBA driver"); MODULE_LICENSE("GPL"); @@ -101,7 +102,7 @@ static void __init zfcp_init_device_setup(char *devstr) token = strsep(&str, ","); if (!token || strlen(token) >= ZFCP_BUS_ID_SIZE) goto err_out; - strlcpy(busid, token, ZFCP_BUS_ID_SIZE); + strscpy(busid, token, ZFCP_BUS_ID_SIZE); token = strsep(&str, ","); if (!token || kstrtoull(token, 0, (unsigned long long *) &wwpn)) @@ -290,6 +291,14 @@ static void _zfcp_status_read_scheduler(struct work_struct *work) stat_work)); } +static void zfcp_version_change_lost_work(struct work_struct *work) +{ + struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter, + version_change_lost_work); + + zfcp_fsf_exchange_config_data_sync(adapter->qdio, NULL); +} + static void zfcp_print_sl(struct seq_file *m, struct service_level *sl) { struct zfcp_adapter *adapter = @@ -302,15 +311,13 @@ static void zfcp_print_sl(struct seq_file *m, struct service_level *sl) static int zfcp_setup_adapter_work_queue(struct zfcp_adapter *adapter) { - char name[TASK_COMM_LEN]; - - snprintf(name, sizeof(name), "zfcp_q_%s", - dev_name(&adapter->ccw_device->dev)); - adapter->work_queue = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM); + adapter->work_queue = + alloc_ordered_workqueue("zfcp_q_%s", WQ_MEM_RECLAIM, + dev_name(&adapter->ccw_device->dev)); + if (!adapter->work_queue) + return -ENOMEM; - if (adapter->work_queue) - return 0; - return -ENOMEM; + return 0; } static void zfcp_destroy_adapter_work_queue(struct zfcp_adapter *adapter) @@ -351,11 +358,16 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); INIT_DELAYED_WORK(&adapter->scan_work, zfcp_fc_scan_ports); INIT_WORK(&adapter->ns_up_work, zfcp_fc_sym_name_update); + INIT_WORK(&adapter->version_change_lost_work, + zfcp_version_change_lost_work); adapter->next_port_scan = jiffies; adapter->erp_action.adapter = adapter; + if (zfcp_diag_adapter_setup(adapter)) + goto failed; + if (zfcp_qdio_setup(adapter)) goto failed; @@ -398,21 +410,33 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) dev_set_drvdata(&ccw_device->dev, adapter); - if (sysfs_create_group(&ccw_device->dev.kobj, - &zfcp_sysfs_adapter_attrs)) - goto failed; + if (device_add_groups(&ccw_device->dev, zfcp_sysfs_adapter_attr_groups)) + goto err_sysfs; /* report size limit per scatter-gather segment */ - adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN; adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM; - if (!zfcp_scsi_adapter_register(adapter)) - return adapter; + return adapter; +err_sysfs: failed: - zfcp_adapter_unregister(adapter); + /* TODO: make this more fine-granular */ + cancel_delayed_work_sync(&adapter->scan_work); + cancel_work_sync(&adapter->stat_work); + cancel_work_sync(&adapter->ns_up_work); + cancel_work_sync(&adapter->version_change_lost_work); + zfcp_destroy_adapter_work_queue(adapter); + + zfcp_fc_wka_ports_force_offline(adapter->gs); + zfcp_scsi_adapter_unregister(adapter); + + zfcp_erp_thread_kill(adapter); + zfcp_dbf_adapter_unregister(adapter); + zfcp_qdio_destroy(adapter->qdio); + + zfcp_ccw_adapter_put(adapter); /* final put to release */ return ERR_PTR(-ENOMEM); } @@ -423,11 +447,12 @@ void zfcp_adapter_unregister(struct zfcp_adapter *adapter) cancel_delayed_work_sync(&adapter->scan_work); cancel_work_sync(&adapter->stat_work); cancel_work_sync(&adapter->ns_up_work); + cancel_work_sync(&adapter->version_change_lost_work); zfcp_destroy_adapter_work_queue(adapter); zfcp_fc_wka_ports_force_offline(adapter->gs); zfcp_scsi_adapter_unregister(adapter); - sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs); + device_remove_groups(&cdev->dev, zfcp_sysfs_adapter_attr_groups); zfcp_erp_thread_kill(adapter); zfcp_dbf_adapter_unregister(adapter); @@ -450,6 +475,7 @@ void zfcp_adapter_release(struct kref *ref) dev_set_drvdata(&adapter->ccw_device->dev, NULL); zfcp_fc_gs_destroy(adapter); zfcp_free_low_mem_buffers(adapter); + zfcp_diag_adapter_free(adapter); kfree(adapter->req_list); kfree(adapter->fc_stats); kfree(adapter->stats_reset_data); @@ -489,12 +515,12 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, if (port) { put_device(&port->dev); retval = -EEXIST; - goto err_out; + goto err_put; } port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); if (!port) - goto err_out; + goto err_put; rwlock_init(&port->unit_list_lock); INIT_LIST_HEAD(&port->unit_list); @@ -517,7 +543,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { kfree(port); - goto err_out; + goto err_put; } retval = -EINVAL; @@ -534,7 +560,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, return port; -err_out: +err_put: zfcp_ccw_adapter_put(adapter); +err_out: return ERR_PTR(retval); } |
