]> www.infradead.org Git - users/hch/nvme-cli.git/commitdiff
Add Dera plugin extension.
authorwudequan <wudequan@derastorage.com>
Mon, 18 Nov 2019 02:44:12 +0000 (10:44 +0800)
committerKeith Busch <kbusch@kernel.org>
Sun, 24 Nov 2019 16:37:51 +0000 (09:37 -0700)
Add stat sub-command to retrieve Dera device status and additional SMART log.

Makefile
plugins/dera/dera-nvme.c [new file with mode: 0644]
plugins/dera/dera-nvme.h [new file with mode: 0644]

index 692051eb3a5d9d225aafb45e60379ba12413bd4b..d88404dd51f60909e45a0c4dfc9bfa08281ef501 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -68,7 +68,8 @@ PLUGIN_OBJS :=                                        \
        plugins/micron/micron-nvme.o            \
        plugins/seagate/seagate-nvme.o          \
        plugins/virtium/virtium-nvme.o          \
-       plugins/shannon/shannon-nvme.o
+       plugins/shannon/shannon-nvme.o          \
+       plugins/dera/dera-nvme.o
 
 nvme: nvme.c nvme.h $(OBJS) $(PLUGIN_OBJS) $(UTIL_OBJS) NVME-VERSION-FILE
        $(CC) $(CPPFLAGS) $(CFLAGS) $(INC) nvme.c -o $(NVME) $(OBJS) $(PLUGIN_OBJS) $(UTIL_OBJS) $(LDFLAGS)
diff --git a/plugins/dera/dera-nvme.c b/plugins/dera/dera-nvme.c
new file mode 100644 (file)
index 0000000..8ac55ab
--- /dev/null
@@ -0,0 +1,210 @@
+#include <fcntl.h>\r
+#include <errno.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include <string.h>\r
+#include <dirent.h> \r
+#include <ctype.h> \r
+#include <sys/stat.h>\r
+#include <sys/time.h>\r
+\r
+#include "nvme.h"\r
+#include "nvme-print.h"\r
+#include "nvme-ioctl.h"\r
+#include "plugin.h"\r
+\r
+#include "argconfig.h"\r
+#include "suffix.h"\r
+\r
+#define CREATE_CMD\r
+#include "dera-nvme.h"\r
+\r
+static int char4_to_int(__u8 *data)\r
+{\r
+       int i;\r
+       int result = 0;\r
+\r
+       for (i = 0; i < 4; i++) {\r
+               result = result << 8;\r
+               result += data[3 - i];\r
+       }\r
+       return result;\r
+}\r
+\r
+struct nvme_dera_smart_info_log\r
+{\r
+       __u8 quick_rebuild_cnt0[4]; \r
+       __u8 quick_rebuild_cnt1[4]; \r
+       __u8 full_rebuild_cnt0[4];\r
+       __u8 full_rebuild_cnt1[4];\r
+       __u8 raw_rebuild_cnt0[4];\r
+       __u8 raw_rebuild_cnt1[4];\r
+       __u8 cap_aged;          \r
+       __u8 cap_aged_ratio;\r
+       __u8 cap_status;        \r
+       __u8 cap_voltage[4];\r
+       __u8 cap_charge_ctrl_en;         \r
+       __u8 cap_charge_ctrl_val[2];\r
+       __u8 cap_charge_max_thr[2]; \r
+       __u8 cap_charge_min_thr[2]; \r
+       __u8 dev_status; \r
+       __u8 dev_status_up;\r
+       __u8 nand_erase_err_cnt[4]; \r
+       __u8 nand_program_err_cnt[4]; \r
+       __u8 ddra_1bit_err[2];\r
+       __u8 ddra_2bit_err[2];\r
+       __u8 ddrb_1bit_err[2];\r
+       __u8 ddrb_2bit_err[2];\r
+       __u8 ddr_err_bit;\r
+       __u8 pcie_corr_err[2];\r
+       __u8 pcie_uncorr_err[2];\r
+       __u8 pcie_fatal_err[2];\r
+       __u8 pcie_err_bit;\r
+       __u8 power_level; \r
+       __u8 current_power[2]; \r
+       __u8 nand_init_fail[2]; \r
+       __u8 fw_loader_version[8]; \r
+       __u8 uefi_driver_version[8]; \r
+       __u8 gpio0_err[2]; \r
+       __u8 gpio5_err[2]; \r
+       __u8 gpio_err_bit[2]; \r
+       __u8 rebuild_percent; \r
+       __u8 pcie_volt_status; \r
+       __u8 current_pcie_volt[2]; \r
+       __u8 init_pcie_volt_thr[2]; \r
+       __u8 rt_pcie_volt_thr[2]; \r
+       __u8 init_pcie_volt_low[2]; \r
+       __u8 rt_pcie_volt_low[2]; \r
+       __u8 temp_sensor_abnormal[2];\r
+       __u8 nand_read_retry_fail_cnt[4]; \r
+       __u8 fw_slot_version[8]; \r
+       __u8 rsved[395];\r
+};\r
+\r
+enum dera_device_status\r
+{\r
+       DEVICE_STATUS_READY = 0x00,\r
+       DEVICE_STATUS_QUICK_REBUILDING = 0x01,\r
+       DEVICE_STATUS_FULL_REBUILDING = 0x02,\r
+       DEVICE_STATUS_RAW_REBUILDING = 0x03,\r
+       DEVICE_STATUS_CARD_READ_ONLY = 0x04,\r
+       DEVICE_STATUS_FATAL_ERROR = 0x05,\r
+       DEVICE_STATUS_BUSY = 0x06,\r
+       DEVICE_STAUTS_LOW_LEVEL_FORMAT = 0x07,\r
+       DEVICE_STAUTS_FW_COMMITING = 0x08,\r
+       DEVICE_STAUTS__OVER_TEMPRATURE = 0x09,\r
+};\r
+\r
+static int nvme_dera_get_device_status(int fd, enum dera_device_status *result)\r
+{\r
+       int err = 0;\r
+\r
+       struct nvme_passthru_cmd cmd = {\r
+               .opcode = 0xc0, \r
+               .addr = (__u64)(uintptr_t)NULL,\r
+               .data_len = 0,\r
+               .cdw10 = 0,\r
+               .cdw12 = 0x104, \r
+       };\r
+\r
+       err = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &cmd);\r
+       if (!err && result) {\r
+               *result = cmd.result;\r
+       }\r
+\r
+       return err;\r
+}\r
+\r
+static int get_status(int argc, char **argv, struct command *cmd, struct plugin *plugin)\r
+{\r
+       int fd, err;\r
+       struct nvme_dera_smart_info_log log;\r
+       enum dera_device_status state = DEVICE_STATUS_FATAL_ERROR;\r
+       char *desc = "Get the Dera device status";\r
+       const struct argconfig_commandline_options command_line_options[] = {\r
+               { 0 }\r
+       };\r
+\r
+       fd = parse_and_open(argc, argv, desc, command_line_options, NULL, 0); \r
+       if (fd < 0)\r
+               return fd;\r
+       \r
+       err = nvme_get_log(fd, 0xffffffff, 0xc0, false, sizeof(log), &log);\r
+       if (err) {\r
+               goto exit;\r
+       }\r
+\r
+       const char* dev_status[] = {\r
+               "Normal",\r
+               "Quick Rebuilding",\r
+               "Full Rebuilding",\r
+               "Raw Rebuilding",\r
+               "Card Read Only",\r
+               "Fatal Error",\r
+               "Busy",\r
+               "Low Level Format",\r
+               "Firmware Committing",\r
+               "Over Temperature" };\r
+\r
+       const char *volt_status[] = {\r
+               "Normal",\r
+               "Initial Low",\r
+               "Runtime Low",\r
+       };\r
+\r
+       err = nvme_dera_get_device_status(fd, &state);\r
+       if (!err){\r
+               if (state > 0 && state < 4){\r
+                       printf("device_status                       : %s %d%% completed\n", dev_status[state], log.rebuild_percent);\r
+               }\r
+               else{\r
+                       printf("device_status                       : %s\n", dev_status[state]);\r
+               }\r
+       }\r
+       else {\r
+               goto exit;\r
+       }\r
+       \r
+       printf("dev_status_up                       : %s\n", dev_status[log.dev_status_up]);\r
+       printf("cap_aged                            : %s\n", log.cap_aged == 1 ? "True" : "False");\r
+       printf("cap_aged_ratio                      : %d%%\n", log.cap_aged_ratio < 100 ? log.cap_aged_ratio : 100);\r
+       printf("cap_status                          : %s\n", log.cap_status == 0 ? "Normal" : (log.cap_status == 1 ? "Warning" : "Critical"));\r
+       printf("cap_voltage                         : %d mV\n", char4_to_int(log.cap_voltage));\r
+       printf("nand_erase_err_cnt                  : %d\n", char4_to_int(log.nand_erase_err_cnt));\r
+       printf("nand_program_err_cnt                : %d\n", char4_to_int(log.nand_program_err_cnt));\r
+       printf("ddra_1bit_err                       : %d\n", log.ddra_1bit_err[1] << 8 | log.ddra_1bit_err[0]);\r
+       printf("ddra_2bit_err                       : %d\n", log.ddra_2bit_err[1] << 8 | log.ddra_2bit_err[0]);\r
+       printf("ddrb_1bit_err                       : %d\n", log.ddrb_1bit_err[1] << 8 | log.ddrb_1bit_err[0]);\r
+       printf("ddrb_2bit_err                       : %d\n", log.ddrb_2bit_err[1] << 8 | log.ddrb_2bit_err[0]);\r
+       printf("ddr_err_bit                         : %d\n", log.ddr_err_bit);\r
+       printf("pcie_corr_err                       : %d\n", log.pcie_corr_err[1] << 8 | log.pcie_corr_err[0]);\r
+       printf("pcie_uncorr_err                     : %d\n", log.pcie_uncorr_err[1] << 8 | log.pcie_uncorr_err[0]);\r
+       printf("pcie_fatal_err                      : %d\n", log.pcie_fatal_err[1] << 8 | log.pcie_fatal_err[0]);\r
+       printf("power_level                         : %d W\n", log.power_level);\r
+       printf("current_power                       : %d mW\n", log.current_power[1] << 8 | log.current_power[0]);\r
+       printf("nand_init_fail                      : %d\n", log.nand_init_fail[1] << 8 | log.nand_init_fail[0]);\r
+       printf("fw_loader_version                   : %.*s\n", 8, log.fw_loader_version);\r
+       printf("uefi_driver_version                 : %.*s\n", 8, log.uefi_driver_version);\r
+\r
+       if (log.pcie_volt_status >= 0 && log.pcie_volt_status <= sizeof(volt_status) / sizeof(const char *)){\r
+               printf("pcie_volt_status                    : %s\n", volt_status[log.pcie_volt_status]);\r
+       }\r
+       else{\r
+               printf("pcie_volt_status                    : Unknown\n");\r
+       }\r
+\r
+       printf("current_pcie_volt                   : %d mV\n", log.current_pcie_volt[1] << 8 | log.current_pcie_volt[0]);\r
+       printf("init_pcie_volt_low_cnt              : %d\n", log.init_pcie_volt_low[1] << 8 | log.init_pcie_volt_low[0]);\r
+       printf("rt_pcie_volt_low_cnt                : %d\n", log.rt_pcie_volt_low[1] << 8 | log.rt_pcie_volt_low[0]);\r
+       printf("temp_sensor_abnormal_cnt            : %d\n", log.temp_sensor_abnormal[1] << 8 | log.temp_sensor_abnormal[0]);\r
+       printf("nand_read_retry_fail_cnt            : %d\n", char4_to_int(log.nand_read_retry_fail_cnt));\r
+       printf("fw_slot_version                     : %.*s\n", 8, log.fw_slot_version);\r
+\r
+exit:\r
+       if (err > 0)\r
+               fprintf(stderr, "\nNVMe status:%s(0x%x)\n",     nvme_status_to_string(err), err);\r
+\r
+       return err;\r
+}\r
+\r
diff --git a/plugins/dera/dera-nvme.h b/plugins/dera/dera-nvme.h
new file mode 100644 (file)
index 0000000..929c7de
--- /dev/null
@@ -0,0 +1,17 @@
+#undef CMD_INC_FILE
+#define CMD_INC_FILE plugins/dera/dera-nvme
+
+#if !defined(DERA_NVME) || defined(CMD_HEADER_MULTI_READ)
+#define DERA_NVME
+
+#include "cmd.h"
+
+PLUGIN(NAME("dera", "Dera vendor specific extensions"),
+       COMMAND_LIST(
+               ENTRY("stat", "Retrieve Dera device status, show it", get_status)
+       )
+);
+
+#endif
+
+#include "define_cmd.h"