summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNilesh Javali <njavali@marvell.com>2026-07-23 10:33:44 +0530
committerMartin K. Petersen (Oracle) <mkp@kernel.org>2026-08-06 16:35:45 -0400
commitc454800348a4e0c70503bd3d4c2dcc27dfdb19e6 (patch)
tree6cc1685b9cd1a9226af098b94332b1376608d8c4
parent4cff96e29e3f911cf40e6e31970694bc2d248aac (diff)
downloadlinux-c454800348a4e0c70503bd3d4c2dcc27dfdb19e6.tar.gz
linux-c454800348a4e0c70503bd3d4c2dcc27dfdb19e6.zip
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>
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c156
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c78
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c1
3 files changed, 168 insertions, 67 deletions
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 514f04aa1423..7a4d2fdc095f 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -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);
+
+ 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;
- return (ct_pkt);
+ 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 = (struct ct_entry_24xx_ext *)ha->ms_iocb;
+ memset(ct_pkt, 0, sizeof(struct ct_entry_24xx_ext));
+
+ 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 = cpu_to_le16(vha->vp_idx);
- 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);
+ 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[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;
+ 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;
+ 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;
}
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 1ca50fc200d6..7315bc4df00e 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -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,
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4f7e5f9372ef..0b7c4ee73ebf 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -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);