Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 309621
b: refs/heads/master
c: c1bb4f3
h: refs/heads/master
i:
  309619: e5e5ca5
v: v3
  • Loading branch information
Bhanu Prakash Gollapudi authored and James Bottomley committed May 22, 2012
1 parent 43b032b commit 3d47540
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 48 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: de9c05fafc296aa95b58352bad7f23f6199aa90d
refs/heads/master: c1bb4f33de87ad18ace1cf484ed0c78683d933a1
106 changes: 60 additions & 46 deletions trunk/drivers/scsi/bnx2fc/bnx2fc_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,48 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
}

int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req)
{
struct bnx2fc_rport *tgt = io_req->tgt;
struct fc_rport_priv *rdata = tgt->rdata;
int logo_issued;
int rc = SUCCESS;
int wait_cnt = 0;

BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n",
tgt->flags);
logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO,
&tgt->flags);
io_req->wait_for_comp = 1;
bnx2fc_initiate_cleanup(io_req);

spin_unlock_bh(&tgt->tgt_lock);

wait_for_completion(&io_req->tm_done);

io_req->wait_for_comp = 0;
/*
* release the reference taken in eh_abort to allow the
* target to re-login after flushing IOs
*/
kref_put(&io_req->refcount, bnx2fc_cmd_release);

if (!logo_issued) {
clear_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags);
mutex_lock(&lport->disc.disc_mutex);
lport->tt.rport_logoff(rdata);
mutex_unlock(&lport->disc.disc_mutex);
do {
msleep(BNX2FC_RELOGIN_WAIT_TIME);
if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT) {
rc = FAILED;
break;
}
} while (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags));
}
spin_lock_bh(&tgt->tgt_lock);
return rc;
}
/**
* bnx2fc_eh_abort - eh_abort_handler api to abort an outstanding
* SCSI command
Expand All @@ -1103,10 +1145,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
struct fc_rport_libfc_priv *rp = rport->dd_data;
struct bnx2fc_cmd *io_req;
struct fc_lport *lport;
struct fc_rport_priv *rdata;
struct bnx2fc_rport *tgt;
int logo_issued;
int wait_cnt = 0;
int rc = FAILED;


Expand Down Expand Up @@ -1183,58 +1222,31 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
list_add_tail(&io_req->link, &tgt->io_retire_queue);

init_completion(&io_req->tm_done);
io_req->wait_for_comp = 1;

if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) {
/* Cancel the current timer running on this io_req */
if (cancel_delayed_work(&io_req->timeout_work))
kref_put(&io_req->refcount,
bnx2fc_cmd_release); /* drop timer hold */
set_bit(BNX2FC_FLAG_EH_ABORT, &io_req->req_flags);
rc = bnx2fc_initiate_abts(io_req);
} else {
if (test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) {
printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) "
"already in abts processing\n", io_req->xid);
if (cancel_delayed_work(&io_req->timeout_work))
kref_put(&io_req->refcount,
bnx2fc_cmd_release); /* drop timer hold */
bnx2fc_initiate_cleanup(io_req);
rc = bnx2fc_expl_logo(lport, io_req);
goto out;
}

/* Cancel the current timer running on this io_req */
if (cancel_delayed_work(&io_req->timeout_work))
kref_put(&io_req->refcount,
bnx2fc_cmd_release); /* drop timer hold */
set_bit(BNX2FC_FLAG_EH_ABORT, &io_req->req_flags);
io_req->wait_for_comp = 1;
rc = bnx2fc_initiate_abts(io_req);
if (rc == FAILED) {
bnx2fc_initiate_cleanup(io_req);
spin_unlock_bh(&tgt->tgt_lock);

wait_for_completion(&io_req->tm_done);

spin_lock_bh(&tgt->tgt_lock);
io_req->wait_for_comp = 0;
rdata = io_req->tgt->rdata;
logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO,
&tgt->flags);
kref_put(&io_req->refcount, bnx2fc_cmd_release);
spin_unlock_bh(&tgt->tgt_lock);

if (!logo_issued) {
BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n",
tgt->flags);
mutex_lock(&lport->disc.disc_mutex);
lport->tt.rport_logoff(rdata);
mutex_unlock(&lport->disc.disc_mutex);
do {
msleep(BNX2FC_RELOGIN_WAIT_TIME);
/*
* If session not recovered, let SCSI-ml
* escalate error recovery.
*/
if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT)
return FAILED;
} while (!test_bit(BNX2FC_FLAG_SESSION_READY,
&tgt->flags));
}
return SUCCESS;
}
if (rc == FAILED) {
kref_put(&io_req->refcount, bnx2fc_cmd_release);
spin_unlock_bh(&tgt->tgt_lock);
return rc;
goto done;
}
spin_unlock_bh(&tgt->tgt_lock);

Expand All @@ -1247,7 +1259,8 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
/* Let the scsi-ml try to recover this command */
printk(KERN_ERR PFX "abort failed, xid = 0x%x\n",
io_req->xid);
rc = FAILED;
rc = bnx2fc_expl_logo(lport, io_req);
goto out;
} else {
/*
* We come here even when there was a race condition
Expand All @@ -1259,9 +1272,10 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
bnx2fc_scsi_done(io_req, DID_ABORT);
kref_put(&io_req->refcount, bnx2fc_cmd_release);
}

done:
/* release the reference taken in eh_abort */
kref_put(&io_req->refcount, bnx2fc_cmd_release);
out:
spin_unlock_bh(&tgt->tgt_lock);
return rc;
}
Expand Down
11 changes: 10 additions & 1 deletion trunk/drivers/scsi/bnx2fc/bnx2fc_tgt.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,17 @@ void bnx2fc_flush_active_ios(struct bnx2fc_rport *tgt)

BNX2FC_IO_DBG(io_req, "retire_queue flush\n");

if (cancel_delayed_work(&io_req->timeout_work))
if (cancel_delayed_work(&io_req->timeout_work)) {
if (test_and_clear_bit(BNX2FC_FLAG_EH_ABORT,
&io_req->req_flags)) {
/* Handle eh_abort timeout */
BNX2FC_IO_DBG(io_req, "eh_abort for IO "
"in retire_q\n");
if (io_req->wait_for_comp)
complete(&io_req->tm_done);
}
kref_put(&io_req->refcount, bnx2fc_cmd_release);
}

clear_bit(BNX2FC_FLAG_ISSUE_RRQ, &io_req->req_flags);
}
Expand Down

0 comments on commit 3d47540

Please sign in to comment.