diff options
author | Bhanu Prakash Gollapudi <bprakash@broadcom.com> | 2011-01-28 19:05:27 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-02-12 12:09:04 -0500 |
commit | 75a2792df296c77004a72056c76628a1f835bc93 (patch) | |
tree | 767bafd5718fc112d440bf3d8d1369eeb1d557e9 | |
parent | acc1a921659561c4ea97eca6e3c2633adecbcd81 (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.c | 1 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 19 | ||||
-rw-r--r-- | include/scsi/libfc.h | 15 |
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 | } |
89 | EXPORT_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 | * |