diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_ccw.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 40 |
1 files changed, 14 insertions, 26 deletions
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 | } | ||