mirror of
https://github.com/SCST-project/scst.git
synced 2026-10-22 14:12:33 +00:00
qla2x00t-32gbit: Add LS4 pass-through IOCB handling for 29xx series
Extend the LS4 pass-through IOCB handling to support the 128-byte pt_ls4_request_ext layout used by 29xx series adapters. The extension grows inline DSD capacity from 2 to 5 entries. Function signatures are widened to void * so both layouts can be passed without casts. pt_ls4_request_ext overlays pt_ls4_request through exchange_address (offsets 0-27 are byte-identical), so common-header writes go through a single struct pt_ls4_request * view; only the divergent fields (vp_index width, tx_/rx_byte_count offset, dsd[] base) are branched. Signed-off-by: Manish Rangankar <mrangankar@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Reviewed-by: Hannes Reinecke <hare@kernel.org> Link: https://patch.msgid.link/20260723050413.3897522-39-njavali@marvell.com Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org> [ commit 33c37242b8128fe6de92af26f9f9b48a9de1d568 upstream ]
This commit is contained in:
committed by
Gleb Chesnokov
parent
48d4c315db
commit
90be72c38f
@@ -295,6 +295,43 @@ struct ct_entry_24xx_ext {
|
||||
struct dsd64 dsd[NUM_CT_DSDS]; /* Data Segment Descriptors */
|
||||
};
|
||||
|
||||
/*
|
||||
* 29xx extended Link Service pass-through request IOCB (128 bytes).
|
||||
*
|
||||
* Same wire purpose as the 64-byte struct pt_ls4_request used on 24xx-class
|
||||
* adapters, but laid out for the 128-byte 29xx request ring:
|
||||
* - vp_index widened to __le16 (bits [8:0] meaningful, see
|
||||
* CMD_EXT_VP_INDEX_MASK).
|
||||
* - reserved area expanded to 32 bytes between exchange_address and
|
||||
* rx_byte_count.
|
||||
* - inline DSD capacity grown from 2 to 5.
|
||||
* Header through 'tx_dseg_count' (offset 14) and the control_flags /
|
||||
* exchange_address fields keep the same offsets as struct pt_ls4_request,
|
||||
* so common code can populate them via either type once IS_QLA29XX(ha) is
|
||||
* branched for the layout-divergent fields.
|
||||
*/
|
||||
#define NUM_PT_LS4_EXT_DSDS 5
|
||||
struct pt_ls4_request_ext {
|
||||
uint8_t entry_type;
|
||||
uint8_t entry_count;
|
||||
uint8_t sys_define;
|
||||
uint8_t entry_status;
|
||||
uint32_t handle;
|
||||
__le16 status;
|
||||
__le16 nport_handle;
|
||||
__le16 tx_dseg_count;
|
||||
__le16 vp_index; /* VP Index 9 bits; see CMD_EXT_VP_INDEX_MASK */
|
||||
__le16 timeout;
|
||||
__le16 control_flags; /* CF_LS4_* (see struct pt_ls4_request) */
|
||||
__le16 rx_dseg_count;
|
||||
__le16 rsvd2;
|
||||
__le32 exchange_address;
|
||||
uint8_t rsvd3[32];
|
||||
__le32 rx_byte_count;
|
||||
__le32 tx_byte_count;
|
||||
struct dsd64 dsd[NUM_PT_LS4_EXT_DSDS];
|
||||
};
|
||||
|
||||
/*
|
||||
* ISP queue - PUREX IOCB entry structure definition
|
||||
*/
|
||||
|
||||
+50
-24
@@ -4055,39 +4055,65 @@ static void qla2x00_send_notify_ack_iocb(srb_t *sp,
|
||||
}
|
||||
|
||||
/*
|
||||
* Build NVME LS request
|
||||
* Build NVME LS request.
|
||||
*
|
||||
* pt_ls4_request_ext overlays pt_ls4_request through exchange_address
|
||||
* (offsets 0-27 are byte-identical), so the common-header writes go
|
||||
* through one struct pt_ls4_request * view. The ext layout has a wider
|
||||
* __le16 vp_index and places rx_/tx_byte_count and dsd[] at different
|
||||
* offsets, so those assignments diverge per stride.
|
||||
*/
|
||||
static void
|
||||
qla_nvme_ls(srb_t *sp, struct pt_ls4_request *cmd_pkt)
|
||||
qla_nvme_ls(srb_t *sp, void *cmd_pkt)
|
||||
{
|
||||
struct srb_iocb *nvme;
|
||||
struct srb_iocb *nvme = &sp->u.iocb_cmd;
|
||||
struct qla_hw_data *ha = sp->vha->hw;
|
||||
struct pt_ls4_request *pkt = cmd_pkt;
|
||||
|
||||
nvme = &sp->u.iocb_cmd;
|
||||
cmd_pkt->entry_type = PT_LS4_REQUEST;
|
||||
cmd_pkt->entry_count = 1;
|
||||
|
||||
cmd_pkt->timeout = cpu_to_le16(nvme->u.nvme.timeout_sec);
|
||||
cmd_pkt->vp_index = sp->fcport->vha->vp_idx;
|
||||
pkt->entry_type = PT_LS4_REQUEST;
|
||||
pkt->entry_count = 1;
|
||||
pkt->timeout = cpu_to_le16(nvme->u.nvme.timeout_sec);
|
||||
pkt->tx_dseg_count = cpu_to_le16(1);
|
||||
|
||||
if (sp->unsol_rsp) {
|
||||
cmd_pkt->control_flags =
|
||||
cpu_to_le16(CF_LS4_RESPONDER << CF_LS4_SHIFT);
|
||||
cmd_pkt->nport_handle = nvme->u.nvme.nport_handle;
|
||||
cmd_pkt->exchange_address = nvme->u.nvme.exchange_address;
|
||||
pkt->control_flags =
|
||||
cpu_to_le16(CF_LS4_RESPONDER << CF_LS4_SHIFT);
|
||||
pkt->nport_handle = nvme->u.nvme.nport_handle;
|
||||
pkt->exchange_address = nvme->u.nvme.exchange_address;
|
||||
} else {
|
||||
cmd_pkt->control_flags =
|
||||
cpu_to_le16(CF_LS4_ORIGINATOR << CF_LS4_SHIFT);
|
||||
cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
cmd_pkt->rx_dseg_count = cpu_to_le16(1);
|
||||
cmd_pkt->rx_byte_count = nvme->u.nvme.rsp_len;
|
||||
cmd_pkt->dsd[1].length = nvme->u.nvme.rsp_len;
|
||||
put_unaligned_le64(nvme->u.nvme.rsp_dma, &cmd_pkt->dsd[1].address);
|
||||
pkt->control_flags =
|
||||
cpu_to_le16(CF_LS4_ORIGINATOR << CF_LS4_SHIFT);
|
||||
pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
pkt->rx_dseg_count = cpu_to_le16(1);
|
||||
}
|
||||
|
||||
cmd_pkt->tx_dseg_count = cpu_to_le16(1);
|
||||
cmd_pkt->tx_byte_count = nvme->u.nvme.cmd_len;
|
||||
cmd_pkt->dsd[0].length = nvme->u.nvme.cmd_len;
|
||||
put_unaligned_le64(nvme->u.nvme.cmd_dma, &cmd_pkt->dsd[0].address);
|
||||
if (IS_QLA29XX(ha)) {
|
||||
struct pt_ls4_request_ext *ext = cmd_pkt;
|
||||
|
||||
ext->vp_index = cpu_to_le16(sp->fcport->vha->vp_idx);
|
||||
ext->tx_byte_count = nvme->u.nvme.cmd_len;
|
||||
ext->dsd[0].length = nvme->u.nvme.cmd_len;
|
||||
put_unaligned_le64(nvme->u.nvme.cmd_dma,
|
||||
&ext->dsd[0].address);
|
||||
if (!sp->unsol_rsp) {
|
||||
ext->rx_byte_count = nvme->u.nvme.rsp_len;
|
||||
ext->dsd[1].length = nvme->u.nvme.rsp_len;
|
||||
put_unaligned_le64(nvme->u.nvme.rsp_dma,
|
||||
&ext->dsd[1].address);
|
||||
}
|
||||
} else {
|
||||
pkt->vp_index = sp->fcport->vha->vp_idx;
|
||||
pkt->tx_byte_count = nvme->u.nvme.cmd_len;
|
||||
pkt->dsd[0].length = nvme->u.nvme.cmd_len;
|
||||
put_unaligned_le64(nvme->u.nvme.cmd_dma,
|
||||
&pkt->dsd[0].address);
|
||||
if (!sp->unsol_rsp) {
|
||||
pkt->rx_byte_count = nvme->u.nvme.rsp_len;
|
||||
pkt->dsd[1].length = nvme->u.nvme.rsp_len;
|
||||
put_unaligned_le64(nvme->u.nvme.rsp_dma,
|
||||
&pkt->dsd[1].address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -4058,7 +4058,7 @@ qla24xx_abort_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
}
|
||||
|
||||
void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha,
|
||||
struct pt_ls4_request *pkt, struct req_que *req)
|
||||
void *pkt, struct req_que *req)
|
||||
{
|
||||
srb_t *sp;
|
||||
const char func[] = "LS4_IOCB";
|
||||
@@ -4068,7 +4068,9 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha,
|
||||
if (!sp)
|
||||
return;
|
||||
|
||||
comp_status = le16_to_cpu(pkt->status);
|
||||
/* status lives at the same offset (8) in both IOCB strides */
|
||||
comp_status = le16_to_cpu(((struct pt_ls4_request *)pkt)->status);
|
||||
|
||||
sp->done(sp, comp_status);
|
||||
}
|
||||
|
||||
@@ -4236,8 +4238,7 @@ process_err:
|
||||
qlt_response_pkt_all_vps(vha, rsp, (response_t *)pkt);
|
||||
break;
|
||||
case PT_LS4_REQUEST:
|
||||
qla24xx_nvme_ls4_iocb(vha, (struct pt_ls4_request *)pkt,
|
||||
rsp->req);
|
||||
qla24xx_nvme_ls4_iocb(vha, pkt, rsp->req);
|
||||
break;
|
||||
case NOTIFY_ACK_TYPE:
|
||||
if (((response_t *)pkt)->handle == QLA_TGT_SKIP_HANDLE)
|
||||
|
||||
+39
-19
@@ -1132,37 +1132,57 @@ static void qla_nvme_fc_format_rjt(void *buf, u8 ls_cmd, u8 reason,
|
||||
rjt->rjt.vendor = vendor;
|
||||
}
|
||||
|
||||
/*
|
||||
* pt_ls4_request_ext overlays pt_ls4_request through exchange_address
|
||||
* (offsets 0-27 are byte-identical), so the common-header writes go
|
||||
* through one struct pt_ls4_request * view. The ext layout has a wider
|
||||
* __le16 vp_index and places tx_/rx_byte_count and dsd[] at different
|
||||
* offsets, so those assignments diverge per stride.
|
||||
*/
|
||||
static void qla_nvme_lsrjt_pt_iocb(struct scsi_qla_host *vha,
|
||||
struct pt_ls4_request *lsrjt_iocb,
|
||||
void *lsrjt_iocb,
|
||||
struct qla_nvme_lsrjt_pt_arg *a)
|
||||
{
|
||||
lsrjt_iocb->entry_type = PT_LS4_REQUEST;
|
||||
lsrjt_iocb->entry_count = 1;
|
||||
lsrjt_iocb->sys_define = 0;
|
||||
lsrjt_iocb->entry_status = 0;
|
||||
lsrjt_iocb->handle = QLA_SKIP_HANDLE;
|
||||
lsrjt_iocb->nport_handle = a->nport_handle;
|
||||
lsrjt_iocb->exchange_address = a->xchg_address;
|
||||
lsrjt_iocb->vp_index = a->vp_idx;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct pt_ls4_request *pkt = lsrjt_iocb;
|
||||
|
||||
lsrjt_iocb->control_flags = cpu_to_le16(a->control_flags);
|
||||
pkt->entry_type = PT_LS4_REQUEST;
|
||||
pkt->entry_count = 1;
|
||||
pkt->sys_define = 0;
|
||||
pkt->entry_status = 0;
|
||||
pkt->handle = QLA_SKIP_HANDLE;
|
||||
pkt->nport_handle = a->nport_handle;
|
||||
pkt->exchange_address = a->xchg_address;
|
||||
pkt->control_flags = cpu_to_le16(a->control_flags);
|
||||
pkt->tx_dseg_count = cpu_to_le16(1);
|
||||
pkt->rx_dseg_count = 0;
|
||||
|
||||
put_unaligned_le64(a->tx_addr, &lsrjt_iocb->dsd[0].address);
|
||||
lsrjt_iocb->dsd[0].length = cpu_to_le32(a->tx_byte_count);
|
||||
lsrjt_iocb->tx_dseg_count = cpu_to_le16(1);
|
||||
lsrjt_iocb->tx_byte_count = cpu_to_le32(a->tx_byte_count);
|
||||
if (IS_QLA29XX(ha)) {
|
||||
struct pt_ls4_request_ext *ext = lsrjt_iocb;
|
||||
|
||||
put_unaligned_le64(a->rx_addr, &lsrjt_iocb->dsd[1].address);
|
||||
lsrjt_iocb->dsd[1].length = 0;
|
||||
lsrjt_iocb->rx_dseg_count = 0;
|
||||
lsrjt_iocb->rx_byte_count = 0;
|
||||
ext->vp_index = cpu_to_le16(a->vp_idx);
|
||||
ext->tx_byte_count = cpu_to_le32(a->tx_byte_count);
|
||||
ext->rx_byte_count = 0;
|
||||
put_unaligned_le64(a->tx_addr, &ext->dsd[0].address);
|
||||
ext->dsd[0].length = cpu_to_le32(a->tx_byte_count);
|
||||
put_unaligned_le64(a->rx_addr, &ext->dsd[1].address);
|
||||
ext->dsd[1].length = 0;
|
||||
} else {
|
||||
pkt->vp_index = a->vp_idx;
|
||||
pkt->tx_byte_count = cpu_to_le32(a->tx_byte_count);
|
||||
pkt->rx_byte_count = 0;
|
||||
put_unaligned_le64(a->tx_addr, &pkt->dsd[0].address);
|
||||
pkt->dsd[0].length = cpu_to_le32(a->tx_byte_count);
|
||||
put_unaligned_le64(a->rx_addr, &pkt->dsd[1].address);
|
||||
pkt->dsd[1].length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
qla_nvme_ls_reject_iocb(struct scsi_qla_host *vha, struct qla_qpair *qp,
|
||||
struct qla_nvme_lsrjt_pt_arg *a, bool is_xchg_terminate)
|
||||
{
|
||||
struct pt_ls4_request *lsrjt_iocb;
|
||||
void *lsrjt_iocb;
|
||||
|
||||
lsrjt_iocb = __qla2x00_alloc_iocbs(qp, NULL);
|
||||
if (!lsrjt_iocb) {
|
||||
|
||||
@@ -169,7 +169,7 @@ static inline void qla_nvme_delete(struct scsi_qla_host *vha)
|
||||
}
|
||||
#endif
|
||||
|
||||
void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *,
|
||||
struct req_que *);
|
||||
void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha, void *pkt,
|
||||
struct req_que *req);
|
||||
void qla24xx_async_gffid_sp_done(struct srb *sp, int);
|
||||
#endif
|
||||
|
||||
@@ -8655,6 +8655,7 @@ qla2x00_module_init(void)
|
||||
BUILD_BUG_ON(sizeof(struct nvram_24xx) != 512);
|
||||
BUILD_BUG_ON(sizeof(struct nvram_81xx) != 512);
|
||||
BUILD_BUG_ON(sizeof(struct pt_ls4_request) != 64);
|
||||
BUILD_BUG_ON(sizeof(struct pt_ls4_request_ext) != 128);
|
||||
BUILD_BUG_ON(sizeof(struct pt_ls4_rx_unsol) != 64);
|
||||
BUILD_BUG_ON(sizeof(struct purex_entry_24xx) != 64);
|
||||
BUILD_BUG_ON(sizeof(struct purex_entry_24xx_ext) != 128);
|
||||
|
||||
Reference in New Issue
Block a user