aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Schuetz <sven@linux.vnet.ibm.com>2009-04-06 12:31:47 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-12 15:20:05 -0400
commit9d544f2b9bd4a0f7ba2784cc47e3591667a7b8d4 (patch)
tree5497f9b83aaa2e17da5d6ef0901de0c731e7b8a3
parent9e4f5e29610162fd426366f3b29e3cc6e575b858 (diff)
[SCSI] zfcp: Add FC pass-through support
Provide the ability to do fibre channel requests from the userspace to our zfcp driver. Patch builds upon extension to the fibre channel tranport class by James Smart and Seokmann Ju. See here http://marc.info/?l=linux-scsi&m=123808882309133&w=2 Signed-off-by: Sven Schuetz <sven@linux.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.c10
-rw-r--r--drivers/s390/scsi/zfcp_def.h18
-rw-r--r--drivers/s390/scsi/zfcp_erp.c2
-rw-r--r--drivers/s390/scsi/zfcp_ext.h6
-rw-r--r--drivers/s390/scsi/zfcp_fc.c188
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c15
6 files changed, 219 insertions, 20 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 3ac27ee47396..2ccbd185a5fb 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -470,6 +470,12 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
470 if (!adapter) 470 if (!adapter)
471 return -ENOMEM; 471 return -ENOMEM;
472 472
473 adapter->gs = kzalloc(sizeof(struct zfcp_wka_ports), GFP_KERNEL);
474 if (!adapter->gs) {
475 kfree(adapter);
476 return -ENOMEM;
477 }
478
473 ccw_device->handler = NULL; 479 ccw_device->handler = NULL;
474 adapter->ccw_device = ccw_device; 480 adapter->ccw_device = ccw_device;
475 atomic_set(&adapter->refcount, 0); 481 atomic_set(&adapter->refcount, 0);
@@ -523,8 +529,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
523 goto sysfs_failed; 529 goto sysfs_failed;
524 530
525 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); 531 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
526 532 zfcp_fc_wka_ports_init(adapter);
527 zfcp_fc_nameserver_init(adapter);
528 533
529 if (!zfcp_adapter_scsi_register(adapter)) 534 if (!zfcp_adapter_scsi_register(adapter))
530 return 0; 535 return 0;
@@ -571,6 +576,7 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
571 kfree(adapter->req_list); 576 kfree(adapter->req_list);
572 kfree(adapter->fc_stats); 577 kfree(adapter->fc_stats);
573 kfree(adapter->stats_reset_data); 578 kfree(adapter->stats_reset_data);
579 kfree(adapter->gs);
574 kfree(adapter); 580 kfree(adapter);
575} 581}
576 582
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 2074d45dbf6c..49d0532bca1c 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -22,6 +22,8 @@
22#include <linux/syscalls.h> 22#include <linux/syscalls.h>
23#include <linux/scatterlist.h> 23#include <linux/scatterlist.h>
24#include <linux/ioctl.h> 24#include <linux/ioctl.h>
25#include <scsi/fc/fc_fs.h>
26#include <scsi/fc/fc_gs.h>
25#include <scsi/scsi.h> 27#include <scsi/scsi.h>
26#include <scsi/scsi_tcq.h> 28#include <scsi/scsi_tcq.h>
27#include <scsi/scsi_cmnd.h> 29#include <scsi/scsi_cmnd.h>
@@ -29,6 +31,7 @@
29#include <scsi/scsi_host.h> 31#include <scsi/scsi_host.h>
30#include <scsi/scsi_transport.h> 32#include <scsi/scsi_transport.h>
31#include <scsi/scsi_transport_fc.h> 33#include <scsi/scsi_transport_fc.h>
34#include <scsi/scsi_bsg_fc.h>
32#include <asm/ccwdev.h> 35#include <asm/ccwdev.h>
33#include <asm/qdio.h> 36#include <asm/qdio.h>
34#include <asm/debug.h> 37#include <asm/debug.h>
@@ -228,11 +231,6 @@ struct zfcp_ls_adisc {
228 231
229/* FC-PH/FC-GS well-known address identifiers for generic services */ 232/* FC-PH/FC-GS well-known address identifiers for generic services */
230#define ZFCP_DID_WKA 0xFFFFF0 233#define ZFCP_DID_WKA 0xFFFFF0
231#define ZFCP_DID_MANAGEMENT_SERVICE 0xFFFFFA
232#define ZFCP_DID_TIME_SERVICE 0xFFFFFB
233#define ZFCP_DID_DIRECTORY_SERVICE 0xFFFFFC
234#define ZFCP_DID_ALIAS_SERVICE 0xFFFFF8
235#define ZFCP_DID_KEY_DISTRIBUTION_SERVICE 0xFFFFF7
236 234
237/* remote port status */ 235/* remote port status */
238#define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001 236#define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001
@@ -376,6 +374,14 @@ struct zfcp_wka_port {
376 struct delayed_work work; 374 struct delayed_work work;
377}; 375};
378 376
377struct zfcp_wka_ports {
378 struct zfcp_wka_port ms; /* management service */
379 struct zfcp_wka_port ts; /* time service */
380 struct zfcp_wka_port ds; /* directory service */
381 struct zfcp_wka_port as; /* alias service */
382 struct zfcp_wka_port ks; /* key distribution service */
383};
384
379struct zfcp_qdio_queue { 385struct zfcp_qdio_queue {
380 struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; 386 struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
381 u8 first; /* index of next free bfr in queue */ 387 u8 first; /* index of next free bfr in queue */
@@ -461,7 +467,7 @@ struct zfcp_adapter {
461 actions */ 467 actions */
462 u32 erp_low_mem_count; /* nr of erp actions waiting 468 u32 erp_low_mem_count; /* nr of erp actions waiting
463 for memory */ 469 for memory */
464 struct zfcp_wka_port nsp; /* adapter's nameserver */ 470 struct zfcp_wka_ports *gs; /* generic services */
465 debug_info_t *rec_dbf; 471 debug_info_t *rec_dbf;
466 debug_info_t *hba_dbf; 472 debug_info_t *hba_dbf;
467 debug_info_t *san_dbf; /* debug feature areas */ 473 debug_info_t *san_dbf; /* debug feature areas */
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index e50ea465bc2b..8030e25152fb 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -719,7 +719,7 @@ static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act)
719 zfcp_qdio_close(adapter); 719 zfcp_qdio_close(adapter);
720 zfcp_fsf_req_dismiss_all(adapter); 720 zfcp_fsf_req_dismiss_all(adapter);
721 adapter->fsf_req_seq_no = 0; 721 adapter->fsf_req_seq_no = 0;
722 zfcp_fc_wka_port_force_offline(&adapter->nsp); 722 zfcp_fc_wka_port_force_offline(&adapter->gs->ds);
723 /* all ports and units are closed */ 723 /* all ports and units are closed */
724 zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL, 724 zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL,
725 ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); 725 ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 120a9a1c81f7..3044c6010306 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -106,8 +106,12 @@ extern int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *);
106extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); 106extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
107extern void zfcp_test_link(struct zfcp_port *); 107extern void zfcp_test_link(struct zfcp_port *);
108extern void zfcp_fc_link_test_work(struct work_struct *); 108extern void zfcp_fc_link_test_work(struct work_struct *);
109extern void zfcp_fc_nameserver_init(struct zfcp_adapter *);
110extern void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *); 109extern void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *);
110extern void zfcp_fc_wka_ports_init(struct zfcp_adapter *);
111extern int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *);
112extern int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *);
113extern void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *);
114
111 115
112/* zfcp_fsf.c */ 116/* zfcp_fsf.c */
113extern int zfcp_fsf_open_port(struct zfcp_erp_action *); 117extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index bb2752b4130f..da10e0df6879 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -120,14 +120,13 @@ static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port)
120 schedule_delayed_work(&wka_port->work, HZ / 100); 120 schedule_delayed_work(&wka_port->work, HZ / 100);
121} 121}
122 122
123void zfcp_fc_nameserver_init(struct zfcp_adapter *adapter) 123static void zfcp_fc_wka_port_init(struct zfcp_wka_port *wka_port, u32 d_id,
124 struct zfcp_adapter *adapter)
124{ 125{
125 struct zfcp_wka_port *wka_port = &adapter->nsp;
126
127 init_waitqueue_head(&wka_port->completion_wq); 126 init_waitqueue_head(&wka_port->completion_wq);
128 127
129 wka_port->adapter = adapter; 128 wka_port->adapter = adapter;
130 wka_port->d_id = ZFCP_DID_DIRECTORY_SERVICE; 129 wka_port->d_id = d_id;
131 130
132 wka_port->status = ZFCP_WKA_PORT_OFFLINE; 131 wka_port->status = ZFCP_WKA_PORT_OFFLINE;
133 atomic_set(&wka_port->refcount, 0); 132 atomic_set(&wka_port->refcount, 0);
@@ -143,6 +142,17 @@ void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
143 mutex_unlock(&wka->mutex); 142 mutex_unlock(&wka->mutex);
144} 143}
145 144
145void zfcp_fc_wka_ports_init(struct zfcp_adapter *adapter)
146{
147 struct zfcp_wka_ports *gs = adapter->gs;
148
149 zfcp_fc_wka_port_init(&gs->ms, FC_FID_MGMT_SERV, adapter);
150 zfcp_fc_wka_port_init(&gs->ts, FC_FID_TIME_SERV, adapter);
151 zfcp_fc_wka_port_init(&gs->ds, FC_FID_DIR_SERV, adapter);
152 zfcp_fc_wka_port_init(&gs->as, FC_FID_ALIASES, adapter);
153 zfcp_fc_wka_port_init(&gs->ks, FC_FID_SEC_KEY, adapter);
154}
155
146static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, 156static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
147 struct fcp_rscn_element *elem) 157 struct fcp_rscn_element *elem)
148{ 158{
@@ -282,7 +292,7 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
282 292
283 /* setup parameters for send generic command */ 293 /* setup parameters for send generic command */
284 gid_pn->port = erp_action->port; 294 gid_pn->port = erp_action->port;
285 gid_pn->ct.wka_port = &adapter->nsp; 295 gid_pn->ct.wka_port = &adapter->gs->ds;
286 gid_pn->ct.handler = zfcp_fc_ns_handler; 296 gid_pn->ct.handler = zfcp_fc_ns_handler;
287 gid_pn->ct.handler_data = (unsigned long) &compl_rec; 297 gid_pn->ct.handler_data = (unsigned long) &compl_rec;
288 gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; 298 gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT;
@@ -329,13 +339,13 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action)
329 339
330 memset(gid_pn, 0, sizeof(*gid_pn)); 340 memset(gid_pn, 0, sizeof(*gid_pn));
331 341
332 ret = zfcp_wka_port_get(&adapter->nsp); 342 ret = zfcp_wka_port_get(&adapter->gs->ds);
333 if (ret) 343 if (ret)
334 goto out; 344 goto out;
335 345
336 ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn); 346 ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn);
337 347
338 zfcp_wka_port_put(&adapter->nsp); 348 zfcp_wka_port_put(&adapter->gs->ds);
339out: 349out:
340 mempool_free(gid_pn, adapter->pool.data_gid_pn); 350 mempool_free(gid_pn, adapter->pool.data_gid_pn);
341 return ret; 351 return ret;
@@ -525,7 +535,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
525 req->fc4_type = ZFCP_CT_SCSI_FCP; 535 req->fc4_type = ZFCP_CT_SCSI_FCP;
526 536
527 /* prepare zfcp_send_ct */ 537 /* prepare zfcp_send_ct */
528 ct->wka_port = &adapter->nsp; 538 ct->wka_port = &adapter->gs->ds;
529 ct->handler = zfcp_fc_ns_handler; 539 ct->handler = zfcp_fc_ns_handler;
530 ct->handler_data = (unsigned long)&compl_rec; 540 ct->handler_data = (unsigned long)&compl_rec;
531 ct->timeout = 10; 541 ct->timeout = 10;
@@ -644,7 +654,7 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
644 fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV) 654 fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
645 return 0; 655 return 0;
646 656
647 ret = zfcp_wka_port_get(&adapter->nsp); 657 ret = zfcp_wka_port_get(&adapter->gs->ds);
648 if (ret) 658 if (ret)
649 return ret; 659 return ret;
650 660
@@ -666,7 +676,7 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
666 } 676 }
667 zfcp_free_sg_env(gpn_ft, buf_num); 677 zfcp_free_sg_env(gpn_ft, buf_num);
668out: 678out:
669 zfcp_wka_port_put(&adapter->nsp); 679 zfcp_wka_port_put(&adapter->gs->ds);
670 return ret; 680 return ret;
671} 681}
672 682
@@ -675,3 +685,161 @@ void _zfcp_scan_ports_later(struct work_struct *work)
675{ 685{
676 zfcp_scan_ports(container_of(work, struct zfcp_adapter, scan_work)); 686 zfcp_scan_ports(container_of(work, struct zfcp_adapter, scan_work));
677} 687}
688
689struct zfcp_els_fc_job {
690 struct zfcp_send_els els;
691 struct fc_bsg_job *job;
692};
693
694static void zfcp_fc_generic_els_handler(unsigned long data)
695{
696 struct zfcp_els_fc_job *els_fc_job = (struct zfcp_els_fc_job *) data;
697 struct fc_bsg_job *job = els_fc_job->job;
698 struct fc_bsg_reply *reply = job->reply;
699
700 if (els_fc_job->els.status) {
701 /* request rejected or timed out */
702 reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_REJECT;
703 goto out;
704 }
705
706 reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
707 reply->reply_payload_rcv_len = blk_rq_bytes(job->req->next_rq);
708
709out:
710 job->state_flags = FC_RQST_STATE_DONE;
711 job->job_done(job);
712 kfree(els_fc_job);
713}
714
715int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *job)
716{
717 struct zfcp_els_fc_job *els_fc_job;
718 struct fc_rport *rport = job->rport;
719 struct Scsi_Host *shost;
720 struct zfcp_adapter *adapter;
721 struct zfcp_port *port;
722 u8 *port_did;
723
724 shost = rport ? rport_to_shost(rport) : job->shost;
725 adapter = (struct zfcp_adapter *)shost->hostdata[0];
726
727 if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
728 return -EINVAL;
729
730 els_fc_job = kzalloc(sizeof(struct zfcp_els_fc_job), GFP_KERNEL);
731 if (!els_fc_job)
732 return -ENOMEM;
733
734 els_fc_job->els.adapter = adapter;
735 if (rport) {
736 read_lock_irq(&zfcp_data.config_lock);
737 port = rport->dd_data;
738 if (port)
739 zfcp_port_get(port);
740 read_unlock_irq(&zfcp_data.config_lock);
741 if (!port) {
742 kfree(els_fc_job);
743 return -EINVAL;
744 }
745 els_fc_job->els.port = port;
746 els_fc_job->els.d_id = port->d_id;
747 zfcp_port_put(port);
748 } else {
749 port_did = job->request->rqst_data.h_els.port_id;
750 els_fc_job->els.d_id = (port_did[0] << 16) +
751 (port_did[1] << 8) + port_did[2];
752 }
753
754 els_fc_job->els.req = job->request_payload.sg_list;
755 els_fc_job->els.resp = job->reply_payload.sg_list;
756 els_fc_job->els.handler = zfcp_fc_generic_els_handler;
757 els_fc_job->els.handler_data = (unsigned long) els_fc_job;
758 els_fc_job->job = job;
759
760 return zfcp_fsf_send_els(&els_fc_job->els);
761}
762
763struct zfcp_ct_fc_job {
764 struct zfcp_send_ct ct;
765 struct fc_bsg_job *job;
766};
767
768static void zfcp_fc_generic_ct_handler(unsigned long data)
769{
770 struct zfcp_ct_fc_job *ct_fc_job = (struct zfcp_ct_fc_job *) data;
771 struct fc_bsg_job *job = ct_fc_job->job;
772
773 job->reply->reply_data.ctels_reply.status = ct_fc_job->ct.status ?
774 FC_CTELS_STATUS_REJECT : FC_CTELS_STATUS_OK;
775 job->state_flags = FC_RQST_STATE_DONE;
776 job->reply->reply_payload_rcv_len = blk_rq_bytes(job->req->next_rq);
777 job->job_done(job);
778
779 zfcp_wka_port_put(ct_fc_job->ct.wka_port);
780
781 kfree(ct_fc_job);
782}
783
784int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job)
785{
786 int ret;
787 u8 gs_type;
788 struct fc_rport *rport = job->rport;
789 struct Scsi_Host *shost;
790 struct zfcp_adapter *adapter;
791 struct zfcp_ct_fc_job *ct_fc_job;
792 u32 preamble_word1;
793
794 shost = rport ? rport_to_shost(rport) : job->shost;
795
796 adapter = (struct zfcp_adapter *)shost->hostdata[0];
797 if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN))
798 return -EINVAL;
799
800 ct_fc_job = kzalloc(sizeof(struct zfcp_ct_fc_job), GFP_KERNEL);
801 if (!ct_fc_job)
802 return -ENOMEM;
803
804 preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
805 gs_type = (preamble_word1 & 0xff000000) >> 24;
806
807 switch (gs_type) {
808 case FC_FST_ALIAS:
809 ct_fc_job->ct.wka_port = &adapter->gs->as;
810 break;
811 case FC_FST_MGMT:
812 ct_fc_job->ct.wka_port = &adapter->gs->ms;
813 break;
814 case FC_FST_TIME:
815 ct_fc_job->ct.wka_port = &adapter->gs->ts;
816 break;
817 case FC_FST_DIR:
818 ct_fc_job->ct.wka_port = &adapter->gs->ds;
819 break;
820 default:
821 kfree(ct_fc_job);
822 return -EINVAL; /* no such service */
823 }
824
825 ret = zfcp_wka_port_get(ct_fc_job->ct.wka_port);
826 if (ret) {
827 kfree(ct_fc_job);
828 return ret;
829 }
830
831 ct_fc_job->ct.req = job->request_payload.sg_list;
832 ct_fc_job->ct.resp = job->reply_payload.sg_list;
833 ct_fc_job->ct.timeout = ZFCP_FSF_REQUEST_TIMEOUT;
834 ct_fc_job->ct.handler = zfcp_fc_generic_ct_handler;
835 ct_fc_job->ct.handler_data = (unsigned long) ct_fc_job;
836 ct_fc_job->ct.completion = NULL;
837 ct_fc_job->job = job;
838
839 ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL, NULL);
840 if (ret) {
841 kfree(ct_fc_job);
842 zfcp_wka_port_put(ct_fc_job->ct.wka_port);
843 }
844 return ret;
845}
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 7d0da230eb63..967ede73f4c5 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -623,6 +623,20 @@ void zfcp_scsi_scan(struct work_struct *work)
623 zfcp_unit_put(unit); 623 zfcp_unit_put(unit);
624} 624}
625 625
626static int zfcp_execute_fc_job(struct fc_bsg_job *job)
627{
628 switch (job->request->msgcode) {
629 case FC_BSG_RPT_ELS:
630 case FC_BSG_HST_ELS_NOLOGIN:
631 return zfcp_fc_execute_els_fc_job(job);
632 case FC_BSG_RPT_CT:
633 case FC_BSG_HST_CT:
634 return zfcp_fc_execute_ct_fc_job(job);
635 default:
636 return -EINVAL;
637 }
638}
639
626struct fc_function_template zfcp_transport_functions = { 640struct fc_function_template zfcp_transport_functions = {
627 .show_starget_port_id = 1, 641 .show_starget_port_id = 1,
628 .show_starget_port_name = 1, 642 .show_starget_port_name = 1,
@@ -644,6 +658,7 @@ struct fc_function_template zfcp_transport_functions = {
644 .dev_loss_tmo_callbk = zfcp_scsi_dev_loss_tmo_callbk, 658 .dev_loss_tmo_callbk = zfcp_scsi_dev_loss_tmo_callbk,
645 .terminate_rport_io = zfcp_scsi_terminate_rport_io, 659 .terminate_rport_io = zfcp_scsi_terminate_rport_io,
646 .show_host_port_state = 1, 660 .show_host_port_state = 1,
661 .bsg_request = zfcp_execute_fc_job,
647 /* no functions registered for following dynamic attributes but 662 /* no functions registered for following dynamic attributes but
648 directly set by LLDD */ 663 directly set by LLDD */
649 .show_host_port_type = 1, 664 .show_host_port_type = 1,