aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>2011-01-28 19:05:27 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-12 12:09:04 -0500
commit75a2792df296c77004a72056c76628a1f835bc93 (patch)
tree767bafd5718fc112d440bf3d8d1369eeb1d557e9 /drivers/scsi/libfc
parentacc1a921659561c4ea97eca6e3c2633adecbcd81 (diff)
[SCSI] libfc: introduce LLD event callback
This patch enables LLD to listen to rport events and perform LLD specific operations based on the rport event. This patch also stores sp_features and spp_type in rdata for further reference by LLD. Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r--drivers/scsi/libfc/fc_npiv.c1
-rw-r--r--drivers/scsi/libfc/fc_rport.c19
2 files changed, 19 insertions, 1 deletions
diff --git a/drivers/scsi/libfc/fc_npiv.c b/drivers/scsi/libfc/fc_npiv.c
index dd2b43bb1c7..076cd5ff0e4 100644
--- a/drivers/scsi/libfc/fc_npiv.c
+++ b/drivers/scsi/libfc/fc_npiv.c
@@ -86,6 +86,7 @@ struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id)
86 86
87 return lport; 87 return lport;
88} 88}
89EXPORT_SYMBOL(fc_vport_id_lookup);
89 90
90/* 91/*
91 * When setting the link state of vports during an lport state change, it's 92 * When setting the link state of vports during an lport state change, it's
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 9ded6123ff6..59b16bbb66a 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -145,8 +145,10 @@ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport,
145 rdata->maxframe_size = FC_MIN_MAX_PAYLOAD; 145 rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
146 INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout); 146 INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
147 INIT_WORK(&rdata->event_work, fc_rport_work); 147 INIT_WORK(&rdata->event_work, fc_rport_work);
148 if (port_id != FC_FID_DIR_SERV) 148 if (port_id != FC_FID_DIR_SERV) {
149 rdata->lld_event_callback = lport->tt.rport_event_callback;
149 list_add_rcu(&rdata->peers, &lport->disc.rports); 150 list_add_rcu(&rdata->peers, &lport->disc.rports);
151 }
150 return rdata; 152 return rdata;
151} 153}
152 154
@@ -302,6 +304,10 @@ static void fc_rport_work(struct work_struct *work)
302 FC_RPORT_DBG(rdata, "callback ev %d\n", event); 304 FC_RPORT_DBG(rdata, "callback ev %d\n", event);
303 rport_ops->event_callback(lport, rdata, event); 305 rport_ops->event_callback(lport, rdata, event);
304 } 306 }
307 if (rdata->lld_event_callback) {
308 FC_RPORT_DBG(rdata, "lld callback ev %d\n", event);
309 rdata->lld_event_callback(lport, rdata, event);
310 }
305 kref_put(&rdata->kref, lport->tt.rport_destroy); 311 kref_put(&rdata->kref, lport->tt.rport_destroy);
306 break; 312 break;
307 313
@@ -324,6 +330,10 @@ static void fc_rport_work(struct work_struct *work)
324 FC_RPORT_DBG(rdata, "callback ev %d\n", event); 330 FC_RPORT_DBG(rdata, "callback ev %d\n", event);
325 rport_ops->event_callback(lport, rdata, event); 331 rport_ops->event_callback(lport, rdata, event);
326 } 332 }
333 if (rdata->lld_event_callback) {
334 FC_RPORT_DBG(rdata, "lld callback ev %d\n", event);
335 rdata->lld_event_callback(lport, rdata, event);
336 }
327 cancel_delayed_work_sync(&rdata->retry_work); 337 cancel_delayed_work_sync(&rdata->retry_work);
328 338
329 /* 339 /*
@@ -890,6 +900,9 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
890 rdata->ids.port_name = get_unaligned_be64(&plp->fl_wwpn); 900 rdata->ids.port_name = get_unaligned_be64(&plp->fl_wwpn);
891 rdata->ids.node_name = get_unaligned_be64(&plp->fl_wwnn); 901 rdata->ids.node_name = get_unaligned_be64(&plp->fl_wwnn);
892 902
903 /* save plogi response sp_features for further reference */
904 rdata->sp_features = ntohs(plp->fl_csp.sp_features);
905
893 if (lport->point_to_multipoint) 906 if (lport->point_to_multipoint)
894 fc_rport_login_complete(rdata, fp); 907 fc_rport_login_complete(rdata, fp);
895 csp_seq = ntohs(plp->fl_csp.sp_tot_seq); 908 csp_seq = ntohs(plp->fl_csp.sp_tot_seq);
@@ -997,6 +1010,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
997 resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK); 1010 resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK);
998 FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x\n", 1011 FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x\n",
999 pp->spp.spp_flags); 1012 pp->spp.spp_flags);
1013 rdata->spp_type = pp->spp.spp_type;
1000 if (resp_code != FC_SPP_RESP_ACK) { 1014 if (resp_code != FC_SPP_RESP_ACK) {
1001 if (resp_code == FC_SPP_RESP_CONF) 1015 if (resp_code == FC_SPP_RESP_CONF)
1002 fc_rport_error(rdata, fp); 1016 fc_rport_error(rdata, fp);
@@ -1010,6 +1024,8 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
1010 fcp_parm = ntohl(pp->spp.spp_params); 1024 fcp_parm = ntohl(pp->spp.spp_params);
1011 if (fcp_parm & FCP_SPPF_RETRY) 1025 if (fcp_parm & FCP_SPPF_RETRY)
1012 rdata->flags |= FC_RP_FLAGS_RETRY; 1026 rdata->flags |= FC_RP_FLAGS_RETRY;
1027 if (fcp_parm & FCP_SPPF_CONF_COMPL)
1028 rdata->flags |= FC_RP_FLAGS_CONF_REQ;
1013 1029
1014 prov = fc_passive_prov[FC_TYPE_FCP]; 1030 prov = fc_passive_prov[FC_TYPE_FCP];
1015 if (prov) { 1031 if (prov) {
@@ -1719,6 +1735,7 @@ static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
1719 spp = &pp->spp; 1735 spp = &pp->spp;
1720 mutex_lock(&fc_prov_mutex); 1736 mutex_lock(&fc_prov_mutex);
1721 while (len >= plen) { 1737 while (len >= plen) {
1738 rdata->spp_type = rspp->spp_type;
1722 spp->spp_type = rspp->spp_type; 1739 spp->spp_type = rspp->spp_type;
1723 spp->spp_type_ext = rspp->spp_type_ext; 1740 spp->spp_type_ext = rspp->spp_type_ext;
1724 resp = 0; 1741 resp = 0;