]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Add NVMe MI Features: Controller Metadata (0x7E) and Namespace Metadata (0x7F).
authorNate Roiger <nate.roiger@hpe.com>
Sat, 3 Apr 2021 00:59:19 +0000 (19:59 -0500)
committerNate Roiger <nate.roiger@hpe.com>
Sat, 3 Apr 2021 00:59:19 +0000 (19:59 -0500)
Signed-off-by: Nate Roiger <nate.roiger@hpe.com>
linux/nvme.h
nvme-print.c
nvme.c

index 4ad09eec7309107e459a4847d592e3c276e6532e..17d4197055c8f36f249a3d06352bacc59a1001a0 100644 (file)
@@ -1191,6 +1191,31 @@ struct nvme_feat_auto_pst {
        __le64 entries[32];
 };
 
+struct nvme_mi_host_metadata_element_desc {
+       __u8                    type;   /* Element Type */
+       __u8                    rev;    /* Element Revision */
+       __u16                   len;    /* Element Length */
+       __u8                    val[0]; /* Element Value (UTF-8) */
+};
+
+struct nvme_mi_host_metadata {
+       __u8                                            ndesc;
+       __u8                                            rsvd1;
+       struct nvme_mi_host_metadata_element_desc       descs[0];
+};
+
+enum {
+       NVME_MI_CTRL_METADATA_OS_CTRL_NAME              = 0x01,
+       NVME_MI_CTRL_METADATA_OS_DRIVER_NAME            = 0x02,
+       NVME_MI_CTRL_METADATA_OS_DRIVER_VER             = 0x03,
+       NVME_MI_CTRL_METADATA_PRE_BOOT_CTRL_NAME        = 0x04,
+       NVME_MI_CTRL_METADATA_PRE_BOOT_DRIVER_NAME      = 0x05,
+       NVME_MI_CTRL_METADATA_PRE_BOOT_DRIVER_VER       = 0x06,
+
+       NVME_MI_NS_METADATA_OS_NS_NAME          = 0x01,
+       NVME_MI_NS_METADATA_PRE_BOOT_NS_NAME    = 0x02,
+};
+
 enum {
        NVME_HOST_MEM_ENABLE    = (1 << 0),
        NVME_HOST_MEM_RETURN    = (1 << 1),
@@ -1284,13 +1309,17 @@ enum nvme_feat {
        NVME_LBA_STATUS_INFO    = 0x15,
        NVME_FEAT_HOST_BEHAVIOR = 0x16,
        NVME_FEAT_SANITIZE      = 0x17,
-      NVME_FEAT_ENDURANCE     = 0x18,
+       NVME_FEAT_ENDURANCE     = 0x18,
        NVME_FEAT_IOCS_PROFILE  = 0x19,
        NVME_FEAT_SW_PROGRESS   = 0x80,
        NVME_FEAT_HOST_ID       = 0x81,
        NVME_FEAT_RESV_MASK     = 0x82,
        NVME_FEAT_RESV_PERSIST  = 0x83,
        NVME_FEAT_WRITE_PROTECT = 0x84,
+
+       NVME_MI_FEAT_CTRL_METADATA      = 0x7E,
+       NVME_MI_FEAT_NS_METADATA        = 0x7F,
+
 } __attribute__ ((__packed__));
 
 enum {
index 1a8f3cde05ec8984a7fa0590a8ba43cb699f9e81..838194994abf5a7fc7e3f0d10f7115a4a7518a60 100755 (executable)
@@ -5085,7 +5085,7 @@ const char *nvme_feature_to_string(enum nvme_feat feature)
        case NVME_FEAT_PLM_CONFIG:      return "Predicatable Latency Mode Config";
        case NVME_FEAT_PLM_WINDOW:      return "Predicatable Latency Mode Window";
        case NVME_LBA_STATUS_INFO:      return "LBA Status Infomation Attributes";
-      case NVME_FEAT_ENDURANCE:       return "Enduarance Event Group Configuration";
+       case NVME_FEAT_ENDURANCE:       return "Enduarance Event Group Configuration";
        case NVME_FEAT_IOCS_PROFILE:    return "I/O Command Set Profile";
        case NVME_FEAT_SW_PROGRESS:     return "Software Progress";
        case NVME_FEAT_HOST_ID:         return "Host Identifier";
@@ -5096,6 +5096,8 @@ const char *nvme_feature_to_string(enum nvme_feat feature)
        case NVME_FEAT_HCTM:            return "Host Controlled Thermal Management";
        case NVME_FEAT_HOST_BEHAVIOR:   return "Host Behavior";
        case NVME_FEAT_SANITIZE:        return "Sanitize";
+       case NVME_MI_FEAT_CTRL_METADATA:return "MI Controller Metadata";
+       case NVME_MI_FEAT_NS_METADATA:  return "MI Namespace Metadata";
        }
        /*
         * We don't use the "default:" statement to let the compiler warning if
@@ -5602,6 +5604,65 @@ static void nvme_show_plm_config(struct nvme_plm_config *plmcfg)
        printf("\tDTWIN Time Threshold  :%"PRIu64"\n", le64_to_cpu(plmcfg->dtwin_time_thresh));
 }
 
+static char* nvme_show_mi_host_metadata_type_to_string(enum nvme_feat fid, __u8 type)
+{
+       switch (fid) {
+       case NVME_MI_FEAT_CTRL_METADATA:        
+               switch (type) {
+               case NVME_MI_CTRL_METADATA_OS_CTRL_NAME: 
+                       return "Operating System Controller Name";
+               case NVME_MI_CTRL_METADATA_OS_DRIVER_NAME:
+                       return "Operating System Driver Name";
+               case NVME_MI_CTRL_METADATA_OS_DRIVER_VER:
+                       return "Operating System Driver Version";
+               case NVME_MI_CTRL_METADATA_PRE_BOOT_CTRL_NAME:
+                       return "Pre-boot Controller Name";
+               case NVME_MI_CTRL_METADATA_PRE_BOOT_DRIVER_NAME:
+                       return "Pre-boot Driver Name";
+               case NVME_MI_CTRL_METADATA_PRE_BOOT_DRIVER_VER:
+                       return "Pre-boot Driver Version";
+               default:
+                       return "Unknown Controller Type";
+               }
+       case NVME_MI_FEAT_NS_METADATA:
+               switch (type) {
+               case NVME_MI_NS_METADATA_OS_NS_NAME:
+                       return "Operating System Namespace Name";
+               case NVME_MI_NS_METADATA_PRE_BOOT_NS_NAME:
+                       return "Pre-boot Namespace Name";
+               default:
+                       return "Unknown Namespace Type";
+               }
+       default:
+               return "Unknown Feature";
+       }
+}
+
+static void nvme_show_mi_host_metadata(enum nvme_feat fid, 
+                                      struct nvme_mi_host_metadata *data)
+{
+       struct nvme_mi_host_metadata_element_desc *desc = &data->descs[0];
+       int i;
+       char val[4096];
+       __u16 len;
+       
+       printf("\tNum Metadata Element Descriptors: %d\n", data->ndesc);
+       for (i = 0; i < data->ndesc; i++) {
+               len = le16_to_cpu(desc->len);
+               strncpy(val, (char *)desc->val, min(sizeof(val) - 1, len));
+
+               printf("\tElement[%-3d]:\n", i);
+               printf("\t\tType     : 0x%02x (%s)\n", desc->type,
+                       nvme_show_mi_host_metadata_type_to_string(fid, desc->type));
+               printf("\t\tRevision : %d\n", desc->rev);
+               printf("\t\tLength   : %d\n", len);
+               printf("\t\tValue    : %s\n", val);
+
+               desc = (struct nvme_mi_host_metadata_element_desc *)
+                       &desc->val[desc->len];
+       }
+}
+
 void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned char *buf)
 {
        __u8 field;
@@ -5737,6 +5798,10 @@ void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned
        case NVME_FEAT_RRL:
                printf("\tRead Recovery Level (RRL): %u\n", result & 0xf);
                break;
+       case NVME_MI_FEAT_CTRL_METADATA:
+       case NVME_MI_FEAT_NS_METADATA:
+               nvme_show_mi_host_metadata(fid, (struct nvme_mi_host_metadata *)buf);
+               break;
        }
 }
 
diff --git a/nvme.c b/nvme.c
index 926651f51d33f5c22ed439ecf42ebe6c2b59af42..0c980e3295a785913f3d5ff3a6d9c2abb0e824ef 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -91,7 +91,9 @@ static __u16 nvme_feat_buf_len[0x100] = {
        [NVME_FEAT_HOST_ID]             = 8,
        [NVME_FEAT_PLM_CONFIG]          = 512,
        [NVME_FEAT_TIMESTAMP]           = 8,
-       [NVME_FEAT_HOST_BEHAVIOR]       = 512
+       [NVME_FEAT_HOST_BEHAVIOR]       = 512,
+       [NVME_MI_FEAT_CTRL_METADATA]    = 4096,
+       [NVME_MI_FEAT_NS_METADATA]      = 4096,
 };
 
 const char *output_format = "Output format: normal|json|binary";
@@ -3654,7 +3656,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
                 memset(buf, 0, cfg.data_len);
                 memcpy(buf, &number, NVME_FEAT_TIMESTAMP_DATA_SIZE);
             }
-        }
+       }
        }
 
        err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value,