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

Robert Love robert.w.love at intel.com
Thu Sep 11 23:35:48 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()

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 |   98 +++++++++++++++++++++++------------------
 1 files changed, 54 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index b8a9ab0..3f5d329 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 *);
@@ -439,46 +461,34 @@ 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;
+	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) {
+		if (!fp)
+			delay = msecs_to_jiffies(500);
 		get_device(&rport->dev);
-		schedule_delayed_work(&rp->retry_work, 0);
+		schedule_delayed_work(&rdata->retry_work, delay);
 	} else
 		fc_rport_reject(rport);
-
-	fc_rport_unlock(rport);
 }
 
 /**
@@ -530,7 +540,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
 			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 */
+				fc_rport_error(rport, fp);    /* try again */
 			else
 				fc_rport_reject(rport);   /* error */
 		}
@@ -557,7 +567,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);
@@ -569,7 +579,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);
 }
 
 /**
@@ -711,7 +721,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));
@@ -728,7 +738,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);
 }
 
 /**
@@ -795,7 +805,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));
@@ -807,7 +817,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);
 }
 
 /**
@@ -826,7 +836,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;
@@ -840,7 +850,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