scsi: qla2xxx: Enhance ct_entry_24xx_ext iocb handling for 29xx series

Refine the handling of I/O control blocks (IOCBs) for the 29xx series by
introducing support for the extended structure ct_entry_24xx_ext.
Update function signatures to accept a generic pointer for IOCB packets,
differentiating between standard and extended structures, and ensuring
proper initialization and processing of command and response data.
Additionally, the size check for the extended structure is added to
maintain integrity.

Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-28-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
Nilesh Javali
2026-08-06 16:35:45 -04:00
committed by Martin K. Petersen (Oracle)
parent 4cff96e29e
commit c454800348
3 changed files with 168 additions and 67 deletions
+117 -39
View File
@@ -68,30 +68,62 @@ void *
qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
{
struct qla_hw_data *ha = vha->hw;
struct ct_entry_24xx *ct_pkt;
ct_pkt = (struct ct_entry_24xx *)arg->iocb;
memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
if (IS_QLA29XX(ha)) {
struct ct_entry_24xx_ext *ct_pkt;
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle);
ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size);
ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size);
ct_pkt = (struct ct_entry_24xx_ext *)arg->iocb;
memset(ct_pkt, 0, sizeof(struct ct_entry_24xx_ext));
put_unaligned_le64(arg->req_dma, &ct_pkt->dsd[0].address);
ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle);
ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size);
ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size);
put_unaligned_le64(arg->rsp_dma, &ct_pkt->dsd[1].address);
ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
ct_pkt->vp_index = vha->vp_idx;
put_unaligned_le64(arg->req_dma,
&ct_pkt->dsd[0].address);
ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
vha->qla_stats.control_requests++;
put_unaligned_le64(arg->rsp_dma,
&ct_pkt->dsd[1].address);
ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
ct_pkt->vp_index = cpu_to_le16(vha->vp_idx);
return (ct_pkt);
vha->qla_stats.control_requests++;
return ct_pkt;
} else {
struct ct_entry_24xx *ct_pkt;
ct_pkt = (struct ct_entry_24xx *)arg->iocb;
memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle);
ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size);
ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size);
put_unaligned_le64(arg->req_dma,
&ct_pkt->dsd[0].address);
ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
put_unaligned_le64(arg->rsp_dma,
&ct_pkt->dsd[1].address);
ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
ct_pkt->vp_index = vha->vp_idx;
vha->qla_stats.control_requests++;
return ct_pkt;
}
}
/**
@@ -132,7 +164,10 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
routine, ms_pkt->entry_status, vha->d_id.b.domain,
vha->d_id.b.area, vha->d_id.b.al_pa);
} else {
if (IS_FWI2_CAPABLE(ha))
if (IS_QLA29XX(ha))
comp_status = le16_to_cpu(
((struct ct_entry_24xx_ext *)ms_pkt)->comp_status);
else if (IS_FWI2_CAPABLE(ha))
comp_status = le16_to_cpu(
((struct ct_entry_24xx *)ms_pkt)->comp_status);
else
@@ -1437,42 +1472,85 @@ void *
qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
uint32_t rsp_size)
{
struct ct_entry_24xx *ct_pkt;
struct qla_hw_data *ha = vha->hw;
ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
if (IS_QLA29XX(ha)) {
struct ct_entry_24xx_ext *ct_pkt;
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
ct_pkt = (struct ct_entry_24xx_ext *)ha->ms_iocb;
memset(ct_pkt, 0, sizeof(struct ct_entry_24xx_ext));
put_unaligned_le64(ha->ct_sns_dma, &ct_pkt->dsd[0].address);
ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle =
cpu_to_le16(vha->mgmt_svr_loop_id);
ct_pkt->timeout =
cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
put_unaligned_le64(ha->ct_sns_dma, &ct_pkt->dsd[1].address);
ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
ct_pkt->vp_index = vha->vp_idx;
put_unaligned_le64(ha->ct_sns_dma,
&ct_pkt->dsd[0].address);
ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
return ct_pkt;
put_unaligned_le64(ha->ct_sns_dma,
&ct_pkt->dsd[1].address);
ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
ct_pkt->vp_index = cpu_to_le16(vha->vp_idx);
return ct_pkt;
} else {
struct ct_entry_24xx *ct_pkt;
ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
ct_pkt->entry_type = CT_IOCB_TYPE;
ct_pkt->entry_count = 1;
ct_pkt->nport_handle =
cpu_to_le16(vha->mgmt_svr_loop_id);
ct_pkt->timeout =
cpu_to_le16(ha->r_a_tov / 10 * 2);
ct_pkt->cmd_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_dsd_count = cpu_to_le16(1);
ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
put_unaligned_le64(ha->ct_sns_dma,
&ct_pkt->dsd[0].address);
ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
put_unaligned_le64(ha->ct_sns_dma,
&ct_pkt->dsd[1].address);
ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
ct_pkt->vp_index = vha->vp_idx;
return ct_pkt;
}
}
static void
qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
{
struct qla_hw_data *ha = vha->hw;
ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
if (IS_FWI2_CAPABLE(ha)) {
if (IS_QLA29XX(ha)) {
struct ct_entry_24xx_ext *ct_pkt =
(struct ct_entry_24xx_ext *)ha->ms_iocb;
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
} else if (IS_FWI2_CAPABLE(ha)) {
struct ct_entry_24xx *ct_pkt =
(struct ct_entry_24xx *)ha->ms_iocb;
ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
} else {
ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
ms_pkt->req_bytecount = cpu_to_le32(req_size);
ms_pkt->req_dsd.length = ms_pkt->req_bytecount;
}
+50 -28
View File
@@ -3468,7 +3468,7 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb)
}
static void
qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
qla24xx_ct_iocb(srb_t *sp, void *pkt)
{
uint16_t avail_dsds;
struct dsd64 *cur_dsd;
@@ -3480,36 +3480,50 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
struct bsg_job *bsg_job = sp->u.bsg_job;
int entry_count = 1;
ct_iocb->entry_type = CT_IOCB_TYPE;
ct_iocb->entry_status = 0;
ct_iocb->sys_define = 0;
ct_iocb->handle = sp->handle;
ct_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
ct_iocb->vp_index = sp->vha->vp_idx;
ct_iocb->comp_status = cpu_to_le16(0);
cmd_dsds = bsg_job->request_payload.sg_cnt;
rsp_dsds = bsg_job->reply_payload.sg_cnt;
ct_iocb->cmd_dsd_count = cpu_to_le16(cmd_dsds);
ct_iocb->timeout = 0;
ct_iocb->rsp_dsd_count = cpu_to_le16(rsp_dsds);
ct_iocb->cmd_byte_count =
cpu_to_le32(bsg_job->request_payload.payload_len);
if (IS_QLA29XX(ha)) {
struct ct_entry_24xx_ext *ct_iocb = pkt;
ct_iocb->entry_type = CT_IOCB_TYPE;
ct_iocb->entry_status = 0;
ct_iocb->sys_define = 0;
ct_iocb->handle = sp->handle;
ct_iocb->nport_handle =
cpu_to_le16(sp->fcport->loop_id);
ct_iocb->vp_index = cpu_to_le16(sp->vha->vp_idx);
ct_iocb->comp_status = cpu_to_le16(0);
ct_iocb->cmd_dsd_count = cpu_to_le16(cmd_dsds);
ct_iocb->timeout = 0;
ct_iocb->rsp_dsd_count = cpu_to_le16(rsp_dsds);
ct_iocb->cmd_byte_count =
cpu_to_le32(bsg_job->request_payload.payload_len);
avail_dsds = NUM_CT_DSDS;
cur_dsd = ct_iocb->dsd;
} else {
struct ct_entry_24xx *ct_iocb = pkt;
ct_iocb->entry_type = CT_IOCB_TYPE;
ct_iocb->entry_status = 0;
ct_iocb->sys_define = 0;
ct_iocb->handle = sp->handle;
ct_iocb->nport_handle =
cpu_to_le16(sp->fcport->loop_id);
ct_iocb->vp_index = sp->vha->vp_idx;
ct_iocb->comp_status = cpu_to_le16(0);
ct_iocb->cmd_dsd_count = cpu_to_le16(cmd_dsds);
ct_iocb->timeout = 0;
ct_iocb->rsp_dsd_count = cpu_to_le16(rsp_dsds);
ct_iocb->cmd_byte_count =
cpu_to_le32(bsg_job->request_payload.payload_len);
avail_dsds = 2;
cur_dsd = ct_iocb->dsd;
}
avail_dsds = 2;
cur_dsd = ct_iocb->dsd;
index = 0;
for_each_sg(bsg_job->request_payload.sg_list, sg, cmd_dsds, index) {
/*
* Allocate additional continuation packets. 24xx uses the
* 64-byte cont_a64_entry_t (5 DSDs); 29xx uses the 128-byte
* cont_a64_entry_ext_t (NUM_CONT1_DSDS) and advances through
* the ring_ext_ptr stride so the CT head IOCB isn't
* overlapped.
*/
if (avail_dsds == 0) {
if (IS_QLA29XX(ha)) {
struct cont_a64_entry_ext *cont_pkt;
@@ -3558,7 +3572,11 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
append_dsd64(&cur_dsd, sg);
avail_dsds--;
}
ct_iocb->entry_count = entry_count;
if (IS_QLA29XX(ha))
((struct ct_entry_24xx_ext *)pkt)->entry_count = entry_count;
else
((struct ct_entry_24xx *)pkt)->entry_count = entry_count;
}
/*
@@ -3931,11 +3949,15 @@ qla2x00_mb_iocb(srb_t *sp, struct mbx_24xx_entry *mbx)
}
static void
qla2x00_ctpthru_cmd_iocb(srb_t *sp, struct ct_entry_24xx *ct_pkt)
qla2x00_ctpthru_cmd_iocb(srb_t *sp, void *pkt)
{
sp->u.iocb_cmd.u.ctarg.iocb = ct_pkt;
sp->u.iocb_cmd.u.ctarg.iocb = pkt;
qla24xx_prep_ms_iocb(sp->vha, &sp->u.iocb_cmd.u.ctarg);
ct_pkt->handle = sp->handle;
if (IS_QLA29XX(sp->vha->hw))
((struct ct_entry_24xx_ext *)pkt)->handle = sp->handle;
else
((struct ct_entry_24xx *)pkt)->handle = sp->handle;
}
static void qla2x00_send_notify_ack_iocb(srb_t *sp,
+1
View File
@@ -8349,6 +8349,7 @@ qla2x00_module_init(void)
BUILD_BUG_ON(sizeof(struct cmd_type_7_fx00) != 64);
BUILD_BUG_ON(sizeof(struct cmd_type_crc_2) != 64);
BUILD_BUG_ON(sizeof(struct ct_entry_24xx) != 64);
BUILD_BUG_ON(sizeof(struct ct_entry_24xx_ext) != 128);
BUILD_BUG_ON(sizeof(struct ct_fdmi1_hba_attributes) != 2604);
BUILD_BUG_ON(sizeof(struct ct_fdmi2_hba_attributes) != 4424);
BUILD_BUG_ON(sizeof(struct ct_fdmi2_port_attributes) != 4164);