aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
authorKiran Patil <kiran.patil@intel.com>2011-06-20 19:59:30 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 17:30:17 -0400
commite3e65c69c3cfe8e407797c78fd11808aee1a8a81 (patch)
tree7c4991ae5419e5f94c5fb7cfd13945d2e6d28d06 /drivers/scsi/libfc
parent29bdd2bb3e48c742e6b5a0be2ff2fa00e9838fe0 (diff)
[SCSI] libfc:Fix for exchange/seq loopup failure when FCoE stack is used as target and connected to windows initaitor
Problem: Linux based SW target (TCM) connected to windows initiator was unable to satisfy write request of size > 2K. Fix: Existing linux implememtation of FCoE stack is expecting sequence number to match w.r.t incoming framme. When DDP is used on target in response to write request from initiator, SW stack is notified only when last data frame arrives and only the pakcket header of last data frame is posted to NetRx queue of storage. When that last packet was processed in libfc:Exchange layer, implementation was expecting sequence number to match, but in this case sequence number which is embedded in FC Header is assigned by windows initaitor, hence due to sequence number mismatch post-processing which shall result into sending RSP is not done. Enhanced the code to utilize the sequence number of incoming last frame and process the packet so that, it will eventually complete the write request by sending write response (RSP) GOOD. Notes/Dependencies: This patch is validated using windows and linux initiator to make sure, it doesn't break anything. Signed-off-by: Kiran Patil <kiran.patil@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r--drivers/scsi/libfc/fc_exch.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 3b8a6451ea28..f5a0665b6773 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -965,8 +965,30 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
965 sp = &ep->seq; 965 sp = &ep->seq;
966 if (sp->id != fh->fh_seq_id) { 966 if (sp->id != fh->fh_seq_id) {
967 atomic_inc(&mp->stats.seq_not_found); 967 atomic_inc(&mp->stats.seq_not_found);
968 reject = FC_RJT_SEQ_ID; /* sequence/exch should exist */ 968 if (f_ctl & FC_FC_END_SEQ) {
969 goto rel; 969 /*
970 * Update sequence_id based on incoming last
971 * frame of sequence exchange. This is needed
972 * for FCoE target where DDP has been used
973 * on target where, stack is indicated only
974 * about last frame's (payload _header) header.
975 * Whereas "seq_id" which is part of
976 * frame_header is allocated by initiator
977 * which is totally different from "seq_id"
978 * allocated when XFER_RDY was sent by target.
979 * To avoid false -ve which results into not
980 * sending RSP, hence write request on other
981 * end never finishes.
982 */
983 spin_lock_bh(&ep->ex_lock);
984 sp->ssb_stat |= SSB_ST_RESP;
985 sp->id = fh->fh_seq_id;
986 spin_unlock_bh(&ep->ex_lock);
987 } else {
988 /* sequence/exch should exist */
989 reject = FC_RJT_SEQ_ID;
990 goto rel;
991 }
970 } 992 }
971 } 993 }
972 WARN_ON(ep != fc_seq_exch(sp)); 994 WARN_ON(ep != fc_seq_exch(sp));