aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2008-06-10 12:21:00 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-12 09:22:26 -0400
commitcc8c282963bd258a5bf49d3aa52675a4ae6d31f6 (patch)
treed0f353c918158b203c71603d9afdf4b71c126f63
parent85a82392fe6fe7620d8fe0eb694f926cefe62e1f (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>
-rw-r--r--drivers/s390/scsi/zfcp_aux.c36
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c4
-rw-r--r--drivers/s390/scsi/zfcp_def.h5
-rw-r--r--drivers/s390/scsi/zfcp_erp.c42
-rw-r--r--drivers/s390/scsi/zfcp_ext.h4
-rw-r--r--drivers/s390/scsi/zfcp_fc.c248
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c3
-rw-r--r--drivers/s390/scsi/zfcp_sysfs_adapter.c25
8 files changed, 336 insertions, 31 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
571static 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 */
877int
878zfcp_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
891void zfcp_sg_free_table(struct scatterlist *sg, int count) 895void zfcp_sg_free_table(struct scatterlist *sg, int count)
892{ 896{
893 int i; 897 int i;
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 7c72f502eb0f..3e9f0abb22f9 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -596,6 +596,10 @@ static const char *zfcp_rec_dbf_ids[] = {
596 [145] = "recovery action being processed", 596 [145] = "recovery action being processed",
597 [146] = "recovery action ready for next step", 597 [146] = "recovery action ready for next step",
598 [147] = "qdio error inbound", 598 [147] = "qdio error inbound",
599 [148] = "nameserver needed for port scan",
600 [149] = "port scan",
601 [150] = "ptp attach",
602 [151] = "port validation failed",
599}; 603};
600 604
601static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view, 605static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view,
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 73425dbb2be8..1e837d46ea74 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -282,7 +282,10 @@ struct zfcp_rc_entry {
282#define ZFCP_CT_DIRECTORY_SERVICE 0xFC 282#define ZFCP_CT_DIRECTORY_SERVICE 0xFC
283#define ZFCP_CT_NAME_SERVER 0x02 283#define ZFCP_CT_NAME_SERVER 0x02
284#define ZFCP_CT_SYNCHRONOUS 0x00 284#define ZFCP_CT_SYNCHRONOUS 0x00
285#define ZFCP_CT_SCSI_FCP 0x08
286#define ZFCP_CT_UNABLE_TO_PERFORM_CMD 0x09
285#define ZFCP_CT_GID_PN 0x0121 287#define ZFCP_CT_GID_PN 0x0121
288#define ZFCP_CT_GPN_FT 0x0172
286#define ZFCP_CT_MAX_SIZE 0x1020 289#define ZFCP_CT_MAX_SIZE 0x1020
287#define ZFCP_CT_ACCEPT 0x8002 290#define ZFCP_CT_ACCEPT 0x8002
288#define ZFCP_CT_REJECT 0x8001 291#define ZFCP_CT_REJECT 0x8001
@@ -311,6 +314,7 @@ struct zfcp_rc_entry {
311#define ZFCP_STATUS_COMMON_ERP_INUSE 0x01000000 314#define ZFCP_STATUS_COMMON_ERP_INUSE 0x01000000
312#define ZFCP_STATUS_COMMON_ACCESS_DENIED 0x00800000 315#define ZFCP_STATUS_COMMON_ACCESS_DENIED 0x00800000
313#define ZFCP_STATUS_COMMON_ACCESS_BOXED 0x00400000 316#define ZFCP_STATUS_COMMON_ACCESS_BOXED 0x00400000
317#define ZFCP_STATUS_COMMON_NOESC 0x00200000
314 318
315/* adapter status */ 319/* adapter status */
316#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002 320#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002
@@ -629,6 +633,7 @@ struct zfcp_adapter {
629 struct fc_host_statistics *fc_stats; 633 struct fc_host_statistics *fc_stats;
630 struct fsf_qtcb_bottom_port *stats_reset_data; 634 struct fsf_qtcb_bottom_port *stats_reset_data;
631 unsigned long stats_reset; 635 unsigned long stats_reset;
636 struct work_struct scan_work;
632}; 637};
633 638
634/* 639/*
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index c06156b288ea..9b9c999cf39f 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -1199,6 +1199,10 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
1199 zfcp_erp_port_unblock(port); 1199 zfcp_erp_port_unblock(port);
1200 break; 1200 break;
1201 case ZFCP_ERP_FAILED : 1201 case ZFCP_ERP_FAILED :
1202 if (atomic_test_mask(ZFCP_STATUS_COMMON_NOESC, &port->status)) {
1203 zfcp_erp_port_block(port, 0);
1204 result = ZFCP_ERP_EXIT;
1205 }
1202 atomic_inc(&port->erp_counter); 1206 atomic_inc(&port->erp_counter);
1203 if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS) 1207 if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS)
1204 zfcp_erp_port_failed(port, 22, NULL); 1208 zfcp_erp_port_failed(port, 22, NULL);
@@ -1607,6 +1611,7 @@ zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close)
1607 goto failed_openfcp; 1611 goto failed_openfcp;
1608 1612
1609 atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &erp_action->adapter->status); 1613 atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &erp_action->adapter->status);
1614 schedule_work(&erp_action->adapter->scan_work);
1610 goto out; 1615 goto out;
1611 1616
1612 close_only: 1617 close_only:
@@ -1665,10 +1670,19 @@ zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
1665 return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); 1670 return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
1666} 1671}
1667 1672
1673static void zfcp_erp_open_ptp_port(struct zfcp_adapter *adapter)
1674{
1675 struct zfcp_port *port;
1676 port = zfcp_port_enqueue(adapter, adapter->peer_wwpn, 0,
1677 adapter->peer_d_id);
1678 if (!port) /* error or port already attached */
1679 return;
1680 zfcp_erp_port_reopen_internal(port, 0, 150, NULL);
1681}
1682
1668static int 1683static int
1669zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) 1684zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
1670{ 1685{
1671 int retval = ZFCP_ERP_SUCCEEDED;
1672 int retries; 1686 int retries;
1673 int sleep = ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP; 1687 int sleep = ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP;
1674 struct zfcp_adapter *adapter = erp_action->adapter; 1688 struct zfcp_adapter *adapter = erp_action->adapter;
@@ -1682,8 +1696,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
1682 zfcp_erp_action_to_running(erp_action); 1696 zfcp_erp_action_to_running(erp_action);
1683 write_unlock_irq(&adapter->erp_lock); 1697 write_unlock_irq(&adapter->erp_lock);
1684 if (zfcp_fsf_exchange_config_data(erp_action)) { 1698 if (zfcp_fsf_exchange_config_data(erp_action)) {
1685 retval = ZFCP_ERP_FAILED; 1699 atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
1686 break; 1700 &adapter->status);
1701 return ZFCP_ERP_FAILED;
1687 } 1702 }
1688 1703
1689 /* 1704 /*
@@ -1719,9 +1734,12 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
1719 1734
1720 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, 1735 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
1721 &adapter->status)) 1736 &adapter->status))
1722 retval = ZFCP_ERP_FAILED; 1737 return ZFCP_ERP_FAILED;
1723 1738
1724 return retval; 1739 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
1740 zfcp_erp_open_ptp_port(adapter);
1741
1742 return ZFCP_ERP_SUCCEEDED;
1725} 1743}
1726 1744
1727static int 1745static int
@@ -1899,14 +1917,12 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
1899 retval = zfcp_erp_port_strategy_open_port(erp_action); 1917 retval = zfcp_erp_port_strategy_open_port(erp_action);
1900 break; 1918 break;
1901 } 1919 }
1902 if (!(adapter->nameserver_port)) { 1920
1903 retval = zfcp_nameserver_enqueue(adapter); 1921 if (!adapter->nameserver_port) {
1904 if (retval != 0) { 1922 dev_err(&adapter->ccw_device->dev,
1905 dev_err(&adapter->ccw_device->dev, 1923 "Nameserver port unavailable.\n");
1906 "Nameserver port unavailable.\n"); 1924 retval = ZFCP_ERP_FAILED;
1907 retval = ZFCP_ERP_FAILED; 1925 break;
1908 break;
1909 }
1910 } 1926 }
1911 if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, 1927 if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
1912 &adapter->nameserver_port->status)) { 1928 &adapter->nameserver_port->status)) {
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 9aa412bd6637..c3b51338abfa 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -37,6 +37,8 @@ extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, wwn_t,
37extern void zfcp_port_dequeue(struct zfcp_port *); 37extern void zfcp_port_dequeue(struct zfcp_port *);
38extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, fcp_lun_t); 38extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, fcp_lun_t);
39extern void zfcp_unit_dequeue(struct zfcp_unit *); 39extern void zfcp_unit_dequeue(struct zfcp_unit *);
40extern int zfcp_scan_ports(struct zfcp_adapter *);
41extern void _zfcp_scan_ports_later(struct work_struct *work);
40 42
41/******************************* S/390 IO ************************************/ 43/******************************* S/390 IO ************************************/
42extern int zfcp_ccw_register(void); 44extern int zfcp_ccw_register(void);
@@ -97,8 +99,6 @@ extern int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *);
97extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); 99extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
98extern void zfcp_test_link(struct zfcp_port *); 100extern void zfcp_test_link(struct zfcp_port *);
99 101
100extern int zfcp_nameserver_enqueue(struct zfcp_adapter *);
101
102/******************************* SCSI ****************************************/ 102/******************************* SCSI ****************************************/
103extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); 103extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
104extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); 104extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index bb07c3bf2258..aa2d9a668d17 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -8,6 +8,37 @@
8 8
9#include "zfcp_ext.h" 9#include "zfcp_ext.h"
10 10
11struct ct_iu_gpn_ft_req {
12 struct ct_hdr header;
13 u8 flags;
14 u8 domain_id_scope;
15 u8 area_id_scope;
16 u8 fc4_type;
17} __attribute__ ((packed));
18
19struct gpn_ft_resp_acc {
20 u8 control;
21 u8 port_id[3];
22 u8 reserved[4];
23 u64 wwpn;
24} __attribute__ ((packed));
25
26#define ZFCP_GPN_FT_ENTRIES ((PAGE_SIZE - sizeof(struct ct_hdr)) \
27 / sizeof(struct gpn_ft_resp_acc))
28#define ZFCP_GPN_FT_BUFFERS 4
29#define ZFCP_GPN_FT_MAX_ENTRIES ZFCP_GPN_FT_BUFFERS * (ZFCP_GPN_FT_ENTRIES + 1)
30
31struct ct_iu_gpn_ft_resp {
32 struct ct_hdr header;
33 struct gpn_ft_resp_acc accept[ZFCP_GPN_FT_ENTRIES];
34} __attribute__ ((packed));
35
36struct zfcp_gpn_ft {
37 struct zfcp_send_ct ct;
38 struct scatterlist sg_req;
39 struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS];
40};
41
11static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, 42static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
12 struct fcp_rscn_element *elem) 43 struct fcp_rscn_element *elem)
13{ 44{
@@ -68,6 +99,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
68 } 99 }
69 _zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element); 100 _zfcp_fc_incoming_rscn(fsf_req, range_mask, fcp_rscn_element);
70 } 101 }
102 schedule_work(&fsf_req->adapter->scan_work);
71} 103}
72 104
73static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, wwn_t wwpn) 105static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, wwn_t wwpn)
@@ -303,3 +335,219 @@ void zfcp_test_link(struct zfcp_port *port)
303 zfcp_port_put(port); 335 zfcp_port_put(port);
304 zfcp_erp_port_forced_reopen(port, 0, 65, NULL); 336 zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
305} 337}
338
339static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
340{
341 int ret;
342
343 if (!adapter->nameserver_port)
344 return -EINTR;
345
346 if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
347 &adapter->nameserver_port->status)) {
348 ret = zfcp_erp_port_reopen(adapter->nameserver_port, 0, 148,
349 NULL);
350 if (ret)
351 return ret;
352 zfcp_erp_wait(adapter);
353 zfcp_port_put(adapter->nameserver_port);
354 }
355 return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
356 &adapter->nameserver_port->status);
357}
358
359static void zfcp_gpn_ft_handler(unsigned long _done)
360{
361 complete((struct completion *)_done);
362}
363
364static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft)
365{
366 struct scatterlist *sg = &gpn_ft->sg_req;
367
368 kfree(sg_virt(sg)); /* free request buffer */
369 zfcp_sg_free_table(gpn_ft->sg_resp, ZFCP_GPN_FT_BUFFERS);
370
371 kfree(gpn_ft);
372}
373
374static struct zfcp_gpn_ft *zfcp_alloc_sg_env(void)
375{
376 struct zfcp_gpn_ft *gpn_ft;
377 struct ct_iu_gpn_ft_req *req;
378
379 gpn_ft = kzalloc(sizeof(*gpn_ft), GFP_KERNEL);
380 if (!gpn_ft)
381 return NULL;
382
383 req = kzalloc(sizeof(struct ct_iu_gpn_ft_req), GFP_KERNEL);
384 if (!req) {
385 kfree(gpn_ft);
386 gpn_ft = NULL;
387 goto out;
388 }
389 sg_init_one(&gpn_ft->sg_req, req, sizeof(*req));
390
391 if (zfcp_sg_setup_table(gpn_ft->sg_resp, ZFCP_GPN_FT_BUFFERS)) {
392 zfcp_free_sg_env(gpn_ft);
393 gpn_ft = NULL;
394 }
395out:
396 return gpn_ft;
397}
398
399
400static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
401 struct zfcp_adapter *adapter)
402{
403 struct zfcp_send_ct *ct = &gpn_ft->ct;
404 struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
405 struct completion done;
406 int ret;
407
408 /* prepare CT IU for GPN_FT */
409 req->header.revision = ZFCP_CT_REVISION;
410 req->header.gs_type = ZFCP_CT_DIRECTORY_SERVICE;
411 req->header.gs_subtype = ZFCP_CT_NAME_SERVER;
412 req->header.options = ZFCP_CT_SYNCHRONOUS;
413 req->header.cmd_rsp_code = ZFCP_CT_GPN_FT;
414 req->header.max_res_size = (sizeof(struct gpn_ft_resp_acc) *
415 (ZFCP_GPN_FT_MAX_ENTRIES - 1)) >> 2;
416 req->flags = 0;
417 req->domain_id_scope = 0;
418 req->area_id_scope = 0;
419 req->fc4_type = ZFCP_CT_SCSI_FCP;
420
421 /* prepare zfcp_send_ct */
422 ct->port = adapter->nameserver_port;
423 ct->handler = zfcp_gpn_ft_handler;
424 ct->handler_data = (unsigned long)&done;
425 ct->timeout = 10;
426 ct->req = &gpn_ft->sg_req;
427 ct->resp = gpn_ft->sg_resp;
428 ct->req_count = 1;
429 ct->resp_count = ZFCP_GPN_FT_BUFFERS;
430
431 init_completion(&done);
432 ret = zfcp_fsf_send_ct(ct, NULL, NULL);
433 if (!ret)
434 wait_for_completion(&done);
435 return ret;
436}
437
438static void zfcp_validate_port(struct zfcp_port *port)
439{
440 struct zfcp_adapter *adapter = port->adapter;
441
442 atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status);
443
444 if (port == adapter->nameserver_port)
445 return;
446 if ((port->supported_classes != 0) || (port->units != 0)) {
447 zfcp_port_put(port);
448 return;
449 }
450 zfcp_erp_port_shutdown(port, 0, 151, NULL);
451 zfcp_erp_wait(adapter);
452 zfcp_port_put(port);
453 zfcp_port_dequeue(port);
454}
455
456static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
457{
458 struct zfcp_send_ct *ct = &gpn_ft->ct;
459 struct scatterlist *sg = gpn_ft->sg_resp;
460 struct ct_hdr *hdr = sg_virt(sg);
461 struct gpn_ft_resp_acc *acc = sg_virt(sg);
462 struct zfcp_adapter *adapter = ct->port->adapter;
463 struct zfcp_port *port, *tmp;
464 u32 d_id;
465 int ret = 0, x;
466
467 if (ct->status)
468 return -EIO;
469
470 if (hdr->cmd_rsp_code != ZFCP_CT_ACCEPT) {
471 if (hdr->reason_code == ZFCP_CT_UNABLE_TO_PERFORM_CMD)
472 return -EAGAIN; /* might be a temporary condition */
473 return -EIO;
474 }
475
476 if (hdr->max_res_size)
477 return -E2BIG;
478
479 down(&zfcp_data.config_sema);
480
481 /* first entry is the header */
482 for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES; x++) {
483 if (x % (ZFCP_GPN_FT_ENTRIES + 1))
484 acc++;
485 else
486 acc = sg_virt(++sg);
487
488 d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
489 acc->port_id[2];
490
491 /* skip the adapter's port and known remote ports */
492 if (acc->wwpn == fc_host_port_name(adapter->scsi_host) ||
493 zfcp_get_port_by_did(adapter, d_id))
494 continue;
495
496 port = zfcp_port_enqueue(adapter, acc->wwpn,
497 ZFCP_STATUS_PORT_DID_DID |
498 ZFCP_STATUS_COMMON_NOESC, d_id);
499 if (port)
500 zfcp_erp_port_reopen(port, 0, 149, NULL);
501 else
502 ret = -ENOMEM;
503 if (acc->control & 0x80) /* last entry */
504 break;
505 }
506
507 zfcp_erp_wait(adapter);
508 list_for_each_entry_safe(port, tmp, &adapter->port_list_head, list)
509 zfcp_validate_port(port);
510 up(&zfcp_data.config_sema);
511 return ret;
512}
513
514/**
515 * zfcp_scan_ports - scan remote ports and attach new ports
516 * @adapter: pointer to struct zfcp_adapter
517 */
518int zfcp_scan_ports(struct zfcp_adapter *adapter)
519{
520 int ret, i;
521 struct zfcp_gpn_ft *gpn_ft;
522
523 if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT)
524 return 0;
525
526 ret = zfcp_scan_get_nameserver(adapter);
527 if (ret)
528 return ret;
529
530 gpn_ft = zfcp_alloc_sg_env();
531 if (!gpn_ft)
532 return -ENOMEM;
533
534 for (i = 0; i < 3; i++) {
535 ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter);
536 if (!ret) {
537 ret = zfcp_scan_eval_gpn_ft(gpn_ft);
538 if (ret == -EAGAIN)
539 ssleep(1);
540 else
541 break;
542 }
543 }
544 zfcp_free_sg_env(gpn_ft);
545
546 return ret;
547}
548
549
550void _zfcp_scan_ports_later(struct work_struct *work)
551{
552 zfcp_scan_ports(container_of(work, struct zfcp_adapter, scan_work));
553}
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 01ed5fb46c44..243e792f2407 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -874,6 +874,9 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
874 if (status_buffer->status_subtype & 874 if (status_buffer->status_subtype &
875 FSF_STATUS_READ_SUB_ACT_UPDATED) 875 FSF_STATUS_READ_SUB_ACT_UPDATED)
876 zfcp_erp_adapter_access_changed(adapter, 135, fsf_req); 876 zfcp_erp_adapter_access_changed(adapter, 135, fsf_req);
877 if (status_buffer->status_subtype &
878 FSF_STATUS_READ_SUB_INCOMING_ELS)
879 schedule_work(&adapter->scan_work);
877 break; 880 break;
878 881
879 case FSF_STATUS_READ_CFDC_UPDATED: 882 case FSF_STATUS_READ_CFDC_UPDATED:
diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c
index 1f2a8c21b731..a4cae60f69d4 100644
--- a/drivers/s390/scsi/zfcp_sysfs_adapter.c
+++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c
@@ -85,6 +85,30 @@ zfcp_sysfs_port_add_store(struct device *dev, struct device_attribute *attr, con
85static DEVICE_ATTR(port_add, S_IWUSR, NULL, zfcp_sysfs_port_add_store); 85static DEVICE_ATTR(port_add, S_IWUSR, NULL, zfcp_sysfs_port_add_store);
86 86
87/** 87/**
88 * zfcp_sysfs_port_rescan - trigger manual port rescan
89 * @dev: pointer to belonging device
90 * @attr: pointer to struct device_attribute
91 * @buf: pointer to input buffer
92 * @count: number of bytes in buffer
93 */
94static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
95 struct device_attribute *attr,
96 const char *buf, size_t count)
97{
98 struct zfcp_adapter *adapter;
99 int ret;
100
101 adapter = dev_get_drvdata(dev);
102 if (atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status))
103 return -EBUSY;
104
105 ret = zfcp_scan_ports(adapter);
106
107 return ret ? ret : (ssize_t) count;
108}
109static DEVICE_ATTR(port_rescan, S_IWUSR, NULL, zfcp_sysfs_port_rescan_store);
110
111/**
88 * zfcp_sysfs_port_remove_store - remove a port from sysfs tree 112 * zfcp_sysfs_port_remove_store - remove a port from sysfs tree
89 * @dev: pointer to belonging device 113 * @dev: pointer to belonging device
90 * @buf: pointer to input buffer 114 * @buf: pointer to input buffer
@@ -214,6 +238,7 @@ static struct attribute *zfcp_adapter_attrs[] = {
214 &dev_attr_in_recovery.attr, 238 &dev_attr_in_recovery.attr,
215 &dev_attr_port_remove.attr, 239 &dev_attr_port_remove.attr,
216 &dev_attr_port_add.attr, 240 &dev_attr_port_add.attr,
241 &dev_attr_port_rescan.attr,
217 &dev_attr_peer_wwnn.attr, 242 &dev_attr_peer_wwnn.attr,
218 &dev_attr_peer_wwpn.attr, 243 &dev_attr_peer_wwpn.attr,
219 &dev_attr_peer_d_id.attr, 244 &dev_attr_peer_d_id.attr,