aboutsummaryrefslogtreecommitdiffstatshomepage
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.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 7ec30ded0169..8d9662e8b717 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -216,20 +216,32 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
{
struct ccw_device *cdev = to_ccwdev(dev);
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
+ int retval = 0;
if (!adapter)
return -ENODEV;
/*
+ * If `scsi_host` is missing, we can't schedule `scan_work`, as it
+ * makes use of the corresponding fc_host object. But this state is
+ * only possible if xconfig/xport data has never completed yet,
+ * and we couldn't successfully scan for ports anyway.
+ */
+ if (adapter->scsi_host == NULL) {
+ retval = -ENODEV;
+ goto out;
+ }
+
+ /*
* Users wish is our command: immediately schedule and flush a
* worker to conduct a synchronous port scan, that is, neither
* a random delay nor a rate limit is applied here.
*/
queue_delayed_work(adapter->work_queue, &adapter->scan_work, 0);
flush_delayed_work(&adapter->scan_work);
+out:
zfcp_ccw_adapter_put(adapter);
-
- return (ssize_t) count;
+ return retval ? retval : (ssize_t) count;
}
static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
zfcp_sysfs_port_rescan_store);