From 6501ee1ec51187b685d6c3e7e771f40cd848f75f Mon Sep 17 00:00:00 2001 From: Nilesh Javali Date: Thu, 23 Jul 2026 10:33:49 +0530 Subject: [PATCH] qla2x00t-32gbit: Enhance task management IOCB handling for 29xx series Update qla24xx_tm_iocb() and __qla24xx_issue_tmf() to support the extended task management structure (tsk_mgmt_entry_ext) for 29xx adapters. tsk_mgmt_entry_ext overlays tsk_mgmt_entry through control_flags (offsets 0-27 are byte-identical): entry_type, entry_count, handle, nport_handle, timeout, lun and control_flags sit at the same offsets and widths. The layouts diverge only after that point: - the 24xx layout has port_id[3] + u8 vp_index; - the ext layout has __le16 vp_index and no port_id. Factor the common IOCB header writes through a single tsk_mgmt_entry * view and branch on IS_QLA29XX() only for the diverging port_id / vp_index assignments. Change qla24xx_tm_iocb() to accept void *pkt to allow casting to either structure type. Add tsk_ext member to the tsk_mgmt_cmd union and a BUILD_BUG_ON size check for the 128-byte extended structure. Signed-off-by: Nilesh Javali Reviewed-by: Hannes Reinecke Link: https://patch.msgid.link/20260723050413.3897522-33-njavali@marvell.com Signed-off-by: Martin K. Petersen (Oracle) [ commit 67aff6b6fe8f678bb8b3ce4778dedd673db3c688 upstream ] --- qla2x00t-32gbit/qla_iocb.c | 31 ++++++++++++++++++++++--------- qla2x00t-32gbit/qla_mbx.c | 18 ++++++++++++++---- qla2x00t-32gbit/qla_os.c | 1 + 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 411a3e557..1d0bf95cd 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2743,7 +2743,7 @@ qla2x00_adisc_iocb(srb_t *sp, struct mbx_entry *mbx) } static void -qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk) +qla24xx_tm_iocb(srb_t *sp, void *pkt) { uint32_t flags; uint64_t lun; @@ -2752,26 +2752,39 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk) struct qla_hw_data *ha = vha->hw; struct srb_iocb *iocb = &sp->u.iocb_cmd; struct req_que *req = sp->qpair->req; + struct tsk_mgmt_entry *tsk; flags = iocb->u.tmf.flags; lun = iocb->u.tmf.lun; + /* + * tsk_mgmt_entry_ext overlays tsk_mgmt_entry through control_flags + * (offsets 0-27 are byte-identical), so the common header writes + * go through one struct tsk_mgmt_entry * view. The ext layout + * has no port_id and uses a wider __le16 vp_index at a different + * offset, so port_id / vp_index assignments diverge per stride. + */ + tsk = pkt; tsk->entry_type = TSK_MGMT_IOCB_TYPE; tsk->entry_count = 1; tsk->handle = make_handle(req->id, tsk->handle); tsk->nport_handle = cpu_to_le16(fcport->loop_id); tsk->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); tsk->control_flags = cpu_to_le32(flags); - tsk->port_id[0] = fcport->d_id.b.al_pa; - tsk->port_id[1] = fcport->d_id.b.area; - tsk->port_id[2] = fcport->d_id.b.domain; - tsk->vp_index = fcport->vha->vp_idx; + if (IS_QLA29XX(ha)) { + ((struct tsk_mgmt_entry_ext *)pkt)->vp_index = + cpu_to_le16(fcport->vha->vp_idx); + } else { + tsk->port_id[0] = fcport->d_id.b.al_pa; + tsk->port_id[1] = fcport->d_id.b.area; + tsk->port_id[2] = fcport->d_id.b.domain; + tsk->vp_index = fcport->vha->vp_idx; + } - if (flags & (TCF_LUN_RESET | TCF_ABORT_TASK_SET| - TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) { + 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)); + host_to_fcp_swap((uint8_t *)&tsk->lun, sizeof(tsk->lun)); } } diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 7dff22789..9bef87862 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -3411,6 +3411,7 @@ qla24xx_abort_command(srb_t *sp) struct tsk_mgmt_cmd { union { struct tsk_mgmt_entry tsk; + struct tsk_mgmt_entry_ext tsk_ext; struct sts_entry_24xx sts; struct sts_entry_24xx_ext sts_ext; } p; @@ -3450,16 +3451,25 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, return QLA_MEMORY_ALLOC_FAILED; } + /* + * tsk_mgmt_entry_ext overlays tsk_mgmt_entry through control_flags; + * the common-header writes go through tsk->p.tsk and only port_id + * (24xx-only) and vp_index width / offset diverge. + */ tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE; tsk->p.tsk.entry_count = 1; tsk->p.tsk.handle = make_handle(req->id, tsk->p.tsk.handle); tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); tsk->p.tsk.control_flags = cpu_to_le32(type); - tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; - tsk->p.tsk.port_id[1] = fcport->d_id.b.area; - tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; - tsk->p.tsk.vp_index = fcport->vha->vp_idx; + if (IS_QLA29XX(ha)) { + tsk->p.tsk_ext.vp_index = cpu_to_le16(fcport->vha->vp_idx); + } else { + tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; + tsk->p.tsk.port_id[1] = fcport->d_id.b.area; + tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; + tsk->p.tsk.vp_index = fcport->vha->vp_idx; + } if (type == TCF_LUN_RESET) { int_to_scsilun(l, &tsk->p.tsk.lun); host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index aed099005..2979bfa0e 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -8681,6 +8681,7 @@ qla2x00_module_init(void) BUILD_BUG_ON(sizeof(struct sts_entry_24xx) != 64); BUILD_BUG_ON(sizeof(struct sts_entry_24xx_ext) != 128); BUILD_BUG_ON(sizeof(struct tsk_mgmt_entry) != 64); + BUILD_BUG_ON(sizeof(struct tsk_mgmt_entry_ext) != 128); BUILD_BUG_ON(sizeof(struct tsk_mgmt_entry_fx00) != 64); BUILD_BUG_ON(sizeof(struct verify_chip_entry_84xx) != 64); BUILD_BUG_ON(sizeof(struct verify_chip_rsp_84xx) != 52);