diff options
Diffstat (limited to 'drivers/scsi/bnx2fc/bnx2fc_io.c')
| -rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_io.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 0c64d184d731..84a78af83f90 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 | ||
| 1280 | void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req, | 1317 | void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req, |
