diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_ccw.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index e08339428ecf..aca2047dc2d5 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
@@ -100,10 +100,11 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
100 | 100 | ||
101 | mutex_lock(&zfcp_data.config_mutex); | 101 | mutex_lock(&zfcp_data.config_mutex); |
102 | adapter = dev_get_drvdata(&ccw_device->dev); | 102 | adapter = dev_get_drvdata(&ccw_device->dev); |
103 | if (!adapter) | ||
104 | goto out; | ||
105 | mutex_unlock(&zfcp_data.config_mutex); | 103 | mutex_unlock(&zfcp_data.config_mutex); |
106 | 104 | ||
105 | if (!adapter) | ||
106 | return; | ||
107 | |||
107 | cancel_work_sync(&adapter->scan_work); | 108 | cancel_work_sync(&adapter->scan_work); |
108 | 109 | ||
109 | mutex_lock(&zfcp_data.config_mutex); | 110 | mutex_lock(&zfcp_data.config_mutex); |
@@ -111,18 +112,21 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
111 | /* this also removes the scsi devices, so call it first */ | 112 | /* this also removes the scsi devices, so call it first */ |
112 | zfcp_adapter_scsi_unregister(adapter); | 113 | zfcp_adapter_scsi_unregister(adapter); |
113 | 114 | ||
114 | write_lock_irq(&zfcp_data.config_lock); | 115 | write_lock_irq(&adapter->port_list_lock); |
115 | list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { | 116 | list_for_each_entry_safe(port, p, &adapter->port_list, list) { |
116 | list_for_each_entry_safe(unit, u, &port->unit_list_head, list) { | 117 | write_lock(&port->unit_list_lock); |
117 | list_move(&unit->list, &unit_remove_lh); | 118 | list_for_each_entry_safe(unit, u, &port->unit_list, list) { |
118 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, | 119 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, |
119 | &unit->status); | 120 | &unit->status); |
121 | list_move(&unit->list, &unit_remove_lh); | ||
120 | } | 122 | } |
121 | list_move(&port->list, &port_remove_lh); | 123 | write_unlock(&port->unit_list_lock); |
122 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); | 124 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); |
125 | list_move(&port->list, &port_remove_lh); | ||
123 | } | 126 | } |
124 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); | 127 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); |
125 | write_unlock_irq(&zfcp_data.config_lock); | 128 | write_unlock_irq(&adapter->port_list_lock); |
129 | mutex_unlock(&zfcp_data.config_mutex); | ||
126 | 130 | ||
127 | list_for_each_entry_safe(port, p, &port_remove_lh, list) { | 131 | list_for_each_entry_safe(port, p, &port_remove_lh, list) { |
128 | list_for_each_entry_safe(unit, u, &unit_remove_lh, list) | 132 | list_for_each_entry_safe(unit, u, &unit_remove_lh, list) |
@@ -131,9 +135,6 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
131 | } | 135 | } |
132 | wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); | 136 | wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); |
133 | zfcp_adapter_dequeue(adapter); | 137 | zfcp_adapter_dequeue(adapter); |
134 | |||
135 | out: | ||
136 | mutex_unlock(&zfcp_data.config_mutex); | ||
137 | } | 138 | } |
138 | 139 | ||
139 | /** | 140 | /** |