aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/scsi/libfc/fc_npiv.c1
-rw-r--r--drivers/scsi/libfc/fc_rport.c19
-rw-r--r--include/scsi/libfc.h15
3 files changed, 34 insertions, 1 deletions
diff --git a/drivers/scsi/libfc/fc_npiv.c b/drivers/scsi/libfc/fc_npiv.c
index dd2b43bb1c70..076cd5ff0e40 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 9ded6123ff6d..59b16bbb66a3 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;
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 6d64e44bc3bf..24193c1b0da0 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -158,6 +158,7 @@ struct fc_rport_libfc_priv {
158 #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) 158 #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0)
159 #define FC_RP_FLAGS_RETRY (1 << 1) 159 #define FC_RP_FLAGS_RETRY (1 << 1)
160 #define FC_RP_STARTED (1 << 2) 160 #define FC_RP_STARTED (1 << 2)
161 #define FC_RP_FLAGS_CONF_REQ (1 << 3)
161 unsigned int e_d_tov; 162 unsigned int e_d_tov;
162 unsigned int r_a_tov; 163 unsigned int r_a_tov;
163}; 164};
@@ -207,6 +208,11 @@ struct fc_rport_priv {
207 u32 supported_classes; 208 u32 supported_classes;
208 u16 prli_count; 209 u16 prli_count;
209 struct rcu_head rcu; 210 struct rcu_head rcu;
211 u16 sp_features;
212 u8 spp_type;
213 void (*lld_event_callback)(struct fc_lport *,
214 struct fc_rport_priv *,
215 enum fc_rport_event);
210}; 216};
211 217
212/** 218/**
@@ -677,6 +683,15 @@ struct libfc_function_template {
677 void (*rport_destroy)(struct kref *); 683 void (*rport_destroy)(struct kref *);
678 684
679 /* 685 /*
686 * Callback routine after the remote port is logged in
687 *
688 * STATUS: OPTIONAL
689 */
690 void (*rport_event_callback)(struct fc_lport *,
691 struct fc_rport_priv *,
692 enum fc_rport_event);
693
694 /*
680 * Send a fcp cmd from fsp pkt. 695 * Send a fcp cmd from fsp pkt.
681 * Called with the SCSI host lock unlocked and irqs disabled. 696 * Called with the SCSI host lock unlocked and irqs disabled.
682 * 697 *