From c8944d20a3f6925258012ff92ea932167b5c5cc3 Mon Sep 17 00:00:00 2001 From: Manish Rangankar Date: Thu, 23 Jul 2026 10:33:21 +0530 Subject: [PATCH] scsi: qla2xxx: Add 29xx support in queue initialisation path Extend the queue initialisation and multi-queue management mailbox commands to include IS_QLA29XX() checks, following the same mailbox interface as 27xx/28xx. Unlike earlier adapters that use 64-byte request/response ring entries (request_t / response_t), 29xx uses 128-byte entries. Add struct request_ext and struct response_ext, which extend the legacy 64-byte layout with a 64-byte reserved area. The first 64 bytes are layout-compatible with the legacy structures, so common header accesses remain valid. The enlarged entry stride doubles the DMA ring memory allocated for both request and response queues on 29xx, and all ring pointer arithmetic must account for the wider entries (handled by later patches in this series). Signed-off-by: Manish Rangankar Signed-off-by: Nilesh Javali Reviewed-by: Hannes Reinecke Link: https://patch.msgid.link/20260723050413.3897522-5-njavali@marvell.com Signed-off-by: Martin K. Petersen (Oracle) --- drivers/scsi/qla2xxx/qla_def.h | 30 ++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_mbx.c | 20 +++++++++++++------- drivers/scsi/qla2xxx/qla_mid.c | 25 +++++++++++++++++++++---- 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 89ddf332cdbd..1ec7ee578e0c 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1989,6 +1989,18 @@ typedef struct { #define RESPONSE_PROCESSED 0xDEADDEAD /* Signature */ } response_t; +struct response_ext { + uint8_t entry_type; /* Entry type. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t handle; /* System defined handle */ + uint8_t data[52]; + uint32_t signature; + uint8_t reserved[64]; +#define RESPONSE_PROCESSED 0xDEADDEAD /* Signature */ +}; + /* * ISP queue - ATIO queue entry definition. */ @@ -2067,6 +2079,24 @@ typedef struct { struct dsd64 dsd[2]; } cmd_a64_entry_t, request_t; +struct request_ext { + uint8_t entry_type; /* Entry type. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System defined. */ + uint8_t entry_status; /* Entry Status. */ + uint32_t handle; /* System handle. */ + target_id_t target; /* SCSI ID */ + __le16 lun; /* SCSI LUN */ + __le16 control_flags; /* Control flags. */ + uint16_t reserved_1; + __le16 timeout; /* Command timeout. */ + __le16 dseg_count; /* Data segment count. */ + uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ + uint32_t byte_count; /* Total byte count. */ + struct dsd64 dsd[2]; + uint8_t reserved[64]; +}; + /* * ISP queue - continuation entry structure definition. */ diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 2d052f870b2b..2b232b225c90 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -4584,7 +4584,8 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) mcp->mb[12] = req->qos; mcp->mb[11] = req->vp_idx; mcp->mb[13] = req->rid; - if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha) || + IS_QLA29XX(ha)) mcp->mb[15] = 0; mcp->mb[4] = req->id; @@ -4599,9 +4600,10 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) mcp->tov = MBX_TOV_SECONDS * 2; if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || - IS_QLA28XX(ha)) + IS_QLA28XX(ha) || IS_QLA29XX(ha)) mcp->in_mb |= MBX_1; - if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha) || + IS_QLA29XX(ha)) { mcp->out_mb |= MBX_15; /* debug q create issue in SR-IOV */ mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; @@ -4610,7 +4612,8 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) spin_lock_irqsave(&ha->hardware_lock, flags); if (!(req->options & BIT_0)) { wrt_reg_dword(req->req_q_in, 0); - if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha) && + !IS_QLA29XX(ha)) wrt_reg_dword(req->req_q_out, 0); } spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -4654,7 +4657,8 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) mcp->mb[5] = rsp->length; mcp->mb[14] = rsp->msix->entry; mcp->mb[13] = rsp->rid; - if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha) || + IS_QLA29XX(ha)) mcp->mb[15] = 0; mcp->mb[4] = rsp->id; @@ -4671,7 +4675,8 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) if (IS_QLA81XX(ha)) { mcp->out_mb |= MBX_12|MBX_11|MBX_10; mcp->in_mb |= MBX_1; - } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { + } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha) || + IS_QLA29XX(ha)) { mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10; mcp->in_mb |= MBX_1; /* debug q create issue in SR-IOV */ @@ -4681,7 +4686,8 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) spin_lock_irqsave(&ha->hardware_lock, flags); if (!(rsp->options & BIT_0)) { wrt_reg_dword(rsp->rsp_q_out, 0); - if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha) && + !IS_QLA29XX(ha)) wrt_reg_dword(rsp->rsp_q_in, 0); } diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index c563133f751e..e75b7ae22bc5 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -574,9 +574,13 @@ qla25xx_free_req_que(struct scsi_qla_host *vha, struct req_que *req) { struct qla_hw_data *ha = vha->hw; uint16_t que_id = req->id; + uint16_t reqsz; + + reqsz = IS_QLA29XX(ha) ? sizeof(struct request_ext) : + sizeof(request_t); dma_free_coherent(&ha->pdev->dev, (req->length + 1) * - sizeof(request_t), req->ring, req->dma); + reqsz, req->ring, req->dma); req->ring = NULL; req->dma = 0; if (que_id) { @@ -594,6 +598,10 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) { struct qla_hw_data *ha = vha->hw; uint16_t que_id = rsp->id; + uint16_t rspsz; + + rspsz = IS_QLA29XX(ha) ? sizeof(struct response_ext) : + sizeof(response_t); if (rsp->msix && rsp->msix->have_irq) { free_irq(rsp->msix->vector, rsp->msix->handle); @@ -601,8 +609,9 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) rsp->msix->in_use = 0; rsp->msix->handle = NULL; } + dma_free_coherent(&ha->pdev->dev, (rsp->length + 1) * - sizeof(response_t), rsp->ring, rsp->dma); + rspsz, rsp->ring, rsp->dma); rsp->ring = NULL; rsp->dma = 0; if (que_id) { @@ -706,6 +715,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, uint16_t que_id = 0; device_reg_t *reg; uint32_t cnt; + uint16_t reqsz; req = kzalloc_obj(struct req_que); if (req == NULL) { @@ -714,9 +724,12 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, goto failed; } + reqsz = IS_QLA29XX(ha) ? sizeof(struct request_ext) : + sizeof(request_t); + req->length = REQUEST_ENTRY_CNT_24XX; req->ring = dma_alloc_coherent(&ha->pdev->dev, - (req->length + 1) * sizeof(request_t), + (req->length + 1) * reqsz, &req->dma, GFP_KERNEL); if (req->ring == NULL) { ql_log(ql_log_fatal, base_vha, 0x00da, @@ -833,6 +846,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev); uint16_t que_id = 0; device_reg_t *reg; + uint16_t rspsz; rsp = kzalloc_obj(struct rsp_que); if (rsp == NULL) { @@ -841,9 +855,12 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, goto failed; } + rspsz = IS_QLA29XX(ha) ? sizeof(struct response_ext) : + sizeof(response_t); + rsp->length = RESPONSE_ENTRY_CNT_MQ; rsp->ring = dma_alloc_coherent(&ha->pdev->dev, - (rsp->length + 1) * sizeof(response_t), + (rsp->length + 1) * rspsz, &rsp->dma, GFP_KERNEL); if (rsp->ring == NULL) { ql_log(ql_log_warn, base_vha, 0x00e1,