From: 丁剑 Date: Tue, 10 Mar 2020 07:16:32 +0000 (+0800) Subject: [Memblaze] modify SMART info X-Git-Tag: v1.11~8^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=e19a8303429976cb2a42f07e55946ffdfcc3e278;p=users%2Fhch%2Fnvme-cli.git [Memblaze] modify SMART info 1. Modify SMART info fellow Intel format; 2. Add Memblaze private SMART info; 3. Compatible with both new and old formats; Signed-off-by: 丁剑 --- diff --git a/plugins/memblaze/memblaze-nvme.c b/plugins/memblaze/memblaze-nvme.c index 387548f..b549414 100644 --- a/plugins/memblaze/memblaze-nvme.c +++ b/plugins/memblaze/memblaze-nvme.c @@ -16,78 +16,10 @@ #define CREATE_CMD #include "memblaze-nvme.h" +#include "memblaze-utils.h" enum { - TOTAL_WRITE, - TOTAL_READ, - THERMAL_THROTTLE, - TEMPT_SINCE_RESET, - POWER_CONSUMPTION, - TEMPT_SINCE_BOOTUP, - POWER_LOSS_PROTECTION, - WEARLEVELING_COUNT, - HOST_WRITE, - THERMAL_THROTTLE_CNT, - CORRECT_PCIE_PORT0, - CORRECT_PCIE_PORT1, - REBUILD_FAIL, - ERASE_FAIL, - PROGRAM_FAIL, - READ_FAIL, - NR_SMART_ITEMS, -}; - -enum { - MB_FEAT_POWER_MGMT = 0Xc6, -}; - -#pragma pack(push, 1) -struct nvme_memblaze_smart_log_item { - __u8 id[3]; - union { - __u8 __nmval[2]; - __le16 nmval; - }; - union { - __u8 rawval[6]; - struct temperature { - __le16 max; - __le16 min; - __le16 curr; - } temperature; - struct power { - __le16 max; - __le16 min; - __le16 curr; - } power; - struct thermal_throttle_mb { - __u8 on; - __u32 count; - } thermal_throttle; - struct temperature_p { - __le16 max; - __le16 min; - } temperature_p; - struct power_loss_protection { - __u8 curr; - } power_loss_protection; - struct wearleveling_count { - __le16 min; - __le16 max; - __le16 avg; - } wearleveling_count; - struct thermal_throttle_cnt { - __u8 active; - __le32 cnt; - } thermal_throttle_cnt; - }; - __u8 resv; -}; -#pragma pack(pop) - -struct nvme_memblaze_smart_log { - struct nvme_memblaze_smart_log_item items[NR_SMART_ITEMS]; - __u8 resv[512 - sizeof(struct nvme_memblaze_smart_log_item) * NR_SMART_ITEMS]; + MB_FEAT_POWER_MGMT = 0xc6, }; /* @@ -97,138 +29,317 @@ struct nvme_memblaze_smart_log { */ static int compare_fw_version(const char *fw1, const char *fw2) { - while (*fw1 != '\0') { - if (*fw2 == '\0' || *fw1 > *fw2) - return 1; - if (*fw1 < *fw2) - return -1; - fw1++; - fw2++; - } + while (*fw1 != '\0') { + if (*fw2 == '\0' || *fw1 > *fw2) + return 1; + if (*fw1 < *fw2) + return -1; + fw1++; + fw2++; + } + + if (*fw2 != '\0') + return -1; + + return 0; +} + +/********************************************************** + * input: firmware version string + * output: + * 1: new intel format + * 0: old memblaze format + * *******************************************************/ +#define MEMBLAZE_FORMAT (0) +#define INTEL_FORMAT (1) - if (*fw2 != '\0') - return -1; +// 2.83 = raisin +#define IS_RAISIN(str) (!strcmp(str, "2.83")) +#define STR_VER_SIZE 5 - return 0; +int getlogpage_format_type(char *fw_ver) +{ + char fw_ver_local[STR_VER_SIZE]; + strncpy(fw_ver_local, fw_ver, STR_VER_SIZE); + *(fw_ver_local + STR_VER_SIZE - 1) = '\0'; + if ( IS_RAISIN(fw_ver_local) ) + { + return INTEL_FORMAT; + } + else + { + return MEMBLAZE_FORMAT; + } } static __u32 item_id_2_u32(struct nvme_memblaze_smart_log_item *item) { - __le32 __id = 0; - memcpy(&__id, item->id, 3); - return le32_to_cpu(__id); + __le32 __id = 0; + memcpy(&__id, item->id, 3); + return le32_to_cpu(__id); } static __u64 raw_2_u64(const __u8 *buf, size_t len) { - __le64 val = 0; - memcpy(&val, buf, len); - return le64_to_cpu(val); + __le64 val = 0; + memcpy(&val, buf, len); + return le64_to_cpu(val); } -static int show_memblaze_smart_log(int fd, __u32 nsid, const char *devname, - struct nvme_memblaze_smart_log *smart) +#define STRN2_01 "Additional Smart Log for NVME device" +#define STRN2_02 "namespace-id" +#define STRN1_01 "key" +#define STRN1_02 "normalized" +#define STRN1_03 "raw" +#define STR00_01 "program_fail_count" +#define STR01_01 "erase_fail_count" +#define STR02_01 "wear_leveling" +#define STR02_03 "min: " +#define STR02_04 ", max: " +#define STR02_05 ", avg: " +#define STR03_01 "end_to_end_error_detection_count" +#define STR04_01 "crc_error_count" +#define STR05_01 "timed_workload_media_wear" +#define STR06_01 "timed_workload_host_reads" +#define STR07_01 "timed_workload_timer" +#define STR07_02 " min" +#define STR08_01 "thermal_throttle_status" +#define STR08_02 ", cnt: " +#define STR09_01 "retry_buffer_overflow_count" +#define STR10_01 "pll_lock_loss_count" +#define STR11_01 "nand_bytes_written" +#define STR11_03 "sectors: " +#define STR12_01 "host_bytes_written" +#define STR12_03 "sectors: " +#define STR13_01 "system_area_life_left" +#define STR14_01 "total_read" +#define STR15_01 "tempt_since_born" +#define STR15_03 "max: " +#define STR15_04 ", min: " +#define STR15_05 ", curr: " +#define STR16_01 "power_consumption" +#define STR16_03 "max: " +#define STR16_04 ", min: " +#define STR16_05 ", curr: " +#define STR17_01 "tempt_since_bootup" +#define STR17_03 "max: " +#define STR17_04 ", min: " +#define STR17_05 ", curr: " +#define STR18_01 "power_loss_protection" +#define STR19_01 "read_fail" +#define STR20_01 "thermal_throttle_time" +#define STR21_01 "flash_media_error" + +static void get_memblaze_new_smart_info(struct nvme_p4_smart_log *smart, int index, u8 *nm_val, u8 *raw_val) { - struct nvme_id_ctrl ctrl; - char fw_ver[10]; - int err = 0; - struct nvme_memblaze_smart_log_item *item; - - err = nvme_identify_ctrl(fd, &ctrl); - if (err) - return err; - snprintf(fw_ver, sizeof(fw_ver), "%c.%c%c.%c%c%c%c", - ctrl.fr[0], ctrl.fr[1], ctrl.fr[2], ctrl.fr[3], - ctrl.fr[4], ctrl.fr[5], ctrl.fr[6]); - - printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid); - - printf("Total write in GB since last factory reset : %"PRIu64"\n", - int48_to_long(smart->items[TOTAL_WRITE].rawval)); - printf("Total read in GB since last factory reset : %"PRIu64"\n", - int48_to_long(smart->items[TOTAL_READ].rawval)); - - printf("Thermal throttling status[1:HTP in progress] : %u\n", - smart->items[THERMAL_THROTTLE].thermal_throttle.on); - printf("Total thermal throttling minutes since power on : %u\n", - smart->items[THERMAL_THROTTLE].thermal_throttle.count); - - printf("Maximum temperature in Kelvin since last factory reset : %u\n", - le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.max)); - printf("Minimum temperature in Kelvin since last factory reset : %u\n", - le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.min)); - if (compare_fw_version(fw_ver, "0.09.0300") != 0) { - printf("Maximum temperature in Kelvin since power on : %u\n", - le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.max)); - printf("Minimum temperature in Kelvin since power on : %u\n", - le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.min)); - } - printf("Current temperature in Kelvin : %u\n", - le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.curr)); - - printf("Maximum power in watt since power on : %u\n", - le16_to_cpu(smart->items[POWER_CONSUMPTION].power.max)); - printf("Minimum power in watt since power on : %u\n", - le16_to_cpu(smart->items[POWER_CONSUMPTION].power.min)); - printf("Current power in watt : %u\n", - le16_to_cpu(smart->items[POWER_CONSUMPTION].power.curr)); - - item = &smart->items[POWER_LOSS_PROTECTION]; - if (item_id_2_u32(item) == 0xEC) - printf("Power loss protection normalized value : %u\n", - item->power_loss_protection.curr); - - item = &smart->items[WEARLEVELING_COUNT]; - if (item_id_2_u32(item) == 0xAD) { - printf("Percentage of wearleveling count left : %u\n", - le16_to_cpu(item->nmval)); - printf("Wearleveling count min erase cycle : %u\n", - le16_to_cpu(item->wearleveling_count.min)); - printf("Wearleveling count max erase cycle : %u\n", - le16_to_cpu(item->wearleveling_count.max)); - printf("Wearleveling count avg erase cycle : %u\n", - le16_to_cpu(item->wearleveling_count.avg)); - } + memcpy(nm_val, smart->itemArr[index].nmVal, NM_SIZE); + memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE); +} - item = &smart->items[HOST_WRITE]; - if (item_id_2_u32(item) == 0xF5) - printf("Total host write in GiB since device born : %llu\n", - (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); - - item = &smart->items[THERMAL_THROTTLE_CNT]; - if (item_id_2_u32(item) == 0xEB) - printf("Thermal throttling count since device born : %u\n", - item->thermal_throttle_cnt.cnt); - - item = &smart->items[CORRECT_PCIE_PORT0]; - if (item_id_2_u32(item) == 0xED) - printf("PCIE Correctable Error Count of Port0 : %llu\n", - (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); - - item = &smart->items[CORRECT_PCIE_PORT1]; - if (item_id_2_u32(item) == 0xEE) - printf("PCIE Correctable Error Count of Port1 : %llu\n", - (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); - - item = &smart->items[REBUILD_FAIL]; - if (item_id_2_u32(item) == 0xEF) - printf("End-to-End Error Detection Count : %llu\n", - (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); - - item = &smart->items[ERASE_FAIL]; - if (item_id_2_u32(item) == 0xF0) - printf("Erase Fail Count : %llu\n", - (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); +static void show_memblaze_smart_log_new(struct nvme_memblaze_smart_log *s, + unsigned int nsid, const char *devname) +{ + struct nvme_p4_smart_log *smart = (struct nvme_p4_smart_log *)s; + u8 *nm = malloc(NM_SIZE * sizeof(u8)); + u8 *raw = malloc(RAW_SIZE * sizeof(u8)); + + /* Table Title */ + printf("%s:%s %s:%x\n", STRN2_01, devname, STRN2_02, nsid); + /* Clumn Name*/ + printf("%-34s%-11s%s\n", STRN1_01, STRN1_02, STRN1_03); + /* 00 RAISIN_SI_VD_PROGRAM_FAIL */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PROGRAM_FAIL, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR00_01, *nm, int48_to_long(raw)); + /* 01 RAISIN_SI_VD_ERASE_FAIL */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_ERASE_FAIL, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR01_01, *nm, int48_to_long(raw)); + /* 02 RAISIN_SI_VD_WEARLEVELING_COUNT */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_WEARLEVELING_COUNT, nm, raw); + printf("%-31s : %3d%% %s%u%s%u%s%u\n", STR02_01, *nm, + STR02_03, *raw, STR02_04, *(raw+2), STR02_05, *(raw+4)); + /* 03 RAISIN_SI_VD_E2E_DECTECTION_COUNT */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_E2E_DECTECTION_COUNT, nm, raw); + printf("%-31s: %3d%% %"PRIu64"\n", STR03_01, *nm, int48_to_long(raw)); + /* 04 RAISIN_SI_VD_PCIE_CRC_ERR_COUNT */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PCIE_CRC_ERR_COUNT, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR04_01, *nm, int48_to_long(raw)); + /* 05 RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR, nm, raw); + printf("%-32s: %3d%% %.3f%%\n", STR05_01, *nm, ((float)int48_to_long(raw))/1000); + /* 06 RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ, nm, raw); + printf("%-32s: %3d%% %"PRIu64"%%\n", STR06_01, *nm, int48_to_long(raw)); + /* 07 RAISIN_SI_VD_TIMED_WORKLOAD_TIMER */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_TIMER, nm, raw); + printf("%-32s: %3d%% %"PRIu64"%s\n", STR07_01, *nm, int48_to_long(raw), STR07_02); + /* 08 RAISIN_SI_VD_THERMAL_THROTTLE_STATUS */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_STATUS, nm, raw); + printf("%-32s: %3d%% %"PRIu64"%%%s%"PRIu64"\n", STR08_01, *nm, + int48_to_long(raw), STR08_02, int48_to_long(raw+1)); + /* 09 RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR09_01, *nm, int48_to_long(raw)); + /* 10 RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR10_01, *nm, int48_to_long(raw)); + /* 11 RAISIN_SI_VD_TOTAL_WRITE */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_WRITE, nm, raw); + printf("%-32s: %3d%% %s%"PRIu64"\n", STR11_01, *nm, STR11_03, int48_to_long(raw)); + /* 12 RAISIN_SI_VD_HOST_WRITE */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_HOST_WRITE, nm, raw); + printf("%-32s: %3d%% %s%"PRIu64"\n", STR12_01, *nm, STR12_03, int48_to_long(raw)); + /* 13 RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR13_01, *nm, int48_to_long(raw)); + /* 14 RAISIN_SI_VD_TOTAL_READ */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_READ, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR14_01, *nm, int48_to_long(raw)); + /* 15 RAISIN_SI_VD_TEMPT_SINCE_BORN */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BORN, nm, raw); + printf("%-32s: %3d%% %s%u%s%u%s%u\n", STR15_01, *nm, + STR15_03, *raw, STR15_04, *(raw+2), STR15_05, *(raw+4)); + /* 16 RAISIN_SI_VD_POWER_CONSUMPTION */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_POWER_CONSUMPTION, nm, raw); + printf("%-32s: %3d%% %s%u%s%u%s%u\n", STR16_01, *nm, + STR16_03, *raw, STR16_04, *(raw+2), STR16_05, *(raw+4)); + /* 17 RAISIN_SI_VD_TEMPT_SINCE_BOOTUP */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BOOTUP, nm, raw); + printf("%-32s: %3d%% %s%u%s%u%s%u\n", STR17_01, *nm, STR17_03, *raw, + STR17_04, *(raw+2), STR17_05, *(raw+4)); + /* 18 RAISIN_SI_VD_POWER_LOSS_PROTECTION */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_POWER_LOSS_PROTECTION, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR18_01, *nm, int48_to_long(raw)); + /* 19 RAISIN_SI_VD_READ_FAIL */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_READ_FAIL, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR19_01, *nm, int48_to_long(raw)); + /* 20 RAISIN_SI_VD_THERMAL_THROTTLE_TIME */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_TIME, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR20_01, *nm, int48_to_long(raw)); + /* 21 RAISIN_SI_VD_FLASH_MEDIA_ERROR */ + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_FLASH_MEDIA_ERROR, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", STR21_01, *nm, int48_to_long(raw)); + + free(nm); + free(raw); +} + +static void show_memblaze_smart_log_old(struct nvme_memblaze_smart_log *smart, + unsigned int nsid, const char *devname, const char *fw_ver) +{ + struct nvme_memblaze_smart_log_item *item; + + printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid); + + printf("Total write in GB since last factory reset : %"PRIu64"\n", + int48_to_long(smart->items[TOTAL_WRITE].rawval)); + printf("Total read in GB since last factory reset : %"PRIu64"\n", + int48_to_long(smart->items[TOTAL_READ].rawval)); + + printf("Thermal throttling status[1:HTP in progress] : %u\n", + smart->items[THERMAL_THROTTLE].thermal_throttle.on); + printf("Total thermal throttling minutes since power on : %u\n", + smart->items[THERMAL_THROTTLE].thermal_throttle.count); + + printf("Maximum temperature in Kelvin since last factory reset : %u\n", + le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.max)); + printf("Minimum temperature in Kelvin since last factory reset : %u\n", + le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.min)); + if (compare_fw_version(fw_ver, "0.09.0300") != 0) { + printf("Maximum temperature in Kelvin since power on : %u\n", + le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.max)); + printf("Minimum temperature in Kelvin since power on : %u\n", + le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.min)); + } + printf("Current temperature in Kelvin : %u\n", + le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.curr)); + + printf("Maximum power in watt since power on : %u\n", + le16_to_cpu(smart->items[POWER_CONSUMPTION].power.max)); + printf("Minimum power in watt since power on : %u\n", + le16_to_cpu(smart->items[POWER_CONSUMPTION].power.min)); + printf("Current power in watt : %u\n", + le16_to_cpu(smart->items[POWER_CONSUMPTION].power.curr)); + + item = &smart->items[POWER_LOSS_PROTECTION]; + if (item_id_2_u32(item) == 0xEC) + printf("Power loss protection normalized value : %u\n", + item->power_loss_protection.curr); + + item = &smart->items[WEARLEVELING_COUNT]; + if (item_id_2_u32(item) == 0xAD) { + printf("Percentage of wearleveling count left : %u\n", + le16_to_cpu(item->nmval)); + printf("Wearleveling count min erase cycle : %u\n", + le16_to_cpu(item->wearleveling_count.min)); + printf("Wearleveling count max erase cycle : %u\n", + le16_to_cpu(item->wearleveling_count.max)); + printf("Wearleveling count avg erase cycle : %u\n", + le16_to_cpu(item->wearleveling_count.avg)); + } + + item = &smart->items[HOST_WRITE]; + if (item_id_2_u32(item) == 0xF5) + printf("Total host write in GiB since device born : %llu\n", + (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); + + item = &smart->items[THERMAL_THROTTLE_CNT]; + if (item_id_2_u32(item) == 0xEB) + printf("Thermal throttling count since device born : %u\n", + item->thermal_throttle_cnt.cnt); + + item = &smart->items[CORRECT_PCIE_PORT0]; + if (item_id_2_u32(item) == 0xED) + printf("PCIE Correctable Error Count of Port0 : %llu\n", + (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); + + item = &smart->items[CORRECT_PCIE_PORT1]; + if (item_id_2_u32(item) == 0xEE) + printf("PCIE Correctable Error Count of Port1 : %llu\n", + (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); + + item = &smart->items[REBUILD_FAIL]; + if (item_id_2_u32(item) == 0xEF) + printf("End-to-End Error Detection Count : %llu\n", + (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); + + item = &smart->items[ERASE_FAIL]; + if (item_id_2_u32(item) == 0xF0) + printf("Erase Fail Count : %llu\n", + (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); item = &smart->items[PROGRAM_FAIL]; - if (item_id_2_u32(item) == 0xF1) - printf("Program Fail Count : %llu\n", - (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); - - item = &smart->items[READ_FAIL]; - if (item_id_2_u32(item) == 0xF2) - printf("Read Fail Count : %llu\n", - (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); + if (item_id_2_u32(item) == 0xF1) + printf("Program Fail Count : %llu\n", + (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); + + item = &smart->items[READ_FAIL]; + if (item_id_2_u32(item) == 0xF2) + printf("Read Fail Count : %llu\n", + (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval))); +} + +static int show_memblaze_smart_log(int fd, __u32 nsid, const char *devname, + struct nvme_memblaze_smart_log *smart) +{ + struct nvme_id_ctrl ctrl; + char fw_ver[10]; + int err = 0; + + err = nvme_identify_ctrl(fd, &ctrl); + if (err) + return err; + snprintf(fw_ver, sizeof(fw_ver), "%c.%c%c.%c%c%c%c", + ctrl.fr[0], ctrl.fr[1], ctrl.fr[2], ctrl.fr[3], + ctrl.fr[4], ctrl.fr[5], ctrl.fr[6]); + + if (getlogpage_format_type(fw_ver)) // Intel Format & new format + { + show_memblaze_smart_log_new(smart, nsid, devname); + } + else // Memblaze Format & old format + { + show_memblaze_smart_log_old(smart, nsid, devname, fw_ver); + } return err; } @@ -481,3 +592,4 @@ free: free(buf); return err; } + diff --git a/plugins/memblaze/memblaze-utils.h b/plugins/memblaze/memblaze-utils.h new file mode 100644 index 0000000..f5bec94 --- /dev/null +++ b/plugins/memblaze/memblaze-utils.h @@ -0,0 +1,164 @@ +#ifndef __MEMBLAZE_UTILS_H__ +#define __MEMBLAZE_UTILS_H__ + +#define SMART_INFO_OLD_SIZE 512 +#define SMART_INFO_NEW_SIZE 4096 + +#define ID_SIZE 3 +#define NM_SIZE 2 +#define RAW_SIZE 7 + +typedef unsigned char u8; + +// Intel Format & new format +/* Raisin Additional smart external ID */ +#define RAISIN_SI_VD_PROGRAM_FAIL_ID 0xAB +#define RAISIN_SI_VD_ERASE_FAIL_ID 0xAC +#define RAISIN_SI_VD_WEARLEVELING_COUNT_ID 0xAD +#define RAISIN_SI_VD_E2E_DECTECTION_COUNT_ID 0xB8 +#define RAISIN_SI_VD_PCIE_CRC_ERR_COUNT_ID 0xC7 +#define RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR_ID 0xE2 +#define RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ_ID 0xE3 +#define RAISIN_SI_VD_TIMED_WORKLOAD_TIMER_ID 0xE4 +#define RAISIN_SI_VD_THERMAL_THROTTLE_STATUS_ID 0xEA +#define RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT_ID 0xF0 +#define RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT_ID 0xF3 +#define RAISIN_SI_VD_TOTAL_WRITE_ID 0xF4 +#define RAISIN_SI_VD_HOST_WRITE_ID 0xF5 +#define RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT_ID 0xF6 +#define RAISIN_SI_VD_TOTAL_READ_ID 0xFA +#define RAISIN_SI_VD_TEMPT_SINCE_BORN_ID 0xE7 +#define RAISIN_SI_VD_POWER_CONSUMPTION_ID 0xE8 +#define RAISIN_SI_VD_TEMPT_SINCE_BOOTUP_ID 0xAF +#define RAISIN_SI_VD_POWER_LOSS_PROTECTION_ID 0xEC +#define RAISIN_SI_VD_READ_FAIL_ID 0xF2 +#define RAISIN_SI_VD_THERMAL_THROTTLE_TIME_ID 0xEB +#define RAISIN_SI_VD_FLASH_MEDIA_ERROR_ID 0xED + +/* Raisin Addtional smart internal ID */ +typedef enum +{ + /* smart attr following intel */ + RAISIN_SI_VD_PROGRAM_FAIL = 0, /* 0xAB */ + RAISIN_SI_VD_ERASE_FAIL = 1, /* 0xAC */ + RAISIN_SI_VD_WEARLEVELING_COUNT = 2,/* 0xAD */ + RAISIN_SI_VD_E2E_DECTECTION_COUNT = 3, /* 0xB8 */ + RAISIN_SI_VD_PCIE_CRC_ERR_COUNT = 4, /* 0xC7, 2 port data in one attribute */ + RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR = 5, /* 0xE2 , unknown definition*/ + RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ = 6, /* 0xE3 , unknown definition */ + RAISIN_SI_VD_TIMED_WORKLOAD_TIMER = 7, /* 0xE4 , unknown definition */ + RAISIN_SI_VD_THERMAL_THROTTLE_STATUS = 8, /* 0xEA */ + RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT = 9, /* 0xF0, unknown definition*/ + RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT = 10, /* 0xF3, unknown definition*/ + RAISIN_SI_VD_TOTAL_WRITE = 11, /* 0xF4, unit is 32MiB */ + RAISIN_SI_VD_HOST_WRITE = 12, /* 0xF5, unit is 32MiB */ + RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT = 13, /* 0xF6, unknown definition*/ + RAISIN_SI_VD_TOTAL_READ = 14, /* 0xFA, unit is 32MiB */ + + /* smart attr self defined */ + RAISIN_SI_VD_TEMPT_SINCE_BORN = 15, /* 0xE7 */ + RAISIN_SI_VD_POWER_CONSUMPTION = 16, /* 0xE8 */ + RAISIN_SI_VD_TEMPT_SINCE_BOOTUP = 17, /* 0xAF */ + RAISIN_SI_VD_POWER_LOSS_PROTECTION = 18, /* 0xEC */ + RAISIN_SI_VD_READ_FAIL = 19, /* 0xF2 */ + RAISIN_SI_VD_THERMAL_THROTTLE_TIME = 20, /* 0xEB */ + RAISIN_SI_VD_FLASH_MEDIA_ERROR = 21, /* 0xED */ + RAISIN_SI_VD_SMART_INFO_ITEMS_MAX, +} RAISIN_si_vendor_smart_item_e; + +// Memblaze Format & old format +enum { + TOTAL_WRITE = 0, + TOTAL_READ, + THERMAL_THROTTLE, + TEMPT_SINCE_RESET, + POWER_CONSUMPTION, + TEMPT_SINCE_BOOTUP, + POWER_LOSS_PROTECTION, + WEARLEVELING_COUNT, + HOST_WRITE, + THERMAL_THROTTLE_CNT, + CORRECT_PCIE_PORT0, + CORRECT_PCIE_PORT1, + REBUILD_FAIL, + ERASE_FAIL, + PROGRAM_FAIL, + READ_FAIL, + NR_SMART_ITEMS = RAISIN_SI_VD_SMART_INFO_ITEMS_MAX, +}; + +// Memblaze Format & old format +#pragma pack(push, 1) +struct nvme_memblaze_smart_log_item { + __u8 id[3]; + union { + __u8 __nmval[2]; + __le16 nmval; + }; + union { + __u8 rawval[6]; + struct temperature { + __le16 max; + __le16 min; + __le16 curr; + } temperature; + struct power { + __le16 max; + __le16 min; + __le16 curr; + } power; + struct thermal_throttle_mb { + __u8 on; + __u32 count; + } thermal_throttle; + struct temperature_p { + __le16 max; + __le16 min; + } temperature_p; + struct power_loss_protection { + __u8 curr; + } power_loss_protection; + struct wearleveling_count { + __le16 min; + __le16 max; + __le16 avg; + } wearleveling_count; + struct thermal_throttle_cnt { + __u8 active; + __le32 cnt; + } thermal_throttle_cnt; + }; + __u8 resv; +}; +#pragma pack(pop) + +struct nvme_memblaze_smart_log { + struct nvme_memblaze_smart_log_item items[NR_SMART_ITEMS]; + u8 resv[SMART_INFO_OLD_SIZE - sizeof(struct nvme_memblaze_smart_log_item) * NR_SMART_ITEMS]; +}; + +// Intel Format & new format +struct nvme_p4_smart_log_item +{ + /* Item identifier */ + u8 id[ID_SIZE]; + /* Normalized value or percentage. In the range from 0 to 100. */ + u8 nmVal[NM_SIZE]; + /* raw value */ + u8 rawVal[RAW_SIZE]; +}; + +struct nvme_p4_smart_log +{ + struct nvme_p4_smart_log_item itemArr[NR_SMART_ITEMS]; + + /** + * change 512 to 4096. + * because micron's getlogpage request,the size of many commands have changed to 4k. + * request size > user malloc size,casuing parameters that are closed in momery are dirty. + */ + u8 resv[SMART_INFO_NEW_SIZE - sizeof(struct nvme_p4_smart_log_item) * NR_SMART_ITEMS]; +}; + +#endif // __MEMBLAZE_UTILS_H__ +