aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,