__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),
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 {
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";
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
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;
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;
}
}
[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";
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,