aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/scsi/zfcp_aux.c2
-rw-r--r--drivers/s390/scsi/zfcp_def.h1
-rw-r--r--drivers/s390/scsi/zfcp_erp.c2
-rw-r--r--drivers/s390/scsi/zfcp_ext.h1
-rw-r--r--drivers/s390/scsi/zfcp_fc.c120
-rw-r--r--drivers/s390/scsi/zfcp_fc.h42
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c1
7 files changed, 169 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 88691adc1283..645b0fcbb370 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -362,6 +362,7 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
362 362
363 INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler); 363 INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
364 INIT_WORK(&adapter->scan_work, zfcp_fc_scan_ports); 364 INIT_WORK(&adapter->scan_work, zfcp_fc_scan_ports);
365 INIT_WORK(&adapter->ns_up_work, zfcp_fc_sym_name_update);
365 366
366 if (zfcp_qdio_setup(adapter)) 367 if (zfcp_qdio_setup(adapter))
367 goto failed; 368 goto failed;
@@ -427,6 +428,7 @@ void zfcp_adapter_unregister(struct zfcp_adapter *adapter)
427 428
428 cancel_work_sync(&adapter->scan_work); 429 cancel_work_sync(&adapter->scan_work);
429 cancel_work_sync(&adapter->stat_work); 430 cancel_work_sync(&adapter->stat_work);
431 cancel_work_sync(&adapter->ns_up_work);
430 zfcp_destroy_adapter_work_queue(adapter); 432 zfcp_destroy_adapter_work_queue(adapter);
431 433
432 zfcp_fc_wka_ports_force_offline(adapter->gs); 434 zfcp_fc_wka_ports_force_offline(adapter->gs);
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 1566208997b6..527ba48eea57 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -189,6 +189,7 @@ struct zfcp_adapter {
189 struct fsf_qtcb_bottom_port *stats_reset_data; 189 struct fsf_qtcb_bottom_port *stats_reset_data;
190 unsigned long stats_reset; 190 unsigned long stats_reset;
191 struct work_struct scan_work; 191 struct work_struct scan_work;
192 struct work_struct ns_up_work;
192 struct service_level service_level; 193 struct service_level service_level;
193 struct workqueue_struct *work_queue; 194 struct workqueue_struct *work_queue;
194 struct device_dma_parameters dma_parms; 195 struct device_dma_parameters dma_parms;
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 6c1cddf0d0a0..e1b4f800e226 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -1231,8 +1231,10 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
1231 if (result == ZFCP_ERP_SUCCEEDED) { 1231 if (result == ZFCP_ERP_SUCCEEDED) {
1232 register_service_level(&adapter->service_level); 1232 register_service_level(&adapter->service_level);
1233 queue_work(adapter->work_queue, &adapter->scan_work); 1233 queue_work(adapter->work_queue, &adapter->scan_work);
1234 queue_work(adapter->work_queue, &adapter->ns_up_work);
1234 } else 1235 } else
1235 unregister_service_level(&adapter->service_level); 1236 unregister_service_level(&adapter->service_level);
1237
1236 kref_put(&adapter->ref, zfcp_adapter_release); 1238 kref_put(&adapter->ref, zfcp_adapter_release);
1237 break; 1239 break;
1238 } 1240 }
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 410d9ddc175a..03627cfd81cd 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -96,6 +96,7 @@ extern int zfcp_fc_gs_setup(struct zfcp_adapter *);
96extern void zfcp_fc_gs_destroy(struct zfcp_adapter *); 96extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
97extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *); 97extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
98extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *); 98extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
99extern void zfcp_fc_sym_name_update(struct work_struct *);
99 100
100/* zfcp_fsf.c */ 101/* zfcp_fsf.c */
101extern struct kmem_cache *zfcp_fsf_qtcb_cache; 102extern struct kmem_cache *zfcp_fsf_qtcb_cache;
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index c839a3b6879d..297e6b71ce9c 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/utsname.h>
14#include <scsi/fc/fc_els.h> 15#include <scsi/fc/fc_els.h>
15#include <scsi/libfc.h> 16#include <scsi/libfc.h>
16#include "zfcp_ext.h" 17#include "zfcp_ext.h"
@@ -696,6 +697,125 @@ out:
696 zfcp_fc_wka_port_put(&adapter->gs->ds); 697 zfcp_fc_wka_port_put(&adapter->gs->ds);
697} 698}
698 699
700static int zfcp_fc_gspn(struct zfcp_adapter *adapter,
701 struct zfcp_fc_req *fc_req)
702{
703 DECLARE_COMPLETION_ONSTACK(completion);
704 char devno[] = "DEVNO:";
705 struct zfcp_fsf_ct_els *ct_els = &fc_req->ct_els;
706 struct zfcp_fc_gspn_req *gspn_req = &fc_req->u.gspn.req;
707 struct zfcp_fc_gspn_rsp *gspn_rsp = &fc_req->u.gspn.rsp;
708 int ret;
709
710 zfcp_fc_ct_ns_init(&gspn_req->ct_hdr, FC_NS_GSPN_ID,
711 FC_SYMBOLIC_NAME_SIZE);
712 hton24(gspn_req->gspn.fp_fid, fc_host_port_id(adapter->scsi_host));
713
714 sg_init_one(&fc_req->sg_req, gspn_req, sizeof(*gspn_req));
715 sg_init_one(&fc_req->sg_rsp, gspn_rsp, sizeof(*gspn_rsp));
716
717 ct_els->handler = zfcp_fc_complete;
718 ct_els->handler_data = &completion;
719 ct_els->req = &fc_req->sg_req;
720 ct_els->resp = &fc_req->sg_rsp;
721
722 ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct_els, NULL,
723 ZFCP_FC_CTELS_TMO);
724 if (ret)
725 return ret;
726
727 wait_for_completion(&completion);
728 if (ct_els->status)
729 return ct_els->status;
730
731 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_NPIV &&
732 !(strstr(gspn_rsp->gspn.fp_name, devno)))
733 snprintf(fc_host_symbolic_name(adapter->scsi_host),
734 FC_SYMBOLIC_NAME_SIZE, "%s%s %s NAME: %s",
735 gspn_rsp->gspn.fp_name, devno,
736 dev_name(&adapter->ccw_device->dev),
737 init_utsname()->nodename);
738 else
739 strlcpy(fc_host_symbolic_name(adapter->scsi_host),
740 gspn_rsp->gspn.fp_name, FC_SYMBOLIC_NAME_SIZE);
741
742 return 0;
743}
744
745static void zfcp_fc_rspn(struct zfcp_adapter *adapter,
746 struct zfcp_fc_req *fc_req)
747{
748 DECLARE_COMPLETION_ONSTACK(completion);
749 struct Scsi_Host *shost = adapter->scsi_host;
750 struct zfcp_fsf_ct_els *ct_els = &fc_req->ct_els;
751 struct zfcp_fc_rspn_req *rspn_req = &fc_req->u.rspn.req;
752 struct fc_ct_hdr *rspn_rsp = &fc_req->u.rspn.rsp;
753 int ret, len;
754
755 zfcp_fc_ct_ns_init(&rspn_req->ct_hdr, FC_NS_RSPN_ID,
756 FC_SYMBOLIC_NAME_SIZE);
757 hton24(rspn_req->rspn.fr_fid.fp_fid, fc_host_port_id(shost));
758 len = strlcpy(rspn_req->rspn.fr_name, fc_host_symbolic_name(shost),
759 FC_SYMBOLIC_NAME_SIZE);
760 rspn_req->rspn.fr_name_len = len;
761
762 sg_init_one(&fc_req->sg_req, rspn_req, sizeof(*rspn_req));
763 sg_init_one(&fc_req->sg_rsp, rspn_rsp, sizeof(*rspn_rsp));
764
765 ct_els->handler = zfcp_fc_complete;
766 ct_els->handler_data = &completion;
767 ct_els->req = &fc_req->sg_req;
768 ct_els->resp = &fc_req->sg_rsp;
769
770 ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct_els, NULL,
771 ZFCP_FC_CTELS_TMO);
772 if (!ret)
773 wait_for_completion(&completion);
774}
775
776/**
777 * zfcp_fc_sym_name_update - Retrieve and update the symbolic port name
778 * @work: ns_up_work of the adapter where to update the symbolic port name
779 *
780 * Retrieve the current symbolic port name that may have been set by
781 * the hardware using the GSPN request and update the fc_host
782 * symbolic_name sysfs attribute. When running in NPIV mode (and hence
783 * the port name is unique for this system), update the symbolic port
784 * name to add Linux specific information and update the FC nameserver
785 * using the RSPN request.
786 */
787void zfcp_fc_sym_name_update(struct work_struct *work)
788{
789 struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter,
790 ns_up_work);
791 int ret;
792 struct zfcp_fc_req *fc_req;
793
794 if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT &&
795 fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
796 return;
797
798 fc_req = kmem_cache_zalloc(zfcp_fc_req_cache, GFP_KERNEL);
799 if (!fc_req)
800 return;
801
802 ret = zfcp_fc_wka_port_get(&adapter->gs->ds);
803 if (ret)
804 goto out_free;
805
806 ret = zfcp_fc_gspn(adapter, fc_req);
807 if (ret || fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
808 goto out_ds_put;
809
810 memset(fc_req, 0, sizeof(*fc_req));
811 zfcp_fc_rspn(adapter, fc_req);
812
813out_ds_put:
814 zfcp_fc_wka_port_put(&adapter->gs->ds);
815out_free:
816 kmem_cache_free(zfcp_fc_req_cache, fc_req);
817}
818
699static void zfcp_fc_ct_els_job_handler(void *data) 819static void zfcp_fc_ct_els_job_handler(void *data)
700{ 820{
701 struct fc_bsg_job *job = data; 821 struct fc_bsg_job *job = data;
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
index 5243ce44aa42..4561f3bf7300 100644
--- a/drivers/s390/scsi/zfcp_fc.h
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -84,6 +84,40 @@ struct zfcp_fc_gpn_ft_req {
84} __packed; 84} __packed;
85 85
86/** 86/**
87 * struct zfcp_fc_gspn_req - container for ct header plus GSPN_ID request
88 * @ct_hdr: FC GS common transport header
89 * @gspn: GSPN_ID request
90 */
91struct zfcp_fc_gspn_req {
92 struct fc_ct_hdr ct_hdr;
93 struct fc_gid_pn_resp gspn;
94} __packed;
95
96/**
97 * struct zfcp_fc_gspn_rsp - container for ct header plus GSPN_ID response
98 * @ct_hdr: FC GS common transport header
99 * @gspn: GSPN_ID response
100 * @name: The name string of the GSPN_ID response
101 */
102struct zfcp_fc_gspn_rsp {
103 struct fc_ct_hdr ct_hdr;
104 struct fc_gspn_resp gspn;
105 char name[FC_SYMBOLIC_NAME_SIZE];
106} __packed;
107
108/**
109 * struct zfcp_fc_rspn_req - container for ct header plus RSPN_ID request
110 * @ct_hdr: FC GS common transport header
111 * @rspn: RSPN_ID request
112 * @name: The name string of the RSPN_ID request
113 */
114struct zfcp_fc_rspn_req {
115 struct fc_ct_hdr ct_hdr;
116 struct fc_ns_rspn rspn;
117 char name[FC_SYMBOLIC_NAME_SIZE];
118} __packed;
119
120/**
87 * struct zfcp_fc_req - Container for FC ELS and CT requests sent from zfcp 121 * struct zfcp_fc_req - Container for FC ELS and CT requests sent from zfcp
88 * @ct_els: data required for issuing fsf command 122 * @ct_els: data required for issuing fsf command
89 * @sg_req: scatterlist entry for request data 123 * @sg_req: scatterlist entry for request data
@@ -107,6 +141,14 @@ struct zfcp_fc_req {
107 struct scatterlist sg_rsp2[ZFCP_FC_GPN_FT_NUM_BUFS - 1]; 141 struct scatterlist sg_rsp2[ZFCP_FC_GPN_FT_NUM_BUFS - 1];
108 struct zfcp_fc_gpn_ft_req req; 142 struct zfcp_fc_gpn_ft_req req;
109 } gpn_ft; 143 } gpn_ft;
144 struct {
145 struct zfcp_fc_gspn_req req;
146 struct zfcp_fc_gspn_rsp rsp;
147 } gspn;
148 struct {
149 struct zfcp_fc_rspn_req req;
150 struct fc_ct_hdr rsp;
151 } rspn;
110 } u; 152 } u;
111}; 153};
112 154
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index dbba0827127f..2a4991d6d4d5 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -720,6 +720,7 @@ struct fc_function_template zfcp_transport_functions = {
720 /* no functions registered for following dynamic attributes but 720 /* no functions registered for following dynamic attributes but
721 directly set by LLDD */ 721 directly set by LLDD */
722 .show_host_port_type = 1, 722 .show_host_port_type = 1,
723 .show_host_symbolic_name = 1,
723 .show_host_speed = 1, 724 .show_host_speed = 1,
724 .show_host_port_id = 1, 725 .show_host_port_id = 1,
725 .dd_bsg_size = sizeof(struct zfcp_fsf_ct_els), 726 .dd_bsg_size = sizeof(struct zfcp_fsf_ct_els),