summaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_sysfs.c')
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c70
1 files changed, 22 insertions, 48 deletions
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 901cc9a6ed2..35e920b4fd8 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, \
unsigned long val; \
int retval = 0; \
\
- if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_REMOVE) { \
- retval = -EBUSY; \
- goto out; \
- } \
+ if (!(_feat && get_device(&_feat->sysfs_device))) \
+ return -EBUSY; \
\
if (strict_strtoul(buf, 0, &val) || val != 0) { \
retval = -EINVAL; \
@@ -120,6 +118,7 @@ static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev, \
_reopen_id, NULL); \
zfcp_erp_wait(_adapter); \
out: \
+ put_device(&_feat->sysfs_device); \
return retval ? retval : (ssize_t) count; \
} \
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,
if (!adapter)
return -ENODEV;
- if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
- retval = -EBUSY;
- goto out;
- }
-
if (strict_strtoul(buf, 0, &val) || val != 0) {
retval = -EINVAL;
goto out;
@@ -195,14 +189,9 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
if (!adapter)
return -ENODEV;
- if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
- ret = -EBUSY;
- goto out;
- }
-
ret = zfcp_fc_scan_ports(adapter);
-out:
zfcp_ccw_adapter_put(adapter);
+
return ret ? ret : (ssize_t) count;
}
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,
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
struct zfcp_port *port;
u64 wwpn;
- int retval = 0;
+ int retval = -EINVAL;
if (!adapter)
return -ENODEV;
- if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
- retval = -EBUSY;
+ if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn))
goto out;
- }
-
- if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) {
- retval = -EINVAL;
- goto out;
- }
port = zfcp_get_port_by_wwpn(adapter, wwpn);
- if (!port) {
- retval = -ENXIO;
+ if (!port)
goto out;
- }
-
- atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
+ else
+ retval = 0;
write_lock_irq(&adapter->port_list_lock);
list_del(&port->list);
@@ -283,10 +263,8 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
u64 fcp_lun;
int retval = -EINVAL;
- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
- retval = -EBUSY;
- goto out;
- }
+ if (!(port && get_device(&port->sysfs_device)))
+ return -EBUSY;
if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
goto out;
@@ -294,13 +272,14 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
unit = zfcp_unit_enqueue(port, fcp_lun);
if (IS_ERR(unit))
goto out;
-
- retval = 0;
+ else
+ retval = 0;
zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
zfcp_erp_wait(unit->port->adapter);
flush_work(&unit->scsi_work);
out:
+ put_device(&port->sysfs_device);
return retval ? retval : (ssize_t) count;
}
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,
sysfs_device);
struct zfcp_unit *unit;
u64 fcp_lun;
- int retval = 0;
+ int retval = -EINVAL;
- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
- retval = -EBUSY;
- goto out;
- }
+ if (!(port && get_device(&port->sysfs_device)))
+ return -EBUSY;
- if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) {
- retval = -EINVAL;
+ if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
goto out;
- }
unit = zfcp_get_unit_by_lun(port, fcp_lun);
- if (!unit) {
- retval = -EINVAL;
+ if (!unit)
goto out;
- }
+ else
+ retval = 0;
/* wait for possible timeout during SCSI probe */
flush_work(&unit->scsi_work);
- atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
-
write_lock_irq(&port->unit_list_lock);
list_del(&unit->list);
write_unlock_irq(&port->unit_list_lock);
@@ -345,6 +318,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
zfcp_device_unregister(&unit->sysfs_device, &zfcp_sysfs_unit_attrs);
out:
+ put_device(&port->sysfs_device);
return retval ? retval : (ssize_t) count;
}
static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);