Commit 50a87414 authored by Chad Dupuis's avatar Chad Dupuis Committed by James Bottomley

bnx2fc: Remove explicit logouts.

Explicit logouts from bnx2fc were causing race conditions in either returning
stale SCSI commands or not allowing a target to log back in.
Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: default avatarChad Dupuis <chad.dupuis@qlogic.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent adcf7dfb
...@@ -303,7 +303,6 @@ struct bnx2fc_rport { ...@@ -303,7 +303,6 @@ struct bnx2fc_rport {
#define BNX2FC_FLAG_OFLD_REQ_CMPL 0x5 #define BNX2FC_FLAG_OFLD_REQ_CMPL 0x5
#define BNX2FC_FLAG_CTX_ALLOC_FAILURE 0x6 #define BNX2FC_FLAG_CTX_ALLOC_FAILURE 0x6
#define BNX2FC_FLAG_UPLD_REQ_COMPL 0x7 #define BNX2FC_FLAG_UPLD_REQ_COMPL 0x7
#define BNX2FC_FLAG_EXPL_LOGO 0x8
#define BNX2FC_FLAG_DISABLE_FAILED 0x9 #define BNX2FC_FLAG_DISABLE_FAILED 0x9
#define BNX2FC_FLAG_ENABLED 0xa #define BNX2FC_FLAG_ENABLED 0xa
......
...@@ -689,8 +689,7 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op, ...@@ -689,8 +689,7 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
rc = -EINVAL; rc = -EINVAL;
goto els_err; goto els_err;
} }
if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) || if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))) {
(test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags))) {
printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op); printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op);
rc = -EINVAL; rc = -EINVAL;
goto els_err; goto els_err;
......
...@@ -40,11 +40,8 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) ...@@ -40,11 +40,8 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
{ {
struct bnx2fc_cmd *io_req = container_of(work, struct bnx2fc_cmd, struct bnx2fc_cmd *io_req = container_of(work, struct bnx2fc_cmd,
timeout_work.work); timeout_work.work);
struct fc_lport *lport;
struct fc_rport_priv *rdata;
u8 cmd_type = io_req->cmd_type; u8 cmd_type = io_req->cmd_type;
struct bnx2fc_rport *tgt = io_req->tgt; struct bnx2fc_rport *tgt = io_req->tgt;
int logo_issued;
int rc; int rc;
BNX2FC_IO_DBG(io_req, "cmd_timeout, cmd_type = %d," BNX2FC_IO_DBG(io_req, "cmd_timeout, cmd_type = %d,"
...@@ -80,25 +77,14 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) ...@@ -80,25 +77,14 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
io_req->refcount.refcount.counter); io_req->refcount.refcount.counter);
if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
&io_req->req_flags))) { &io_req->req_flags))) {
/*
lport = io_req->port->lport; * Cleanup and return original command to
rdata = io_req->tgt->rdata; * mid-layer.
logo_issued = test_and_set_bit( */
BNX2FC_FLAG_EXPL_LOGO, bnx2fc_initiate_cleanup(io_req);
&tgt->flags);
kref_put(&io_req->refcount, bnx2fc_cmd_release); kref_put(&io_req->refcount, bnx2fc_cmd_release);
spin_unlock_bh(&tgt->tgt_lock); spin_unlock_bh(&tgt->tgt_lock);
/* Explicitly logo the target */
if (!logo_issued) {
BNX2FC_IO_DBG(io_req, "Explicit "
"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);
}
return; return;
} }
} else { } else {
...@@ -116,28 +102,10 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) ...@@ -116,28 +102,10 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
rc = bnx2fc_initiate_abts(io_req); rc = bnx2fc_initiate_abts(io_req);
if (rc == SUCCESS) if (rc == SUCCESS)
goto done; goto done;
/*
* Explicitly logo the target if
* abts initiation fails
*/
lport = io_req->port->lport;
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); kref_put(&io_req->refcount, bnx2fc_cmd_release);
spin_unlock_bh(&tgt->tgt_lock); spin_unlock_bh(&tgt->tgt_lock);
if (!logo_issued) {
BNX2FC_IO_DBG(io_req, "Explicit "
"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);
}
return; return;
} else { } else {
BNX2FC_IO_DBG(io_req, "IO already in " BNX2FC_IO_DBG(io_req, "IO already in "
...@@ -152,22 +120,9 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) ...@@ -152,22 +120,9 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
if (!test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, if (!test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
&io_req->req_flags)) { &io_req->req_flags)) {
lport = io_req->port->lport;
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); kref_put(&io_req->refcount, bnx2fc_cmd_release);
spin_unlock_bh(&tgt->tgt_lock); spin_unlock_bh(&tgt->tgt_lock);
/* Explicitly logo the target */
if (!logo_issued) {
BNX2FC_IO_DBG(io_req, "Explicitly logo"
"(els)\n");
mutex_lock(&lport->disc.disc_mutex);
lport->tt.rport_logoff(rdata);
mutex_unlock(&lport->disc.disc_mutex);
}
return; return;
} }
} else { } else {
...@@ -1112,18 +1067,11 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd) ...@@ -1112,18 +1067,11 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET); return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
} }
int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req) int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
{ {
struct bnx2fc_rport *tgt = io_req->tgt; struct bnx2fc_rport *tgt = io_req->tgt;
struct fc_rport_priv *rdata = tgt->rdata;
int logo_issued;
int rc = SUCCESS; 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; io_req->wait_for_comp = 1;
bnx2fc_initiate_cleanup(io_req); bnx2fc_initiate_cleanup(io_req);
...@@ -1136,21 +1084,8 @@ int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req) ...@@ -1136,21 +1084,8 @@ int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req)
* release the reference taken in eh_abort to allow the * release the reference taken in eh_abort to allow the
* target to re-login after flushing IOs * target to re-login after flushing IOs
*/ */
kref_put(&io_req->refcount, bnx2fc_cmd_release); 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); spin_lock_bh(&tgt->tgt_lock);
return rc; return rc;
} }
...@@ -1252,7 +1187,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) ...@@ -1252,7 +1187,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
if (cancel_delayed_work(&io_req->timeout_work)) if (cancel_delayed_work(&io_req->timeout_work))
kref_put(&io_req->refcount, kref_put(&io_req->refcount,
bnx2fc_cmd_release); /* drop timer hold */ bnx2fc_cmd_release); /* drop timer hold */
rc = bnx2fc_expl_logo(lport, io_req); rc = bnx2fc_abts_cleanup(io_req);
/* This only occurs when an task abort was requested while ABTS /* This only occurs when an task abort was requested while ABTS
is in progress. Setting the IO_CLEANUP flag will skip the is in progress. Setting the IO_CLEANUP flag will skip the
RRQ process in the case when the fw generated SCSI_CMD cmpl RRQ process in the case when the fw generated SCSI_CMD cmpl
...@@ -1291,7 +1226,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) ...@@ -1291,7 +1226,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
/* Let the scsi-ml try to recover this command */ /* Let the scsi-ml try to recover this command */
printk(KERN_ERR PFX "abort failed, xid = 0x%x\n", printk(KERN_ERR PFX "abort failed, xid = 0x%x\n",
io_req->xid); io_req->xid);
rc = bnx2fc_expl_logo(lport, io_req); rc = bnx2fc_abts_cleanup(io_req);
goto out; goto out;
} else { } else {
/* /*
......
...@@ -560,12 +560,6 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport, ...@@ -560,12 +560,6 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport,
(hba->num_ofld_sess == 0)) { (hba->num_ofld_sess == 0)) {
wake_up_interruptible(&hba->shutdown_wait); wake_up_interruptible(&hba->shutdown_wait);
} }
if (test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags)) {
printk(KERN_ERR PFX "Relogin to the tgt\n");
mutex_lock(&lport->disc.disc_mutex);
lport->tt.rport_login(rdata);
mutex_unlock(&lport->disc.disc_mutex);
}
mutex_unlock(&hba->hba_mutex); mutex_unlock(&hba->hba_mutex);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment