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: Hannes Reinecke <hare@suse.de> Link: https://lore.kernel.org/r/20231002154328.43718-6-hare@suse.de Cc: Saurav Kashyap <skashyap@marvell.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>pull/318/merge
parent
ade4fb9457
commit
6a137a967b
|
|
@ -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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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 @@ retry_tmf:
|
||||||
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 @@ retry_tmf:
|
||||||
/* 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 @@ retry_tmf:
|
||||||
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 @@ cleanup_err:
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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 @@ io_compl:
|
||||||
|
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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,6 +1574,7 @@ 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 (sc_cmd) {
|
||||||
if (!bnx2fc_priv(sc_cmd)->io_req) {
|
if (!bnx2fc_priv(sc_cmd)->io_req) {
|
||||||
printk(KERN_ERR PFX "tm_compl: io_req is NULL\n");
|
printk(KERN_ERR PFX "tm_compl: io_req is NULL\n");
|
||||||
return;
|
return;
|
||||||
|
|
@ -1596,6 +1601,10 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
|
||||||
sc_cmd = io_req->sc_cmd;
|
sc_cmd = io_req->sc_cmd;
|
||||||
io_req->sc_cmd = NULL;
|
io_req->sc_cmd = NULL;
|
||||||
|
|
||||||
|
bnx2fc_priv(sc_cmd)->io_req = 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,
|
||||||
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)
|
||||||
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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue