diff options
author | Yi Zou <yi.zou@intel.com> | 2012-07-06 13:40:31 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-07-20 03:58:56 -0400 |
commit | a752359f2b0a291c5f229e883842e4b30c698387 (patch) | |
tree | 6ead324702ca37a69af584be38f31e6d5ecb9f83 | |
parent | ac166d2fbd2d0c295454bcee7b3c930cb96e72cc (diff) |
[SCSI] libfc: fix sending REC after FCP_RESP is received
This is exposed in the case the FCP_DATA frames somehow got lost and fc_fcp got
the FCP_RSP, in fc_fcp_recv_resp(), since xfer_len is less than the expected_len
it resets the the timer to wait to 2 more jiffies in case the data frames are
already queued locally. However, for target does not support REC, it would just
send RJT w/ ELS_RJT_UNSUP. The rec response handler thus only clears the rport
flag for not doing REC later, but does not do fcp_io_complete() on the
associated fsp.
The fix is just check status of FCP_RSP being received already, i.e. using the
FC_SRB_RCV_STATUS flag, in fc_fcp_timeout before start sending REC. We should
have waited long enough if there is truely data frames queued locally.
Signed-off-by: Yi Zou <yi.zou@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/libfc/fc_fcp.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 3c96e9300d00..14243fa5f8e8 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
@@ -1380,10 +1380,10 @@ static void fc_fcp_timeout(unsigned long data) | |||
1380 | 1380 | ||
1381 | fsp->state |= FC_SRB_FCP_PROCESSING_TMO; | 1381 | fsp->state |= FC_SRB_FCP_PROCESSING_TMO; |
1382 | 1382 | ||
1383 | if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED) | 1383 | if (fsp->state & FC_SRB_RCV_STATUS) |
1384 | fc_fcp_rec(fsp); | ||
1385 | else if (fsp->state & FC_SRB_RCV_STATUS) | ||
1386 | fc_fcp_complete_locked(fsp); | 1384 | fc_fcp_complete_locked(fsp); |
1385 | else if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED) | ||
1386 | fc_fcp_rec(fsp); | ||
1387 | else | 1387 | else |
1388 | fc_fcp_recovery(fsp, FC_TIMED_OUT); | 1388 | fc_fcp_recovery(fsp, FC_TIMED_OUT); |
1389 | fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO; | 1389 | fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO; |