diff options
author | Joe Eykholt <jeykholt@cisco.com> | 2010-06-11 19:44:57 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-27 13:01:53 -0400 |
commit | f034260db330bb3ffc815fcb682b1c84aca09591 (patch) | |
tree | 4570860e30b7dfcaedceff905eeb1ab244b1a504 | |
parent | 4b2164d4d212e437c9f080023a67f8f9356d2c4c (diff) |
[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 <jeykholt@cisco.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 6 | ||||
-rw-r--r-- | include/scsi/libfc.h | 2 |
2 files changed, 7 insertions, 1 deletions
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) | |||
257 | case RPORT_EV_READY: | 257 | case RPORT_EV_READY: |
258 | ids = rdata->ids; | 258 | ids = rdata->ids; |
259 | rdata->event = RPORT_EV_NONE; | 259 | rdata->event = RPORT_EV_NONE; |
260 | rdata->major_retries = 0; | ||
260 | kref_get(&rdata->kref); | 261 | kref_get(&rdata->kref); |
261 | mutex_unlock(&rdata->rp_mutex); | 262 | mutex_unlock(&rdata->rp_mutex); |
262 | 263 | ||
@@ -323,7 +324,10 @@ static void fc_rport_work(struct work_struct *work) | |||
323 | if (port_id == FC_FID_DIR_SERV) { | 324 | if (port_id == FC_FID_DIR_SERV) { |
324 | rdata->event = RPORT_EV_NONE; | 325 | rdata->event = RPORT_EV_NONE; |
325 | mutex_unlock(&rdata->rp_mutex); | 326 | mutex_unlock(&rdata->rp_mutex); |
326 | } else if (rdata->flags & FC_RP_STARTED) { | 327 | } else if ((rdata->flags & FC_RP_STARTED) && |
328 | rdata->major_retries < | ||
329 | lport->max_rport_retry_count) { | ||
330 | rdata->major_retries++; | ||
327 | rdata->event = RPORT_EV_NONE; | 331 | rdata->event = RPORT_EV_NONE; |
328 | FC_RPORT_DBG(rdata, "work restart\n"); | 332 | FC_RPORT_DBG(rdata, "work restart\n"); |
329 | fc_rport_enter_plogi(rdata); | 333 | 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 { | |||
189 | * @disc_id: The discovery identifier | 189 | * @disc_id: The discovery identifier |
190 | * @maxframe_size: The maximum frame size | 190 | * @maxframe_size: The maximum frame size |
191 | * @retries: The retry count for the current state | 191 | * @retries: The retry count for the current state |
192 | * @major_retries: The retry count for the entire PLOGI/PRLI state machine | ||
192 | * @e_d_tov: Error detect timeout value (in msec) | 193 | * @e_d_tov: Error detect timeout value (in msec) |
193 | * @r_a_tov: Resource allocation timeout value (in msec) | 194 | * @r_a_tov: Resource allocation timeout value (in msec) |
194 | * @rp_mutex: The mutex that protects the remote port | 195 | * @rp_mutex: The mutex that protects the remote port |
@@ -206,6 +207,7 @@ struct fc_rport_priv { | |||
206 | u16 disc_id; | 207 | u16 disc_id; |
207 | u16 maxframe_size; | 208 | u16 maxframe_size; |
208 | unsigned int retries; | 209 | unsigned int retries; |
210 | unsigned int major_retries; | ||
209 | unsigned int e_d_tov; | 211 | unsigned int e_d_tov; |
210 | unsigned int r_a_tov; | 212 | unsigned int r_a_tov; |
211 | struct mutex rp_mutex; | 213 | struct mutex rp_mutex; |