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 | } | ||
