aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2fc
diff options
context:
space:
mode:
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>2011-10-24 02:23:56 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-30 05:28:55 -0400
commit99cc600cdd6f938633394523447378f7a43f4340 (patch)
treedec41281d61e685201b01da0e655f3833154a1a2 /drivers/scsi/bnx2fc
parentc68bf8eeaa57c852e74adcf597237be149eef830 (diff)
[SCSI] bnx2fc: Handle ABTS timeout during ulp timeout
If the IO and the corresponding ABTS are not responded by a target, cleanup the IO and issue explicit logout when ulp timer expires while waiting for ABTS to complete. Wait for the session to be ready before returning to the SCSI layer. If the session is not ready let the SCSI-ml escalate the error recovery. Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bnx2fc')
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc.h3
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_io.c37
2 files changed, 40 insertions, 0 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 63de1c7cd0c..b843d710688 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -145,6 +145,9 @@
145#define REC_RETRY_COUNT 1 145#define REC_RETRY_COUNT 1
146#define BNX2FC_NUM_ERR_BITS 63 146#define BNX2FC_NUM_ERR_BITS 63
147 147
148#define BNX2FC_RELOGIN_WAIT_TIME 200
149#define BNX2FC_RELOGIN_WAIT_CNT 10
150
148/* bnx2fc driver uses only one instance of fcoe_percpu_s */ 151/* bnx2fc driver uses only one instance of fcoe_percpu_s */
149extern struct fcoe_percpu_s bnx2fc_global; 152extern struct fcoe_percpu_s bnx2fc_global;
150 153
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 0c64d184d73..84a78af83f9 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1103,7 +1103,10 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
1103 struct fc_rport_libfc_priv *rp = rport->dd_data; 1103 struct fc_rport_libfc_priv *rp = rport->dd_data;
1104 struct bnx2fc_cmd *io_req; 1104 struct bnx2fc_cmd *io_req;
1105 struct fc_lport *lport; 1105 struct fc_lport *lport;
1106 struct fc_rport_priv *rdata;
1106 struct bnx2fc_rport *tgt; 1107 struct bnx2fc_rport *tgt;
1108 int logo_issued;
1109 int wait_cnt = 0;
1107 int rc = FAILED; 1110 int rc = FAILED;
1108 1111
1109 1112
@@ -1192,8 +1195,40 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
1192 } else { 1195 } else {
1193 printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) " 1196 printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) "
1194 "already in abts processing\n", io_req->xid); 1197 "already in abts processing\n", io_req->xid);
1198 if (cancel_delayed_work(&io_req->timeout_work))
1199 kref_put(&io_req->refcount,
1200 bnx2fc_cmd_release); /* drop timer hold */
1201 bnx2fc_initiate_cleanup(io_req);
1202
1203 spin_unlock_bh(&tgt->tgt_lock);
1204
1205 wait_for_completion(&io_req->tm_done);
1206
1207 spin_lock_bh(&tgt->tgt_lock);
1208 io_req->wait_for_comp = 0;
1209 rdata = io_req->tgt->rdata;
1210 logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO,
1211 &tgt->flags);
1195 kref_put(&io_req->refcount, bnx2fc_cmd_release); 1212 kref_put(&io_req->refcount, bnx2fc_cmd_release);
1196 spin_unlock_bh(&tgt->tgt_lock); 1213 spin_unlock_bh(&tgt->tgt_lock);
1214
1215 if (!logo_issued) {
1216 BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n",
1217 tgt->flags);
1218 mutex_lock(&lport->disc.disc_mutex);
1219 lport->tt.rport_logoff(rdata);
1220 mutex_unlock(&lport->disc.disc_mutex);
1221 do {
1222 msleep(BNX2FC_RELOGIN_WAIT_TIME);
1223 /*
1224 * If session not recovered, let SCSI-ml
1225 * escalate error recovery.
1226 */
1227 if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT)
1228 return FAILED;
1229 } while (!test_bit(BNX2FC_FLAG_SESSION_READY,
1230 &tgt->flags));
1231 }
1197 return SUCCESS; 1232 return SUCCESS;
1198 } 1233 }
1199 if (rc == FAILED) { 1234 if (rc == FAILED) {
@@ -1275,6 +1310,8 @@ void bnx2fc_process_cleanup_compl(struct bnx2fc_cmd *io_req,
1275 io_req->refcount.refcount.counter, io_req->cmd_type); 1310 io_req->refcount.refcount.counter, io_req->cmd_type);
1276 bnx2fc_scsi_done(io_req, DID_ERROR); 1311 bnx2fc_scsi_done(io_req, DID_ERROR);
1277 kref_put(&io_req->refcount, bnx2fc_cmd_release); 1312 kref_put(&io_req->refcount, bnx2fc_cmd_release);
1313 if (io_req->wait_for_comp)
1314 complete(&io_req->tm_done);
1278} 1315}
1279 1316
1280void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req, 1317void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req,