From: Tokunori Ikegami Date: Tue, 4 Apr 2023 17:11:57 +0000 (+0900) Subject: nvme: Add support for NVMe-MI send command X-Git-Tag: v2.5~187 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f1f0e92d4923ecf6b465e93c4efea5275577a211;p=users%2Fsagi%2Fnvme-cli.git nvme: Add support for NVMe-MI send command Signed-off-by: Tokunori Ikegami --- diff --git a/nvme-builtin.h b/nvme-builtin.h index 3ab7991b..27a9f8df 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -110,6 +110,7 @@ COMMAND_LIST( ENTRY("io-mgmt-recv", "I/O Management Receive", io_mgmt_recv) ENTRY("io-mgmt-send", "I/O Management Send", io_mgmt_send) ENTRY("nvme-mi-recv", "Submit a NVMe-MI Receive command, return results", nmi_recv) + ENTRY("nvme-mi-send", "Submit a NVMe-MI Send command, return results", nmi_send) ); #endif diff --git a/nvme.c b/nvme.c index 703e591a..b4f0dedb 100644 --- a/nvme.c +++ b/nvme.c @@ -9186,9 +9186,8 @@ static int dim_cmd(int argc, char **argv, struct command *command, struct plugin return nvmf_dim(desc, argc, argv); } -static int nmi_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc) { - const char *desc = "Send a NVMe-MI Receive command to the specified device, return results."; const char *opcode = "opcode (required)"; const char *data_len = "data I/O length (bytes)"; const char *nmimt = "nvme-mi message type"; @@ -9198,7 +9197,10 @@ static int nmi_recv(int argc, char **argv, struct command *cmd, struct plugin *p int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH; void *data = NULL; - int err = 0, fd; + int err = 0; + bool send = admin_opcode == nvme_admin_nvme_mi_send ? true : false; + int fd = send ? STDIN_FILENO : STDOUT_FILENO; + int flags = send ? O_RDONLY : O_WRONLY | O_CREAT; struct nvme_dev *dev; __u32 result; bool huge = false; @@ -9238,10 +9240,8 @@ static int nmi_recv(int argc, char **argv, struct command *cmd, struct plugin *p if (err) goto ret; - fd = STDOUT_FILENO; - if (strlen(cfg.input_file)) { - fd = open(cfg.input_file, O_WRONLY | O_CREAT, mode); + fd = open(cfg.input_file, flags, mode); if (fd < 0) { perror(cfg.input_file); err = -EINVAL; @@ -9255,9 +9255,17 @@ static int nmi_recv(int argc, char **argv, struct command *cmd, struct plugin *p err = -ENOMEM; goto close_fd; } + if (send) { + if (read(fd, data, cfg.data_len) < 0) { + err = -errno; + fprintf(stderr, "failed to read write buffer %s\n", + strerror(errno)); + goto free_data; + } + } } - err = nvme_cli_admin_passthru(dev, nvme_admin_nvme_mi_recv, 0, 0, cfg.namespace_id, 0, 0, + err = nvme_cli_admin_passthru(dev, admin_opcode, 0, 0, cfg.namespace_id, 0, 0, cfg.nmimt << 11 | 4, cfg.opcode, cfg.nmd0, cfg.nmd1, 0, 0, cfg.data_len, data, 0, NULL, 0, &result); if (err < 0) { @@ -9266,18 +9274,19 @@ static int nmi_recv(int argc, char **argv, struct command *cmd, struct plugin *p nvme_show_status(err); } else { printf("%s Command is Success and result: 0x%08x (status: 0x%02x, response: 0x%06x)\n", - nvme_cmd_to_string(true, nvme_admin_nvme_mi_recv), + nvme_cmd_to_string(true, admin_opcode), result, result & 0xff, result >> 8); if (result & 0xff) printf("status: %s\n", nvme_mi_status_to_string(result & 0xff)); - if (strlen(cfg.input_file)) { + if (!send && strlen(cfg.input_file)) { if (write(fd, (void *)data, cfg.data_len) < 0) perror("failed to write data buffer"); - } else if (data && !err) { + } else if (data && !send && !err) { d((unsigned char *)data, cfg.data_len, 16, 1); } } +free_data: nvme_free(data, huge); close_fd: if (strlen(cfg.input_file)) @@ -9288,6 +9297,20 @@ ret: return err; } +static int nmi_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Send a NVMe-MI Receive command to the specified device, return results."; + + return nvme_mi(argc, argv, nvme_admin_nvme_mi_recv, desc); +} + +static int nmi_send(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "Send a NVMe-MI Send command to the specified device, return results."; + + return nvme_mi(argc, argv, nvme_admin_nvme_mi_send, desc); +} + void register_extension(struct plugin *plugin) { plugin->parent = &nvme;