diff options
Diffstat (limited to '')
-rw-r--r-- | plugins/memblaze/memblaze-nvme.c | 1530 |
1 files changed, 751 insertions, 779 deletions
diff --git a/plugins/memblaze/memblaze-nvme.c b/plugins/memblaze/memblaze-nvme.c index 7a4633a..c0a70ee 100644 --- a/plugins/memblaze/memblaze-nvme.c +++ b/plugins/memblaze/memblaze-nvme.c @@ -19,22 +19,22 @@ #include "memblaze-utils.h" enum { - // feature id - MB_FEAT_POWER_MGMT = 0x02, - MB_FEAT_HIGH_LATENCY = 0xE1, - // log id - GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM = 0xC1, - GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM = 0xC2, - GLP_ID_VU_GET_HIGH_LATENCY_LOG = 0xC3, - MB_FEAT_CLEAR_ERRORLOG = 0xF7, + /* feature id */ + MB_FEAT_POWER_MGMT = 0x02, + MB_FEAT_HIGH_LATENCY = 0xE1, + /* log id */ + GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM = 0xC1, + GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM = 0xC2, + GLP_ID_VU_GET_HIGH_LATENCY_LOG = 0xC3, + MB_FEAT_CLEAR_ERRORLOG = 0xF7, }; -#define LOG_PAGE_SIZE (0x1000) -#define DO_PRINT_FLAG (1) -#define NOT_PRINT_FLAG (0) -#define FID_C1_LOG_FILENAME "log_c1.csv" -#define FID_C2_LOG_FILENAME "log_c2.csv" -#define FID_C3_LOG_FILENAME "log_c3.csv" +#define LOG_PAGE_SIZE (0x1000) +#define DO_PRINT_FLAG (1) +#define NOT_PRINT_FLAG (0) +#define FID_C1_LOG_FILENAME "log_c1.csv" +#define FID_C2_LOG_FILENAME "log_c2.csv" +#define FID_C3_LOG_FILENAME "log_c3.csv" /* * Return -1 if @fw1 < @fw2 @@ -43,373 +43,370 @@ enum { */ 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++; - } - - if (*fw2 != '\0') - return -1; - - return 0; + 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 + * 1: new intel format + * 0: old memblaze format * *******************************************************/ -#define MEMBLAZE_FORMAT (0) -#define INTEL_FORMAT (1) +#define MEMBLAZE_FORMAT (0) +#define INTEL_FORMAT (1) -// 2.13 = papaya -#define IS_PAPAYA(str) (!strcmp(str, "2.13")) -// 2.83 = raisin -#define IS_RAISIN(str) (!strcmp(str, "2.83")) -// 2.94 = kumquat -#define IS_KUMQUAT(str) (!strcmp(str, "2.94")) -// 0.60 = loquat -#define IS_LOQUAT(str) (!strcmp(str, "0.60")) +/* 2.13 = papaya */ +#define IS_PAPAYA(str) (!strcmp(str, "2.13")) +/* 2.83 = raisin */ +#define IS_RAISIN(str) (!strcmp(str, "2.83")) +/* 2.94 = kumquat */ +#define IS_KUMQUAT(str) (!strcmp(str, "2.94")) +/* 0.60 = loquat */ +#define IS_LOQUAT(str) (!strcmp(str, "0.60")) -#define STR_VER_SIZE (5) +#define STR_VER_SIZE (5) int getlogpage_format_type(char *model_name) { - int logpage_format_type = INTEL_FORMAT; - const char *boundary_model_name1 = "P"; // MEMBLAZE P7936DT0640M00 - const char *boundary_model_name2 = "P5920"; // Use INTEL_FORMAT from Raisin P5920. - if (0 == strncmp(model_name, boundary_model_name1, strlen(boundary_model_name1))) - { - if (strncmp(model_name, boundary_model_name2, strlen(boundary_model_name2)) < 0) - { - logpage_format_type = MEMBLAZE_FORMAT; - } - } - return logpage_format_type; + int logpage_format_type = INTEL_FORMAT; + const char *boundary_model_name1 = "P"; /* MEMBLAZE P7936DT0640M00 */ + const char *boundary_model_name2 = "P5920"; /* Use INTEL_FORMAT from Raisin P5920. */ + + if (!strncmp(model_name, boundary_model_name1, strlen(boundary_model_name1))) { + if (strncmp(model_name, boundary_model_name2, strlen(boundary_model_name2)) < 0) + logpage_format_type = MEMBLAZE_FORMAT; + } + return logpage_format_type; } 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 void get_memblaze_new_smart_info(struct nvme_p4_smart_log *smart, int index, __u8 *nm_val, __u8 *raw_val) { - memcpy(nm_val, smart->itemArr[index].nmVal, NM_SIZE); - memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE); + memcpy(nm_val, smart->itemArr[index].nmVal, NM_SIZE); + memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE); } static void show_memblaze_smart_log_new(struct nvme_memblaze_smart_log *s, - unsigned int nsid, const char *devname) + 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)); + 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)); - if (!nm) { - if (raw) - free(raw); - return; - } - if (!raw) { - free(nm); - return; - } + if (!nm) { + if (raw) + free(raw); + return; + } + if (!raw) { + free(nm); + return; + } - printf("%s:%s %s:%x\n", "Additional Smart Log for NVME device", devname, "namespace-id", nsid); - printf("%-34s%-11s%s\n", "key", "normalized", "raw"); + printf("%s:%s %s:%x\n", "Additional Smart Log for NVME device", devname, "namespace-id", nsid); + printf("%-34s%-11s%s\n", "key", "normalized", "raw"); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PROGRAM_FAIL, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "program_fail_count", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PROGRAM_FAIL, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "program_fail_count", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_ERASE_FAIL, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "erase_fail_count", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_ERASE_FAIL, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "erase_fail_count", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_WEARLEVELING_COUNT, nm, raw); - printf("%-31s : %3d%% %s%u%s%u%s%u\n", "wear_leveling", *nm, - "min: ", *(__u16 *)raw, ", max: ", *(__u16 *)(raw+2), ", avg: ", *(__u16 *)(raw+4)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_WEARLEVELING_COUNT, nm, raw); + printf("%-31s : %3d%% %s%u%s%u%s%u\n", "wear_leveling", *nm, + "min: ", *(__u16 *)raw, ", max: ", *(__u16 *)(raw+2), ", avg: ", *(__u16 *)(raw+4)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_E2E_DECTECTION_COUNT, nm, raw); - printf("%-31s: %3d%% %"PRIu64"\n", "end_to_end_error_detection_count", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_E2E_DECTECTION_COUNT, nm, raw); + printf("%-31s: %3d%% %"PRIu64"\n", "end_to_end_error_detection_count", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PCIE_CRC_ERR_COUNT, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "crc_error_count", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PCIE_CRC_ERR_COUNT, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "crc_error_count", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR, nm, raw); - printf("%-32s: %3d%% %.3f%%\n", "timed_workload_media_wear", *nm, ((float)int48_to_long(raw))/1000); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR, nm, raw); + printf("%-32s: %3d%% %.3f%%\n", "timed_workload_media_wear", *nm, ((float)int48_to_long(raw))/1000); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ, nm, raw); - printf("%-32s: %3d%% %"PRIu64"%%\n", "timed_workload_host_reads", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ, nm, raw); + printf("%-32s: %3d%% %"PRIu64"%%\n", "timed_workload_host_reads", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_TIMER, nm, raw); - printf("%-32s: %3d%% %"PRIu64"%s\n", "timed_workload_timer", *nm, int48_to_long(raw), " min"); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_TIMER, nm, raw); + printf("%-32s: %3d%% %"PRIu64"%s\n", "timed_workload_timer", *nm, int48_to_long(raw), " min"); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_STATUS, nm, raw); - printf("%-32s: %3d%% %u%%%s%"PRIu64"\n", "thermal_throttle_status", *nm, - *raw, ", cnt: ", int48_to_long(raw+1)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_STATUS, nm, raw); + printf("%-32s: %3d%% %u%%%s%"PRIu64"\n", "thermal_throttle_status", *nm, + *raw, ", cnt: ", int48_to_long(raw+1)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "retry_buffer_overflow_count", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "retry_buffer_overflow_count", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "pll_lock_loss_count", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "pll_lock_loss_count", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_WRITE, nm, raw); - printf("%-32s: %3d%% %s%"PRIu64"\n", "nand_bytes_written", *nm, "sectors: ", int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_WRITE, nm, raw); + printf("%-32s: %3d%% %s%"PRIu64"\n", "nand_bytes_written", *nm, "sectors: ", int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_HOST_WRITE, nm, raw); - printf("%-32s: %3d%% %s%"PRIu64"\n", "host_bytes_written", *nm, "sectors: ", int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_HOST_WRITE, nm, raw); + printf("%-32s: %3d%% %s%"PRIu64"\n", "host_bytes_written", *nm, "sectors: ", int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "system_area_life_left", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "system_area_life_left", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_READ, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "total_read", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_READ, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "total_read", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BORN, nm, raw); - printf("%-32s: %3d%% %s%u%s%u%s%u\n", "tempt_since_born", *nm, - "max: ", *(__u16 *)raw, ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BORN, nm, raw); + printf("%-32s: %3d%% %s%u%s%u%s%u\n", "tempt_since_born", *nm, + "max: ", *(__u16 *)raw, ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_POWER_CONSUMPTION, nm, raw); - printf("%-32s: %3d%% %s%u%s%u%s%u\n", "power_consumption", *nm, - "max: ", *(__u16 *)raw, ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_POWER_CONSUMPTION, nm, raw); + printf("%-32s: %3d%% %s%u%s%u%s%u\n", "power_consumption", *nm, + "max: ", *(__u16 *)raw, ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BOOTUP, nm, raw); - printf("%-32s: %3d%% %s%u%s%u%s%u\n", "tempt_since_bootup", *nm, "max: ", *(__u16 *)raw, - ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BOOTUP, nm, raw); + printf("%-32s: %3d%% %s%u%s%u%s%u\n", "tempt_since_bootup", *nm, "max: ", *(__u16 *)raw, + ", min: ", *(__u16 *)(raw+2), ", curr: ", *(__u16 *)(raw+4)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_READ_FAIL, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "read_fail_count", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_READ_FAIL, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "read_fail_count", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_TIME, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "thermal_throttle_time", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_TIME, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "thermal_throttle_time", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(smart, RAISIN_SI_VD_FLASH_MEDIA_ERROR, nm, raw); - printf("%-32s: %3d%% %"PRIu64"\n", "flash_media_error", *nm, int48_to_long(raw)); + get_memblaze_new_smart_info(smart, RAISIN_SI_VD_FLASH_MEDIA_ERROR, nm, raw); + printf("%-32s: %3d%% %"PRIu64"\n", "flash_media_error", *nm, int48_to_long(raw)); - free(nm); - free(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) + unsigned int nsid, const char *devname, const char *fw_ver) { - char fw_ver_local[STR_VER_SIZE + 1]; - struct nvme_memblaze_smart_log_item *item; - - strncpy(fw_ver_local, fw_ver, STR_VER_SIZE); - *(fw_ver_local + STR_VER_SIZE) = '\0'; - - 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 kelvins since last factory reset : %u\n", - le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.max)); - printf("Minimum temperature in kelvins 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 kelvins since power on : %u\n", - le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.max)); - printf("Minimum temperature in kelvins since power on : %u\n", - le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.min)); - } - printf("Current temperature in kelvins : %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 ( IS_PAPAYA(fw_ver_local) ) { - struct nvme_p4_smart_log *s = (struct nvme_p4_smart_log *)smart; - __u8 *nm = malloc(NM_SIZE * sizeof(__u8)); - __u8 *raw = malloc(RAW_SIZE * sizeof(__u8)); - - if (!nm) { - if (raw) - free(raw); - return; + char fw_ver_local[STR_VER_SIZE + 1]; + struct nvme_memblaze_smart_log_item *item; + + strncpy(fw_ver_local, fw_ver, STR_VER_SIZE); + *(fw_ver_local + STR_VER_SIZE) = '\0'; + + 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 kelvins since last factory reset : %u\n", + le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.max)); + printf("Minimum temperature in kelvins 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 kelvins since power on : %u\n", + le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.max)); + printf("Minimum temperature in kelvins since power on : %u\n", + le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.min)); } - if (!raw) { - free(nm); - return; + printf("Current temperature in kelvins : %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)); } - get_memblaze_new_smart_info(s, PROGRAM_FAIL, nm, raw); - printf("%-32s : %3d%% %"PRIu64"\n", + + 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 (IS_PAPAYA(fw_ver_local)) { + struct nvme_p4_smart_log *s = (struct nvme_p4_smart_log *)smart; + __u8 *nm = malloc(NM_SIZE * sizeof(__u8)); + __u8 *raw = malloc(RAW_SIZE * sizeof(__u8)); + + if (!nm) { + if (raw) + free(raw); + return; + } + if (!raw) { + free(nm); + return; + } + get_memblaze_new_smart_info(s, PROGRAM_FAIL, nm, raw); + printf("%-32s : %3d%% %"PRIu64"\n", "program_fail_count", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(s, ERASE_FAIL, nm, raw); - printf("%-32s : %3d%% %"PRIu64"\n", + get_memblaze_new_smart_info(s, ERASE_FAIL, nm, raw); + printf("%-32s : %3d%% %"PRIu64"\n", "erase_fail_count", *nm, int48_to_long(raw)); - get_memblaze_new_smart_info(s, WEARLEVELING_COUNT, nm, raw); - printf("%-31s : %3d%% %s%u%s%u%s%u\n", + get_memblaze_new_smart_info(s, WEARLEVELING_COUNT, nm, raw); + printf("%-31s : %3d%% %s%u%s%u%s%u\n", "wear_leveling", *nm, "min: ", *(__u16 *)raw, ", max: ", *(__u16 *)(raw+2), ", avg: ", *(__u16 *)(raw+4)); - get_memblaze_new_smart_info(s, TOTAL_WRITE, nm, raw); - printf("%-32s : %3d%% %"PRIu64"\n", + get_memblaze_new_smart_info(s, TOTAL_WRITE, nm, raw); + printf("%-32s : %3d%% %"PRIu64"\n", "nand_bytes_written", *nm, 32*int48_to_long(raw)); - get_memblaze_new_smart_info(s, HOST_WRITE, nm, raw); - printf("%-32s : %3d%% %"PRIu64"\n", + get_memblaze_new_smart_info(s, HOST_WRITE, nm, raw); + printf("%-32s : %3d%% %"PRIu64"\n", "host_bytes_written", *nm, 32*int48_to_long(raw)); - free(nm); - free(raw); - } + free(nm); + free(raw); + } } static int show_memblaze_smart_log(int fd, __u32 nsid, const char *devname, - struct nvme_memblaze_smart_log *smart) + 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(ctrl.mn)) // 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); - } + 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(ctrl.mn)) /* 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; } int parse_params(char *str, int number, ...) { - va_list argp; - int *param; - char *c; - int value; - - va_start(argp, number); - - while (number > 0) { - c = strtok(str, ","); - if ( c == NULL) { - printf("No enough parameters. abort...\n"); - va_end(argp); - return 1; - } - - if (isalnum((int)*c) == 0) { - printf("%s is not a valid number\n", c); - va_end(argp); - return 1; - } - value = atoi(c); - param = va_arg(argp, int *); - *param = value; - - if (str) { - str = strchr(str, ','); - if (str) { str++; } - } - number--; - } - va_end(argp); - - return 0; + va_list argp; + int *param; + char *c; + int value; + + va_start(argp, number); + + while (number > 0) { + c = strtok(str, ","); + if (!c) { + printf("No enough parameters. abort...\n"); + va_end(argp); + return 1; + } + + if (!isalnum((int)*c)) { + printf("%s is not a valid number\n", c); + va_end(argp); + return 1; + } + value = atoi(c); + param = va_arg(argp, int *); + *param = value; + + if (str) { + str = strchr(str, ','); + if (str) + str++; + } + number--; + } + va_end(argp); + + return 0; } static int mb_get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) { struct nvme_memblaze_smart_log smart_log; - char *desc = "Get Memblaze vendor specific additional smart log (optionally, "\ - "for the specified namespace), and show it."; + char *desc = + "Get Memblaze vendor specific additional smart log (optionally, for the specified namespace), and show it."; const char *namespace = "(optional) desired namespace"; const char *raw = "dump output in binary format"; struct nvme_dev *dev; @@ -425,7 +422,7 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm OPT_ARGS(opts) = { OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace), - OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), + OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), OPT_END() }; @@ -437,9 +434,8 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm sizeof(smart_log), &smart_log); if (!err) { if (!cfg.raw_binary) - err = show_memblaze_smart_log(dev_fd(dev), - cfg.namespace_id, - dev->name, &smart_log); + err = show_memblaze_smart_log(dev_fd(dev), cfg.namespace_id, dev->name, + &smart_log); else d_raw((unsigned char *)&smart_log, sizeof(smart_log)); } @@ -452,324 +448,318 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm static char *mb_feature_to_string(int feature) { - switch (feature) { - case MB_FEAT_POWER_MGMT: return "Memblaze power management"; - case MB_FEAT_HIGH_LATENCY: return "Memblaze high latency log"; - case MB_FEAT_CLEAR_ERRORLOG: return "Memblaze clear error log"; - default: return "Unknown"; - } + switch (feature) { + case MB_FEAT_POWER_MGMT: + return "Memblaze power management"; + case MB_FEAT_HIGH_LATENCY: + return "Memblaze high latency log"; + case MB_FEAT_CLEAR_ERRORLOG: + return "Memblaze clear error log"; + default: + return "Unknown"; + } } static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd, struct plugin *plugin) { - const char *desc = "Get Memblaze power management ststus\n (value 0 - 25w, 1 - 20w, 2 - 15w)"; - __u32 result; - __u32 feature_id = MB_FEAT_POWER_MGMT; - struct nvme_dev *dev; - int err; - - OPT_ARGS(opts) = { - OPT_END() - }; - - err = parse_and_open(&dev, argc, argv, desc, opts); - if (err) - return err; - - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = feature_id, - .nsid = 0, - .sel = 0, - .cdw11 = 0, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_get_features(&args); - if (err < 0) { - perror("get-feature"); - } - if (!err) { - printf("get-feature:0x%02x (%s), %s value: %#08x\n", feature_id, - mb_feature_to_string(feature_id), - nvme_select_to_string(0), result); - } else if (err > 0) - nvme_show_status(err); - dev_close(dev); - return err; + const char *desc = "Get Memblaze power management ststus\n (value 0 - 25w, 1 - 20w, 2 - 15w)"; + __u32 result; + __u32 feature_id = MB_FEAT_POWER_MGMT; + struct nvme_dev *dev; + int err; + + OPT_ARGS(opts) = { + OPT_END() + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; + + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = dev_fd(dev), + .fid = feature_id, + .nsid = 0, + .sel = 0, + .cdw11 = 0, + .uuidx = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = &result, + }; + err = nvme_get_features(&args); + if (err < 0) + perror("get-feature"); + if (!err) + printf("get-feature:0x%02x (%s), %s value: %#08x\n", feature_id, + mb_feature_to_string(feature_id), nvme_select_to_string(0), result); + else if (err > 0) + nvme_show_status(err); + dev_close(dev); + return err; } static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd, struct plugin *plugin) { - const char *desc = "Set Memblaze power management status\n (value 0 - 25w, 1 - 20w, 2 - 15w)"; - const char *value = "new value of feature (required)"; - const char *save = "specifies that the controller shall save the attribute"; - struct nvme_dev *dev; - __u32 result; - int err; - - struct config { - __u32 feature_id; - __u32 value; - bool save; - }; - - struct config cfg = { - .feature_id = MB_FEAT_POWER_MGMT, - .value = 0, - .save = 0, - }; - - OPT_ARGS(opts) = { - OPT_UINT("value", 'v', &cfg.value, value), - OPT_FLAG("save", 's', &cfg.save, save), - OPT_END() - }; - - err = parse_and_open(&dev, argc, argv, desc, opts); - if (err) - return err; - - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = cfg.feature_id, - .nsid = 0, - .cdw11 = cfg.value, - .cdw12 = 0, - .save = cfg.save, - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); - if (err < 0) { - perror("set-feature"); - } - if (!err) { - printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id, - mb_feature_to_string(cfg.feature_id), cfg.value); - } else if (err > 0) - nvme_show_status(err); - - dev_close(dev); - return err; + const char *desc = "Set Memblaze power management status\n (value 0 - 25w, 1 - 20w, 2 - 15w)"; + const char *value = "new value of feature (required)"; + const char *save = "specifies that the controller shall save the attribute"; + struct nvme_dev *dev; + __u32 result; + int err; + + struct config { + __u32 feature_id; + __u32 value; + bool save; + }; + + struct config cfg = { + .feature_id = MB_FEAT_POWER_MGMT, + .value = 0, + .save = 0, + }; + + OPT_ARGS(opts) = { + OPT_UINT("value", 'v', &cfg.value, value), + OPT_FLAG("save", 's', &cfg.save, save), + OPT_END() + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; + + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = dev_fd(dev), + .fid = cfg.feature_id, + .nsid = 0, + .cdw11 = cfg.value, + .cdw12 = 0, + .save = cfg.save, + .uuidx = 0, + .cdw15 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = &result, + }; + err = nvme_set_features(&args); + if (err < 0) + perror("set-feature"); + if (!err) + printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id, + mb_feature_to_string(cfg.feature_id), cfg.value); + else if (err > 0) + nvme_show_status(err); + + dev_close(dev); + return err; } -#define P2MIN (1) -#define P2MAX (5000) -#define MB_FEAT_HIGH_LATENCY_VALUE_SHIFT (15) +#define P2MIN (1) +#define P2MAX (5000) +#define MB_FEAT_HIGH_LATENCY_VALUE_SHIFT (15) static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) { - const char *desc = "Set Memblaze high latency log\n"\ - " input parameter p1,p2\n"\ - " p1 value: 0 is disable, 1 is enable\n"\ - " p2 value: 1 .. 5000 ms"; - const char *param = "input parameters"; - int param1 = 0, param2 = 0; - struct nvme_dev *dev; - __u32 result; - int err; - - struct config { - __u32 feature_id; - char * param; - __u32 value; - }; - - struct config cfg = { - .feature_id = MB_FEAT_HIGH_LATENCY, - .param = "0,0", - .value = 0, - }; - - OPT_ARGS(opts) = { - OPT_LIST("param", 'p', &cfg.param, param), - OPT_END() - }; - - err = parse_and_open(&dev, argc, argv, desc, opts); - if (err) - return err; - - if (parse_params(cfg.param, 2, ¶m1, ¶m2)) { - printf("setfeature: invalid formats %s\n", cfg.param); - dev_close(dev); - return EINVAL; - } - if ((param1 == 1) && (param2 < P2MIN || param2 > P2MAX)) { - printf("setfeature: invalid high io latency threshold %d\n", param2); - dev_close(dev); - return EINVAL; - } - cfg.value = (param1 << MB_FEAT_HIGH_LATENCY_VALUE_SHIFT) | param2; - - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = cfg.feature_id, - .nsid = 0, - .cdw11 = cfg.value, - .cdw12 = 0, - .save = false, - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); - if (err < 0) { - perror("set-feature"); - } - if (!err) { - printf("set-feature:0x%02X (%s), value:%#08x\n", cfg.feature_id, - mb_feature_to_string(cfg.feature_id), cfg.value); - } else if (err > 0) - nvme_show_status(err); - - dev_close(dev); - return err; + const char *desc = "Set Memblaze high latency log\n" + " input parameter p1,p2\n" + " p1 value: 0 is disable, 1 is enable\n" + " p2 value: 1 .. 5000 ms"; + const char *param = "input parameters"; + int param1 = 0, param2 = 0; + struct nvme_dev *dev; + __u32 result; + int err; + + struct config { + __u32 feature_id; + char *param; + __u32 value; + }; + + struct config cfg = { + .feature_id = MB_FEAT_HIGH_LATENCY, + .param = "0,0", + .value = 0, + }; + + OPT_ARGS(opts) = { + OPT_LIST("param", 'p', &cfg.param, param), + OPT_END() + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; + + if (parse_params(cfg.param, 2, ¶m1, ¶m2)) { + printf("setfeature: invalid formats %s\n", cfg.param); + dev_close(dev); + return -EINVAL; + } + if ((param1 == 1) && (param2 < P2MIN || param2 > P2MAX)) { + printf("setfeature: invalid high io latency threshold %d\n", param2); + dev_close(dev); + return -EINVAL; + } + cfg.value = (param1 << MB_FEAT_HIGH_LATENCY_VALUE_SHIFT) | param2; + + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = dev_fd(dev), + .fid = cfg.feature_id, + .nsid = 0, + .cdw11 = cfg.value, + .cdw12 = 0, + .save = false, + .uuidx = 0, + .cdw15 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = &result, + }; + err = nvme_set_features(&args); + if (err < 0) + perror("set-feature"); + if (!err) + printf("set-feature:0x%02X (%s), value:%#08x\n", cfg.feature_id, + mb_feature_to_string(cfg.feature_id), cfg.value); + else if (err > 0) + nvme_show_status(err); + + dev_close(dev); + return err; } static int glp_high_latency_show_bar(FILE *fdi, int print) { - fPRINT_PARAM1("Memblaze High Latency Log\n"); - fPRINT_PARAM1("---------------------------------------------------------------------------------------------\n"); - fPRINT_PARAM1("Timestamp Type QID CID NSID StartLBA NumLBA Latency\n"); - fPRINT_PARAM1("---------------------------------------------------------------------------------------------\n"); - return 0; + fPRINT_PARAM1("Memblaze High Latency Log\n"); + fPRINT_PARAM1("---------------------------------------------------------------------------------------------\n"); + fPRINT_PARAM1("Timestamp Type QID CID NSID StartLBA NumLBA Latency\n"); + fPRINT_PARAM1("---------------------------------------------------------------------------------------------\n"); + return 0; } -/* High latency log page definiton +/* + * High latency log page definiton * Total 32 bytes */ -typedef struct -{ - __u8 port; - __u8 revision; - __u16 rsvd; - __u8 opcode; - __u8 sqe; - __u16 cid; - __u32 nsid; - __u32 latency; - __u64 sLBA; - __u16 numLBA; - __u16 timestampH; - __u32 timestampL; -} log_page_high_latency_t; /* total 32 bytes */ +struct log_page_high_latency { + __u8 port; + __u8 revision; + __u16 rsvd; + __u8 opcode; + __u8 sqe; + __u16 cid; + __u32 nsid; + __u32 latency; + __u64 sLBA; + __u16 numLBA; + __u16 timestampH; + __u32 timestampL; +}; /* total 32 bytes */ static int find_deadbeef(char *buf) { - if (((*(buf + 0) & 0xff) == 0xef) && ((*(buf + 1) & 0xff) == 0xbe) && \ - ((*(buf + 2) & 0xff) == 0xad) && ((*(buf + 3) & 0xff) == 0xde)) - { - return 1; - } - return 0; + if (((*(buf + 0) & 0xff) == 0xef) && ((*(buf + 1) & 0xff) == 0xbe) && + ((*(buf + 2) & 0xff) == 0xad) && ((*(buf + 3) & 0xff) == 0xde)) + return 1; + return 0; } -#define TIME_STR_SIZE (44) +#define TIME_STR_SIZE (44) static int glp_high_latency(FILE *fdi, char *buf, int buflen, int print) { - log_page_high_latency_t *logEntry; - char string[TIME_STR_SIZE]; - int i, entrySize; - __u64 timestamp; - time_t tt = 0; - struct tm *t = NULL; - int millisec = 0; - - if (find_deadbeef(buf)) return 0; - - entrySize = sizeof(log_page_high_latency_t); - for (i = 0; i < buflen; i += entrySize) - { - logEntry = (log_page_high_latency_t *)(buf + i); - - if (logEntry->latency == 0 && logEntry->revision == 0) - { - return 1; - } - - if (0 == logEntry->timestampH) // generate host time string - { - snprintf(string, sizeof(string), "%d", logEntry->timestampL); - } - else // sort - { - timestamp = logEntry->timestampH; - timestamp = timestamp << 32; - timestamp += logEntry->timestampL; - tt = timestamp / 1000; - millisec = timestamp % 1000; - t = gmtime(&tt); - snprintf(string, sizeof(string), "%4d%02d%02d--%02d:%02d:%02d.%03d UTC", - 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, millisec); - } - - if (fdi) { - fprintf(fdi, "%-32s %-7x %-6x %-6x %-8x %4x%08x %-8x %-d\n", - string, logEntry->opcode, logEntry->sqe, - logEntry->cid, logEntry->nsid, - (__u32)(logEntry->sLBA >> 32), - (__u32)logEntry->sLBA, logEntry->numLBA, - logEntry->latency); + struct log_page_high_latency *logEntry; + char string[TIME_STR_SIZE]; + int i, entrySize; + __u64 timestamp; + time_t tt = 0; + struct tm *t = NULL; + int millisec = 0; + + if (find_deadbeef(buf)) + return 0; + + entrySize = sizeof(struct log_page_high_latency); + for (i = 0; i < buflen; i += entrySize) { + logEntry = (struct log_page_high_latency *)(buf + i); + + if (logEntry->latency == 0 && logEntry->revision == 0) + return 1; + + if (!logEntry->timestampH) { /* generate host time string */ + snprintf(string, sizeof(string), "%d", logEntry->timestampL); + } else { /* sort */ + timestamp = logEntry->timestampH; + timestamp = timestamp << 32; + timestamp += logEntry->timestampL; + tt = timestamp / 1000; + millisec = timestamp % 1000; + t = gmtime(&tt); + snprintf(string, sizeof(string), "%4d%02d%02d--%02d:%02d:%02d.%03d UTC", + 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, + t->tm_min, t->tm_sec, millisec); + } + + if (fdi) + fprintf(fdi, "%-32s %-7x %-6x %-6x %-8x %4x%08x %-8x %-d\n", + string, logEntry->opcode, logEntry->sqe, + logEntry->cid, logEntry->nsid, + (__u32)(logEntry->sLBA >> 32), + (__u32)logEntry->sLBA, logEntry->numLBA, + logEntry->latency); + if (print) + printf("%-32s %-7x %-6x %-6x %-8x %4x%08x %-8x %-d\n", + string, logEntry->opcode, logEntry->sqe, logEntry->cid, + logEntry->nsid, (__u32)(logEntry->sLBA >> 32), (__u32)logEntry->sLBA, + logEntry->numLBA, logEntry->latency); } - if (print) - { - printf("%-32s %-7x %-6x %-6x %-8x %4x%08x %-8x %-d\n", - string, logEntry->opcode, logEntry->sqe, logEntry->cid, logEntry->nsid, - (__u32)(logEntry->sLBA >> 32), (__u32)logEntry->sLBA, logEntry->numLBA, logEntry->latency); - } - } - return 1; + return 1; } static int mb_high_latency_log_print(int argc, char **argv, struct command *cmd, struct plugin *plugin) { - const char *desc = "Get Memblaze high latency log"; - char buf[LOG_PAGE_SIZE]; - struct nvme_dev *dev; - FILE *fdi = NULL; - int err; - - OPT_ARGS(opts) = { - OPT_END() - }; + const char *desc = "Get Memblaze high latency log"; + char buf[LOG_PAGE_SIZE]; + struct nvme_dev *dev; + FILE *fdi = NULL; + int err; - err = parse_and_open(&dev, argc, argv, desc, opts); - if (err) - return err; + OPT_ARGS(opts) = { + OPT_END() + }; - fdi = fopen(FID_C3_LOG_FILENAME, "w+"); + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; - glp_high_latency_show_bar(fdi, DO_PRINT_FLAG); - err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG, - sizeof(buf), &buf); + fdi = fopen(FID_C3_LOG_FILENAME, "w+"); - while (1) { - if (!glp_high_latency(fdi, buf, LOG_PAGE_SIZE, DO_PRINT_FLAG)) break; - err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG, + glp_high_latency_show_bar(fdi, DO_PRINT_FLAG); + err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG, sizeof(buf), &buf); - if ( err) { - nvme_show_status(err); - break; - } - } - - if (NULL != fdi) fclose(fdi); - dev_close(dev); - return err; + + while (1) { + if (!glp_high_latency(fdi, buf, LOG_PAGE_SIZE, DO_PRINT_FLAG)) + break; + err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG, + sizeof(buf), &buf); + if (err) { + nvme_show_status(err); + break; + } + } + + if (fdi) + fclose(fdi); + dev_close(dev); + return err; } static int memblaze_fw_commit(int fd, int select) @@ -777,7 +767,7 @@ static int memblaze_fw_commit(int fd, int select) struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_fw_commit, .cdw10 = 8, - .cdw12 = select, + .cdw12 = select, }; return nvme_submit_admin_passthru(fd, &cmd, NULL); @@ -786,9 +776,9 @@ static int memblaze_fw_commit(int fd, int select) static int mb_selective_download(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = - "This performs a selective firmware download, which allows the user to " - "select which firmware binary to update for 9200 devices. This requires a power cycle once the " - "update completes. The options available are: \n\n" + "This performs a selective firmware download, which allows the user to\n" + "select which firmware binary to update for 9200 devices. This requires a power cycle once the\n" + "update completes. The options available are:\n\n" "OOB - This updates the OOB and main firmware\n" "EEP - This updates the eeprom and main firmware\n" "ALL - This updates the eeprom, OOB, and main firmware"; @@ -796,18 +786,18 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str const char *select = "FW Select (e.g., --select=OOB, EEP, ALL)"; int xfer = 4096; void *fw_buf; - int selectNo,fw_fd,fw_size,err,offset = 0; + int selectNo, fw_fd, fw_size, err, offset = 0; struct nvme_dev *dev; struct stat sb; int i; struct config { - char *fw; - char *select; + char *fw; + char *select; }; struct config cfg = { - .fw = "", + .fw = "", .select = "\0", }; @@ -827,15 +817,14 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str goto out; } - for (i = 0; i < 3; i++) { + for (i = 0; i < 3; i++) cfg.select[i] = toupper(cfg.select[i]); - } - if (strncmp(cfg.select,"OOB", 3) == 0) { + if (!strncmp(cfg.select, "OOB", 3)) { selectNo = 18; - } else if (strncmp(cfg.select,"EEP", 3) == 0) { + } else if (!strncmp(cfg.select, "EEP", 3)) { selectNo = 10; - } else if (strncmp(cfg.select,"ALL", 3) == 0) { + } else if (!strncmp(cfg.select, "ALL", 3)) { selectNo = 26; } else { fprintf(stderr, "Invalid select flag\n"); @@ -895,14 +884,14 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str nvme_show_status(err); goto out_free; } - fw_buf += xfer; + fw_buf += xfer; fw_size -= xfer; offset += xfer; } err = memblaze_fw_commit(dev_fd(dev), selectNo); - if(err == 0x10B || err == 0x20B) { + if (err == 0x10B || err == 0x20B) { err = 0; fprintf(stderr, "Update successful! Please power cycle for changes to take effect\n"); } @@ -917,198 +906,181 @@ out: } static void ioLatencyHistogramOutput(FILE *fd, int index, int start, int end, char *unit0, - char *unit1, unsigned int *pHistogram, int print) + char *unit1, unsigned int *pHistogram, int print) { - int len; - char string[64], subString0[12], subString1[12]; - - snprintf(subString0, sizeof(subString0), "%d%s", start, unit0); - if (end != 0x7FFFFFFF) - snprintf(subString1, sizeof(subString1), "%d%s", end, unit1); - else - snprintf(subString1, sizeof(subString1), "%s", "+INF"); - len = snprintf(string, sizeof(string), "%-11d %-11s %-11s %-11u\n", + int len; + char string[64], subString0[12], subString1[12]; + + snprintf(subString0, sizeof(subString0), "%d%s", start, unit0); + if (end != 0x7FFFFFFF) + snprintf(subString1, sizeof(subString1), "%d%s", end, unit1); + else + snprintf(subString1, sizeof(subString1), "%s", "+INF"); + len = snprintf(string, sizeof(string), "%-11d %-11s %-11s %-11u\n", index, subString0, subString1, - pHistogram[index]); - fwrite(string, 1, len, fd); - if (print) - printf("%s", string); + pHistogram[index]); + fwrite(string, 1, len, fd); + if (print) + printf("%s", string); } int io_latency_histogram(char *file, char *buf, int print, int logid) { - FILE *fdi = fopen(file, "w+"); - int i, index; - char unit[2][3]; - unsigned int *revision = (unsigned int *)buf; - - if (logid == GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM) - { - fPRINT_PARAM1("Memblaze IO Read Command Latency Histogram\n"); - } - else if (logid == GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM) - { - fPRINT_PARAM1("Memblaze IO Write Command Latency Histogram\n"); - } - fPRINT_PARAM2("Major Revision : %d\n", revision[1]); - fPRINT_PARAM2("Minor Revision : %d\n", revision[0]); - buf += 8; - - if (revision[1] == 1 && revision[0] == 0) - { - fPRINT_PARAM1("--------------------------------------------------\n"); - fPRINT_PARAM1("Bucket Start End Value \n"); - fPRINT_PARAM1("--------------------------------------------------\n"); - index = 0; - strcpy(unit[0], "us"); - strcpy(unit[1], "us"); - for (i = 0; i < 32; i++, index++) - { - if (i == 31) - { - strcpy(unit[1], "ms"); - ioLatencyHistogramOutput(fdi, index, i * 32, 1, unit[0], unit[1], (unsigned int *)buf, print); - } - else - { - ioLatencyHistogramOutput(fdi, index, i * 32, (i + 1) * 32, unit[0], unit[1], (unsigned int *)buf, - print); - } - } - - strcpy(unit[0], "ms"); - strcpy(unit[1], "ms"); - for (i = 1; i < 32; i++, index++) - { - ioLatencyHistogramOutput(fdi, index, i, i + 1, unit[0], unit[1], (unsigned int *)buf, print); - } - - for (i = 1; i < 32; i++, index++) - { - if (i == 31) - { - strcpy(unit[1], "s"); - ioLatencyHistogramOutput(fdi, index, i * 32, 1, unit[0], unit[1], (unsigned int *)buf, print); - } - else - { - ioLatencyHistogramOutput(fdi, index, i * 32, (i + 1) * 32, unit[0], unit[1], (unsigned int *)buf, - print); - } - } - - strcpy(unit[0], "s"); - strcpy(unit[1], "s"); - for (i = 1; i < 4; i++, index++) - { - ioLatencyHistogramOutput(fdi, index, i, i + 1, unit[0], unit[1], (unsigned int *)buf, print); - } - - ioLatencyHistogramOutput(fdi, index, i, 0x7FFFFFFF, unit[0], unit[1], (unsigned int *)buf, print); - } - else - { - fPRINT_PARAM1("Unsupported io latency histogram revision\n"); - } - - if (fdi) - fclose(fdi); - return 1; + FILE *fdi = fopen(file, "w+"); + int i, index; + char unit[2][3]; + unsigned int *revision = (unsigned int *)buf; + + if (logid == GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM) + fPRINT_PARAM1("Memblaze IO Read Command Latency Histogram\n"); + else if (logid == GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM) + fPRINT_PARAM1("Memblaze IO Write Command Latency Histogram\n"); + fPRINT_PARAM2("Major Revision : %d\n", revision[1]); + fPRINT_PARAM2("Minor Revision : %d\n", revision[0]); + buf += 8; + + if (revision[1] == 1 && revision[0] == 0) { + fPRINT_PARAM1("--------------------------------------------------\n"); + fPRINT_PARAM1("Bucket Start End Value\n"); + fPRINT_PARAM1("--------------------------------------------------\n"); + index = 0; + strcpy(unit[0], "us"); + strcpy(unit[1], "us"); + for (i = 0; i < 32; i++, index++) { + if (i == 31) { + strcpy(unit[1], "ms"); + ioLatencyHistogramOutput(fdi, index, i * 32, 1, unit[0], unit[1], + (unsigned int *)buf, print); + } else { + ioLatencyHistogramOutput(fdi, index, i * 32, (i + 1) * 32, unit[0], + unit[1], (unsigned int *)buf, print); + } + } + + strcpy(unit[0], "ms"); + strcpy(unit[1], "ms"); + for (i = 1; i < 32; i++, index++) + ioLatencyHistogramOutput(fdi, index, i, i + 1, unit[0], unit[1], (unsigned int *)buf, print); + + for (i = 1; i < 32; i++, index++) { + if (i == 31) { + strcpy(unit[1], "s"); + ioLatencyHistogramOutput(fdi, index, i * 32, 1, unit[0], unit[1], + (unsigned int *)buf, print); + } else { + ioLatencyHistogramOutput(fdi, index, i * 32, (i + 1) * 32, unit[0], + unit[1], (unsigned int *)buf, print); + } + } + + strcpy(unit[0], "s"); + strcpy(unit[1], "s"); + for (i = 1; i < 4; i++, index++) + ioLatencyHistogramOutput(fdi, index, i, i + 1, unit[0], unit[1], (unsigned int *)buf, print); + + ioLatencyHistogramOutput(fdi, index, i, 0x7FFFFFFF, unit[0], unit[1], (unsigned int *)buf, print); + } else { + fPRINT_PARAM1("Unsupported io latency histogram revision\n"); + } + + if (fdi) + fclose(fdi); + return 1; } static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, struct plugin *plugin) { - char stats[LOG_PAGE_SIZE]; - char f1[] = FID_C1_LOG_FILENAME; - char f2[] = FID_C2_LOG_FILENAME; - struct nvme_dev *dev; - int err; - - const char *desc = "Get Latency Statistics log and show it."; - const char *write = "Get write statistics (read default)"; - - struct config { - bool write; - }; - struct config cfg = { - .write = 0, - }; - - OPT_ARGS(opts) = { - OPT_FLAG("write", 'w', &cfg.write, write), - OPT_END() - }; - - err = parse_and_open(&dev, argc, argv, desc, opts); - if (err) - return err; - - err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc2 : 0xc1, - sizeof(stats), &stats); - if (!err) - io_latency_histogram(cfg.write ? f2 : f1, stats, DO_PRINT_FLAG, - cfg.write ? GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM : GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM); - else - nvme_show_status(err); - - dev_close(dev); - return err; + char stats[LOG_PAGE_SIZE]; + char f1[] = FID_C1_LOG_FILENAME; + char f2[] = FID_C2_LOG_FILENAME; + struct nvme_dev *dev; + int err; + + const char *desc = "Get Latency Statistics log and show it."; + const char *write = "Get write statistics (read default)"; + + struct config { + bool write; + }; + struct config cfg = { + .write = 0, + }; + + OPT_ARGS(opts) = { + OPT_FLAG("write", 'w', &cfg.write, write), + OPT_END() + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; + + err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc2 : 0xc1, + sizeof(stats), &stats); + if (!err) + io_latency_histogram(cfg.write ? f2 : f1, stats, DO_PRINT_FLAG, + cfg.write ? GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM : + GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM); + else + nvme_show_status(err); + + dev_close(dev); + return err; } static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) { - char *desc = "Clear Memblaze devices error log."; - struct nvme_dev *dev; - int err; - - __u32 result; - - struct config { - __u32 feature_id; - __u32 value; - int save; - }; - - struct config cfg = { - .feature_id = 0xf7, - .value = 0x534d0001, - .save = 0, - }; - - OPT_ARGS(opts) = { - OPT_END() - }; - - err = parse_and_open(&dev, argc, argv, desc, opts); - if (err) - return err; - - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = cfg.feature_id, - .nsid = 0, - .cdw11 = cfg.value, - .cdw12 = 0, - .save = cfg.save, - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); - if (err < 0) { - perror("set-feature"); - } - if (!err) { - printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id, mb_feature_to_string(cfg.feature_id), cfg.value); - } else if (err > 0) - nvme_show_status(err); - - dev_close(dev); - return err; + char *desc = "Clear Memblaze devices error log."; + struct nvme_dev *dev; + int err; + + __u32 result; + + struct config { + __u32 feature_id; + __u32 value; + int save; + }; + + struct config cfg = { + .feature_id = 0xf7, + .value = 0x534d0001, + .save = 0, + }; + + OPT_ARGS(opts) = { + OPT_END() + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; + + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = dev_fd(dev), + .fid = cfg.feature_id, + .nsid = 0, + .cdw11 = cfg.value, + .cdw12 = 0, + .save = cfg.save, + .uuidx = 0, + .cdw15 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = &result, + }; + err = nvme_set_features(&args); + if (err < 0) + perror("set-feature"); + if (!err) + printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id, mb_feature_to_string(cfg.feature_id), cfg.value); + else if (err > 0) + nvme_show_status(err); + + dev_close(dev); + return err; } static int mb_set_lat_stats(int argc, char **argv, @@ -1207,7 +1179,7 @@ static int mb_set_lat_stats(int argc, char **argv, break; case True: case False: - err = nvme_set_features(&args_set); + err = nvme_set_features(&args_set); if (err > 0) { nvme_show_status(err); } else if (err < 0) { |