From e1b1026ff11db4c82bfc9dbb26d1c9fb85beb19a Mon Sep 17 00:00:00 2001 From: Dmitry Sherstoboev Date: Fri, 2 May 2025 15:27:03 +0800 Subject: [PATCH] types: Change LM CDQ sz argument from u8 to u32. To maintain backwards compatibility, the old sz renamed to sz_u8. According to NVMe 2.1 Base Specificaiton, Controller Data Queue Size (CDQSIZE) occupies bits 31:00 of CDW12, so it should be using u32. Signed-off-by: Dmitry Sherstoboev --- src/nvme/api-types.h | 8 ++++++-- src/nvme/ioctl.c | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/nvme/api-types.h b/src/nvme/api-types.h index 23c512aeb..149ba22c7 100644 --- a/src/nvme/api-types.h +++ b/src/nvme/api-types.h @@ -976,7 +976,9 @@ struct nvme_dim_args { * by the controller if no error is present. For Delete CDQ, this field is the CDQID * to delete. * @sel: Select (SEL): This field specifies the type of management operation to perform. - * @sz: For Create CDQ, specifies the size of CDQ, in dwords + * @sz_u8: For Create CDQ, specifies the size of CDQ, in dwords - 1 byte + * @rsvd1: Reserved + * @sz: For Create CDQ, specifies the size of CDQ, in dwords - 4 byte */ struct nvme_lm_cdq_args { __u32 *result; @@ -988,7 +990,9 @@ struct nvme_lm_cdq_args { __u16 cntlid; __u16 cdqid; __u8 sel; - __u8 sz; + __u8 sz_u8; + __u8 rsvd1[4]; + __u32 sz; }; /** diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 4e362c95d..9a9db0be3 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -2353,15 +2353,27 @@ int nvme_dim_send(struct nvme_dim_args *args) int nvme_lm_cdq(struct nvme_lm_cdq_args *args) { + const size_t size_v1 = sizeof_args(struct nvme_lm_cdq_args, sz_u8, __u64); + const size_t size_v2 = sizeof_args(struct nvme_lm_cdq_args, sz, __u64); __u32 cdw10 = NVME_SET(args->sel, LM_CDQ_SEL) | NVME_SET(args->mos, LM_CDQ_MOS); - __u32 cdw11 = 0, data_len = 0; + __u32 cdw11 = 0, data_len = 0, sz = 0; int err; + if (args->args_size < size_v1 || args->args_size > size_v2) { + errno = EINVAL; + return -1; + } + + if (args->args_size == size_v1) + sz = args->sz_u8; + else + sz = args->sz; + if (args->sel == NVME_LM_SEL_CREATE_CDQ) { cdw11 = NVME_SET(args->cntlid, LM_CREATE_CDQ_CNTLID) | NVME_LM_CREATE_CDQ_PC; - data_len = args->sz << 2; + data_len = sz << 2; } else if (args->sel == NVME_LM_SEL_DELETE_CDQ) { cdw11 = NVME_SET(args->cdqid, LM_DELETE_CDQ_CDQID); } @@ -2370,7 +2382,7 @@ int nvme_lm_cdq(struct nvme_lm_cdq_args *args) .opcode = nvme_admin_ctrl_data_queue, .cdw10 = cdw10, .cdw11 = cdw11, - .cdw12 = args->sz, + .cdw12 = sz, .addr = (__u64)(uintptr_t)args->data, .data_len = data_len, .timeout_ms = args->timeout,