diff options
Diffstat (limited to '')
-rw-r--r-- | plugins/ymtc/ymtc-nvme.c | 148 | ||||
-rw-r--r-- | plugins/ymtc/ymtc-nvme.h | 24 | ||||
-rw-r--r-- | plugins/ymtc/ymtc-utils.h | 80 |
3 files changed, 252 insertions, 0 deletions
diff --git a/plugins/ymtc/ymtc-nvme.c b/plugins/ymtc/ymtc-nvme.c new file mode 100644 index 0000000..91e52be --- /dev/null +++ b/plugins/ymtc/ymtc-nvme.c @@ -0,0 +1,148 @@ +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "linux/nvme_ioctl.h" + +#include "nvme.h" +#include "nvme-print.h" +#include "nvme-ioctl.h" +#include "plugin.h" + +#include "argconfig.h" +#include "suffix.h" + +#define CREATE_CMD +#include "ymtc-nvme.h" +#include "ymtc-utils.h" + +static void get_ymtc_smart_info(struct nvme_ymtc_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); +} + +static int show_ymtc_smart_log(int fd, __u32 nsid, const char *devname, + struct nvme_ymtc_smart_log *smart) +{ + struct nvme_id_ctrl ctrl; + char fw_ver[10]; + int err = 0; + + u8 *nm = malloc(NM_SIZE * sizeof(u8)); + u8 *raw = malloc(RAW_SIZE * sizeof(u8)); + + 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]); + + /* Table Title */ + printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid); + /* Clumn Name*/ + printf("key normalized raw\n"); + /* 00 SI_VD_PROGRAM_FAIL */ + get_ymtc_smart_info(smart, SI_VD_PROGRAM_FAIL, nm, raw); + printf("program_fail_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 01 SI_VD_ERASE_FAIL */ + get_ymtc_smart_info(smart, SI_VD_ERASE_FAIL, nm, raw); + printf("erase_fail_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 02 SI_VD_WEARLEVELING_COUNT */ + get_ymtc_smart_info(smart, SI_VD_WEARLEVELING_COUNT, nm, raw); + printf("wear_leveling : %3d%% min: %u, max: %u, avg: %u\n", *nm, + *raw, *(raw+2), *(raw+4)); + /* 03 SI_VD_E2E_DECTECTION_COUNT */ + get_ymtc_smart_info(smart, SI_VD_E2E_DECTECTION_COUNT, nm, raw); + printf("end_to_end_error_detection_count: %3d%% %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 04 SI_VD_PCIE_CRC_ERR_COUNT */ + get_ymtc_smart_info(smart, SI_VD_PCIE_CRC_ERR_COUNT, nm, raw); + printf("crc_error_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 08 SI_VD_THERMAL_THROTTLE_STATUS */ + get_ymtc_smart_info(smart, SI_VD_THERMAL_THROTTLE_STATUS, nm, raw); + printf("thermal_throttle_status : %3d%% %"PRIu64"%%, cnt: %"PRIu64"\n", *nm, + int48_to_long(raw), int48_to_long(raw+1)); + /* 11 SI_VD_TOTAL_WRITE */ + get_ymtc_smart_info(smart, SI_VD_TOTAL_WRITE, nm, raw); + printf("nand_bytes_written : %3d%% sectors: %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 12 SI_VD_HOST_WRITE */ + get_ymtc_smart_info(smart, SI_VD_HOST_WRITE, nm, raw); + printf("host_bytes_written : %3d%% sectors: %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 14 SI_VD_TOTAL_READ */ + get_ymtc_smart_info(smart, SI_VD_TOTAL_READ, nm, raw); + printf("nand_bytes_read : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 15 SI_VD_TEMPT_SINCE_BORN */ + get_ymtc_smart_info(smart, SI_VD_TEMPT_SINCE_BORN, nm, raw); + printf("tempt_since_born : %3d%% max: %u, min: %u, curr: %u\n", *nm, + *raw, *(raw+2), *(raw+4)); + /* 16 SI_VD_POWER_CONSUMPTION */ + get_ymtc_smart_info(smart, SI_VD_POWER_CONSUMPTION, nm, raw); + printf("power_consumption : %3d%% max: %u, min: %u, curr: %u\n", *nm, + *raw, *(raw+2), *(raw+4)); + /* 17 SI_VD_TEMPT_SINCE_BOOTUP */ + get_ymtc_smart_info(smart, SI_VD_TEMPT_SINCE_BOOTUP, nm, raw); + printf("tempt_since_bootup : %3d%% max: %u, min: %u, curr: %u\n", *nm, *raw, + *(raw+2), *(raw+4)); + /* 18 SI_VD_POWER_LOSS_PROTECTION */ + get_ymtc_smart_info(smart, SI_VD_POWER_LOSS_PROTECTION, nm, raw); + printf("power_loss_protection : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 19 SI_VD_READ_FAIL */ + get_ymtc_smart_info(smart, SI_VD_READ_FAIL, nm, raw); + printf("read_fail : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 20 SI_VD_THERMAL_THROTTLE_TIME */ + get_ymtc_smart_info(smart, SI_VD_THERMAL_THROTTLE_TIME, nm, raw); + printf("thermal_throttle_time : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw)); + /* 21 SI_VD_FLASH_MEDIA_ERROR */ + get_ymtc_smart_info(smart, SI_VD_FLASH_MEDIA_ERROR, nm, raw); + printf("flash_error_media_count : %3d%% %"PRIu64"\n", *nm, int48_to_long(raw)); + + free(nm); + free(raw); + + return err; +} + +static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + struct nvme_ymtc_smart_log smart_log; + int err, fd; + char *desc = "Get Ymtc 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 config { + __u32 namespace_id; + int raw_binary; + }; + + struct config cfg = { + .namespace_id = NVME_NSID_ALL, + }; + + OPT_ARGS(opts) = { + OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace), + OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), + OPT_END() + }; + + fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) + return fd; + + err = nvme_get_log(fd, cfg.namespace_id, 0xca, false, + NVME_NO_LOG_LSP, sizeof(smart_log), &smart_log); + if (!err) { + if (!cfg.raw_binary) + err = show_ymtc_smart_log(fd, cfg.namespace_id, devicename, &smart_log); + else + d_raw((unsigned char *)&smart_log, sizeof(smart_log)); + } + if (err > 0) + fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(err), err); + + return err; +} diff --git a/plugins/ymtc/ymtc-nvme.h b/plugins/ymtc/ymtc-nvme.h new file mode 100644 index 0000000..739fd37 --- /dev/null +++ b/plugins/ymtc/ymtc-nvme.h @@ -0,0 +1,24 @@ +#undef CMD_INC_FILE +#define CMD_INC_FILE plugins/ymtc/ymtc-nvme + +#if !defined(YMTC_NVME) || defined(CMD_HEADER_MULTI_READ) +#define YMTC_NVME + +#include "cmd.h" +#include "common.h" + +#include <ctype.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + +PLUGIN(NAME("ymtc", "Ymtc vendor specific extensions"), + COMMAND_LIST( + ENTRY("smart-log-add", "Retrieve Ymtc SMART Log, show it", get_additional_smart_log) + ) +); + +#endif + +#include "define_cmd.h" + diff --git a/plugins/ymtc/ymtc-utils.h b/plugins/ymtc/ymtc-utils.h new file mode 100644 index 0000000..700c764 --- /dev/null +++ b/plugins/ymtc/ymtc-utils.h @@ -0,0 +1,80 @@ +#ifndef __YMTC_UTILS_H__ +#define __YMTC_UTILS_H__ + +#define SMART_INFO_SIZE 4096 + +#define ID_SIZE 3 +#define NM_SIZE 2 +#define RAW_SIZE 7 + +typedef unsigned char u8; + +/* Additional smart external ID */ +#define SI_VD_PROGRAM_FAIL_ID 0xAB +#define SI_VD_ERASE_FAIL_ID 0xAC +#define SI_VD_WEARLEVELING_COUNT_ID 0xAD +#define SI_VD_E2E_DECTECTION_COUNT_ID 0xB8 +#define SI_VD_PCIE_CRC_ERR_COUNT_ID 0xC7 +#define SI_VD_TIMED_WORKLOAD_MEDIA_WEAR_ID 0xE2 +#define SI_VD_TIMED_WORKLOAD_HOST_READ_ID 0xE3 +#define SI_VD_TIMED_WORKLOAD_TIMER_ID 0xE4 +#define SI_VD_THERMAL_THROTTLE_STATUS_ID 0xEA +#define SI_VD_RETRY_BUFF_OVERFLOW_COUNT_ID 0xF0 +#define SI_VD_PLL_LOCK_LOSS_COUNT_ID 0xF3 +#define SI_VD_TOTAL_WRITE_ID 0xF4 +#define SI_VD_HOST_WRITE_ID 0xF5 +#define SI_VD_SYSTEM_AREA_LIFE_LEFT_ID 0xF6 +#define SI_VD_TOTAL_READ_ID 0xFA +#define SI_VD_TEMPT_SINCE_BORN_ID 0xE7 +#define SI_VD_POWER_CONSUMPTION_ID 0xE8 +#define SI_VD_TEMPT_SINCE_BOOTUP_ID 0xAF +#define SI_VD_POWER_LOSS_PROTECTION_ID 0xEC +#define SI_VD_READ_FAIL_ID 0xF2 +#define SI_VD_THERMAL_THROTTLE_TIME_ID 0xEB +#define SI_VD_FLASH_MEDIA_ERROR_ID 0xED + +/* Addtional smart internal ID */ +typedef enum +{ + /* smart attr following intel */ + SI_VD_PROGRAM_FAIL = 0, /* 0xAB */ + SI_VD_ERASE_FAIL = 1, /* 0xAC */ + SI_VD_WEARLEVELING_COUNT = 2,/* 0xAD */ + SI_VD_E2E_DECTECTION_COUNT = 3, /* 0xB8 */ + SI_VD_PCIE_CRC_ERR_COUNT = 4, /* 0xC7, 2 port data in one attribute */ + SI_VD_THERMAL_THROTTLE_STATUS = 8, /* 0xEA */ + SI_VD_TOTAL_WRITE = 11, /* 0xF4, unit is 32MiB */ + SI_VD_HOST_WRITE = 12, /* 0xF5, unit is 32MiB */ + SI_VD_TOTAL_READ = 14, /* 0xFA, unit is 32MiB */ + + /* smart attr self defined */ + SI_VD_TEMPT_SINCE_BORN = 15, /* 0xE7 */ + SI_VD_POWER_CONSUMPTION = 16, /* 0xE8 */ + SI_VD_TEMPT_SINCE_BOOTUP = 17, /* 0xAF */ + SI_VD_POWER_LOSS_PROTECTION = 18, /* 0xEC */ + SI_VD_READ_FAIL = 19, /* 0xF2 */ + SI_VD_THERMAL_THROTTLE_TIME = 20, /* 0xEB */ + SI_VD_FLASH_MEDIA_ERROR = 21, /* 0xED */ + NR_SMART_ITEMS, +} si_vendor_smart_item_e; + +// Intel Format +struct nvme_ymtc_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_ymtc_smart_log +{ + struct nvme_ymtc_smart_log_item itemArr[NR_SMART_ITEMS]; + + u8 resv[SMART_INFO_SIZE - sizeof(struct nvme_ymtc_smart_log_item) * NR_SMART_ITEMS]; +}; + +#endif // __YMTC_UTILS_H__ + |