diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_sysfs.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 70 |
1 files changed, 22 insertions, 48 deletions
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 901cc9a6ed20..35e920b4fd8a 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c | |||
@@ -104,10 +104,8 @@ static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev, \ | |||
104 | unsigned long val; \ | 104 | unsigned long val; \ |
105 | int retval = 0; \ | 105 | int retval = 0; \ |
106 | \ | 106 | \ |
107 | if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_REMOVE) { \ | 107 | if (!(_feat && get_device(&_feat->sysfs_device))) \ |
108 | retval = -EBUSY; \ | 108 | return -EBUSY; \ |
109 | goto out; \ | ||
110 | } \ | ||
111 | \ | 109 | \ |
112 | if (strict_strtoul(buf, 0, &val) || val != 0) { \ | 110 | if (strict_strtoul(buf, 0, &val) || val != 0) { \ |
113 | retval = -EINVAL; \ | 111 | retval = -EINVAL; \ |
@@ -120,6 +118,7 @@ static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev, \ | |||
120 | _reopen_id, NULL); \ | 118 | _reopen_id, NULL); \ |
121 | zfcp_erp_wait(_adapter); \ | 119 | zfcp_erp_wait(_adapter); \ |
122 | out: \ | 120 | out: \ |
121 | put_device(&_feat->sysfs_device); \ | ||
123 | return retval ? retval : (ssize_t) count; \ | 122 | return retval ? retval : (ssize_t) count; \ |
124 | } \ | 123 | } \ |
125 | static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \ | 124 | static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \ |
@@ -161,11 +160,6 @@ static ssize_t zfcp_sysfs_adapter_failed_store(struct device *dev, | |||
161 | if (!adapter) | 160 | if (!adapter) |
162 | return -ENODEV; | 161 | return -ENODEV; |
163 | 162 | ||
164 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) { | ||
165 | retval = -EBUSY; | ||
166 | goto out; | ||
167 | } | ||
168 | |||
169 | if (strict_strtoul(buf, 0, &val) || val != 0) { | 163 | if (strict_strtoul(buf, 0, &val) || val != 0) { |
170 | retval = -EINVAL; | 164 | retval = -EINVAL; |
171 | goto out; | 165 | goto out; |
@@ -195,14 +189,9 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev, | |||
195 | if (!adapter) | 189 | if (!adapter) |
196 | return -ENODEV; | 190 | return -ENODEV; |
197 | 191 | ||
198 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) { | ||
199 | ret = -EBUSY; | ||
200 | goto out; | ||
201 | } | ||
202 | |||
203 | ret = zfcp_fc_scan_ports(adapter); | 192 | ret = zfcp_fc_scan_ports(adapter); |
204 | out: | ||
205 | zfcp_ccw_adapter_put(adapter); | 193 | zfcp_ccw_adapter_put(adapter); |
194 | |||
206 | return ret ? ret : (ssize_t) count; | 195 | return ret ? ret : (ssize_t) count; |
207 | } | 196 | } |
208 | static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL, | 197 | static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL, |
@@ -216,28 +205,19 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, | |||
216 | struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); | 205 | struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); |
217 | struct zfcp_port *port; | 206 | struct zfcp_port *port; |
218 | u64 wwpn; | 207 | u64 wwpn; |
219 | int retval = 0; | 208 | int retval = -EINVAL; |
220 | 209 | ||
221 | if (!adapter) | 210 | if (!adapter) |
222 | return -ENODEV; | 211 | return -ENODEV; |
223 | 212 | ||
224 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) { | 213 | if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) |
225 | retval = -EBUSY; | ||
226 | goto out; | 214 | goto out; |
227 | } | ||
228 | |||
229 | if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) { | ||
230 | retval = -EINVAL; | ||
231 | goto out; | ||
232 | } | ||
233 | 215 | ||
234 | port = zfcp_get_port_by_wwpn(adapter, wwpn); | 216 | port = zfcp_get_port_by_wwpn(adapter, wwpn); |
235 | if (!port) { | 217 | if (!port) |
236 | retval = -ENXIO; | ||
237 | goto out; | 218 | goto out; |
238 | } | 219 | else |
239 | 220 | retval = 0; | |
240 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); | ||
241 | 221 | ||
242 | write_lock_irq(&adapter->port_list_lock); | 222 | write_lock_irq(&adapter->port_list_lock); |
243 | list_del(&port->list); | 223 | list_del(&port->list); |
@@ -283,10 +263,8 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, | |||
283 | u64 fcp_lun; | 263 | u64 fcp_lun; |
284 | int retval = -EINVAL; | 264 | int retval = -EINVAL; |
285 | 265 | ||
286 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { | 266 | if (!(port && get_device(&port->sysfs_device))) |
287 | retval = -EBUSY; | 267 | return -EBUSY; |
288 | goto out; | ||
289 | } | ||
290 | 268 | ||
291 | if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) | 269 | if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) |
292 | goto out; | 270 | goto out; |
@@ -294,13 +272,14 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, | |||
294 | unit = zfcp_unit_enqueue(port, fcp_lun); | 272 | unit = zfcp_unit_enqueue(port, fcp_lun); |
295 | if (IS_ERR(unit)) | 273 | if (IS_ERR(unit)) |
296 | goto out; | 274 | goto out; |
297 | 275 | else | |
298 | retval = 0; | 276 | retval = 0; |
299 | 277 | ||
300 | zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); | 278 | zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL); |
301 | zfcp_erp_wait(unit->port->adapter); | 279 | zfcp_erp_wait(unit->port->adapter); |
302 | flush_work(&unit->scsi_work); | 280 | flush_work(&unit->scsi_work); |
303 | out: | 281 | out: |
282 | put_device(&port->sysfs_device); | ||
304 | return retval ? retval : (ssize_t) count; | 283 | return retval ? retval : (ssize_t) count; |
305 | } | 284 | } |
306 | static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store); | 285 | static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store); |
@@ -313,29 +292,23 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, | |||
313 | sysfs_device); | 292 | sysfs_device); |
314 | struct zfcp_unit *unit; | 293 | struct zfcp_unit *unit; |
315 | u64 fcp_lun; | 294 | u64 fcp_lun; |
316 | int retval = 0; | 295 | int retval = -EINVAL; |
317 | 296 | ||
318 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { | 297 | if (!(port && get_device(&port->sysfs_device))) |
319 | retval = -EBUSY; | 298 | return -EBUSY; |
320 | goto out; | ||
321 | } | ||
322 | 299 | ||
323 | if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) { | 300 | if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) |
324 | retval = -EINVAL; | ||
325 | goto out; | 301 | goto out; |
326 | } | ||
327 | 302 | ||
328 | unit = zfcp_get_unit_by_lun(port, fcp_lun); | 303 | unit = zfcp_get_unit_by_lun(port, fcp_lun); |
329 | if (!unit) { | 304 | if (!unit) |
330 | retval = -EINVAL; | ||
331 | goto out; | 305 | goto out; |
332 | } | 306 | else |
307 | retval = 0; | ||
333 | 308 | ||
334 | /* wait for possible timeout during SCSI probe */ | 309 | /* wait for possible timeout during SCSI probe */ |
335 | flush_work(&unit->scsi_work); | 310 | flush_work(&unit->scsi_work); |
336 | 311 | ||
337 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); | ||
338 | |||
339 | write_lock_irq(&port->unit_list_lock); | 312 | write_lock_irq(&port->unit_list_lock); |
340 | list_del(&unit->list); | 313 | list_del(&unit->list); |
341 | write_unlock_irq(&port->unit_list_lock); | 314 | write_unlock_irq(&port->unit_list_lock); |
@@ -345,6 +318,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, | |||
345 | zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); | 318 | zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL); |
346 | zfcp_device_unregister(&unit->sysfs_device, &zfcp_sysfs_unit_attrs); | 319 | zfcp_device_unregister(&unit->sysfs_device, &zfcp_sysfs_unit_attrs); |
347 | out: | 320 | out: |
321 | put_device(&port->sysfs_device); | ||
348 | return retval ? retval : (ssize_t) count; | 322 | return retval ? retval : (ssize_t) count; |
349 | } | 323 | } |
350 | static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); | 324 | static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); |