From 7fcee0a3da95b3ef8147987823beeb289e03db23 Mon Sep 17 00:00:00 2001 From: Caleb Sander Date: Fri, 8 Sep 2023 12:10:08 -0600 Subject: [PATCH] ioctl: pass data for Get/Set Features commands Several nvme_{g,s}et_features_*() functions take a data buffer but don't provide it to the Get/Set Features commands. Fix them to pass the data buffer to nvme_{g,s}et_features(). Getting the Host Memory Buffer feature also returns a struct nvme_host_mem_buf_attrs data structure, so make a nvme_get_features_host_mem_buf2() function that takes in a data buffer to receive it. Signed-off-by: Caleb Sander --- src/libnvme.map | 1 + src/nvme/ioctl.c | 57 +++++++++++++++++++++++++++++++++++++----------- src/nvme/ioctl.h | 20 ++++++++++++++++- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index 2f12ccef..29f4c180 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -5,6 +5,7 @@ LIBNVME_1_6 { nvme_ctrl_find; nvme_ctrl_get_src_addr; nvme_ctrl_release_fd; + nvme_get_features_host_mem_buf2; nvme_host_release_fds; nvme_ns_release_fd; nvme_root_release_fds; diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index eb6cd8b7..d2b672d2 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -665,10 +665,21 @@ int nvme_set_features_async_event(int fd, __u32 events, int nvme_set_features_auto_pst(int fd, bool apste, bool save, struct nvme_feat_auto_pst *apst, __u32 *result) { - __u32 value = NVME_SET(!!apste, FEAT_APST_APSTE); + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_AUTO_PST, + .nsid = NVME_NSID_NONE, + .cdw11 = NVME_SET(!!apste, FEAT_APST_APSTE), + .save = save, + .uuidx = NVME_UUID_NONE, + .data = apst, + .data_len = sizeof(*apst), + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; - return __nvme_set_features(fd, NVME_FEAT_FID_AUTO_PST, value, save, - result); + return nvme_set_features(&args); } int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp) @@ -748,8 +759,8 @@ int nvme_set_features_plm_config(int fd, bool plm, __u16 nvmsetid, bool save, .save = save, .uuidx = NVME_UUID_NONE, .cdw15 = 0, - .data_len = 0, - .data = NULL, + .data_len = sizeof(*data), + .data = data, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .result = result, }; @@ -952,8 +963,8 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, .sel = sel, .cdw11 = 0, .uuidx = NVME_UUID_NONE, - .data_len = 0, - .data = NULL, + .data_len = sizeof(*data), + .data = data, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .result = result, }; @@ -1037,8 +1048,8 @@ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, .sel = sel, .cdw11 = 0, .uuidx = NVME_UUID_NONE, - .data_len = 0, - .data = NULL, + .data_len = sizeof(*apst), + .data = apst, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .result = result, }; @@ -1052,6 +1063,26 @@ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, return __nvme_get_features(fd, NVME_FEAT_FID_HOST_MEM_BUF, sel, result); } +int nvme_get_features_host_mem_buf2(int fd, enum nvme_get_features_sel sel, + struct nvme_host_mem_buf_attrs *attrs, + __u32 *result) +{ + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_HOST_MEM_BUF, + .nsid = NVME_NSID_NONE, + .sel = sel, + .uuidx = NVME_UUID_NONE, + .data = attrs, + .data_len = sizeof(*attrs), + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); +} + int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts) { @@ -1104,8 +1135,8 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, .sel = sel, .cdw11 = nvmsetid, .uuidx = NVME_UUID_NONE, - .data_len = 0, - .data = NULL, + .data_len = sizeof(*data), + .data = data, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .result = result, }; @@ -1152,8 +1183,8 @@ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, .sel = sel, .cdw11 = 0, .uuidx = NVME_UUID_NONE, - .data_len = 0, - .data = NULL, + .data_len = sizeof(*data), + .data = data, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .result = result, }; diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 2a6c4621..916fa871 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2758,6 +2758,10 @@ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, /** * nvme_get_features_host_mem_buf() - Get host memory buffer feature + * + * Deprecated: doesn't fetch the Host Memory Buffer Attributes data structure. + * Use nvme_get_features_host_mem_buf2() instead. + * * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2766,7 +2770,21 @@ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, - __u32 *result); + __u32 *result) __attribute__((deprecated)); + +/** + * nvme_get_features_host_mem_buf2() - Get host memory buffer feature + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @attrs: Buffer for returned Host Memory Buffer Attributes + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_features_host_mem_buf2(int fd, enum nvme_get_features_sel sel, + struct nvme_host_mem_buf_attrs *attrs, + __u32 *result); /** * nvme_get_features_timestamp() - Get timestamp feature -- 2.50.1