]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: Add support for NVMe-MI send command
authorTokunori Ikegami <ikegami.t@gmail.com>
Tue, 4 Apr 2023 17:11:57 +0000 (02:11 +0900)
committerDaniel Wagner <wagi@monom.org>
Wed, 5 Apr 2023 10:22:28 +0000 (12:22 +0200)
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
nvme-builtin.h
nvme.c

index 3ab7991bd2d9e18fac8260a97304687ba92cf1af..27a9f8df5365f7034e48cd7afcd1cbc65775275a 100644 (file)
@@ -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 703e591af036e788ed1c1f502028071df08b5bc8..b4f0dedb219a68247853e206eb8138d0da0fde48 100644 (file)
--- 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;