]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Identify Primary Controller Capabilities support
authorNate Roiger <nate.roiger@hpe.com>
Tue, 30 Mar 2021 15:02:47 +0000 (10:02 -0500)
committerKeith Busch <kbusch@kernel.org>
Fri, 2 Apr 2021 14:40:05 +0000 (08:40 -0600)
Signed-off-by: Nate Roiger <nate.roiger@hpe.com>
linux/nvme.h
nvme-builtin.h
nvme-ioctl.c
nvme-ioctl.h
nvme-print.c
nvme-print.h
nvme.c

index aa678c974fd27aa53ff3bd569fb665b17e7e0ef2..3aabd8e8c7d56185684d99c60507179b0e49438b 100644 (file)
@@ -354,6 +354,27 @@ struct nvme_id_ctrl {
        __u8                    vs[1024];
 };
 
+struct nvme_pri_ctrl_caps {
+       __le16                  cntlid;
+       __le16                  portid;
+       __u8                    crt;
+       __u8                    rsvd5[27];
+       __le32                  vqfrt;
+       __le32                  vqrfa;
+       __le16                  vqrfap;
+       __le16                  vqprt;
+       __le16                  vqfrsm;
+       __le16                  vqgran;
+       __u8                    rsvd48[16];
+       __le32                  vifrt;
+       __le32                  virfa;
+       __u16                   virfap;
+       __u16                   viprt;
+       __u16                   vifrsm;
+       __u16                   vigran;
+       __u8                    rsvd80[4016];
+};
+
 enum {
        NVME_CTRL_ONCS_COMPARE                  = 1 << 0,
        NVME_CTRL_ONCS_WRITE_UNCORRECTABLE      = 1 << 1,
@@ -441,6 +462,7 @@ enum {
        NVME_ID_CNS_NS_PRESENT          = 0x11,
        NVME_ID_CNS_CTRL_NS_LIST        = 0x12,
        NVME_ID_CNS_CTRL_LIST           = 0x13,
+       NVME_ID_CNS_PRIMARY_CTRL_CAPS   = 0x14,
        NVME_ID_CNS_SCNDRY_CTRL_LIST    = 0x15,
        NVME_ID_CNS_NS_GRANULARITY      = 0x16,
        NVME_ID_CNS_UUID_LIST           = 0x17,
@@ -1483,6 +1505,27 @@ struct nvme_controller_list {
        __le16 identifier[2047];
 };
 
+struct nvme_primary_ctrl_caps {
+       __le16 cntlid;  /* Controller Identifier */
+       __le16 portid;  /* Port Identifier */
+       __u8   crt;     /* Controller Resource Types */
+       __u8   rsvd5[27];
+       __le32 vqfrt;   /* VQ Resources Flexible Total */
+       __le32 vqrfa;   /* VQ Resources Flexible Assigned */
+       __le16 vqrfap;  /* VQ Resources Flexible Allocated to Primary */
+       __le16 vqprt;   /* VQ Resources Private Total */
+       __le16 vqfrsm;  /* VQ Resources Flexible Secondary Maximum */
+       __le16 vqgran;  /* VQ Flexible Resource Preferred Granularity */
+       __u8   rsvd48[16];
+       __le32 vifrt;   /* VI Resources Flexible Total */
+       __le32 virfa;   /* VI Resources Flexible Assigned */
+       __u16  virfap;  /* VI Resources Flexible Allocated to Primary */
+       __u16  viprt;   /* VI Resources Private Total */
+       __u16  vifrsm;  /* VI Resources Flexible Secondary Maximum */
+       __u16  vigran;  /* VI Flexible Resource Preferred Granularity */
+       __u8   rsvd80[4016];
+};
+
 struct nvme_secondary_controller_entry {
        __le16 scid;    /* Secondary Controller Identifier */
        __le16 pcid;    /* Primary Controller Identifier */
index 2679a17a32d57f5135cb78c28a49e4b455d7d800..a413d008023ce8d9bace3dc8fc236aa16bfb78d6 100644 (file)
@@ -15,6 +15,7 @@ COMMAND_LIST(
        ENTRY("list-ns", "Send NVMe Identify List, display structure", list_ns)
        ENTRY("list-ctrl", "Send NVMe Identify Controller List, display structure", list_ctrl)
        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("ns-descs", "Send NVMe Namespace Descriptor List, display structure", ns_descs)
        ENTRY("id-nvmset", "Send NVMe Identify NVM Set List, display structure", id_nvmset)
index 7183cabc0c9a2d9011d2eb24087e339ef8936a0d..b6c27c55eea39c8fc66e0b75895ac578f94fd514 100644 (file)
@@ -413,6 +413,11 @@ int nvme_identify_ctrl_list(int fd, __u32 nsid, __u16 cntid, void *data)
        return nvme_identify(fd, nsid, (cntid << 16) | cns, data);
 }
 
+int nvme_identify_primary_ctrl_caps(int fd, void *data)
+{
+       return nvme_identify(fd, 0, NVME_ID_CNS_PRIMARY_CTRL_CAPS, data);
+}
+
 int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, void *data)
 {
        return nvme_identify(fd, nsid, (cntid << 16) | NVME_ID_CNS_SCNDRY_CTRL_LIST, data);
index 830a1c8e1bc4ae5311c4bda3681246de6efd4740..97f52885e9142b2a89e7ba6a9e76201268cb719e 100644 (file)
@@ -79,6 +79,7 @@ int nvme_identify_ctrl_list(int fd, __u32 nsid, __u16 cntid, void *data);
 int nvme_identify_ns_descs(int fd, __u32 nsid, void *data);
 int nvme_identify_nvmset(int fd, __u16 nvmset_id, void *data);
 int nvme_identify_uuid(int fd, void *data);
+int nvme_identify_primary_ctrl_caps(int fd, void *data);
 int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, void *data);
 int nvme_identify_ns_granularity(int fd, void *data);
 int nvme_identify_ctrl_nvm(int fd, void *data);
index 78357ce2673e36bd501ae9f446730c923519fac3..7585914fae9a5dd9d644d32256f830b673737b09 100755 (executable)
@@ -4200,6 +4200,47 @@ void nvme_show_id_nvmset(struct nvme_id_nvmset *nvmset, unsigned nvmset_id,
        }
 }
 
+static void nvme_show_primary_ctrl_caps_crt(__u8 crt)
+{
+       __u8 rsvd = (crt & 0xFC) >> 2;
+       __u8 vi = (crt & 0x2) >> 1;
+       __u8 vq = (crt & 0x1) >> 0;
+
+       if (rsvd)
+               printf("  [7:2] : %#x\tReserved\n", rsvd);
+       printf("  [1:1] %#x\tVI Resources are %ssupported\n", vi, vi ? "" : "not ");
+       printf("  [1:1] %#x\tVQ Resources are %ssupported\n", vq, vq ? "" : "not ");
+}
+
+void nvme_show_primary_ctrl_caps(const struct nvme_primary_ctrl_caps *caps,
+                                enum nvme_print_flags flags)
+{
+       int human = flags & VERBOSE;
+
+       if (flags & BINARY)
+               return d_raw((unsigned char *)caps, sizeof(*caps));
+
+       printf("NVME Identify Primary Controller Capabilities:\n");
+       printf("cntlid    : %#x\n", le16_to_cpu(caps->cntlid));
+       printf("portid    : %#x\n", le16_to_cpu(caps->portid));
+       printf("crt       : %#x\n", caps->crt);
+       if (human)
+               nvme_show_primary_ctrl_caps_crt(caps->crt);
+       printf("vqfrt     : %d\n", le32_to_cpu(caps->vqfrt));
+       printf("vqrfa     : %d\n", le32_to_cpu(caps->vqrfa));
+       printf("vqrfap    : %d\n", le16_to_cpu(caps->vqrfap));
+       printf("vqprt     : %d\n", le16_to_cpu(caps->vqprt));
+       printf("vqfrsm    : %d\n", le16_to_cpu(caps->vqfrsm));
+       printf("vqgran    : %d\n", le16_to_cpu(caps->vqgran));
+       printf("vifrt     : %d\n", le32_to_cpu(caps->vifrt));
+       printf("virfa     : %d\n", le32_to_cpu(caps->virfa));
+       printf("virfap    : %d\n", le16_to_cpu(caps->virfap));
+       printf("viprt     : %d\n", le16_to_cpu(caps->viprt));
+       printf("vifrsm    : %d\n", le16_to_cpu(caps->vifrsm));
+       printf("vigran    : %d\n", le16_to_cpu(caps->vigran));
+}
+
+
 static void json_nvme_list_secondary_ctrl(const struct nvme_secondary_controllers_list *sc_list,
                                          __u32 count)
 {
index 7392644fe528415504430946b6dbc1fd9df87474..2d8ed4debd8933f3469ecfed97a9f909c3c6d93b 100644 (file)
@@ -75,6 +75,8 @@ void nvme_show_subsystem_list(struct nvme_topology *t,
       enum nvme_print_flags flags);
 void nvme_show_id_nvmset(struct nvme_id_nvmset *nvmset, unsigned nvmset_id,
        enum nvme_print_flags flags);
+void nvme_show_primary_ctrl_caps(const struct nvme_primary_ctrl_caps *caps,
+       enum nvme_print_flags flags);
 void nvme_show_list_secondary_ctrl(const struct nvme_secondary_controllers_list *sc_list,
        __u32 count, enum nvme_print_flags flags);
 void nvme_show_id_ns_granularity_list(const struct nvme_id_ns_granularity_list *glist,
diff --git a/nvme.c b/nvme.c
index ddb99d288aac9e508f3076c0faa37690c32791fb..67ddc26929deb3bb0962fe0260b0efca33e92840 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -2411,6 +2411,60 @@ ret:
        return nvme_status_to_errno(err, false);
 }
 
+static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+       const char *desc = "Send an Identify Primary Controller Capabilities "\
+               "command to the given device and report the information in a "\
+               "human-redable or binary format.";
+       const char *raw = "show capabilities in binary format";
+       const char *human_readable = "show capabilities in readable format";
+
+       enum nvme_print_flags flags = NORMAL;
+       struct nvme_primary_ctrl_caps caps;
+       int err, fd;
+
+       struct config {
+               int raw_binary;
+               int human_readable;
+               char *output_format;
+       };
+
+       struct config cfg = {
+               .output_format = "normal",
+       };
+
+       OPT_ARGS(opts) = {
+               OPT_FMT("output-format",   'o', &cfg.output_format,  output_format),
+               OPT_FLAG("raw-binary",     'b', &cfg.raw_binary,     raw),
+               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;
+
+       err = nvme_identify_primary_ctrl_caps(fd, &caps);
+       if (!err)
+               nvme_show_primary_ctrl_caps(&caps, flags);
+       else if (err >0)
+               nvme_show_status(err);
+       else
+               perror("identify primary controller capabilities");
+close_fd:
+       close(fd);
+ret:
+       return nvme_status_to_errno(err, false);
+}
+
 static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Show secondary controller list associated with the primary controller "\