Signed-off-by: Robert Love <[EMAIL PROTECTED]>
---

 drivers/scsi/libfc/fc_lport.c |  155 ++++++++++++++++++-----------------------
 1 files changed, 67 insertions(+), 88 deletions(-)

diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index c15e37c..4856f5b 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -36,6 +36,8 @@
 
 static int fc_lport_debug;
 
+static void fc_lport_error(struct fc_lport *, struct fc_frame *);
+
 static void fc_lport_enter_flogi(struct fc_lport *);
 static void fc_lport_enter_dns(struct fc_lport *);
 static void fc_lport_enter_reg_pn(struct fc_lport *);
@@ -466,42 +468,10 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
 }
 
 /*
- * re-enter state for retrying a request after a timeout or alloc failure.
- */
-static void fc_lport_enter_retry(struct fc_lport *lport)
-{
-       switch (lport->state) {
-       case LPORT_ST_NONE:
-       case LPORT_ST_READY:
-       case LPORT_ST_RESET:
-               WARN_ON(1);
-               break;
-       case LPORT_ST_FLOGI:
-               fc_lport_enter_flogi(lport);
-               break;
-       case LPORT_ST_DNS:
-               fc_lport_enter_dns(lport);
-               break;
-       case LPORT_ST_REG_PN:
-               fc_lport_enter_reg_pn(lport);
-               break;
-       case LPORT_ST_REG_FT:
-               fc_lport_enter_reg_ft(lport);
-               break;
-       case LPORT_ST_SCR:
-               fc_lport_enter_scr(lport);
-               break;
-       case LPORT_ST_LOGO:
-               fc_lport_enter_logo(lport);
-               break;
-       }
-}
-
-/*
  * enter next state for handling an exchange reject or retry exhaustion
  * in the current state.
  */
-static void fc_lport_enter_reject(struct fc_lport *lport)
+static void fc_lport_reject(struct fc_lport *lport)
 {
        switch (lport->state) {
        case LPORT_ST_NONE:
@@ -519,28 +489,6 @@ static void fc_lport_enter_reject(struct fc_lport *lport)
 }
 
 /*
- * Handle resource allocation problem by retrying in a bit.
- */
-static void fc_lport_retry(struct fc_lport *lport)
-{
-       if (lport->retry_count == 0)
-               FC_DBG("local port %6x alloc failure in state %s "
-                      "- will retry\n", lport->fid, fc_lport_state(lport));
-
-       if (lport->retry_count < lport->max_retry_count) {
-               lport->retry_count++;
-               schedule_delayed_work(&lport->retry_work,
-                                     jiffies +
-                                     msecs_to_jiffies(lport->e_d_tov));
-       } else {
-               FC_DBG("local port %6x alloc failure in state %s "
-                      "- retries exhausted\n", lport->fid,
-                      fc_lport_state(lport));
-               fc_lport_enter_reject(lport);
-       }
-}
-
-/*
  * A received FLOGI request indicates a point-to-point connection.
  * Accept it with the common service parameters indicating our N port.
  * Set up to do a PLOGI if we have the higher-number WWPN.
@@ -604,7 +552,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
                lport->tt.seq_send(lport, sp, fp, f_ctl);
 
        } else {
-               fc_lport_retry(lport);
+               fc_lport_error(lport, fp);
        }
        fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
                           get_unaligned_be64(&flp->fl_wwnn));
@@ -725,30 +673,34 @@ int fc_lport_enter_reset(struct fc_lport *lport)
 }
 EXPORT_SYMBOL(fc_lport_enter_reset);
 
-/*
- * Handle errors on local port requests.
- * Don't get locks if in RESET state.
- * The only possible errors so far are exchange TIMEOUT and CLOSED (reset).
+/**
+ * fc_lport_error - Handler for any errors
+ * @lport: The fc_lport 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
+ * after the e_d_tov time.
  */
 static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
 {
-       if (lport->state == LPORT_ST_RESET)
-               return;
-
-       fc_lport_lock(lport);
-       if (PTR_ERR(fp) == -FC_EX_TIMEOUT) {
-               if (lport->retry_count < lport->max_retry_count) {
-                       lport->retry_count++;
-                       fc_lport_enter_retry(lport);
-               } else {
-                       fc_lport_enter_reject(lport);
-
-               }
-       }
+       unsigned long delay = 0;
        if (fc_lport_debug)
-               FC_DBG("error %ld retries %d limit %d\n",
-                      PTR_ERR(fp), lport->retry_count, lport->max_retry_count);
-       fc_lport_unlock(lport);
+               FC_DBG("Error %ld in state %s, retries %d\n",
+                      PTR_ERR(fp), fc_lport_state(lport),
+                      lport->retry_count);
+
+       if (lport->retry_count < lport->max_retry_count) {
+               lport->retry_count++;
+               if (!fp)
+                       delay = msecs_to_jiffies(500);
+               else
+                       delay = jiffies +
+                               msecs_to_jiffies(lport->e_d_tov);
+       
+               schedule_delayed_work(&lport->retry_work, delay);
+       } else
+               fc_lport_reject(lport);
 }
 
 /*
@@ -769,7 +721,7 @@ static void fc_lport_ns_resp(struct fc_seq *sp, struct 
fc_frame *fp,
                                fc_lport_enter_scr(lport);
 
                } else {
-                       fc_lport_retry(lport);
+                       fc_lport_error(lport, fp);
                }
                fc_lport_unlock(lport);
                fc_frame_free(fp);
@@ -877,9 +829,9 @@ static void fc_lport_enter_reg_ft(struct fc_lport *lport)
                                                     FC_FID_DIR_SERV,
                                                     FC_FC_SEQ_INIT |
                                                     FC_FC_END_SEQ))
-                               fc_lport_retry(lport);
+                               fc_lport_error(lport, fp);
                } else {
-                       fc_lport_retry(lport);
+                       fc_lport_error(lport, fp);
                }
        } else {
                fc_lport_enter_scr(lport);
@@ -903,7 +855,7 @@ static void fc_lport_enter_reg_pn(struct fc_lport *lport)
        fc_lport_state_enter(lport, LPORT_ST_REG_PN);
        fp = fc_frame_alloc(lport, sizeof(*req));
        if (!fp) {
-               fc_lport_retry(lport);
+               fc_lport_error(lport, fp);
                return;
        }
        req = fc_frame_payload_get(fp, sizeof(*req));
@@ -918,7 +870,7 @@ static void fc_lport_enter_reg_pn(struct fc_lport *lport)
                                     lport->fid,
                                     FC_FID_DIR_SERV,
                                     FC_FC_SEQ_INIT | FC_FC_END_SEQ))
-               fc_lport_retry(lport);
+               fc_lport_error(lport, fp);
 }
 
 /*
@@ -966,13 +918,14 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
        }
        return;
 
-       /*
-        * Resource allocation problem (malloc).  Try again in 500 mS.
-        */
 err:
-       fc_lport_retry(lport);
+       fc_lport_error(lport, NULL);
 }
 
+/**
+ * fc_lport_timeout - Handler for the retry_work timer.
+ * @work: The work struct of the fc_lport
+ */
 static void fc_lport_timeout(struct work_struct *work)
 {
        struct fc_lport *lport =
@@ -980,7 +933,33 @@ static void fc_lport_timeout(struct work_struct *work)
                             retry_work.work);
        
        fc_lport_lock(lport);
-       fc_lport_enter_retry(lport);
+
+       switch (lport->state) {
+       case LPORT_ST_NONE:
+       case LPORT_ST_READY:
+       case LPORT_ST_RESET:
+               WARN_ON(1);
+               break;
+       case LPORT_ST_FLOGI:
+               fc_lport_enter_flogi(lport);
+               break;
+       case LPORT_ST_DNS:
+               fc_lport_enter_dns(lport);
+               break;
+       case LPORT_ST_REG_PN:
+               fc_lport_enter_reg_pn(lport);
+               break;
+       case LPORT_ST_REG_FT:
+               fc_lport_enter_reg_ft(lport);
+               break;
+       case LPORT_ST_SCR:
+               fc_lport_enter_scr(lport);
+               break;
+       case LPORT_ST_LOGO:
+               fc_lport_enter_logo(lport);
+               break;
+       }
+       
        fc_lport_unlock(lport);
 }
 
@@ -1117,7 +1096,7 @@ static void fc_lport_flogi_send(struct fc_lport *lport)
 
        fp = fc_frame_alloc(lport, sizeof(*flp));
        if (!fp)
-               return fc_lport_retry(lport);
+               return fc_lport_error(lport, fp);
 
        flp = fc_frame_payload_get(fp, sizeof(*flp));
        fc_lport_flogi_fill(lport, flp, ELS_FLOGI);
@@ -1130,7 +1109,7 @@ static void fc_lport_flogi_send(struct fc_lport *lport)
                                     lport, lport->e_d_tov,
                                     0, FC_FID_FLOGI,
                                     FC_FC_SEQ_INIT | FC_FC_END_SEQ))
-               fc_lport_retry(lport);
+               fc_lport_error(lport, fp);
 }
 
 void fc_lport_enter_flogi(struct fc_lport *lport)

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to