Commit 6a137a96 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Martin K. Petersen

scsi: bnx2fc: Do not rely on a SCSI command for LUN or target reset

When a LUN or target reset is issued, we should not rely on a SCSI command
to be present; we'll have to reset the entire device or target anyway.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Link: https://lore.kernel.org/r/20231002154328.43718-6-hare@suse.de
Cc: Saurav Kashyap <skashyap@marvell.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent ade4fb94
...@@ -384,6 +384,7 @@ struct bnx2fc_rport { ...@@ -384,6 +384,7 @@ struct bnx2fc_rport {
}; };
struct bnx2fc_mp_req { struct bnx2fc_mp_req {
u64 tm_lun;
u8 tm_flags; u8 tm_flags;
u32 req_len; u32 req_len;
......
...@@ -1709,7 +1709,8 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req, ...@@ -1709,7 +1709,8 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
struct fcoe_cached_sge_ctx *cached_sge; struct fcoe_cached_sge_ctx *cached_sge;
struct fcoe_ext_mul_sges_ctx *sgl; struct fcoe_ext_mul_sges_ctx *sgl;
int dev_type = tgt->dev_type; int dev_type = tgt->dev_type;
u64 *fcp_cmnd; struct fcp_cmnd *fcp_cmnd;
u64 *raw_fcp_cmnd;
u64 tmp_fcp_cmnd[4]; u64 tmp_fcp_cmnd[4];
u32 context_id; u32 context_id;
int cnt, i; int cnt, i;
...@@ -1778,16 +1779,19 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req, ...@@ -1778,16 +1779,19 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
task->txwr_rxrd.union_ctx.tx_seq.ctx.seq_cnt = 1; task->txwr_rxrd.union_ctx.tx_seq.ctx.seq_cnt = 1;
/* Fill FCP_CMND IU */ /* Fill FCP_CMND IU */
fcp_cmnd = (u64 *) fcp_cmnd = (struct fcp_cmnd *)&tmp_fcp_cmnd;
bnx2fc_build_fcp_cmnd(io_req, fcp_cmnd);
int_to_scsilun(sc_cmd->device->lun, &fcp_cmnd->fc_lun);
memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);
raw_fcp_cmnd = (u64 *)
task->txwr_rxrd.union_ctx.fcp_cmd.opaque; task->txwr_rxrd.union_ctx.fcp_cmd.opaque;
bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)&tmp_fcp_cmnd);
/* swap fcp_cmnd */ /* swap fcp_cmnd */
cnt = sizeof(struct fcp_cmnd) / sizeof(u64); cnt = sizeof(struct fcp_cmnd) / sizeof(u64);
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
*fcp_cmnd = cpu_to_be64(tmp_fcp_cmnd[i]); *raw_fcp_cmnd = cpu_to_be64(tmp_fcp_cmnd[i]);
fcp_cmnd++; raw_fcp_cmnd++;
} }
/* Rx Write Tx Read */ /* Rx Write Tx Read */
......
...@@ -656,10 +656,9 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req) ...@@ -656,10 +656,9 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req)
return SUCCESS; return SUCCESS;
} }
static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) static int bnx2fc_initiate_tmf(struct fc_lport *lport, struct fc_rport *rport,
u64 tm_lun, u8 tm_flags)
{ {
struct fc_lport *lport;
struct fc_rport *rport;
struct fc_rport_libfc_priv *rp; struct fc_rport_libfc_priv *rp;
struct fcoe_port *port; struct fcoe_port *port;
struct bnx2fc_interface *interface; struct bnx2fc_interface *interface;
...@@ -668,7 +667,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) ...@@ -668,7 +667,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
struct bnx2fc_mp_req *tm_req; struct bnx2fc_mp_req *tm_req;
struct fcoe_task_ctx_entry *task; struct fcoe_task_ctx_entry *task;
struct fcoe_task_ctx_entry *task_page; struct fcoe_task_ctx_entry *task_page;
struct Scsi_Host *host = sc_cmd->device->host;
struct fc_frame_header *fc_hdr; struct fc_frame_header *fc_hdr;
struct fcp_cmnd *fcp_cmnd; struct fcp_cmnd *fcp_cmnd;
int task_idx, index; int task_idx, index;
...@@ -677,8 +675,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) ...@@ -677,8 +675,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
u32 sid, did; u32 sid, did;
unsigned long start = jiffies; unsigned long start = jiffies;
lport = shost_priv(host);
rport = starget_to_rport(scsi_target(sc_cmd->device));
port = lport_priv(lport); port = lport_priv(lport);
interface = port->priv; interface = port->priv;
...@@ -689,7 +685,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) ...@@ -689,7 +685,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
} }
rp = rport->dd_data; rp = rport->dd_data;
rc = fc_block_scsi_eh(sc_cmd); rc = fc_block_rport(rport);
if (rc) if (rc)
return rc; return rc;
...@@ -718,7 +714,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) ...@@ -718,7 +714,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
goto retry_tmf; goto retry_tmf;
} }
/* Initialize rest of io_req fields */ /* Initialize rest of io_req fields */
io_req->sc_cmd = sc_cmd; io_req->sc_cmd = NULL;
io_req->port = port; io_req->port = port;
io_req->tgt = tgt; io_req->tgt = tgt;
...@@ -736,11 +732,13 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) ...@@ -736,11 +732,13 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
/* Set TM flags */ /* Set TM flags */
io_req->io_req_flags = 0; io_req->io_req_flags = 0;
tm_req->tm_flags = tm_flags; tm_req->tm_flags = tm_flags;
tm_req->tm_lun = tm_lun;
/* Fill FCP_CMND */ /* Fill FCP_CMND */
bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)tm_req->req_buf); bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)tm_req->req_buf);
fcp_cmnd = (struct fcp_cmnd *)tm_req->req_buf; fcp_cmnd = (struct fcp_cmnd *)tm_req->req_buf;
memset(fcp_cmnd->fc_cdb, 0, sc_cmd->cmd_len); int_to_scsilun(tm_lun, &fcp_cmnd->fc_lun);
memset(fcp_cmnd->fc_cdb, 0, BNX2FC_MAX_CMD_LEN);
fcp_cmnd->fc_dl = 0; fcp_cmnd->fc_dl = 0;
/* Fill FC header */ /* Fill FC header */
...@@ -763,8 +761,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) ...@@ -763,8 +761,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
task = &(task_page[index]); task = &(task_page[index]);
bnx2fc_init_mp_task(io_req, task); bnx2fc_init_mp_task(io_req, task);
bnx2fc_priv(sc_cmd)->io_req = io_req;
/* Obtain free SQ entry */ /* Obtain free SQ entry */
spin_lock_bh(&tgt->tgt_lock); spin_lock_bh(&tgt->tgt_lock);
bnx2fc_add_2_sq(tgt, xid); bnx2fc_add_2_sq(tgt, xid);
...@@ -1062,7 +1058,10 @@ int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req) ...@@ -1062,7 +1058,10 @@ int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req)
*/ */
int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd) int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd)
{ {
return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_TGT_RESET); struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
struct fc_lport *lport = shost_priv(rport_to_shost(rport));
return bnx2fc_initiate_tmf(lport, rport, 0, FCP_TMF_TGT_RESET);
} }
/** /**
...@@ -1075,7 +1074,11 @@ int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd) ...@@ -1075,7 +1074,11 @@ int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd)
*/ */
int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd) int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
{ {
return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET); struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
struct fc_lport *lport = shost_priv(rport_to_shost(rport));
return bnx2fc_initiate_tmf(lport, rport, sc_cmd->device->lun,
FCP_TMF_LUN_RESET);
} }
static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req) static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
...@@ -1450,10 +1453,9 @@ void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req, ...@@ -1450,10 +1453,9 @@ void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req,
static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req) static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req)
{ {
struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
struct bnx2fc_rport *tgt = io_req->tgt; struct bnx2fc_rport *tgt = io_req->tgt;
struct bnx2fc_cmd *cmd, *tmp; struct bnx2fc_cmd *cmd, *tmp;
u64 tm_lun = sc_cmd->device->lun; struct bnx2fc_mp_req *tm_req = &io_req->mp_req;
u64 lun; u64 lun;
int rc = 0; int rc = 0;
...@@ -1465,8 +1467,10 @@ static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req) ...@@ -1465,8 +1467,10 @@ static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req)
*/ */
list_for_each_entry_safe(cmd, tmp, &tgt->active_cmd_queue, link) { list_for_each_entry_safe(cmd, tmp, &tgt->active_cmd_queue, link) {
BNX2FC_TGT_DBG(tgt, "LUN RST cmpl: scan for pending IOs\n"); BNX2FC_TGT_DBG(tgt, "LUN RST cmpl: scan for pending IOs\n");
if (!cmd->sc_cmd)
continue;
lun = cmd->sc_cmd->device->lun; lun = cmd->sc_cmd->device->lun;
if (lun == tm_lun) { if (lun == tm_req->tm_lun) {
/* Initiate ABTS on this cmd */ /* Initiate ABTS on this cmd */
if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS, if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS,
&cmd->req_flags)) { &cmd->req_flags)) {
...@@ -1570,31 +1574,36 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req, ...@@ -1570,31 +1574,36 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
printk(KERN_ERR PFX "tmf's fc_hdr r_ctl = 0x%x\n", printk(KERN_ERR PFX "tmf's fc_hdr r_ctl = 0x%x\n",
fc_hdr->fh_r_ctl); fc_hdr->fh_r_ctl);
} }
if (!bnx2fc_priv(sc_cmd)->io_req) { if (sc_cmd) {
printk(KERN_ERR PFX "tm_compl: io_req is NULL\n"); if (!bnx2fc_priv(sc_cmd)->io_req) {
return; printk(KERN_ERR PFX "tm_compl: io_req is NULL\n");
} return;
switch (io_req->fcp_status) { }
case FC_GOOD: switch (io_req->fcp_status) {
if (io_req->cdb_status == 0) { case FC_GOOD:
/* Good IO completion */ if (io_req->cdb_status == 0) {
sc_cmd->result = DID_OK << 16; /* Good IO completion */
} else { sc_cmd->result = DID_OK << 16;
/* Transport status is good, SCSI status not good */ } else {
sc_cmd->result = (DID_OK << 16) | io_req->cdb_status; /* Transport status is good, SCSI status not good */
sc_cmd->result = (DID_OK << 16) | io_req->cdb_status;
}
if (io_req->fcp_resid)
scsi_set_resid(sc_cmd, io_req->fcp_resid);
break;
default:
BNX2FC_IO_DBG(io_req, "process_tm_compl: fcp_status = %d\n",
io_req->fcp_status);
break;
} }
if (io_req->fcp_resid)
scsi_set_resid(sc_cmd, io_req->fcp_resid);
break;
default: sc_cmd = io_req->sc_cmd;
BNX2FC_IO_DBG(io_req, "process_tm_compl: fcp_status = %d\n", io_req->sc_cmd = NULL;
io_req->fcp_status);
break;
}
sc_cmd = io_req->sc_cmd; bnx2fc_priv(sc_cmd)->io_req = NULL;
io_req->sc_cmd = NULL; scsi_done(sc_cmd);
}
/* check if the io_req exists in tgt's tmf_q */ /* check if the io_req exists in tgt's tmf_q */
if (io_req->on_tmf_queue) { if (io_req->on_tmf_queue) {
...@@ -1607,9 +1616,6 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req, ...@@ -1607,9 +1616,6 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
return; return;
} }
bnx2fc_priv(sc_cmd)->io_req = NULL;
scsi_done(sc_cmd);
kref_put(&io_req->refcount, bnx2fc_cmd_release); kref_put(&io_req->refcount, bnx2fc_cmd_release);
if (io_req->wait_for_abts_comp) { if (io_req->wait_for_abts_comp) {
BNX2FC_IO_DBG(io_req, "tm_compl - wake up the waiter\n"); BNX2FC_IO_DBG(io_req, "tm_compl - wake up the waiter\n");
...@@ -1738,15 +1744,9 @@ static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req) ...@@ -1738,15 +1744,9 @@ static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req)
void bnx2fc_build_fcp_cmnd(struct bnx2fc_cmd *io_req, void bnx2fc_build_fcp_cmnd(struct bnx2fc_cmd *io_req,
struct fcp_cmnd *fcp_cmnd) struct fcp_cmnd *fcp_cmnd)
{ {
struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd)); memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd));
int_to_scsilun(sc_cmd->device->lun, &fcp_cmnd->fc_lun);
fcp_cmnd->fc_dl = htonl(io_req->data_xfer_len); fcp_cmnd->fc_dl = htonl(io_req->data_xfer_len);
memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);
fcp_cmnd->fc_cmdref = 0; fcp_cmnd->fc_cmdref = 0;
fcp_cmnd->fc_pri_ta = 0; fcp_cmnd->fc_pri_ta = 0;
fcp_cmnd->fc_tm_flags = io_req->mp_req.tm_flags; fcp_cmnd->fc_tm_flags = io_req->mp_req.tm_flags;
......
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