From aef4b82fd14c0fb4be9abf25f45ab0c7074cb9ba Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH] Use argument structure for nvme_fw_download() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 17 +++++++++-------- src/nvme/ioctl.h | 21 +++++++++++++++++---- src/nvme/linux.c | 18 +++++++++++++----- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 44e3d1ba..d4dfe335 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1206,22 +1206,23 @@ int nvme_ns_attach(struct nvme_ns_attach_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, NULL); } -int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, - __u32 timeout, __u32 *result) +int nvme_fw_download(struct nvme_fw_download_args *args) { - __u32 cdw10 = (data_len >> 2) - 1; - __u32 cdw11 = offset >> 2; + __u32 cdw10 = (args->data_len >> 2) - 1; + __u32 cdw11 = args->offset >> 2; struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_fw_download, .cdw10 = cdw10, .cdw11 = cdw11, - .data_len = data_len, - .addr = (__u64)(uintptr_t)data, - .timeout_ms = timeout, + .data_len = args->data_len, + .addr = (__u64)(uintptr_t)args->data, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 4e307919..c07c7f65 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2859,14 +2859,28 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, } /** - * nvme_fw_download() - Download part or all of a firmware image to the - * controller + * nvme_fw_download_args - Arguments for the NVMe Firmware Download command * @fd: File descriptor of nvme device * @offset: Offset in the firmware data * @data_len: Length of data in this command in bytes * @data: Userspace address of the firmware data * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_fw_download_args { + int args_size; + int fd; + __u32 offset; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_fw_download() - Download part or all of a firmware image to the + * controller + * @args: &struct nvme_fw_download_args argument structure * * The Firmware Image Download command downloads all or a portion of an image * for a future update to the controller. The Firmware Image Download command @@ -2884,8 +2898,7 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, - __u32 timeout, __u32 *result); +int nvme_fw_download(struct nvme_fw_download_args *args); /** * nvme_fw_commit() - Commit firmware using the specified action diff --git a/src/nvme/linux.c b/src/nvme/linux.c index 48a12e4a..747d69b2 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -92,17 +92,25 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, void *buf) { int err = 0; + struct nvme_fw_download_args args = { + .args_size = sizeof(args), + .fd = fd, + .offset = offset, + .data_len = xfer, + .data = buf, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; while (size > 0) { - xfer = MIN(xfer, size); - err = nvme_fw_download(fd, offset, xfer, buf, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + args.data_len = MIN(xfer, size); + err = nvme_fw_download(&args); if (err) break; - buf += xfer; + args.data += xfer; size -= xfer; - offset += xfer; + args.offset += xfer; } return err; -- 2.50.1