[Open-FCoE] [PATCH 1/2] libfc: added destructor callback to exch

Vasu Dev vasu.dev at intel.com
Fri Sep 5 23:05:05 UTC 2008


This destructor callback will allow other non-EM layers to
sync up their exch related resource free along with exch free.
The caller can set this destructor and then this will get
called when exch is about to free.

This will be used by fcp layer in next patch to keep fsp pkt
pointer valid after exch done is called.

Signed-off-by: Vasu Dev <vasu.dev at intel.com>
---

 drivers/scsi/libfc/fc_exch.c  |   30 ++++++++++++++++++++----------
 drivers/scsi/libfc/fc_fcp.c   |    8 ++++----
 drivers/scsi/libfc/fc_lport.c |    4 ++--
 drivers/scsi/libfc/fc_ns.c    |   12 ++++++------
 drivers/scsi/libfc/fc_rport.c |    8 ++++----
 include/scsi/libfc/libfc.h    |   21 ++++++++++++++-------
 6 files changed, 50 insertions(+), 33 deletions(-)


diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 3a630c5..f757923 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -99,7 +99,12 @@ struct fc_exch {
 	 * Handler for responses to this current exchange.
 	 */
 	void		(*resp)(struct fc_seq *, struct fc_frame *, void *);
-	void		*resp_arg;	/* 3rd arg for exchange resp handler */
+	void		(*destructor)(struct fc_seq *, void *);
+	/*
+	 * arg is passed as void pointer to exchange
+	 * resp and destructor handlers
+	 */
+	void		*arg;
 };
 
 /*
@@ -295,6 +300,8 @@ static void fc_exch_release(struct fc_exch *ep)
 
 	if (atomic_dec_and_test(&ep->ex_refcnt)) {
 		mp = ep->em;
+		if (ep->destructor)
+			ep->destructor(&ep->seq, ep->arg);
 		if (ep->lp->tt.exch_put)
 			ep->lp->tt.exch_put(ep->lp, mp, ep->xid);
 		WARN_ON(!ep->esb_stat & ESB_ST_COMPLETE);
@@ -445,7 +452,7 @@ static void fc_exch_timeout(unsigned long ep_arg)
 		goto done;
 	} else {
 		resp = ep->resp;
-		arg = ep->resp_arg;
+		arg = ep->arg;
 		ep->resp = NULL;
 		if (e_stat & ESB_ST_ABNORMAL)
 			rc = fc_exch_done_locked(ep);
@@ -1165,7 +1172,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
 		 * first.
 		 */
 		if (ep->resp)
-			ep->resp(sp, fp, ep->resp_arg);
+			ep->resp(sp, fp, ep->arg);
 		else
 			lp->tt.lport_recv(lp, sp, fp);
 		fc_exch_release(ep);	/* release from lookup */
@@ -1227,7 +1234,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
 	if (fc_sof_needs_ack(sof))
 		fc_seq_send_ack(sp, fp);
 	resp = ep->resp;
-	ex_resp_arg = ep->resp_arg;
+	ex_resp_arg = ep->arg;
 
 	if (fh->fh_type != FC_TYPE_FCP && fr_eof(fp) == FC_EOF_T &&
 	    (f_ctl & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
@@ -1337,7 +1344,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
 	}
 
 	resp = ep->resp;
-	ex_resp_arg = ep->resp_arg;
+	ex_resp_arg = ep->arg;
 
 	/* do we need to do some other checks here. Can we reuse more of
 	 * fc_exch_recv_seq_resp
@@ -1490,7 +1497,7 @@ static void fc_exch_reset(struct fc_exch *ep)
 	if (ep->esb_stat & ESB_ST_REC_QUAL)
 		atomic_dec(&ep->ex_refcnt);	/* drop hold for rec_qual */
 	ep->esb_stat &= ~ESB_ST_REC_QUAL;
-	arg = ep->resp_arg;
+	arg = ep->arg;
 	sp = &ep->seq;
 
 	if (ep->fh_type != FC_TYPE_FCP)
@@ -1706,8 +1713,9 @@ static void fc_exch_rrq(struct fc_exch *ep)
 	did = ep->did;
 	if (ep->esb_stat & ESB_ST_RESP)
 		did = ep->sid;
-	rrq_sp = fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, ep, lp->e_d_tov,
-				  lp->fid, did, FC_FC_SEQ_INIT | FC_FC_END_SEQ);
+	rrq_sp = fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep,
+				  lp->e_d_tov, lp->fid, did,
+				  FC_FC_SEQ_INIT | FC_FC_END_SEQ);
 	if (!rrq_sp) {
 		ep->esb_stat |= ESB_ST_REC_QUAL;
 		fc_exch_timer_set_locked(ep, ep->r_a_tov);
@@ -1850,7 +1858,8 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
 				void (*resp)(struct fc_seq *,
 					     struct fc_frame *fp,
 					     void *arg),
-				void *resp_arg, u32 timer_msec,
+				void (*destructor)(struct fc_seq *, void *),
+				void *arg, u32 timer_msec,
 				u32 sid, u32 did, u32 f_ctl)
 {
 	struct fc_exch *ep;
@@ -1867,7 +1876,8 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
 	ep->esb_stat |= ESB_ST_SEQ_INIT;
 	fc_exch_set_addr(ep, sid, did);
 	ep->resp = resp;
-	ep->resp_arg = resp_arg;
+	ep->destructor = destructor;
+	ep->arg = arg;
 	ep->r_a_tov = FC_DEF_R_A_TOV;
 	ep->lp = lp;
 	sp = &ep->seq;
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 9402eba..358a26b 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1023,7 +1023,7 @@ static int fc_fcp_send_cmd(struct fc_fcp_pkt *fsp)
 	fsp->max_payload = rport->maxframe_size;
 	rp = rport->dd_data;
 	sp = lp->tt.exch_seq_send(lp, fp,
-				  fc_fcp_recv,
+				  fc_fcp_recv, NULL,
 				  fsp, 0,
 				  rp->local_port->fid,
 				  rport->port_id,
@@ -1129,7 +1129,7 @@ static void fc_lun_reset_send(unsigned long data)
 	rport = fsp->rport;
 	rp = rport->dd_data;
 	sp = lp->tt.exch_seq_send(lp, fp,
-				  fc_tm_done,
+				  fc_tm_done, NULL,
 				  fsp, 0,
 				  rp->local_port->fid,
 				  rport->port_id,
@@ -1339,7 +1339,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
 	fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
 	fc_frame_set_offset(fp, 0);
 	sp = lp->tt.exch_seq_send(lp, fp,
-				  fc_fcp_rec_resp,
+				  fc_fcp_rec_resp, NULL,
 				  fsp, jiffies_to_msecs(FC_SCSI_REC_TOV),
 				  rp->local_port->fid,
 				  rport->port_id,
@@ -1594,7 +1594,7 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
 	fc_frame_setup(fp, FC_RCTL_ELS4_REQ, FC_TYPE_FCP);
 	fc_frame_set_offset(fp, 0);
 	sp = lp->tt.exch_seq_send(lp, fp,
-				  fc_fcp_srr_resp,
+				  fc_fcp_srr_resp, NULL,
 				  fsp, jiffies_to_msecs(FC_SCSI_REC_TOV),
 				  rp->local_port->fid,
 				  rport->port_id,
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 1cbc2b4..2c15b21 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -756,7 +756,7 @@ static void fc_lport_enter_logo(struct fc_lport *lp)
 	fc_frame_set_offset(fp, 0);
 
 	lp->tt.exch_seq_send(lp, fp,
-			      fc_lport_logo_resp,
+			      fc_lport_logo_resp, NULL,
 			      lp, lp->e_d_tov,
 			      lp->fid, FC_FID_FLOGI,
 			      FC_FC_SEQ_INIT | FC_FC_END_SEQ);
@@ -860,7 +860,7 @@ static void fc_lport_flogi_send(struct fc_lport *lp)
 	fc_frame_set_offset(fp, 0);
 
 	if (!lp->tt.exch_seq_send(lp, fp,
-				   fc_lport_flogi_resp,
+				   fc_lport_flogi_resp, NULL,
 				   lp, lp->e_d_tov,
 				   0, FC_FID_FLOGI,
 				   FC_FC_SEQ_INIT | FC_FC_END_SEQ))
diff --git a/drivers/scsi/libfc/fc_ns.c b/drivers/scsi/libfc/fc_ns.c
index 6204bcc..783e22d 100644
--- a/drivers/scsi/libfc/fc_ns.c
+++ b/drivers/scsi/libfc/fc_ns.c
@@ -226,7 +226,7 @@ static void fc_ns_enter_scr(struct fc_lport *lp)
 	fc_frame_set_offset(fp, 0);
 
 	lp->tt.exch_seq_send(lp, fp,
-			     fc_ns_scr_resp,
+			     fc_ns_scr_resp, NULL,
 			     lp, lp->e_d_tov,
 			     lp->fid, FC_FID_FCTRL,
 			     FC_FC_SEQ_INIT | FC_FC_END_SEQ);
@@ -269,7 +269,7 @@ static void fc_ns_enter_reg_ft(struct fc_lport *lp)
 			req->fts = *lps;
 			fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
 			if (!lp->tt.exch_seq_send(lp, fp,
-						  fc_ns_resp, lp,
+						  fc_ns_resp, NULL, lp,
 						  lp->e_d_tov,
 						  lp->fid,
 						  lp->dns_rp->port_id,
@@ -684,7 +684,7 @@ static void fc_ns_gpn_ft_req(struct fc_lport *lp)
 
 		fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
 		sp = lp->tt.exch_seq_send(lp, fp,
-					  fc_ns_gpn_ft_resp,
+					  fc_ns_gpn_ft_resp, NULL,
 					  lp, lp->e_d_tov,
 					  lp->fid,
 					  lp->dns_rp->port_id,
@@ -940,7 +940,7 @@ static int fc_ns_gpn_id_req(struct fc_lport *lp, struct fc_ns_port *dp)
 
 	fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
 	if (!lp->tt.exch_seq_send(lp, fp,
-				  fc_ns_gpn_id_resp,
+				  fc_ns_gpn_id_resp, NULL,
 				  dp, lp->e_d_tov,
 				  lp->fid,
 				  lp->dns_rp->port_id,
@@ -1141,7 +1141,7 @@ static void fc_ns_enter_reg_pn(struct fc_lport *lp)
 	put_unaligned_be64(lp->wwpn, &req->rn.fr_wwn);
 	fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
 	if (!lp->tt.exch_seq_send(lp, fp,
-				  fc_ns_resp, lp,
+				  fc_ns_resp, NULL, lp,
 				  lp->e_d_tov,
 				  lp->fid,
 				  lp->dns_rp->port_id,
@@ -1197,7 +1197,7 @@ static int fc_ns_gnn_id_req(struct fc_lport *lp, struct fc_ns_port *dp)
 
 	fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
 	if (!lp->tt.exch_seq_send(lp, fp,
-				  fc_ns_gnn_id_resp,
+				  fc_ns_gnn_id_resp, NULL,
 				  dp, lp->e_d_tov,
 				  lp->fid,
 				  lp->dns_rp->port_id,
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index f751f0e..6dcbdca 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -573,7 +573,7 @@ static void fc_rport_enter_plogi(struct fc_rport *rport)
 	rp->e_d_tov = lp->e_d_tov;
 	fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
 	if (!lp->tt.exch_seq_send(lp, fp,
-				  fc_rport_plogi_resp,
+				  fc_rport_plogi_resp, NULL,
 				  rport, lp->e_d_tov,
 				  rp->local_port->fid,
 				  rport->port_id,
@@ -741,7 +741,7 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
 	pp->spp.spp_params = htonl(rp->local_port->service_params);
 	fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
 	if (!lp->tt.exch_seq_send(lp, fp,
-				  fc_rport_prli_resp,
+				  fc_rport_prli_resp, NULL,
 				  rport, lp->e_d_tov,
 				  rp->local_port->fid,
 				  rport->port_id,
@@ -829,7 +829,7 @@ static void fc_rport_enter_rtv(struct fc_rport *rport)
 	rtv->rtv_cmd = ELS_RTV;
 	fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
 	if (!lp->tt.exch_seq_send(lp, fp,
-				  fc_rport_rtv_resp,
+				  fc_rport_rtv_resp, NULL,
 				  rport, lp->e_d_tov,
 				  rp->local_port->fid,
 				  rport->port_id,
@@ -862,7 +862,7 @@ static void fc_rport_enter_logo(struct fc_rport *rport)
 
 	fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
 	if (!lp->tt.exch_seq_send(lp, fp,
-				  fc_rport_logo_resp,
+				  fc_rport_logo_resp, NULL,
 				  rport, lp->e_d_tov,
 				  rp->local_port->fid,
 				  rport->port_id,
diff --git a/include/scsi/libfc/libfc.h b/include/scsi/libfc/libfc.h
index 104e2a6..e61001b 100644
--- a/include/scsi/libfc/libfc.h
+++ b/include/scsi/libfc/libfc.h
@@ -219,9 +219,12 @@ struct libfc_function_template {
 	 * fc_frame pointer in response handler will also indicate timeout
 	 * as error using IS_ERR related macros.
 	 *
-	 * The response handler argumemt resp_arg is passed back to resp
-	 * handler when it is invoked by EM layer in above mentioned
-	 * two scenarios.
+	 * The exchange destructor handler is also set in this routine.
+	 * The destructor handler is invoked by EM layer when exchange
+	 * is about to free, this can be used by caller to free its
+	 * resources along with exchange free.
+	 *
+	 * The arg is passed back to resp and destructor handler.
 	 *
 	 * The timeout value (in msec) for an exchange is set if non zero
 	 * timer_msec argument is specified. The timer is canceled when
@@ -232,10 +235,12 @@ struct libfc_function_template {
 	 */
 	struct fc_seq *(*exch_seq_send)(struct fc_lport *lp,
 					struct fc_frame *fp,
-					void (*resp)(struct fc_seq *,
+					void (*resp)(struct fc_seq *sp,
 						     struct fc_frame *fp,
 						     void *arg),
-					void *resp_arg,	unsigned int timer_msec,
+					void (*destructor)(struct fc_seq *sp,
+							   void *arg),
+					void *arg, unsigned int timer_msec,
 					u32 sid, u32 did, u32 f_ctl);
 
 	/*
@@ -669,10 +674,12 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
  */
 struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
 				struct fc_frame *fp,
-				void (*resp)(struct fc_seq *,
+				void (*resp)(struct fc_seq *sp,
 					     struct fc_frame *fp,
 					     void *arg),
-				void *resp_arg, u32 timer_msec,
+				void (*destructor)(struct fc_seq *sp,
+						   void *arg),
+				void *arg, u32 timer_msec,
 				u32 sid, u32 did, u32 f_ctl);
 
 /*




More information about the devel mailing list