From f034260db330bb3ffc815fcb682b1c84aca09591 Mon Sep 17 00:00:00 2001 From: Joe Eykholt Date: Fri, 11 Jun 2010 16:44:57 -0700 Subject: [SCSI] libfc: fix indefinite rport restart 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 Signed-off-by: Robert Love Signed-off-by: James Bottomley --- drivers/scsi/libfc/fc_rport.c | 6 +++++- include/scsi/libfc.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index d385efc68c15..363cde30c940 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -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); diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index db54c4a2d14b..6d78df77dab6 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -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; -- cgit v1.2.3