diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 33 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 40 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_cfdc.c | 17 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 2 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 22 |
5 files changed, 69 insertions, 45 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 1be6bf7e8ce6..0f79f3af4f54 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -80,28 +80,35 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) | |||
80 | 80 | ||
81 | static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) | 81 | static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) |
82 | { | 82 | { |
83 | struct ccw_device *ccwdev; | ||
83 | struct zfcp_adapter *adapter; | 84 | struct zfcp_adapter *adapter; |
84 | struct zfcp_port *port; | 85 | struct zfcp_port *port; |
85 | struct zfcp_unit *unit; | 86 | struct zfcp_unit *unit; |
86 | 87 | ||
87 | mutex_lock(&zfcp_data.config_mutex); | 88 | ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); |
88 | read_lock_irq(&zfcp_data.config_lock); | 89 | if (!ccwdev) |
89 | adapter = zfcp_get_adapter_by_busid(busid); | 90 | return; |
90 | if (adapter) | 91 | |
91 | zfcp_adapter_get(adapter); | 92 | if (ccw_device_set_online(ccwdev)) |
92 | read_unlock_irq(&zfcp_data.config_lock); | 93 | goto out_ccwdev; |
93 | 94 | ||
95 | mutex_lock(&zfcp_data.config_mutex); | ||
96 | adapter = dev_get_drvdata(&ccwdev->dev); | ||
94 | if (!adapter) | 97 | if (!adapter) |
95 | goto out_adapter; | 98 | goto out_unlock; |
96 | port = zfcp_port_enqueue(adapter, wwpn, 0, 0); | 99 | zfcp_adapter_get(adapter); |
97 | if (IS_ERR(port)) | 100 | |
101 | port = zfcp_get_port_by_wwpn(adapter, wwpn); | ||
102 | if (!port) | ||
98 | goto out_port; | 103 | goto out_port; |
104 | |||
105 | zfcp_port_get(port); | ||
99 | unit = zfcp_unit_enqueue(port, lun); | 106 | unit = zfcp_unit_enqueue(port, lun); |
100 | if (IS_ERR(unit)) | 107 | if (IS_ERR(unit)) |
101 | goto out_unit; | 108 | goto out_unit; |
102 | mutex_unlock(&zfcp_data.config_mutex); | 109 | mutex_unlock(&zfcp_data.config_mutex); |
103 | ccw_device_set_online(adapter->ccw_device); | ||
104 | 110 | ||
111 | zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL); | ||
105 | zfcp_erp_wait(adapter); | 112 | zfcp_erp_wait(adapter); |
106 | flush_work(&unit->scsi_work); | 113 | flush_work(&unit->scsi_work); |
107 | 114 | ||
@@ -111,8 +118,10 @@ out_unit: | |||
111 | zfcp_port_put(port); | 118 | zfcp_port_put(port); |
112 | out_port: | 119 | out_port: |
113 | zfcp_adapter_put(adapter); | 120 | zfcp_adapter_put(adapter); |
114 | out_adapter: | 121 | out_unlock: |
115 | mutex_unlock(&zfcp_data.config_mutex); | 122 | mutex_unlock(&zfcp_data.config_mutex); |
123 | out_ccwdev: | ||
124 | put_device(&ccwdev->dev); | ||
116 | return; | 125 | return; |
117 | } | 126 | } |
118 | 127 | ||
@@ -593,10 +602,8 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) | |||
593 | int retval = 0; | 602 | int retval = 0; |
594 | unsigned long flags; | 603 | unsigned long flags; |
595 | 604 | ||
596 | cancel_work_sync(&adapter->scan_work); | ||
597 | cancel_work_sync(&adapter->stat_work); | 605 | cancel_work_sync(&adapter->stat_work); |
598 | zfcp_fc_wka_ports_force_offline(adapter->gs); | 606 | zfcp_fc_wka_ports_force_offline(adapter->gs); |
599 | zfcp_adapter_scsi_unregister(adapter); | ||
600 | sysfs_remove_group(&adapter->ccw_device->dev.kobj, | 607 | sysfs_remove_group(&adapter->ccw_device->dev.kobj, |
601 | &zfcp_sysfs_adapter_attrs); | 608 | &zfcp_sysfs_adapter_attrs); |
602 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); | 609 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); |
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 0c90f8e71605..e08339428ecf 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
@@ -102,6 +102,14 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
102 | adapter = dev_get_drvdata(&ccw_device->dev); | 102 | adapter = dev_get_drvdata(&ccw_device->dev); |
103 | if (!adapter) | 103 | if (!adapter) |
104 | goto out; | 104 | goto out; |
105 | mutex_unlock(&zfcp_data.config_mutex); | ||
106 | |||
107 | cancel_work_sync(&adapter->scan_work); | ||
108 | |||
109 | mutex_lock(&zfcp_data.config_mutex); | ||
110 | |||
111 | /* this also removes the scsi devices, so call it first */ | ||
112 | zfcp_adapter_scsi_unregister(adapter); | ||
105 | 113 | ||
106 | write_lock_irq(&zfcp_data.config_lock); | 114 | write_lock_irq(&zfcp_data.config_lock); |
107 | list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { | 115 | list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { |
@@ -117,11 +125,8 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
117 | write_unlock_irq(&zfcp_data.config_lock); | 125 | write_unlock_irq(&zfcp_data.config_lock); |
118 | 126 | ||
119 | list_for_each_entry_safe(port, p, &port_remove_lh, list) { | 127 | list_for_each_entry_safe(port, p, &port_remove_lh, list) { |
120 | list_for_each_entry_safe(unit, u, &unit_remove_lh, list) { | 128 | list_for_each_entry_safe(unit, u, &unit_remove_lh, list) |
121 | if (unit->device) | ||
122 | scsi_remove_device(unit->device); | ||
123 | zfcp_unit_dequeue(unit); | 129 | zfcp_unit_dequeue(unit); |
124 | } | ||
125 | zfcp_port_dequeue(port); | 130 | zfcp_port_dequeue(port); |
126 | } | 131 | } |
127 | wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); | 132 | wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); |
@@ -192,13 +197,9 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) | |||
192 | 197 | ||
193 | mutex_lock(&zfcp_data.config_mutex); | 198 | mutex_lock(&zfcp_data.config_mutex); |
194 | adapter = dev_get_drvdata(&ccw_device->dev); | 199 | adapter = dev_get_drvdata(&ccw_device->dev); |
195 | if (!adapter) | ||
196 | goto out; | ||
197 | |||
198 | zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL); | 200 | zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL); |
199 | zfcp_erp_wait(adapter); | 201 | zfcp_erp_wait(adapter); |
200 | mutex_unlock(&zfcp_data.config_mutex); | 202 | mutex_unlock(&zfcp_data.config_mutex); |
201 | out: | ||
202 | return 0; | 203 | return 0; |
203 | } | 204 | } |
204 | 205 | ||
@@ -253,13 +254,17 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev) | |||
253 | 254 | ||
254 | mutex_lock(&zfcp_data.config_mutex); | 255 | mutex_lock(&zfcp_data.config_mutex); |
255 | adapter = dev_get_drvdata(&cdev->dev); | 256 | adapter = dev_get_drvdata(&cdev->dev); |
257 | if (!adapter) | ||
258 | goto out; | ||
259 | |||
256 | zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL); | 260 | zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL); |
257 | zfcp_erp_wait(adapter); | 261 | zfcp_erp_wait(adapter); |
258 | zfcp_erp_thread_kill(adapter); | 262 | zfcp_erp_thread_kill(adapter); |
263 | out: | ||
259 | mutex_unlock(&zfcp_data.config_mutex); | 264 | mutex_unlock(&zfcp_data.config_mutex); |
260 | } | 265 | } |
261 | 266 | ||
262 | static struct ccw_driver zfcp_ccw_driver = { | 267 | struct ccw_driver zfcp_ccw_driver = { |
263 | .owner = THIS_MODULE, | 268 | .owner = THIS_MODULE, |
264 | .name = "zfcp", | 269 | .name = "zfcp", |
265 | .ids = zfcp_ccw_device_id, | 270 | .ids = zfcp_ccw_device_id, |
@@ -284,20 +289,3 @@ int __init zfcp_ccw_register(void) | |||
284 | { | 289 | { |
285 | return ccw_driver_register(&zfcp_ccw_driver); | 290 | return ccw_driver_register(&zfcp_ccw_driver); |
286 | } | 291 | } |
287 | |||
288 | /** | ||
289 | * zfcp_get_adapter_by_busid - find zfcp_adapter struct | ||
290 | * @busid: bus id string of zfcp adapter to find | ||
291 | */ | ||
292 | struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid) | ||
293 | { | ||
294 | struct ccw_device *ccw_device; | ||
295 | struct zfcp_adapter *adapter = NULL; | ||
296 | |||
297 | ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); | ||
298 | if (ccw_device) { | ||
299 | adapter = dev_get_drvdata(&ccw_device->dev); | ||
300 | put_device(&ccw_device->dev); | ||
301 | } | ||
302 | return adapter; | ||
303 | } | ||
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index 8305c874e86f..ef681dfed0cc 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c | |||
@@ -86,8 +86,23 @@ static int zfcp_cfdc_copy_to_user(void __user *user_buffer, | |||
86 | static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno) | 86 | static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno) |
87 | { | 87 | { |
88 | char busid[9]; | 88 | char busid[9]; |
89 | struct ccw_device *ccwdev; | ||
90 | struct zfcp_adapter *adapter = NULL; | ||
91 | |||
89 | snprintf(busid, sizeof(busid), "0.0.%04x", devno); | 92 | snprintf(busid, sizeof(busid), "0.0.%04x", devno); |
90 | return zfcp_get_adapter_by_busid(busid); | 93 | ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); |
94 | if (!ccwdev) | ||
95 | goto out; | ||
96 | |||
97 | adapter = dev_get_drvdata(&ccwdev->dev); | ||
98 | if (!adapter) | ||
99 | goto out_put; | ||
100 | |||
101 | zfcp_adapter_get(adapter); | ||
102 | out_put: | ||
103 | put_device(&ccwdev->dev); | ||
104 | out: | ||
105 | return adapter; | ||
91 | } | 106 | } |
92 | 107 | ||
93 | static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command) | 108 | static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command) |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 36935bc0818f..629edec70405 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -28,7 +28,7 @@ extern int zfcp_sg_setup_table(struct scatterlist *, int); | |||
28 | /* zfcp_ccw.c */ | 28 | /* zfcp_ccw.c */ |
29 | extern int zfcp_ccw_register(void); | 29 | extern int zfcp_ccw_register(void); |
30 | extern int zfcp_ccw_priv_sch(struct zfcp_adapter *); | 30 | extern int zfcp_ccw_priv_sch(struct zfcp_adapter *); |
31 | extern struct zfcp_adapter *zfcp_get_adapter_by_busid(char *); | 31 | extern struct ccw_driver zfcp_ccw_driver; |
32 | 32 | ||
33 | /* zfcp_cfdc.c */ | 33 | /* zfcp_cfdc.c */ |
34 | extern struct miscdevice zfcp_cfdc_misc; | 34 | extern struct miscdevice zfcp_cfdc_misc; |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index f09c863dc6bd..38a7e4a6b639 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -1058,11 +1058,25 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, | |||
1058 | bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req, | 1058 | bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req, |
1059 | SBAL_FLAGS0_TYPE_WRITE_READ, | 1059 | SBAL_FLAGS0_TYPE_WRITE_READ, |
1060 | sg_resp, max_sbals); | 1060 | sg_resp, max_sbals); |
1061 | req->qtcb->bottom.support.resp_buf_length = bytes; | ||
1061 | if (bytes <= 0) | 1062 | if (bytes <= 0) |
1062 | return -EIO; | 1063 | return -EIO; |
1063 | 1064 | ||
1065 | return 0; | ||
1066 | } | ||
1067 | |||
1068 | static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, | ||
1069 | struct scatterlist *sg_req, | ||
1070 | struct scatterlist *sg_resp, | ||
1071 | int max_sbals) | ||
1072 | { | ||
1073 | int ret; | ||
1074 | |||
1075 | ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); | ||
1076 | if (ret) | ||
1077 | return ret; | ||
1078 | |||
1064 | /* common settings for ct/gs and els requests */ | 1079 | /* common settings for ct/gs and els requests */ |
1065 | req->qtcb->bottom.support.resp_buf_length = bytes; | ||
1066 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; | 1080 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; |
1067 | req->qtcb->bottom.support.timeout = 2 * R_A_TOV; | 1081 | req->qtcb->bottom.support.timeout = 2 * R_A_TOV; |
1068 | zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10); | 1082 | zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10); |
@@ -1094,8 +1108,8 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool) | |||
1094 | } | 1108 | } |
1095 | 1109 | ||
1096 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 1110 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
1097 | ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp, | 1111 | ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, |
1098 | FSF_MAX_SBALS_PER_REQ); | 1112 | FSF_MAX_SBALS_PER_REQ); |
1099 | if (ret) | 1113 | if (ret) |
1100 | goto failed_send; | 1114 | goto failed_send; |
1101 | 1115 | ||
@@ -1192,7 +1206,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1192 | } | 1206 | } |
1193 | 1207 | ||
1194 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 1208 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
1195 | ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2); | 1209 | ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2); |
1196 | 1210 | ||
1197 | if (ret) | 1211 | if (ret) |
1198 | goto failed_send; | 1212 | goto failed_send; |