diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2008-06-10 12:21:00 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-07-12 09:22:26 -0400 |
commit | cc8c282963bd258a5bf49d3aa52675a4ae6d31f6 (patch) | |
tree | d0f353c918158b203c71603d9afdf4b71c126f63 /drivers/s390/scsi/zfcp_aux.c | |
parent | 85a82392fe6fe7620d8fe0eb694f926cefe62e1f (diff) |
[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>
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 47739f4f6709..2bd80fdcceff 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -568,6 +568,19 @@ static void _zfcp_status_read_scheduler(struct work_struct *work) | |||
568 | stat_work)); | 568 | stat_work)); |
569 | } | 569 | } |
570 | 570 | ||
571 | static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) | ||
572 | { | ||
573 | struct zfcp_port *port; | ||
574 | |||
575 | port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA, | ||
576 | ZFCP_DID_DIRECTORY_SERVICE); | ||
577 | if (!port) | ||
578 | return -ENXIO; | ||
579 | zfcp_port_put(port); | ||
580 | |||
581 | return 0; | ||
582 | } | ||
583 | |||
571 | /* | 584 | /* |
572 | * Enqueues an adapter at the end of the adapter list in the driver data. | 585 | * Enqueues an adapter at the end of the adapter list in the driver data. |
573 | * All adapter internal structures are set up. | 586 | * All adapter internal structures are set up. |
@@ -648,6 +661,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
648 | /* initialize lock of associated request queue */ | 661 | /* initialize lock of associated request queue */ |
649 | rwlock_init(&adapter->req_q.lock); | 662 | rwlock_init(&adapter->req_q.lock); |
650 | INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); | 663 | INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); |
664 | INIT_WORK(&adapter->scan_work, _zfcp_scan_ports_later); | ||
651 | 665 | ||
652 | /* mark adapter unusable as long as sysfs registration is not complete */ | 666 | /* mark adapter unusable as long as sysfs registration is not complete */ |
653 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); | 667 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); |
@@ -673,6 +687,8 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
673 | 687 | ||
674 | zfcp_data.adapters++; | 688 | zfcp_data.adapters++; |
675 | 689 | ||
690 | zfcp_nameserver_enqueue(adapter); | ||
691 | |||
676 | goto out; | 692 | goto out; |
677 | 693 | ||
678 | generic_services_failed: | 694 | generic_services_failed: |
@@ -704,6 +720,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) | |||
704 | int retval = 0; | 720 | int retval = 0; |
705 | unsigned long flags; | 721 | unsigned long flags; |
706 | 722 | ||
723 | cancel_work_sync(&adapter->scan_work); | ||
707 | cancel_work_sync(&adapter->stat_work); | 724 | cancel_work_sync(&adapter->stat_work); |
708 | zfcp_adapter_scsi_unregister(adapter); | 725 | zfcp_adapter_scsi_unregister(adapter); |
709 | device_unregister(&adapter->generic_services); | 726 | device_unregister(&adapter->generic_services); |
@@ -816,13 +833,15 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, | |||
816 | kfree(port); | 833 | kfree(port); |
817 | return NULL; | 834 | return NULL; |
818 | } | 835 | } |
819 | port->d_id = d_id; | ||
820 | port->sysfs_device.parent = &adapter->generic_services; | 836 | port->sysfs_device.parent = &adapter->generic_services; |
821 | } else { | 837 | } else { |
822 | snprintf(port->sysfs_device.bus_id, | 838 | snprintf(port->sysfs_device.bus_id, |
823 | BUS_ID_SIZE, "0x%016llx", wwpn); | 839 | BUS_ID_SIZE, "0x%016llx", wwpn); |
824 | port->sysfs_device.parent = &adapter->ccw_device->dev; | 840 | port->sysfs_device.parent = &adapter->ccw_device->dev; |
825 | } | 841 | } |
842 | |||
843 | port->d_id = d_id; | ||
844 | |||
826 | port->sysfs_device.release = zfcp_sysfs_port_release; | 845 | port->sysfs_device.release = zfcp_sysfs_port_release; |
827 | dev_set_drvdata(&port->sysfs_device, port); | 846 | dev_set_drvdata(&port->sysfs_device, port); |
828 | 847 | ||
@@ -873,21 +892,6 @@ zfcp_port_dequeue(struct zfcp_port *port) | |||
873 | device_unregister(&port->sysfs_device); | 892 | device_unregister(&port->sysfs_device); |
874 | } | 893 | } |
875 | 894 | ||
876 | /* Enqueues a nameserver port */ | ||
877 | int | ||
878 | zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) | ||
879 | { | ||
880 | struct zfcp_port *port; | ||
881 | |||
882 | port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA, | ||
883 | ZFCP_DID_DIRECTORY_SERVICE); | ||
884 | if (!port) | ||
885 | return -ENXIO; | ||
886 | zfcp_port_put(port); | ||
887 | |||
888 | return 0; | ||
889 | } | ||
890 | |||
891 | void zfcp_sg_free_table(struct scatterlist *sg, int count) | 895 | void zfcp_sg_free_table(struct scatterlist *sg, int count) |
892 | { | 896 | { |
893 | int i; | 897 | int i; |