[Open-FCoE] [PATCH 08/28] libfc: merge all error functions, retry and reject

Robert Love robert.w.love at intel.com
Tue Sep 30 18:25:29 UTC 2008


merges the following into fc_rport_error()
 fc_rport_gnn_id_error()
 fc_rport_gpn_id_error()
 fc_rport_ns_error()
 fc_rport_retry()
 fc_rport_error()
 fc_rport_reject()

Also creates a small function to return a string for
a given rport state so that we can print some debug
statements.

Signed-off-by: Robert Love <robert.w.love at intel.com>
---

 drivers/scsi/libfc/fc_rport.c |  201 ++++++++++++++++++-----------------------
 1 files changed, 89 insertions(+), 112 deletions(-)

diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 22ecd29..3037ffe 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -36,14 +36,12 @@
 
 static int fc_rp_debug;
 
-/*
- * static functions.
- */
 static void fc_rport_enter_plogi(struct fc_rport *);
 static void fc_rport_enter_prli(struct fc_rport *);
 static void fc_rport_enter_rtv(struct fc_rport *);
 static void fc_rport_enter_ready(struct fc_rport *);
 static void fc_rport_enter_logo(struct fc_rport *);
+
 static void fc_rport_recv_plogi_req(struct fc_rport *,
 				    struct fc_seq *, struct fc_frame *);
 static void fc_rport_recv_prli_req(struct fc_rport *,
@@ -53,6 +51,30 @@ static void fc_rport_recv_prlo_req(struct fc_rport *,
 static void fc_rport_recv_logo_req(struct fc_rport *,
 				   struct fc_seq *, struct fc_frame *);
 static void fc_rport_timeout(struct work_struct *);
+static void fc_rport_error(struct fc_rport *, struct fc_frame *);
+
+static const char *fc_rport_state_names[] = {
+	[RPORT_ST_NONE] = "None",
+	[RPORT_ST_INIT] = "Init",
+	[RPORT_ST_PLOGI] = "PLOGI",
+	[RPORT_ST_PLOGI_RECV] = "PLOGI recv",
+	[RPORT_ST_PRLI] = "PRLI",
+	[RPORT_ST_RTV] = "RTV",
+	[RPORT_ST_READY] = "Ready",
+	[RPORT_ST_ERROR] = "Error",
+	[RPORT_ST_LOGO] = "LOGO",
+};
+
+static const char *fc_rport_state(struct fc_rport *rp)
+{
+	const char *cp;
+	struct fc_rport_libfc_priv *rpp = rp->dd_data;
+
+	cp = fc_rport_state_names[rpp->rp_state];
+	if (!cp)
+		cp = "Unknown";
+	return cp;
+}
 
 static struct fc_rport *fc_remote_port_create(struct fc_lport *,
 					      struct fc_rport_identifiers *);
@@ -360,67 +382,13 @@ static void fc_rport_enter_ready(struct fc_rport *rport)
 		rdata->event_callback(lport, rport, LPORT_EV_RPORT_CREATED);
 }
 
-/*
- * Handle exchange reject or retry exhaustion in various states.
- */
-static void fc_rport_reject(struct fc_rport *rport)
-{
-	struct fc_rport_libfc_priv *rp = rport->dd_data;
-	struct fc_lport *lp = rp->local_port;
-	switch (rp->rp_state) {
-	case RPORT_ST_PLOGI:
-	case RPORT_ST_PRLI:
-		fc_rport_state_enter(rport, RPORT_ST_ERROR);
-		if (rport == lp->dns_rp &&
-		    lp->state != LPORT_ST_RESET) {
-			fc_lport_lock(lp);
-			del_timer(&lp->state_timer);
-			lp->dns_rp = NULL;
-			if (lp->state == LPORT_ST_DNS_STOP) {
-				fc_lport_unlock(lp);
-				lp->tt.lport_logout(lp);
-			} else {
-				lp->tt.lport_login(lp);
-				fc_lport_unlock(lp);
-			}
-			fc_remote_port_delete(rport);
-		}
-		break;
-	case RPORT_ST_RTV:
-		fc_rport_enter_ready(rport);
-		break;
-	case RPORT_ST_LOGO:
-		fc_rport_state_enter(rport, RPORT_ST_INIT);
-		if (fc_rp_debug)
-			FC_DBG("remote %6x closed\n", rport->port_id);
-		if (rport == lp->dns_rp &&
-		    lp->state != LPORT_ST_RESET) {
-			fc_lport_lock(lp);
-			del_timer(&lp->state_timer);
-			lp->dns_rp = NULL;
-			if (lp->state == LPORT_ST_DNS_STOP) {
-				fc_lport_unlock(lp);
-				lp->tt.lport_logout(lp);
-			} else {
-				lp->tt.lport_login(lp);
-				fc_lport_unlock(lp);
-			}
-			fc_remote_port_delete(rport);
-		}
-		break;
-	case RPORT_ST_NONE:
-	case RPORT_ST_READY:
-	case RPORT_ST_ERROR:
-	case RPORT_ST_PLOGI_RECV:
-	case RPORT_ST_INIT:
-		BUG();
-		break;
-	}
-	return;
-}
-
-/*
- * Timeout handler for retrying after allocation failures or exchange timeout.
+/**
+ * fc_rport_timeout - Handler for the retry_work timer.
+ *  Simply determine what should be done next.
+ * @work: The work struct of the fc_rport_libfc_priv
+ *
+ * Locking Note: This is an action function so we grab the
+ * lock, call an _enter_* state and then unlock.
  */
 static void fc_rport_timeout(struct work_struct *work)
 {
@@ -453,46 +421,61 @@ static void fc_rport_timeout(struct work_struct *work)
 	put_device(&rport->dev);
 }
 
-/*
- * Handle retry for allocation failure via timeout.
- */
-static void fc_rport_retry(struct fc_rport *rport)
-{
-	struct fc_rport_libfc_priv *rp = rport->dd_data;
-	struct fc_lport *lp = rp->local_port;
-
-	if (rp->retries < lp->max_retry_count) {
-		rp->retries++;
-		get_device(&rport->dev);
-		schedule_delayed_work(&rp->retry_work,
-				      msecs_to_jiffies(rp->e_d_tov));
-	} else {
-		FC_DBG("sess %6x alloc failure in state %d, "
-		       "retries exhausted\n",
-		       rport->port_id, rp->rp_state);
-		fc_rport_reject(rport);
-	}
-}
-
-/*
- * Handle error from a sequence issued by the rport state machine.
+/**
+ * fc_rport_error - Handler for any errors
+ * @rp: The fc_rport object
+ * @fp: The frame pointer
+ *
+ * If the error was caused by a resource allocation failure
+ * then wait for half a second and retry, otherwise retry
+ * immediately.
+ *
+ * Locking Note: The lock is expect to be held before calling
+ * this routine
  */
 static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
 {
-	struct fc_rport_libfc_priv *rp = rport->dd_data;
-	fc_rport_lock(rport);
+	struct fc_rport_libfc_priv *rdata = rport->dd_data;
+	struct fc_lport *lport = rdata->local_port;
+	unsigned long delay = 0;
+
 	if (fc_rp_debug)
-		FC_DBG("state %d error %ld retries %d\n",
-		       rp->rp_state, PTR_ERR(fp), rp->retries);
+		FC_DBG("Error %ld in state %s, retries %d\n",
+		       PTR_ERR(fp), fc_rport_state(rport), rdata->retries);
 
-	if (PTR_ERR(fp) == -FC_EX_TIMEOUT &&
-	    rp->retries++ >= rp->local_port->max_retry_count) {
+	if (rdata->retries < rdata->local_port->max_retry_count) {
+		rdata->retries++;
+		if (!fp)
+			delay = msecs_to_jiffies(500);
 		get_device(&rport->dev);
-		schedule_delayed_work(&rp->retry_work, 0);
-	} else
-		fc_rport_reject(rport);
+		schedule_delayed_work(&rdata->retry_work, delay);
+	} else {
+		switch (rdata->rp_state) {
+		case RPORT_ST_PLOGI:
+		case RPORT_ST_PRLI:
+		case RPORT_ST_LOGO:
+			if (fc_rp_debug)
+				FC_DBG("Remote port (%6x) closed.\n",
+				       rport->port_id);
 
-	fc_rport_unlock(rport);
+			fc_remote_port_delete(rport);
+
+			if (rdata->event_callback)
+				rdata->event_callback(lport, rport,
+						      LPORT_EV_RPORT_FAILED);
+			break;
+		case RPORT_ST_RTV:
+			fc_rport_enter_ready(rport);
+			break;
+		case RPORT_ST_NONE:
+		case RPORT_ST_READY:
+		case RPORT_ST_ERROR:
+		case RPORT_ST_PLOGI_RECV:
+		case RPORT_ST_INIT:
+			BUG();
+			break;
+		}
+	}
 }
 
 /**
@@ -504,7 +487,6 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
 static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
 				void *rp_arg)
 {
-	struct fc_els_ls_rjt *rjp;
 	struct fc_els_flogi *plp;
 	u64 wwpn, wwnn;
 	unsigned int tov;
@@ -541,12 +523,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
 			if (fc_rp_debug)
 				FC_DBG("bad PLOGI response\n");
 
-			rjp = fc_frame_payload_get(fp, sizeof(*rjp));
-			if (op == ELS_LS_RJT && rjp != NULL &&
-			    rjp->er_reason == ELS_RJT_INPROG)
-				fc_rport_retry(rport);    /* try again */
-			else
-				fc_rport_reject(rport);   /* error */
+			fc_rport_error(rport, fp);
 		}
 		fc_rport_unlock(rport);
 		fc_frame_free(fp);
@@ -571,7 +548,7 @@ static void fc_rport_enter_plogi(struct fc_rport *rport)
 	rport->maxframe_size = FC_MIN_MAX_PAYLOAD;
 	fp = fc_frame_alloc(lp, sizeof(*plogi));
 	if (!fp)
-		return fc_rport_retry(rport);
+		return fc_rport_error(rport, fp);
 	plogi = fc_frame_payload_get(fp, sizeof(*plogi));
 	WARN_ON(!plogi);
 	fc_lport_plogi_fill(rp->local_port, plogi, ELS_PLOGI);
@@ -583,7 +560,7 @@ static void fc_rport_enter_plogi(struct fc_rport *rport)
 				  rp->local_port->fid,
 				  rport->port_id,
 				  FC_FC_SEQ_INIT | FC_FC_END_SEQ))
-		fc_rport_retry(rport);
+		fc_rport_error(rport, fp);
 }
 
 /**
@@ -725,7 +702,7 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
 	}
 	fp = fc_frame_alloc(lp, sizeof(*pp));
 	if (!fp)
-		return fc_rport_retry(rport);
+		return fc_rport_error(rport, fp);
 	pp = fc_frame_payload_get(fp, sizeof(*pp));
 	WARN_ON(!pp);
 	memset(pp, 0, sizeof(*pp));
@@ -742,7 +719,7 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
 				  rp->local_port->fid,
 				  rport->port_id,
 				  FC_FC_SEQ_INIT | FC_FC_END_SEQ))
-		fc_rport_retry(rport);
+		fc_rport_error(rport, fp);
 }
 
 /**
@@ -809,7 +786,7 @@ static void fc_rport_enter_rtv(struct fc_rport *rport)
 
 	fp = fc_frame_alloc(lp, sizeof(*rtv));
 	if (!fp)
-		return fc_rport_retry(rport);
+		return fc_rport_error(rport, fp);
 	rtv = fc_frame_payload_get(fp, sizeof(*rtv));
 	WARN_ON(!rtv);
 	memset(rtv, 0, sizeof(*rtv));
@@ -821,7 +798,7 @@ static void fc_rport_enter_rtv(struct fc_rport *rport)
 				  rp->local_port->fid,
 				  rport->port_id,
 				  FC_FC_SEQ_INIT | FC_FC_END_SEQ))
-		fc_rport_retry(rport);
+		fc_rport_error(rport, fp);
 }
 
 /**
@@ -840,7 +817,7 @@ static void fc_rport_enter_logo(struct fc_rport *rport)
 	lp = rp->local_port;
 	fp = fc_frame_alloc(lp, sizeof(*logo));
 	if (!fp)
-		return fc_rport_retry(rport);
+		return fc_rport_error(rport, fp);
 	logo = fc_frame_payload_get(fp, sizeof(*logo));
 	memset(logo, 0, sizeof(*logo));
 	logo->fl_cmd = ELS_LOGO;
@@ -854,7 +831,7 @@ static void fc_rport_enter_logo(struct fc_rport *rport)
 				  rp->local_port->fid,
 				  rport->port_id,
 				  FC_FC_SEQ_INIT | FC_FC_END_SEQ))
-		fc_rport_retry(rport);
+		fc_rport_error(rport, fp);
 }
 
 /*




More information about the devel mailing list