From 2cf1526810360023293f7e64111de8b3cad9b609 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Fri, 14 Oct 2022 01:07:24 +0900 Subject: [PATCH] util: Add get feature length 2 API to support direction parameter Since feature identifier 0Dh: host memory buffer length is affected by the direction as mentioned by the issue #1681. Signed-off-by: Tokunori Ikegami [dwagner: reordered definitions and declerations] Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/util.c | 16 ++++++++++++++++ src/nvme/util.h | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index ac27d129..fdbb5e57 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -5,6 +5,7 @@ LIBNVME_1_2 { nvme_ctrl_get_dhchap_host_key; nvme_ctrl_set_dhchap_host_key; nvmf_get_discovery_wargs; + nvme_get_feature_length2; }; LIBNVME_1_1 { diff --git a/src/nvme/util.c b/src/nvme/util.c index 4363d5e4..653bb362 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -494,6 +494,22 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) return 0; } +int nvme_get_feature_length2(int fid, __u32 cdw11, enum nvme_data_tfr dir, + __u32 *len) +{ + switch (fid) { + case NVME_FEAT_FID_HOST_MEM_BUF: + if (dir == NVME_DATA_TFR_HOST_TO_CTRL) { + *len = 0; + break; + } + fallthrough; + default: + return nvme_get_feature_length(fid, cdw11, len); + } + return 0; +} + int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 *len) { diff --git a/src/nvme/util.h b/src/nvme/util.h index 6f1d3e9f..6848c67f 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -17,6 +17,12 @@ * libnvme utility functions */ +#if __has_attribute(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +#else +# define fallthrough do {} while (0) /* fallthrough */ +#endif + /** * enum nvme_connect_err - nvme connect error codes * @ENVME_CONNECT_RESOLVE: failed to resolve host @@ -155,6 +161,37 @@ void nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs, */ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len); +/** + * enum nvme_data_tfr - Data transfer direction of the command + * @NVME_DATA_TFR_NO_DATA_TFR: No data transfer + * @NVME_DATA_TFR_HOST_TO_CTRL: Host to controller + * @NVME_DATA_TFR_CTRL_TO_HOST: Controller to host + * @NVME_DATA_TFR_BIDIRECTIONAL: Bidirectional + */ +enum nvme_data_tfr { + NVME_DATA_TFR_NO_DATA_TFR, + NVME_DATA_TFR_HOST_TO_CTRL, + NVME_DATA_TFR_CTRL_TO_HOST, + NVME_DATA_TFR_BIDIRECTIONAL +}; + +/** + * nvme_get_feature_length2() - Retreive the command payload length for a + * specific feature identifier + * @fid: Feature identifier, see &enum nvme_features_id. + * @cdw11: The cdw11 value may affect the transfer (only known fid is + * %NVME_FEAT_FID_HOST_ID) + * @dir: Data transfer direction: false - host to controller, true - + * controller to host may affect the transfer (only known fid is + * %NVME_FEAT_FID_HOST_MEM_BUF). + * @len: On success, set to this features payload length in bytes. + * + * Return: 0 on success, -1 with errno set to EINVAL if the function did not + * recognize &fid. + */ +int nvme_get_feature_length2(int fid, __u32 cdw11, enum nvme_data_tfr dir, + __u32 *len); + /** * nvme_get_directive_receive_length() - Get directive receive length * @dtype: Directive type, see &enum nvme_directive_dtype -- 2.50.1