aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
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));