[SCSI] zfcp: Automatically attach remote ports
Automatically attach the remote ports in zfcp when the adapter is set
online. This is done by querying all available ports from the FC
namesever. The scan for remote ports is also triggered by RSCNs and
can be triggered manually with the sysfs attribute 'port_rescan'.
Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 47739f4..2bd80fd 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -568,6 +568,19 @@
stat_work));
}
+static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter)
+{
+ struct zfcp_port *port;
+
+ port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA,
+ ZFCP_DID_DIRECTORY_SERVICE);
+ if (!port)
+ return -ENXIO;
+ zfcp_port_put(port);
+
+ return 0;
+}
+
/*
* Enqueues an adapter at the end of the adapter list in the driver data.
* All adapter internal structures are set up.
@@ -648,6 +661,7 @@
/* initialize lock of associated request queue */
rwlock_init(&adapter->req_q.lock);
INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
+ INIT_WORK(&adapter->scan_work, _zfcp_scan_ports_later);
/* mark adapter unusable as long as sysfs registration is not complete */
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
@@ -673,6 +687,8 @@
zfcp_data.adapters++;
+ zfcp_nameserver_enqueue(adapter);
+
goto out;
generic_services_failed:
@@ -704,6 +720,7 @@
int retval = 0;
unsigned long flags;
+ cancel_work_sync(&adapter->scan_work);
cancel_work_sync(&adapter->stat_work);
zfcp_adapter_scsi_unregister(adapter);
device_unregister(&adapter->generic_services);
@@ -816,13 +833,15 @@
kfree(port);
return NULL;
}
- port->d_id = d_id;
port->sysfs_device.parent = &adapter->generic_services;
} else {
snprintf(port->sysfs_device.bus_id,
BUS_ID_SIZE, "0x%016llx", wwpn);
port->sysfs_device.parent = &adapter->ccw_device->dev;
}
+
+ port->d_id = d_id;
+
port->sysfs_device.release = zfcp_sysfs_port_release;
dev_set_drvdata(&port->sysfs_device, port);
@@ -873,21 +892,6 @@
device_unregister(&port->sysfs_device);
}
-/* Enqueues a nameserver port */
-int
-zfcp_nameserver_enqueue(struct zfcp_adapter *adapter)
-{
- struct zfcp_port *port;
-
- port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA,
- ZFCP_DID_DIRECTORY_SERVICE);
- if (!port)
- return -ENXIO;
- zfcp_port_put(port);
-
- return 0;
-}
-
void zfcp_sg_free_table(struct scatterlist *sg, int count)
{
int i;