mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 16:53:20 -04:00
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:
committed by
Martin K. Petersen (Oracle)
parent
7db93e3c58
commit
87a42b53f4
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user