mirror of
https://github.com/torvalds/linux.git
synced 2024-11-13 23:51:39 +00:00
scsi: qla2xxx: Multi-que support for TMF
Add queue flush for task management command, before placing it on the wire. Do IO flush for all Request Q's. Reported-by: kernel test robot <lkp@intel.com> Link: https://lore.kernel.org/oe-kbuild-all/202304271702.GpIL391S-lkp@intel.com/ Cc: stable@vger.kernel.org Signed-off-by: Quinn Tran <qutran@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Link: https://lore.kernel.org/r/20230428075339.32551-2-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com <mailto:himanshu.madhani@oracle.com>> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
ac9a78681b
commit
d90171dd0d
@ -465,6 +465,14 @@ static inline be_id_t port_id_to_be_id(port_id_t port_id)
|
||||
return res;
|
||||
}
|
||||
|
||||
struct tmf_arg {
|
||||
struct qla_qpair *qpair;
|
||||
struct fc_port *fcport;
|
||||
struct scsi_qla_host *vha;
|
||||
u64 lun;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct els_logo_payload {
|
||||
uint8_t opcode;
|
||||
uint8_t rsvd[3];
|
||||
|
@ -69,7 +69,7 @@ extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *);
|
||||
extern int qla2x00_async_prlo(struct scsi_qla_host *, fc_port_t *);
|
||||
extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t);
|
||||
extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint64_t, uint32_t);
|
||||
struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *,
|
||||
enum qla_work_type);
|
||||
extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *);
|
||||
|
@ -2020,17 +2020,19 @@ static void qla2x00_tmf_sp_done(srb_t *sp, int res)
|
||||
complete(&tmf->u.tmf.comp);
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
|
||||
uint32_t tag)
|
||||
static int
|
||||
__qla2x00_async_tm_cmd(struct tmf_arg *arg)
|
||||
{
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct scsi_qla_host *vha = arg->vha;
|
||||
struct srb_iocb *tm_iocb;
|
||||
srb_t *sp;
|
||||
unsigned long flags;
|
||||
int rval = QLA_FUNCTION_FAILED;
|
||||
|
||||
fc_port_t *fcport = arg->fcport;
|
||||
|
||||
/* ref: INIT */
|
||||
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
|
||||
sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL);
|
||||
if (!sp)
|
||||
goto done;
|
||||
|
||||
@ -2043,15 +2045,15 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
|
||||
|
||||
tm_iocb = &sp->u.iocb_cmd;
|
||||
init_completion(&tm_iocb->u.tmf.comp);
|
||||
tm_iocb->u.tmf.flags = flags;
|
||||
tm_iocb->u.tmf.lun = lun;
|
||||
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x802f,
|
||||
"Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
|
||||
sp->handle, fcport->loop_id, fcport->d_id.b.domain,
|
||||
fcport->d_id.b.area, fcport->d_id.b.al_pa);
|
||||
tm_iocb->u.tmf.flags = arg->flags;
|
||||
tm_iocb->u.tmf.lun = arg->lun;
|
||||
|
||||
rval = qla2x00_start_sp(sp);
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x802f,
|
||||
"Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x ctrl=%x.\n",
|
||||
sp->handle, fcport->loop_id, fcport->d_id.b.domain,
|
||||
fcport->d_id.b.area, fcport->d_id.b.al_pa, arg->flags);
|
||||
|
||||
if (rval != QLA_SUCCESS)
|
||||
goto done_free_sp;
|
||||
wait_for_completion(&tm_iocb->u.tmf.comp);
|
||||
@ -2065,12 +2067,14 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
|
||||
|
||||
if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) {
|
||||
flags = tm_iocb->u.tmf.flags;
|
||||
lun = (uint16_t)tm_iocb->u.tmf.lun;
|
||||
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|
|
||||
TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA))
|
||||
flags = MK_SYNC_ID_LUN;
|
||||
else
|
||||
flags = MK_SYNC_ID;
|
||||
|
||||
/* Issue Marker IOCB */
|
||||
qla2x00_marker(vha, vha->hw->base_qpair,
|
||||
fcport->loop_id, lun,
|
||||
flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
|
||||
qla2x00_marker(vha, sp->qpair,
|
||||
sp->fcport->loop_id, arg->lun, flags);
|
||||
}
|
||||
|
||||
done_free_sp:
|
||||
@ -2080,6 +2084,41 @@ done:
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
|
||||
uint32_t tag)
|
||||
{
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct qla_qpair *qpair;
|
||||
struct tmf_arg a;
|
||||
struct completion comp;
|
||||
int i, rval;
|
||||
|
||||
init_completion(&comp);
|
||||
a.vha = fcport->vha;
|
||||
a.fcport = fcport;
|
||||
a.lun = lun;
|
||||
|
||||
if (vha->hw->mqenable) {
|
||||
for (i = 0; i < vha->hw->num_qpairs; i++) {
|
||||
qpair = vha->hw->queue_pair_map[i];
|
||||
if (!qpair)
|
||||
continue;
|
||||
a.qpair = qpair;
|
||||
a.flags = flags|TCF_NOTMCMD_TO_TARGET;
|
||||
rval = __qla2x00_async_tm_cmd(&a);
|
||||
if (rval)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
a.qpair = vha->hw->base_qpair;
|
||||
a.flags = flags;
|
||||
rval = __qla2x00_async_tm_cmd(&a);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla24xx_async_abort_command(srb_t *sp)
|
||||
{
|
||||
|
@ -2541,7 +2541,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
|
||||
scsi_qla_host_t *vha = fcport->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct srb_iocb *iocb = &sp->u.iocb_cmd;
|
||||
struct req_que *req = vha->req;
|
||||
struct req_que *req = sp->qpair->req;
|
||||
|
||||
flags = iocb->u.tmf.flags;
|
||||
lun = iocb->u.tmf.lun;
|
||||
@ -2557,7 +2557,8 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
|
||||
tsk->port_id[2] = fcport->d_id.b.domain;
|
||||
tsk->vp_index = fcport->vha->vp_idx;
|
||||
|
||||
if (flags == TCF_LUN_RESET) {
|
||||
if (flags & (TCF_LUN_RESET | TCF_ABORT_TASK_SET|
|
||||
TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) {
|
||||
int_to_scsilun(lun, &tsk->lun);
|
||||
host_to_fcp_swap((uint8_t *)&tsk->lun,
|
||||
sizeof(tsk->lun));
|
||||
|
Loading…
Reference in New Issue
Block a user