[SCSI] libfc: fix indefinite rport restart
authorJoe Eykholt <jeykholt@cisco.com>
Fri, 11 Jun 2010 23:44:57 +0000 (16:44 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Tue, 27 Jul 2010 17:01:53 +0000 (12:01 -0500)
Remote ports were restarting indefinitely after getting
rejects in PRLI.

Fix by adding a counter of restarts and limiting that with
the port login retry limit as well.

Signed-off-by: Joe Eykholt <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/libfc/fc_rport.c
include/scsi/libfc.h

index d385efc68c15bb4fb9db13d866f690a68343fcfe..363cde30c940b3c950d699c70de2664fcf268e90 100644 (file)
@@ -257,6 +257,7 @@ static void fc_rport_work(struct work_struct *work)
        case RPORT_EV_READY:
                ids = rdata->ids;
                rdata->event = RPORT_EV_NONE;
+               rdata->major_retries = 0;
                kref_get(&rdata->kref);
                mutex_unlock(&rdata->rp_mutex);
 
@@ -323,7 +324,10 @@ static void fc_rport_work(struct work_struct *work)
                        if (port_id == FC_FID_DIR_SERV) {
                                rdata->event = RPORT_EV_NONE;
                                mutex_unlock(&rdata->rp_mutex);
-                       } else if (rdata->flags & FC_RP_STARTED) {
+                       } else if ((rdata->flags & FC_RP_STARTED) &&
+                                  rdata->major_retries <
+                                  lport->max_rport_retry_count) {
+                               rdata->major_retries++;
                                rdata->event = RPORT_EV_NONE;
                                FC_RPORT_DBG(rdata, "work restart\n");
                                fc_rport_enter_plogi(rdata);
index db54c4a2d14b128f776c5943c6c83ff136a06f0e..6d78df77dab63bcf013571da2543f694cf910246 100644 (file)
@@ -189,6 +189,7 @@ struct fc_rport_libfc_priv {
  * @disc_id:        The discovery identifier
  * @maxframe_size:  The maximum frame size
  * @retries:        The retry count for the current state
+ * @major_retries:  The retry count for the entire PLOGI/PRLI state machine
  * @e_d_tov:        Error detect timeout value (in msec)
  * @r_a_tov:        Resource allocation timeout value (in msec)
  * @rp_mutex:       The mutex that protects the remote port
@@ -206,6 +207,7 @@ struct fc_rport_priv {
        u16                         disc_id;
        u16                         maxframe_size;
        unsigned int                retries;
+       unsigned int                major_retries;
        unsigned int                e_d_tov;
        unsigned int                r_a_tov;
        struct mutex                rp_mutex;