aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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,