scsi: qla2xxx: Update handling of ELS IOCBs for 29xx series

Update ELS IOCB handling to support the extended 128-byte
els_entry_24xx_ext structure used by 29xx series adapters.

Change the signatures of qla24xx_els_logo_iocb(), qla_els_pt_iocb(), and
qla24xx_els_iocb() to accept a generic void pointer, enabling
differentiation between standard and extended ELS structures at runtime.

Introduce a static inline helper qla_els_set_vp_sof() in qla_inline.h
that centralises the 24xx-vs-29xx vp_index/sof_type encoding: the 24xx
layout uses separate u8 vp_index + u8 sof_type (EST_SOFI3), while 29xx
uses a __le16 with bitfields (vp_index:9 / sof_type:4 /
ELS_EXT_EST_SOFI3).  All ELS issue paths now call this helper instead of
open-coding the branch, including the RDP response path in qla_os.c.

In qla2x00_start_sp(), collapse the IS_QLA29XX() branch for the handle
assignment in SRB_ELS_CMD_HST_NOLOGIN: els_entry_24xx::handle and
els_entry_24xx_ext::handle are both u32 at offset 4, so a single
24xx-view write is layout-compatible with both strides.

DMA allocations in qla24xx_process_abts() and
qla24xx_process_purex_rdp() are updated to use the correct size for the
adapter type.  A BUILD_BUG_ON is added to verify the extended structure
size.

Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-30-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This commit is contained in:
Nilesh Javali
2026-07-23 10:33:46 +05:30
committed by Martin K. Petersen (Oracle)
parent 7db93e3c58
commit 87a42b53f4
5 changed files with 85 additions and 30 deletions

View File

@@ -295,7 +295,7 @@ void qla_adjust_buf(struct scsi_qla_host *);
* Global Function Prototypes in qla_iocb.c source file.
*/
void qla_els_pt_iocb(struct scsi_qla_host *vha,
struct els_entry_24xx *pkt, struct qla_els_pt_arg *a);
void *pkt, struct qla_els_pt_arg *a);
cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha,
struct qla_hw_data *ha, struct req_que *que);
struct cont_a64_entry_ext *qla2900_prep_cont_type1_iocb(scsi_qla_host_t *vha,

View File

@@ -863,3 +863,31 @@ qla_sts_fwi2_extract(struct qla_hw_data *ha, void *pkt,
host_to_fcp_swap(s->data, sizeof(s->data));
}
}
/*
* qla_els_set_vp_sof() - write the vp_index / sof_type pair into an ELS
* pass-through IOCB (els_entry_24xx{,_ext}).
*
* Both layouts have the same 16-bit slot at offset 14, but it is encoded
* differently:
* - 24xx: separate u8 vp_index + u8 sof_type with EST_SOFI3 (1 << 4)
* - 29xx: __le16 with bitfields { vp_index:9, reserved_1_sof:3,
* sof_type:4 } and ELS_EXT_EST_SOFI3
* so this is the single point in the driver that knows about that
* encoding split.
*/
static inline void
qla_els_set_vp_sof(struct scsi_qla_host *vha, void *pkt, u16 vp_idx)
{
if (IS_QLA29XX(vha->hw)) {
struct els_entry_24xx_ext *ext = pkt;
ext->vp_index = vp_idx;
ext->sof_type = ELS_EXT_EST_SOFI3;
} else {
struct els_entry_24xx *e = pkt;
e->vp_index = vp_idx;
e->sof_type = EST_SOFI3;
}
}

View File

@@ -2975,8 +2975,9 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
}
static void
qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
qla24xx_els_logo_iocb(srb_t *sp, void *pkt)
{
struct els_entry_24xx *els_iocb = pkt;
scsi_qla_host_t *vha = sp->vha;
struct srb_iocb *elsio = &sp->u.iocb_cmd;
@@ -2987,11 +2988,11 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
els_iocb->handle = sp->handle;
els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
els_iocb->tx_dsd_count = cpu_to_le16(1);
els_iocb->vp_index = vha->vp_idx;
els_iocb->sof_type = EST_SOFI3;
els_iocb->rx_dsd_count = 0;
els_iocb->opcode = elsio->u.els_logo.els_cmd;
qla_els_set_vp_sof(vha, pkt, vha->vp_idx);
els_iocb->d_id[0] = sp->fcport->d_id.b.al_pa;
els_iocb->d_id[1] = sp->fcport->d_id.b.area;
els_iocb->d_id[2] = sp->fcport->d_id.b.domain;
@@ -3322,9 +3323,10 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
/* it is assume qpair lock is held */
void qla_els_pt_iocb(struct scsi_qla_host *vha,
struct els_entry_24xx *els_iocb,
struct qla_els_pt_arg *a)
void *pkt, struct qla_els_pt_arg *a)
{
struct els_entry_24xx *els_iocb = pkt;
els_iocb->entry_type = ELS_IOCB_TYPE;
els_iocb->entry_count = 1;
els_iocb->sys_define = 0;
@@ -3333,11 +3335,11 @@ void qla_els_pt_iocb(struct scsi_qla_host *vha,
els_iocb->nport_handle = a->nport_handle;
els_iocb->rx_xchg_address = a->rx_xchg_address;
els_iocb->tx_dsd_count = cpu_to_le16(1);
els_iocb->vp_index = a->vp_idx;
els_iocb->sof_type = EST_SOFI3;
els_iocb->rx_dsd_count = cpu_to_le16(0);
els_iocb->opcode = a->els_opcode;
qla_els_set_vp_sof(vha, pkt, a->vp_idx);
els_iocb->d_id[0] = a->did.b.al_pa;
els_iocb->d_id[1] = a->did.b.area;
els_iocb->d_id[2] = a->did.b.domain;
@@ -3358,8 +3360,9 @@ void qla_els_pt_iocb(struct scsi_qla_host *vha,
}
static void
qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
qla24xx_els_iocb(srb_t *sp, void *pkt)
{
struct els_entry_24xx *els_iocb = pkt;
struct bsg_job *bsg_job = sp->u.bsg_job;
struct fc_bsg_request *bsg_request = bsg_job->request;
@@ -3370,8 +3373,8 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
els_iocb->handle = sp->handle;
els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
els_iocb->tx_dsd_count = cpu_to_le16(bsg_job->request_payload.sg_cnt);
els_iocb->vp_index = sp->vha->vp_idx;
els_iocb->sof_type = EST_SOFI3;
qla_els_set_vp_sof(sp->vha, pkt, sp->vha->vp_idx);
els_iocb->rx_dsd_count = cpu_to_le16(bsg_job->reply_payload.sg_cnt);
els_iocb->opcode =
@@ -4203,6 +4206,11 @@ qla2x00_start_sp(srb_t *sp)
break;
case SRB_ELS_CMD_HST_NOLOGIN:
qla_els_pt_iocb(sp->vha, pkt, &sp->u.bsg_cmd.u.els_arg);
/*
* els_entry_24xx::handle and els_entry_24xx_ext::handle are
* both u32 at offset 4, so a 24xx-view write is layout-
* compatible with both strides.
*/
((struct els_entry_24xx *)pkt)->handle = sp->handle;
break;
case SRB_CT_CMD:

View File

@@ -83,6 +83,8 @@ qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
dma_addr_t dma;
uint32_t fctl;
int rval;
void *rsp_pkt;
size_t rsp_sz;
ql_dbg(ql_dbg_init, vha, 0x0286, "%s: entered.\n", __func__);
@@ -95,15 +97,22 @@ qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0287,
(uint8_t *)abts, sizeof(*abts));
rsp_els = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_els), &dma,
if (IS_QLA29XX(ha))
rsp_sz = sizeof(struct els_entry_24xx_ext);
else
rsp_sz = sizeof(struct els_entry_24xx);
rsp_pkt = dma_alloc_coherent(&ha->pdev->dev, rsp_sz, &dma,
GFP_KERNEL);
if (!rsp_els) {
if (!rsp_pkt) {
ql_log(ql_log_warn, vha, 0x0287,
"Failed allocate dma buffer ABTS/ELS RSP.\n");
return;
}
rsp_els = rsp_pkt;
/* terminate exchange */
memset(rsp_pkt, 0, rsp_sz);
rsp_els->entry_type = ELS_IOCB_TYPE;
rsp_els->entry_count = 1;
rsp_els->nport_handle = cpu_to_le16(~0);
@@ -115,8 +124,8 @@ qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0283,
"-------- ELS RSP -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0283,
(uint8_t *)rsp_els, sizeof(*rsp_els));
rval = qla2x00_issue_iocb(vha, rsp_els, dma, 0);
(uint8_t *)rsp_pkt, rsp_sz);
rval = qla2x00_issue_iocb(vha, rsp_pkt, dma, 0);
if (rval) {
ql_log(ql_log_warn, vha, 0x0288,
"%s: iocb failed to execute -> %x\n", __func__, rval);
@@ -131,7 +140,7 @@ qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
}
/* send ABTS response */
abts_rsp = (void *)rsp_els;
abts_rsp = rsp_pkt;
memset(abts_rsp, 0, sizeof(*abts_rsp));
abts_rsp->entry_type = ABTS_RSP_TYPE;
abts_rsp->entry_count = 1;
@@ -182,7 +191,7 @@ qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
"%s: done.\n", __func__);
}
dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_els), rsp_els, dma);
dma_free_coherent(&ha->pdev->dev, rsp_sz, rsp_pkt, dma);
}
/**
@@ -2385,7 +2394,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *v, struct req_que *req,
case SRB_ELS_CMD_HST_NOLOGIN:
type = "els";
{
struct els_entry_24xx *els = (void *)pkt;
__le16 ctl_flags =
((struct els_entry_24xx *)pkt)->control_flags;
struct qla_bsg_auth_els_request *p =
(struct qla_bsg_auth_els_request *)bsg_job->request;
@@ -2395,7 +2405,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *v, struct req_que *req,
e->d_id[2], e->d_id[1], e->d_id[0],
comp_status, p->e.extra_rx_xchg_address, bsg_job);
if (!(le16_to_cpu(els->control_flags) & ECF_PAYLOAD_DESCR_MASK)) {
if (!(le16_to_cpu(ctl_flags) & ECF_PAYLOAD_DESCR_MASK)) {
if (sp->remap.remapped) {
n = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt,

View File

@@ -6211,8 +6211,10 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
uint8_t *sfp = NULL;
uint16_t sfp_flags = 0;
uint rsp_payload_length = sizeof(*rsp_payload);
uint8_t vp_idx;
u16 vp_idx;
size_t purex_sz;
size_t rsp_els_sz;
void *rsp_els_pkt = NULL;
int rval;
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0180,
@@ -6240,13 +6242,19 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
rsp_payload_length);
}
rsp_els = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_els),
if (IS_QLA29XX(ha))
rsp_els_sz = sizeof(struct els_entry_24xx_ext);
else
rsp_els_sz = sizeof(struct els_entry_24xx);
rsp_els_pkt = dma_alloc_coherent(&ha->pdev->dev, rsp_els_sz,
&rsp_els_dma, GFP_KERNEL);
if (!rsp_els) {
if (!rsp_els_pkt) {
ql_log(ql_log_warn, vha, 0x0183,
"Failed allocate dma buffer ELS RSP.\n");
"Failed to allocate dma buffer ELS RSP.\n");
goto dealloc;
}
rsp_els = rsp_els_pkt;
rsp_payload = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_payload),
&rsp_payload_dma, GFP_KERNEL);
@@ -6270,12 +6278,12 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
rsp_els->handle = 0;
rsp_els->nport_handle = purex->nport_handle;
rsp_els->tx_dsd_count = cpu_to_le16(1);
rsp_els->vp_index = vp_idx;
rsp_els->sof_type = EST_SOFI3;
rsp_els->rx_xchg_address = purex->rx_xchg_addr;
rsp_els->rx_dsd_count = 0;
rsp_els->opcode = purex->els_frame_payload[0];
qla_els_set_vp_sof(vha, rsp_els_pkt, vp_idx);
rsp_els->d_id[0] = purex->s_id[0];
rsp_els->d_id[1] = purex->s_id[1];
rsp_els->d_id[2] = purex->s_id[2];
@@ -6575,13 +6583,13 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0184,
"-------- ELS RSP -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0185,
rsp_els, sizeof(*rsp_els));
rsp_els_pkt, rsp_els_sz);
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0186,
"-------- ELS RSP PAYLOAD -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0187,
rsp_payload, rsp_payload_length);
rval = qla2x00_issue_iocb(vha, rsp_els, rsp_els_dma, 0);
rval = qla2x00_issue_iocb(vha, rsp_els_pkt, rsp_els_dma, 0);
if (rval) {
ql_log(ql_log_warn, vha, 0x0188,
@@ -6605,9 +6613,9 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
if (rsp_payload)
dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_payload),
rsp_payload, rsp_payload_dma);
if (rsp_els)
dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_els),
rsp_els, rsp_els_dma);
if (rsp_els_pkt)
dma_free_coherent(&ha->pdev->dev, rsp_els_sz,
rsp_els_pkt, rsp_els_dma);
}
void
@@ -8376,6 +8384,7 @@ qla2x00_module_init(void)
BUILD_BUG_ON(sizeof(struct device_reg_82xx) != 1288);
BUILD_BUG_ON(sizeof(struct device_reg_fx00) != 216);
BUILD_BUG_ON(sizeof(struct els_entry_24xx) != 64);
BUILD_BUG_ON(sizeof(struct els_entry_24xx_ext) != 128);
BUILD_BUG_ON(sizeof(struct els_sts_entry_24xx) != 64);
BUILD_BUG_ON(sizeof(struct fxdisc_entry_fx00) != 64);
BUILD_BUG_ON(sizeof(struct imm_ntfy_from_isp) != 64);