]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: Add Identify for CNS 08h NVMe spec 2.0a based
authorSteven Seungcheol Lee <sc108.lee@samsung.com>
Wed, 25 Aug 2021 08:24:02 +0000 (17:24 +0900)
committerDaniel Wagner <dwagner@suse.de>
Mon, 15 Nov 2021 11:06:29 +0000 (12:06 +0100)
I/O Command Set Independent Identify Namespace data structure (CNS
08h) Most of data comes from existing data of id-ns which is common
from All I/O command set

Signed-off-by: Steven Seungcheol Lee <sc108.lee@samsung.com>
[dwagner: ported from monolitic branch and updated context]
Signed-off-by: Daniel Wagner <dwagner@suse.de>
nvme-builtin.h
nvme-print.c
nvme-print.h
nvme.c

index 808394102a893335f946f3653156321fbd024940..53cea34826538633db428b78f20816f7b30b50b9 100644 (file)
@@ -17,6 +17,7 @@ COMMAND_LIST(
        ENTRY("nvm-id-ctrl", "Send NVMe Identify Controller NVM Command Set, display structure", nvm_id_ctrl)
        ENTRY("primary-ctrl-caps", "Send NVMe Identify Primary Controller Capabilities", primary_ctrl_caps)
        ENTRY("list-secondary", "List Secondary Controllers associated with a Primary Controller", list_secondary_ctrl)
+       ENTRY("cmdset-ind-id-ns", "I/O Command Set Independent Identify Namespace", cmd_set_independent_id_ns)
        ENTRY("ns-descs", "Send NVMe Namespace Descriptor List, display structure", ns_descs)
        ENTRY("id-nvmset", "Send NVMe Identify NVM Set List, display structure", id_nvmset)
        ENTRY("id-uuid", "Send NVMe Identify UUID List, display structure", id_uuid)
index 424769a42ceb743e5ed6ecfa020047382ebad3e4..e89d236109b12d4f2f597608b6735220777158e5 100644 (file)
@@ -3542,6 +3542,88 @@ void nvme_show_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
        }
 }
 
+static void nvme_show_cmd_set_independent_id_ns_nsfeat(__u8 nsfeat)
+{
+       __u8 rsvd5 = (nsfeat & 0xE0) >> 5;
+       __u8 rmedia = (nsfeat & 0x10) >> 4;
+       __u8 uidreuse = (nsfeat & 0x8) >> 3;
+       __u8 rsvd0 = (nsfeat & 0x7);
+       if (rsvd5)
+               printf("  [7:5] : %#x\tReserved\n", rsvd5);
+       printf("  [4:4] : %#x\tNamespace %sstore data on rotational media\n",
+               rmedia, rmedia ? "" : "does not ");
+       printf("  [3:3] : %#x\tNGUID and EUI64 fields if non-zero, %sReused\n",
+               uidreuse, uidreuse ? "Never " : "");
+       if (rsvd0)
+               printf("  [2:0] : %#x\tReserved\n", rsvd0);
+       printf("\n");
+}
+
+static void nvme_show_cmd_set_independent_id_ns_nstat(__u8 nstat)
+{
+       __u8 rsvd1 = (nstat & 0xfe) >> 1;
+       __u8 nrdy = nstat & 0x1;
+       if (rsvd1)
+               printf("  [7:1] : %#x\tReserved\n", rsvd1);
+       printf("  [0:0] : %#x\tName space is %sready\n",
+               nrdy, nrdy ? "" : "not ");
+       printf("\n");
+}
+
+static void json_nvme_cmd_set_independent_id_ns(
+       struct nvme_id_independent_id_ns *ns)
+{
+       struct json_object *root;
+       root = json_create_object();
+
+       json_object_add_value_int(root, "nsfeat", ns->nsfeat);
+       json_object_add_value_int(root, "nmic", ns->nmic);
+       json_object_add_value_int(root, "rescap", ns->rescap);
+       json_object_add_value_int(root, "fpi", ns->fpi);
+       json_object_add_value_int(root, "anagrpid", le32_to_cpu(ns->anagrpid));
+       json_object_add_value_int(root, "nsattr", ns->nsattr);
+       json_object_add_value_int(root, "nvmsetid", le16_to_cpu(ns->nvmsetid));
+       json_object_add_value_int(root, "endgid", le16_to_cpu(ns->endgid));
+       json_object_add_value_int(root, "nstat", ns->nstat);
+
+       json_print_object(root, NULL);
+       printf("\n");
+       json_free_object(root);
+}
+
+void nvme_show_cmd_set_independent_id_ns(
+       struct nvme_id_independent_id_ns *ns, unsigned int nsid,
+       enum nvme_print_flags flags)
+{
+       int human = flags & VERBOSE;
+
+       if (flags & BINARY)
+               return d_raw((unsigned char *)ns, sizeof(*ns));
+       if (flags & JSON)
+               return json_nvme_cmd_set_independent_id_ns(ns);
+
+       printf("NVME Identify Command Set Idependent Namespace %d:\n", nsid);
+       printf("nsfeat  : %#x\n", ns->nsfeat);
+       if (human)
+               nvme_show_cmd_set_independent_id_ns_nsfeat(ns->nsfeat);
+       printf("nmic    : %#x\n", ns->nmic);
+       if (human)
+               nvme_show_id_ns_nmic(ns->nmic);
+       printf("rescap  : %#x\n", ns->rescap);
+       if (human)
+               nvme_show_id_ns_rescap(ns->rescap);
+       printf("fpi     : %#x\n", ns->fpi);
+       if (human)
+               nvme_show_id_ns_fpi(ns->fpi);
+       printf("anagrpid: %u\n", le32_to_cpu(ns->anagrpid));
+       printf("nsattr  : %u\n", ns->nsattr);
+       printf("nvmsetid: %d\n", le16_to_cpu(ns->nvmsetid));
+       printf("endgid  : %d\n", le16_to_cpu(ns->endgid));
+
+       printf("nstat   : %#x\n", ns->nstat);
+       if (human)
+               nvme_show_cmd_set_independent_id_ns_nstat(ns->nstat);
+}
 
 static void json_nvme_id_ns_descs(void *data)
 {
index 2d5a0cad5e6152181c4059d65f0a754c2152c695..ce1e81cef9371ab4eca353cb980f72897708e6e0 100644 (file)
@@ -26,6 +26,9 @@ void __nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode,
 void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode);
 void nvme_show_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
        enum nvme_print_flags flags);
+void nvme_show_cmd_set_independent_id_ns(
+       struct nvme_id_independent_id_ns *ns, unsigned int nsid,
+       enum nvme_print_flags flags);
 void nvme_show_resv_report(struct nvme_resv_status *status, int bytes, bool eds,
        enum nvme_print_flags flags);
 void nvme_show_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges);
diff --git a/nvme.c b/nvme.c
index ccd6af8e376ee1abeb3aab1e259f40d276c33d76..66502ba4bbae52c81331ac4ecb7ebc33e3f3bead 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -2233,6 +2233,73 @@ ret:
        return nvme_status_to_errno(err, false);
 }
 
+static int cmd_set_independent_id_ns(int argc, char **argv,
+    struct command *cmd, struct plugin *plugin)
+{
+       const char *desc = "Send an I/O Command Set Independent Identify "\
+               "Namespace command to the given device, returns properties of the "\
+               "specified namespace in human-readable or binary or json format.";
+       const char *raw = "show identify in binary format";
+       const char *human_readable = "show identify in readable format";
+       const char *namespace_id = "identifier of desired namespace";
+
+       enum nvme_print_flags flags;
+       struct nvme_id_independent_id_ns ns;
+       int err = -1, fd;
+
+       struct config {
+               __u32 namespace_id;
+               int   raw_binary;
+               int   human_readable;
+               char *output_format;
+       };
+
+       struct config cfg = {
+               .namespace_id    = 0,
+               .output_format = "normal",
+       };
+
+       OPT_ARGS(opts) = {
+               OPT_UINT("namespace-id",    'n', &cfg.namespace_id,    namespace_id),
+               OPT_FLAG("raw-binary",      'b', &cfg.raw_binary,      raw),
+               OPT_FMT("output-format",    'o', &cfg.output_format,   output_format),
+               OPT_FLAG("human-readable",  'H', &cfg.human_readable,  human_readable),
+               OPT_END()
+       };
+
+       err = fd = parse_and_open(argc, argv, desc, opts);
+       if (fd < 0)
+               goto ret;
+
+       err = flags = validate_output_format(cfg.output_format);
+       if (flags < 0)
+               goto close_fd;
+       if (cfg.raw_binary)
+               flags = BINARY;
+       if (cfg.human_readable)
+               flags |= VERBOSE;
+
+       if (!cfg.namespace_id) {
+               err = cfg.namespace_id = nvme_get_nsid(fd, &cfg.namespace_id);
+               if (err < 0) {
+                       perror("get-namespace-id");
+                       goto close_fd;
+               }
+       }
+
+       err = nvme_identify_independent_identify_ns(fd, cfg.namespace_id, &ns);
+       if (!err)
+               nvme_show_cmd_set_independent_id_ns(&ns, cfg.namespace_id, flags);
+       else if (err > 0)
+               nvme_show_status(err);
+       else
+               perror("I/O command set independent identify namespace");
+close_fd:
+       close(fd);
+ret:
+       return nvme_status_to_errno(err, false);
+}
+
 static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Send an Identify Namespace Granularity List command to the "\