From: wudequan Date: Tue, 26 Nov 2019 02:31:31 +0000 (+0800) Subject: Merge branch 'master' of github.com:linux-nvme/nvme-cli into dera-plugin X-Git-Tag: v1.10~25^2^2~1 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=ebcd2d20ae988b8ae21efd796b48be66e4db93a3;p=users%2Fhch%2Fnvme-cli.git Merge branch 'master' of github.com:linux-nvme/nvme-cli into dera-plugin --- ebcd2d20ae988b8ae21efd796b48be66e4db93a3 diff --cc Documentation/nvme-dera-stat.1 index 0000000,0000000..ca77efe new file mode 100644 --- /dev/null +++ b/Documentation/nvme-dera-stat.1 @@@ -1,0 -1,0 +1,71 @@@ ++'\" t ++.\" Title: nvme-dera-stat ++.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] ++.\" Generator: DocBook XSL Stylesheets v1.78.1 ++.\" Date: 11/26/2019 ++.\" Manual: NVMe Manual ++.\" Source: NVMe ++.\" Language: English ++.\" ++.TH "NVME\-DERA\-STAT" "1" "11/26/2019" "NVMe" "NVMe Manual" ++.\" ----------------------------------------------------------------- ++.\" * Define some portability stuff ++.\" ----------------------------------------------------------------- ++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++.\" http://bugs.debian.org/507673 ++.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html ++.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++.ie \n(.g .ds Aq \(aq ++.el .ds Aq ' ++.\" ----------------------------------------------------------------- ++.\" * set default formatting ++.\" ----------------------------------------------------------------- ++.\" disable hyphenation ++.nh ++.\" disable justification (adjust text to left margin only) ++.ad l ++.\" ----------------------------------------------------------------- ++.\" * MAIN CONTENT STARTS HERE * ++.\" ----------------------------------------------------------------- ++.SH "NAME" ++nvme-dera-stat \- Send NVMe Dera Device status and Additional SMART log page request, returns result and log ++.SH "SYNOPSIS" ++.sp ++.nf ++\fInvme dera stat\fR ++.fi ++.SH "DESCRIPTION" ++.sp ++Retrieves the NVMe Dera Device status and Additional SMART log page from the device and provides the returned structure\&. ++.sp ++The parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1)\&. ++.sp ++On success, the returned status and smart log structure are printed in a readable format\&. ++.SH "OPTIONS" ++.sp ++none ++.SH "EXAMPLES" ++.sp ++.RS 4 ++.ie n \{\ ++\h'-04'\(bu\h'+03'\c ++.\} ++.el \{\ ++.sp -1 ++.IP \(bu 2.3 ++.\} ++Print the Dera Device status and Additional SMART log page in a human readable format: ++.sp ++.if n \{\ ++.RS 4 ++.\} ++.nf ++# nvme dera stat /dev/nvme0 ++.fi ++.if n \{\ ++.RE ++.\} ++.RE ++.SH "NVME" ++.sp ++Part of the nvme\-user suite diff --cc Documentation/nvme-dera-stat.html index 0000000,0000000..49f8d39 new file mode 100644 --- /dev/null +++ b/Documentation/nvme-dera-stat.html @@@ -1,0 -1,0 +1,798 @@@ ++ ++ ++ ++ ++ ++nvme-dera-stat(1) ++ ++ ++ ++ ++ ++
++
++

NAME

++
++

nvme-dera-stat - Send NVMe Dera Device status and Additional SMART log page request, returns result and log

++
++
++
++

SYNOPSIS

++
++
++
nvme dera stat <device>
++
++
++
++
++
++

DESCRIPTION

++
++

Retrieves the NVMe Dera Device status and Additional SMART log page from the device and ++provides the returned structure.

++

The <device> parameter is mandatory and may be either the NVMe character ++device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).

++

On success, the returned status and smart log structure are printed in a readable format.

++
++
++
++

OPTIONS

++
++

none

++
++
++
++

EXAMPLES

++
++
    ++
  • ++

    ++Print the Dera Device status and Additional SMART log page in a human readable format: ++

    ++
    ++
    ++
    # nvme dera stat /dev/nvme0
    ++
    ++
  • ++
++
++
++
++

NVME

++
++

Part of the nvme-user suite

++
++
++
++

++ ++ ++ diff --cc Documentation/nvme-dera-stat.txt index ebc8b5a,0000000..512e584 mode 100644,000000..100644 --- a/Documentation/nvme-dera-stat.txt +++ b/Documentation/nvme-dera-stat.txt @@@ -1,38 -1,0 +1,38 @@@ +nvme-dera-stat(1) - =========================== ++================= + +NAME +---- +nvme-dera-stat - Send NVMe Dera Device status and Additional SMART log page request, returns result and log + +SYNOPSIS +-------- +[verse] +'nvme dera stat' + +DESCRIPTION +----------- +Retrieves the NVMe Dera Device status and Additional SMART log page from the device and +provides the returned structure. + +The parameter is mandatory and may be either the NVMe character +device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1). + +On success, the returned status and smart log structure are printed in a readable format. + +OPTIONS +------- +none + + +EXAMPLES +-------- +* Print the Dera Device status and Additional SMART log page in a human readable format: ++ +------------ +# nvme dera stat /dev/nvme0 +------------ + +NVME +---- +Part of the nvme-user suite diff --cc plugins/dera/dera-nvme.c index 8ac55ab,0000000..dbb40cc mode 100644,000000..100644 --- a/plugins/dera/dera-nvme.c +++ b/plugins/dera/dera-nvme.c @@@ -1,210 -1,0 +1,211 @@@ - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include "nvme.h" - #include "nvme-print.h" - #include "nvme-ioctl.h" - #include "plugin.h" - - #include "argconfig.h" - #include "suffix.h" - - #define CREATE_CMD - #include "dera-nvme.h" - - static int char4_to_int(__u8 *data) - { - int i; - int result = 0; - - for (i = 0; i < 4; i++) { - result = result << 8; - result += data[3 - i]; - } - return result; - } - - struct nvme_dera_smart_info_log - { - __u8 quick_rebuild_cnt0[4]; - __u8 quick_rebuild_cnt1[4]; - __u8 full_rebuild_cnt0[4]; - __u8 full_rebuild_cnt1[4]; - __u8 raw_rebuild_cnt0[4]; - __u8 raw_rebuild_cnt1[4]; - __u8 cap_aged; - __u8 cap_aged_ratio; - __u8 cap_status; - __u8 cap_voltage[4]; - __u8 cap_charge_ctrl_en; - __u8 cap_charge_ctrl_val[2]; - __u8 cap_charge_max_thr[2]; - __u8 cap_charge_min_thr[2]; - __u8 dev_status; - __u8 dev_status_up; - __u8 nand_erase_err_cnt[4]; - __u8 nand_program_err_cnt[4]; - __u8 ddra_1bit_err[2]; - __u8 ddra_2bit_err[2]; - __u8 ddrb_1bit_err[2]; - __u8 ddrb_2bit_err[2]; - __u8 ddr_err_bit; - __u8 pcie_corr_err[2]; - __u8 pcie_uncorr_err[2]; - __u8 pcie_fatal_err[2]; - __u8 pcie_err_bit; - __u8 power_level; - __u8 current_power[2]; - __u8 nand_init_fail[2]; - __u8 fw_loader_version[8]; - __u8 uefi_driver_version[8]; - __u8 gpio0_err[2]; - __u8 gpio5_err[2]; - __u8 gpio_err_bit[2]; - __u8 rebuild_percent; - __u8 pcie_volt_status; - __u8 current_pcie_volt[2]; - __u8 init_pcie_volt_thr[2]; - __u8 rt_pcie_volt_thr[2]; - __u8 init_pcie_volt_low[2]; - __u8 rt_pcie_volt_low[2]; - __u8 temp_sensor_abnormal[2]; - __u8 nand_read_retry_fail_cnt[4]; - __u8 fw_slot_version[8]; - __u8 rsved[395]; - }; - - enum dera_device_status - { - DEVICE_STATUS_READY = 0x00, - DEVICE_STATUS_QUICK_REBUILDING = 0x01, - DEVICE_STATUS_FULL_REBUILDING = 0x02, - DEVICE_STATUS_RAW_REBUILDING = 0x03, - DEVICE_STATUS_CARD_READ_ONLY = 0x04, - DEVICE_STATUS_FATAL_ERROR = 0x05, - DEVICE_STATUS_BUSY = 0x06, - DEVICE_STAUTS_LOW_LEVEL_FORMAT = 0x07, - DEVICE_STAUTS_FW_COMMITING = 0x08, - DEVICE_STAUTS__OVER_TEMPRATURE = 0x09, - }; - - static int nvme_dera_get_device_status(int fd, enum dera_device_status *result) - { - int err = 0; - - struct nvme_passthru_cmd cmd = { - .opcode = 0xc0, - .addr = (__u64)(uintptr_t)NULL, - .data_len = 0, - .cdw10 = 0, - .cdw12 = 0x104, - }; - - err = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &cmd); - if (!err && result) { - *result = cmd.result; - } - - return err; - } - - static int get_status(int argc, char **argv, struct command *cmd, struct plugin *plugin) - { - int fd, err; - struct nvme_dera_smart_info_log log; - enum dera_device_status state = DEVICE_STATUS_FATAL_ERROR; - char *desc = "Get the Dera device status"; - const struct argconfig_commandline_options command_line_options[] = { - { 0 } - }; - - fd = parse_and_open(argc, argv, desc, command_line_options, NULL, 0); - if (fd < 0) - return fd; - - err = nvme_get_log(fd, 0xffffffff, 0xc0, false, sizeof(log), &log); - if (err) { - goto exit; - } - - const char* dev_status[] = { - "Normal", - "Quick Rebuilding", - "Full Rebuilding", - "Raw Rebuilding", - "Card Read Only", - "Fatal Error", - "Busy", - "Low Level Format", - "Firmware Committing", - "Over Temperature" }; - - const char *volt_status[] = { - "Normal", - "Initial Low", - "Runtime Low", - }; - - err = nvme_dera_get_device_status(fd, &state); - if (!err){ - if (state > 0 && state < 4){ - printf("device_status : %s %d%% completed\n", dev_status[state], log.rebuild_percent); - } - else{ - printf("device_status : %s\n", dev_status[state]); - } - } - else { - goto exit; - } - - printf("dev_status_up : %s\n", dev_status[log.dev_status_up]); - printf("cap_aged : %s\n", log.cap_aged == 1 ? "True" : "False"); - printf("cap_aged_ratio : %d%%\n", log.cap_aged_ratio < 100 ? log.cap_aged_ratio : 100); - printf("cap_status : %s\n", log.cap_status == 0 ? "Normal" : (log.cap_status == 1 ? "Warning" : "Critical")); - printf("cap_voltage : %d mV\n", char4_to_int(log.cap_voltage)); - printf("nand_erase_err_cnt : %d\n", char4_to_int(log.nand_erase_err_cnt)); - printf("nand_program_err_cnt : %d\n", char4_to_int(log.nand_program_err_cnt)); - printf("ddra_1bit_err : %d\n", log.ddra_1bit_err[1] << 8 | log.ddra_1bit_err[0]); - printf("ddra_2bit_err : %d\n", log.ddra_2bit_err[1] << 8 | log.ddra_2bit_err[0]); - printf("ddrb_1bit_err : %d\n", log.ddrb_1bit_err[1] << 8 | log.ddrb_1bit_err[0]); - printf("ddrb_2bit_err : %d\n", log.ddrb_2bit_err[1] << 8 | log.ddrb_2bit_err[0]); - printf("ddr_err_bit : %d\n", log.ddr_err_bit); - printf("pcie_corr_err : %d\n", log.pcie_corr_err[1] << 8 | log.pcie_corr_err[0]); - printf("pcie_uncorr_err : %d\n", log.pcie_uncorr_err[1] << 8 | log.pcie_uncorr_err[0]); - printf("pcie_fatal_err : %d\n", log.pcie_fatal_err[1] << 8 | log.pcie_fatal_err[0]); - printf("power_level : %d W\n", log.power_level); - printf("current_power : %d mW\n", log.current_power[1] << 8 | log.current_power[0]); - printf("nand_init_fail : %d\n", log.nand_init_fail[1] << 8 | log.nand_init_fail[0]); - printf("fw_loader_version : %.*s\n", 8, log.fw_loader_version); - printf("uefi_driver_version : %.*s\n", 8, log.uefi_driver_version); - - if (log.pcie_volt_status >= 0 && log.pcie_volt_status <= sizeof(volt_status) / sizeof(const char *)){ - printf("pcie_volt_status : %s\n", volt_status[log.pcie_volt_status]); - } - else{ - printf("pcie_volt_status : Unknown\n"); - } - - printf("current_pcie_volt : %d mV\n", log.current_pcie_volt[1] << 8 | log.current_pcie_volt[0]); - printf("init_pcie_volt_low_cnt : %d\n", log.init_pcie_volt_low[1] << 8 | log.init_pcie_volt_low[0]); - printf("rt_pcie_volt_low_cnt : %d\n", log.rt_pcie_volt_low[1] << 8 | log.rt_pcie_volt_low[0]); - printf("temp_sensor_abnormal_cnt : %d\n", log.temp_sensor_abnormal[1] << 8 | log.temp_sensor_abnormal[0]); - printf("nand_read_retry_fail_cnt : %d\n", char4_to_int(log.nand_read_retry_fail_cnt)); - printf("fw_slot_version : %.*s\n", 8, log.fw_slot_version); - - exit: - if (err > 0) - fprintf(stderr, "\nNVMe status:%s(0x%x)\n", nvme_status_to_string(err), err); - - return err; - } - ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "nvme.h" ++#include "nvme-print.h" ++#include "nvme-ioctl.h" ++#include "plugin.h" ++ ++#include "argconfig.h" ++#include "suffix.h" ++ ++#define CREATE_CMD ++#include "dera-nvme.h" ++ ++static int char4_to_int(__u8 *data) ++{ ++ int i; ++ int result = 0; ++ ++ for (i = 0; i < 4; i++) { ++ result = result << 8; ++ result += data[3 - i]; ++ } ++ return result; ++} ++ ++struct nvme_dera_smart_info_log ++{ ++ __u8 quick_rebuild_cnt0[4]; ++ __u8 quick_rebuild_cnt1[4]; ++ __u8 full_rebuild_cnt0[4]; ++ __u8 full_rebuild_cnt1[4]; ++ __u8 raw_rebuild_cnt0[4]; ++ __u8 raw_rebuild_cnt1[4]; ++ __u8 cap_aged; ++ __u8 cap_aged_ratio; ++ __u8 cap_status; ++ __u8 cap_voltage[4]; ++ __u8 cap_charge_ctrl_en; ++ __u8 cap_charge_ctrl_val[2]; ++ __u8 cap_charge_max_thr[2]; ++ __u8 cap_charge_min_thr[2]; ++ __u8 dev_status; ++ __u8 dev_status_up; ++ __u8 nand_erase_err_cnt[4]; ++ __u8 nand_program_err_cnt[4]; ++ __u8 ddra_1bit_err[2]; ++ __u8 ddra_2bit_err[2]; ++ __u8 ddrb_1bit_err[2]; ++ __u8 ddrb_2bit_err[2]; ++ __u8 ddr_err_bit; ++ __u8 pcie_corr_err[2]; ++ __u8 pcie_uncorr_err[2]; ++ __u8 pcie_fatal_err[2]; ++ __u8 pcie_err_bit; ++ __u8 power_level; ++ __u8 current_power[2]; ++ __u8 nand_init_fail[2]; ++ __u8 fw_loader_version[8]; ++ __u8 uefi_driver_version[8]; ++ __u8 gpio0_err[2]; ++ __u8 gpio5_err[2]; ++ __u8 gpio_err_bit[2]; ++ __u8 rebuild_percent; ++ __u8 pcie_volt_status; ++ __u8 current_pcie_volt[2]; ++ __u8 init_pcie_volt_thr[2]; ++ __u8 rt_pcie_volt_thr[2]; ++ __u8 init_pcie_volt_low[2]; ++ __u8 rt_pcie_volt_low[2]; ++ __u8 temp_sensor_abnormal[2]; ++ __u8 nand_read_retry_fail_cnt[4]; ++ __u8 fw_slot_version[8]; ++ __u8 rsved[395]; ++}; ++ ++enum dera_device_status ++{ ++ DEVICE_STATUS_READY = 0x00, ++ DEVICE_STATUS_QUICK_REBUILDING = 0x01, ++ DEVICE_STATUS_FULL_REBUILDING = 0x02, ++ DEVICE_STATUS_RAW_REBUILDING = 0x03, ++ DEVICE_STATUS_CARD_READ_ONLY = 0x04, ++ DEVICE_STATUS_FATAL_ERROR = 0x05, ++ DEVICE_STATUS_BUSY = 0x06, ++ DEVICE_STAUTS_LOW_LEVEL_FORMAT = 0x07, ++ DEVICE_STAUTS_FW_COMMITING = 0x08, ++ DEVICE_STAUTS__OVER_TEMPRATURE = 0x09, ++}; ++ ++static int nvme_dera_get_device_status(int fd, enum dera_device_status *result) ++{ ++ int err = 0; ++ ++ struct nvme_passthru_cmd cmd = { ++ .opcode = 0xc0, ++ .addr = (__u64)(uintptr_t)NULL, ++ .data_len = 0, ++ .cdw10 = 0, ++ .cdw12 = 0x104, ++ }; ++ ++ err = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &cmd); ++ if (!err && result) { ++ *result = cmd.result; ++ } ++ ++ return err; ++} ++ ++static int get_status(int argc, char **argv, struct command *cmd, struct plugin *plugin) ++{ ++ int fd, err; ++ struct nvme_dera_smart_info_log log; ++ enum dera_device_status state = DEVICE_STATUS_FATAL_ERROR; ++ char *desc = "Get the Dera device status"; ++ ++ OPT_ARGS(opts) = { ++ OPT_END() ++ }; ++ ++ fd = parse_and_open(argc, argv, desc, opts); ++ if (fd < 0) ++ return fd; ++ ++ err = nvme_get_log(fd, 0xffffffff, 0xc0, false, sizeof(log), &log); ++ if (err) { ++ goto exit; ++ } ++ ++ const char* dev_status[] = { ++ "Normal", ++ "Quick Rebuilding", ++ "Full Rebuilding", ++ "Raw Rebuilding", ++ "Card Read Only", ++ "Fatal Error", ++ "Busy", ++ "Low Level Format", ++ "Firmware Committing", ++ "Over Temperature" }; ++ ++ const char *volt_status[] = { ++ "Normal", ++ "Initial Low", ++ "Runtime Low", ++ }; ++ ++ err = nvme_dera_get_device_status(fd, &state); ++ if (!err){ ++ if (state > 0 && state < 4){ ++ printf("device_status : %s %d%% completed\n", dev_status[state], log.rebuild_percent); ++ } ++ else{ ++ printf("device_status : %s\n", dev_status[state]); ++ } ++ } ++ else { ++ goto exit; ++ } ++ ++ printf("dev_status_up : %s\n", dev_status[log.dev_status_up]); ++ printf("cap_aged : %s\n", log.cap_aged == 1 ? "True" : "False"); ++ printf("cap_aged_ratio : %d%%\n", log.cap_aged_ratio < 100 ? log.cap_aged_ratio : 100); ++ printf("cap_status : %s\n", log.cap_status == 0 ? "Normal" : (log.cap_status == 1 ? "Warning" : "Critical")); ++ printf("cap_voltage : %d mV\n", char4_to_int(log.cap_voltage)); ++ printf("nand_erase_err_cnt : %d\n", char4_to_int(log.nand_erase_err_cnt)); ++ printf("nand_program_err_cnt : %d\n", char4_to_int(log.nand_program_err_cnt)); ++ printf("ddra_1bit_err : %d\n", log.ddra_1bit_err[1] << 8 | log.ddra_1bit_err[0]); ++ printf("ddra_2bit_err : %d\n", log.ddra_2bit_err[1] << 8 | log.ddra_2bit_err[0]); ++ printf("ddrb_1bit_err : %d\n", log.ddrb_1bit_err[1] << 8 | log.ddrb_1bit_err[0]); ++ printf("ddrb_2bit_err : %d\n", log.ddrb_2bit_err[1] << 8 | log.ddrb_2bit_err[0]); ++ printf("ddr_err_bit : %d\n", log.ddr_err_bit); ++ printf("pcie_corr_err : %d\n", log.pcie_corr_err[1] << 8 | log.pcie_corr_err[0]); ++ printf("pcie_uncorr_err : %d\n", log.pcie_uncorr_err[1] << 8 | log.pcie_uncorr_err[0]); ++ printf("pcie_fatal_err : %d\n", log.pcie_fatal_err[1] << 8 | log.pcie_fatal_err[0]); ++ printf("power_level : %d W\n", log.power_level); ++ printf("current_power : %d mW\n", log.current_power[1] << 8 | log.current_power[0]); ++ printf("nand_init_fail : %d\n", log.nand_init_fail[1] << 8 | log.nand_init_fail[0]); ++ printf("fw_loader_version : %.*s\n", 8, log.fw_loader_version); ++ printf("uefi_driver_version : %.*s\n", 8, log.uefi_driver_version); ++ ++ if (log.pcie_volt_status >= 0 && log.pcie_volt_status <= sizeof(volt_status) / sizeof(const char *)){ ++ printf("pcie_volt_status : %s\n", volt_status[log.pcie_volt_status]); ++ } ++ else{ ++ printf("pcie_volt_status : Unknown\n"); ++ } ++ ++ printf("current_pcie_volt : %d mV\n", log.current_pcie_volt[1] << 8 | log.current_pcie_volt[0]); ++ printf("init_pcie_volt_low_cnt : %d\n", log.init_pcie_volt_low[1] << 8 | log.init_pcie_volt_low[0]); ++ printf("rt_pcie_volt_low_cnt : %d\n", log.rt_pcie_volt_low[1] << 8 | log.rt_pcie_volt_low[0]); ++ printf("temp_sensor_abnormal_cnt : %d\n", log.temp_sensor_abnormal[1] << 8 | log.temp_sensor_abnormal[0]); ++ printf("nand_read_retry_fail_cnt : %d\n", char4_to_int(log.nand_read_retry_fail_cnt)); ++ printf("fw_slot_version : %.*s\n", 8, log.fw_slot_version); ++ ++exit: ++ if (err > 0) ++ fprintf(stderr, "\nNVMe status:%s(0x%x)\n", nvme_status_to_string(err), err); ++ ++ return err; ++} ++