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)
}
}
+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)
{
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 "\