From d57675fc67455faf7c68d4003a1ce884779e2c7c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 3 Apr 2023 10:17:38 +0200 Subject: Merging upstream version 2.4+really2.3. This reverts commit f42531334c05b7f49ae43c0a27e347a487fb2667. --- plugins/fdp/fdp.c | 3 +- plugins/innogrit/innogrit-nvme.c | 107 +- plugins/inspur/inspur-nvme.c | 4 +- plugins/intel/intel-nvme.c | 2 +- plugins/memblaze/memblaze-nvme.c | 14 +- plugins/meson.build | 56 +- plugins/micron/micron-nvme.c | 2 +- plugins/ocp/meson.build | 1 - plugins/ocp/ocp-clear-fw-update-history.c | 56 +- plugins/ocp/ocp-clear-fw-update-history.h | 3 +- plugins/ocp/ocp-nvme.c | 1276 +++++++++++--------- plugins/ocp/ocp-nvme.h | 12 +- plugins/ocp/ocp-smart-extended-log.c | 352 ------ plugins/ocp/ocp-smart-extended-log.h | 18 - plugins/ocp/ocp-utils.c | 69 +- plugins/ocp/ocp-utils.h | 2 - plugins/solidigm/meson.build | 1 - plugins/solidigm/solidigm-garbage-collection.c | 32 +- plugins/solidigm/solidigm-latency-tracking.c | 22 +- plugins/solidigm/solidigm-nvme.c | 10 +- plugins/solidigm/solidigm-nvme.h | 3 +- plugins/solidigm/solidigm-smart.c | 34 +- plugins/solidigm/solidigm-telemetry.c | 2 +- plugins/solidigm/solidigm-telemetry/cod.c | 8 +- plugins/solidigm/solidigm-telemetry/config.c | 12 +- plugins/solidigm/solidigm-telemetry/config.h | 5 +- plugins/solidigm/solidigm-telemetry/data-area.c | 48 +- plugins/solidigm/solidigm-telemetry/header.c | 32 +- .../solidigm/solidigm-telemetry/telemetry-log.h | 6 +- plugins/solidigm/solidigm-util.c | 20 - plugins/solidigm/solidigm-util.h | 10 - plugins/wdc/wdc-nvme.c | 88 +- plugins/wdc/wdc-nvme.h | 2 +- 33 files changed, 957 insertions(+), 1355 deletions(-) delete mode 100644 plugins/ocp/ocp-smart-extended-log.c delete mode 100644 plugins/ocp/ocp-smart-extended-log.h delete mode 100644 plugins/solidigm/solidigm-util.c delete mode 100644 plugins/solidigm/solidigm-util.h (limited to 'plugins') diff --git a/plugins/fdp/fdp.c b/plugins/fdp/fdp.c index 1e292e8..9fef271 100644 --- a/plugins/fdp/fdp.c +++ b/plugins/fdp/fdp.c @@ -350,8 +350,7 @@ static int fdp_status(int argc, char **argv, struct command *cmd, struct plugin goto out; } - len = sizeof(struct nvme_fdp_ruh_status) + - le16_to_cpu(hdr.nruhsd) * sizeof(struct nvme_fdp_ruh_status_desc); + len = le16_to_cpu(hdr.nruhsd) * sizeof(struct nvme_fdp_ruh_status_desc); buf = malloc(len); if (!buf) { err = -ENOMEM; diff --git a/plugins/innogrit/innogrit-nvme.c b/plugins/innogrit/innogrit-nvme.c index 1771538..b5d40dd 100644 --- a/plugins/innogrit/innogrit-nvme.c +++ b/plugins/innogrit/innogrit-nvme.c @@ -162,7 +162,7 @@ static int innogrit_vsc_geteventlog(int argc, char **argv, { time_t timep; struct tm *logtime; - int icount, ioffset16k, iblock, ivsctype; + int icount, ioffset16k, iblock; char currentdir[128], filename[512]; unsigned char data[4096], data16k[SIZE_16K], zerob[32]; unsigned int *pcheckdata; @@ -195,15 +195,6 @@ static int innogrit_vsc_geteventlog(int argc, char **argv, if (getcwd(currentdir, 128) == NULL) return -1; - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x03, 0x00, 0x00, (char *)data, 4096); - if (ret == -1) - return ret; - - if (data[0] == 0x5A) - ivsctype = 1; - else - ivsctype = 0; - time(&timep); logtime = localtime(&timep); sprintf(filename, "%s/eventlog_%02d%02d-%02d%02d%02d.elog", currentdir, logtime->tm_mon+1, @@ -227,13 +218,10 @@ static int innogrit_vsc_geteventlog(int argc, char **argv, icount++; memset(data, 0, 4096); - if (ivsctype == 1) - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x60, 0x00, 0x00, 0x00,(char *)data, 4096); - else - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET_EVENT_LOG, 0, 0, - (SRB_SIGNATURE >> 32), - (SRB_SIGNATURE & 0xFFFFFFFF), - (char *)data, 4096); + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET_EVENT_LOG, 0, 0, + (SRB_SIGNATURE >> 32), + (SRB_SIGNATURE & 0xFFFFFFFF), + (char *)data, 4096); if (ret == -1) return ret; @@ -314,7 +302,7 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, time_t timep; struct tm *logtime; char currentdir[128], filename[512], fname[128]; - unsigned int itotal, icur, ivsctype; + unsigned int itotal, icur; unsigned char data[4096]; struct cdumpinfo cdumpinfo; unsigned char busevsc = false; @@ -338,44 +326,29 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, time(&timep); logtime = localtime(&timep); - ivsctype = 0; ipackindex = 0; memset(data, 0, 4096); - - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x03, 0x00, 0x00, (char *)data, 4096); - if (ret == -1) - return ret; - - if (data[0] == 0x5A) { - ivsctype = 1; - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00,(char *)data, 4096); - } else { - ivsctype = 0; - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, - (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), - (char *)data, 4096); - } - if (ret == -1) - return ret; - - memcpy(&cdumpinfo, &data[3072], sizeof(cdumpinfo)); - if (cdumpinfo.sig == 0x5a5b5c5d) { - busevsc = true; - ipackcount = cdumpinfo.ipackcount; - if (ipackcount == 0) { - itotal = 0; - } else { - itotal = cdumpinfo.cdumppack[ipackindex].ilenth; - memset(fwvera, 0, sizeof(fwvera)); - memcpy(fwvera, cdumpinfo.cdumppack[ipackindex].fwver, 8); - sprintf(fname, "cdump_%02d%02d-%02d%02d%02d_%d_%s.cdp", logtime->tm_mon+1, - logtime->tm_mday, logtime->tm_hour, logtime->tm_min, logtime->tm_sec, - ipackindex, fwvera); - sprintf(filename, "%s/%s", currentdir, fname); + if (nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, + (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), + (char *)data, 4096) == 0) { + memcpy(&cdumpinfo, &data[3072], sizeof(cdumpinfo)); + if (cdumpinfo.sig == 0x5a5b5c5d) { + busevsc = true; + ipackcount = cdumpinfo.ipackcount; + if (ipackcount == 0) { + itotal = 0; + } else { + itotal = cdumpinfo.cdumppack[ipackindex].ilenth; + memset(fwvera, 0, sizeof(fwvera)); + memcpy(fwvera, cdumpinfo.cdumppack[ipackindex].fwver, 8); + sprintf(fname, "cdump_%02d%02d-%02d%02d%02d_%d_%s.cdp", logtime->tm_mon+1, + logtime->tm_mday, logtime->tm_hour, logtime->tm_min, logtime->tm_sec, + ipackindex, fwvera); + sprintf(filename, "%s/%s", currentdir, fname); + } } } - if (busevsc == false) { memset(data, 0, 4096); ret = nvme_get_nsid_log(dev_fd(dev), true, 0x07, @@ -402,18 +375,16 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, setfilecontent(filename, data, strlen((char *)data)); for (icur = 0; icur < itotal; icur += 4096) { memset(data, 0, 4096); - if (busevsc) { - if (ivsctype == 1) - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00,(char *)data, 4096); - else - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, - (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), - (char *)data, 4096); - } else { + if (busevsc) + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, + VSC_FN_GET_CDUMP, 0x00, + (SRB_SIGNATURE >> 32), + (SRB_SIGNATURE & 0xFFFFFFFF), + (char *)data, 4096); + else ret = nvme_get_nsid_log(dev_fd(dev), true, 0x07, NVME_NSID_ALL, 4096, data); - } if (ret != 0) return ret; @@ -428,19 +399,17 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, ipackindex++; if (ipackindex != ipackcount) { memset(data, 0, 4096); - if (busevsc) { - if (ivsctype == 1) - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00,(char *)data, 4096); - else - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, - (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), - (char *)data, 4096); - } else { + if (busevsc) + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, + VSC_FN_GET_CDUMP, 0x00, + (SRB_SIGNATURE >> 32), + (SRB_SIGNATURE & 0xFFFFFFFF), + (char *)data, 4096); + else ret = nvme_get_nsid_log(dev_fd(dev), true, 0x07, NVME_NSID_ALL, 4096, data); - } if (ret != 0) return ret; diff --git a/plugins/inspur/inspur-nvme.c b/plugins/inspur/inspur-nvme.c index 8c929aa..9d7bb4d 100644 --- a/plugins/inspur/inspur-nvme.c +++ b/plugins/inspur/inspur-nvme.c @@ -222,9 +222,7 @@ static int nvme_get_vendor_log(int argc, char **argv, struct command *cmd, struc return err; memset(local_mem, 0, BYTE_OF_4K); - err = nvme_get_log_simple(dev_fd(dev), - (enum nvme_cmd_get_log_lid)VENDOR_SMART_LOG_PAGE, - sizeof(r1_cli_vendor_log_t), local_mem); + err = nvme_get_log_simple(dev_fd(dev), VENDOR_SMART_LOG_PAGE, sizeof(r1_cli_vendor_log_t), local_mem); if (!err) { show_r1_vendor_log((r1_cli_vendor_log_t *)local_mem); show_r1_media_err_log((r1_cli_vendor_log_t *)local_mem); diff --git a/plugins/intel/intel-nvme.c b/plugins/intel/intel-nvme.c index 8a29cf9..f660b84 100644 --- a/plugins/intel/intel-nvme.c +++ b/plugins/intel/intel-nvme.c @@ -1558,7 +1558,7 @@ static int enable_lat_stats_tracking(int argc, char **argv, .disable = false, }; - struct argconfig_commandline_options command_line_options[] = { + const struct argconfig_commandline_options command_line_options[] = { {"enable", 'e', "", CFG_FLAG, &cfg.enable, no_argument, enable_desc}, {"disable", 'd', "", CFG_FLAG, &cfg.disable, no_argument, disable_desc}, {NULL} diff --git a/plugins/memblaze/memblaze-nvme.c b/plugins/memblaze/memblaze-nvme.c index 7a4633a..fb46841 100644 --- a/plugins/memblaze/memblaze-nvme.c +++ b/plugins/memblaze/memblaze-nvme.c @@ -226,17 +226,17 @@ static void show_memblaze_smart_log_old(struct nvme_memblaze_smart_log *smart, 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", + 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 kelvins since last factory reset : %u\n", + 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 kelvins since power on : %u\n", + 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 kelvins since power on : %u\n", + 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 kelvins : %u\n", + 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", @@ -707,7 +707,7 @@ static int glp_high_latency(FILE *fdi, char *buf, int buflen, int print) } else // sort { - timestamp = logEntry->timestampH; + timestamp = logEntry->timestampH - 1; timestamp = timestamp << 32; timestamp += logEntry->timestampL; tt = timestamp / 1000; @@ -1140,7 +1140,7 @@ static int mb_set_lat_stats(int argc, char **argv, .disable = false, }; - struct argconfig_commandline_options command_line_options[] = { + const struct argconfig_commandline_options command_line_options[] = { {"enable", 'e', "", CFG_FLAG, &cfg.enable, no_argument, enable_desc}, {"disable", 'd', "", CFG_FLAG, &cfg.disable, no_argument, disable_desc}, {NULL} diff --git a/plugins/meson.build b/plugins/meson.build index 2cf2486..c92b208 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -1,31 +1,29 @@ # SPDX-License-Identifier: GPL-2.0-or-later -if json_c_dep.found() - sources += [ - 'plugins/amzn/amzn-nvme.c', - 'plugins/dell/dell-nvme.c', - 'plugins/dera/dera-nvme.c', - 'plugins/fdp/fdp.c', - 'plugins/huawei/huawei-nvme.c', - 'plugins/innogrit/innogrit-nvme.c', - 'plugins/inspur/inspur-nvme.c', - 'plugins/intel/intel-nvme.c', - 'plugins/memblaze/memblaze-nvme.c', - 'plugins/micron/micron-nvme.c', - 'plugins/netapp/netapp-nvme.c', - 'plugins/nvidia/nvidia-nvme.c', - 'plugins/scaleflux/sfx-nvme.c', - 'plugins/seagate/seagate-nvme.c', - 'plugins/shannon/shannon-nvme.c', - 'plugins/solidigm/solidigm-nvme.c', - 'plugins/toshiba/toshiba-nvme.c', - 'plugins/transcend/transcend-nvme.c', - 'plugins/virtium/virtium-nvme.c', - 'plugins/wdc/wdc-nvme.c', - 'plugins/wdc/wdc-utils.c', - 'plugins/ymtc/ymtc-nvme.c', - 'plugins/zns/zns.c', - ] - subdir('solidigm') - subdir('ocp') -endif +sources += [ + 'plugins/amzn/amzn-nvme.c', + 'plugins/dell/dell-nvme.c', + 'plugins/dera/dera-nvme.c', + 'plugins/huawei/huawei-nvme.c', + 'plugins/intel/intel-nvme.c', + 'plugins/innogrit/innogrit-nvme.c', + 'plugins/memblaze/memblaze-nvme.c', + 'plugins/micron/micron-nvme.c', + 'plugins/netapp/netapp-nvme.c', + 'plugins/nvidia/nvidia-nvme.c', + 'plugins/scaleflux/sfx-nvme.c', + 'plugins/seagate/seagate-nvme.c', + 'plugins/shannon/shannon-nvme.c', + 'plugins/solidigm/solidigm-nvme.c', + 'plugins/toshiba/toshiba-nvme.c', + 'plugins/transcend/transcend-nvme.c', + 'plugins/virtium/virtium-nvme.c', + 'plugins/wdc/wdc-utils.c', + 'plugins/wdc/wdc-nvme.c', + 'plugins/ymtc/ymtc-nvme.c', + 'plugins/zns/zns.c', + 'plugins/inspur/inspur-nvme.c', + 'plugins/fdp/fdp.c', +] +subdir('solidigm') +subdir('ocp') diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c index bd5f7d7..3c0904c 100644 --- a/plugins/micron/micron-nvme.c +++ b/plugins/micron/micron-nvme.c @@ -455,7 +455,7 @@ exit_status: */ static int micron_parse_options(struct nvme_dev **dev, int argc, char **argv, const char *desc, - struct argconfig_commandline_options *opts, + const struct argconfig_commandline_options *opts, eDriveModel *modelp) { int idx = 0; diff --git a/plugins/ocp/meson.build b/plugins/ocp/meson.build index 641239a..a4e5d20 100644 --- a/plugins/ocp/meson.build +++ b/plugins/ocp/meson.build @@ -2,6 +2,5 @@ sources += [ 'plugins/ocp/ocp-utils.c', 'plugins/ocp/ocp-nvme.c', 'plugins/ocp/ocp-clear-fw-update-history.c', - 'plugins/ocp/ocp-smart-extended-log.c', ] diff --git a/plugins/ocp/ocp-clear-fw-update-history.c b/plugins/ocp/ocp-clear-fw-update-history.c index b9235b8..fef09cf 100644 --- a/plugins/ocp/ocp-clear-fw-update-history.c +++ b/plugins/ocp/ocp-clear-fw-update-history.c @@ -15,7 +15,59 @@ static const __u8 OCP_FID_CLEAR_FW_ACTIVATION_HISTORY = 0xC1; int ocp_clear_fw_update_history(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = "OCP Clear Firmware Update History"; + __u32 result = 0; + __u32 clear_fw_history = 1 << 31; + struct nvme_dev *dev; + int uuid_index = 0; + bool no_uuid = false; + int err; - return ocp_clear_feature(argc, argv, desc, - OCP_FID_CLEAR_FW_ACTIVATION_HISTORY); + OPT_ARGS(opts) = { + OPT_FLAG("no-uuid", 'n', &no_uuid, + "Skip UUID index search (UUID index not required for OCP 1.0)"), + OPT_END() + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; + if (no_uuid == false) { + // OCP 2.0 requires UUID index support + err = ocp_get_uuid_index(dev, &uuid_index); + if (err || uuid_index == 0) { + fprintf(stderr, "ERROR: No OCP UUID index found\n"); + goto close_dev; + } + } + + struct nvme_set_features_args args = { + .result = &result, + .data = NULL, + .args_size = sizeof(args), + .fd = dev_fd(dev), + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .nsid = 0, + .cdw11 = clear_fw_history, + .cdw12 = 0, + .cdw13 = 0, + .cdw15 = 0, + .data_len = 0, + .save = 0, + .uuidx = uuid_index, + .fid = OCP_FID_CLEAR_FW_ACTIVATION_HISTORY, + }; + + err = nvme_set_features(&args); + + if (err == 0) + printf("Success : %s\n", desc); + else if (err > 0) + nvme_show_status(err); + else + printf("Fail : %s\n", desc); +close_dev: + /* Redundant close() to make static code analysis happy */ + close(dev->direct.fd); + dev_close(dev); + return err; } diff --git a/plugins/ocp/ocp-clear-fw-update-history.h b/plugins/ocp/ocp-clear-fw-update-history.h index cd0844c..25fb6b1 100644 --- a/plugins/ocp/ocp-clear-fw-update-history.h +++ b/plugins/ocp/ocp-clear-fw-update-history.h @@ -6,5 +6,4 @@ * leonardo.da.cunha@solidigm.com */ -int ocp_clear_fw_update_history(int argc, char **argv, - struct command *cmd, struct plugin *plugin); +int ocp_clear_fw_update_history(int argc, char **argv, struct command *cmd, struct plugin *plugin); diff --git a/plugins/ocp/ocp-nvme.c b/plugins/ocp/ocp-nvme.c index a864363..14a5f30 100644 --- a/plugins/ocp/ocp-nvme.c +++ b/plugins/ocp/ocp-nvme.c @@ -3,7 +3,7 @@ * * Authors: Arthur Shau , * Wei Zhang , - * Venkat Ramesh + * Venkat Ramesh */ #include #include @@ -22,627 +22,753 @@ #include "linux/types.h" #include "util/types.h" #include "nvme-print.h" - -#include "ocp-smart-extended-log.h" #include "ocp-clear-fw-update-history.h" #define CREATE_CMD #include "ocp-nvme.h" -#include "ocp-utils.h" -#define C0_ACTIVE_BUCKET_TIMER_INCREMENT 5 -#define C0_ACTIVE_THRESHOLD_INCREMENT 5 -#define C0_MINIMUM_WINDOW_INCREMENT 100 +/* C0 SCAO Log Page */ +#define C0_SMART_CLOUD_ATTR_LEN 0x200 +#define C0_SMART_CLOUD_ATTR_OPCODE 0xC0 +#define C0_GUID_LENGTH 16 +#define C0_ACTIVE_BUCKET_TIMER_INCREMENT 5 +#define C0_ACTIVE_THRESHOLD_INCREMENT 5 +#define C0_MINIMUM_WINDOW_INCREMENT 100 -/* C3 Latency Monitor Log Page */ -#define C3_LATENCY_MON_LOG_BUF_LEN 0x200 -#define C3_LATENCY_MON_OPCODE 0xC3 -#define C3_LATENCY_MON_VERSION 0x0001 -#define C3_GUID_LENGTH 16 -static __u8 lat_mon_guid[C3_GUID_LENGTH] = { - 0x92, 0x7a, 0xc0, 0x8c, - 0xd0, 0x84, 0x6c, 0x9c, - 0x70, 0x43, 0xe6, 0xd4, - 0x58, 0x5e, 0xd4, 0x85 -}; +static __u8 scao_guid[C0_GUID_LENGTH] = { 0xC5, 0xAF, 0x10, 0x28, 0xEA, 0xBF, + 0xF2, 0xA4, 0x9C, 0x4F, 0x6F, 0x7C, 0xC9, 0x14, 0xD5, 0xAF }; -#define READ 0 -#define WRITE 1 -#define TRIM 2 -#define RESERVED 3 +/* C3 Latency Monitor Log Page */ +#define C3_LATENCY_MON_LOG_BUF_LEN 0x200 +#define C3_LATENCY_MON_OPCODE 0xC3 +#define C3_LATENCY_MON_VERSION 0x0001 +#define C3_GUID_LENGTH 16 +static __u8 lat_mon_guid[C3_GUID_LENGTH] = { 0x92, 0x7a, 0xc0, 0x8c, 0xd0, 0x84, + 0x6c, 0x9c, 0x70, 0x43, 0xe6, 0xd4, 0x58, 0x5e, 0xd4, 0x85 }; + +#define READ 0 +#define WRITE 1 +#define TRIM 2 +#define RESERVED 3 + +typedef enum { + SCAO_PMUW = 0, /* Physical media units written */ + SCAO_PMUR = 16, /* Physical media units read */ + SCAO_BUNBR = 32, /* Bad user nand blocks raw */ + SCAO_BUNBN = 38, /* Bad user nand blocks normalized */ + SCAO_BSNBR = 40, /* Bad system nand blocks raw */ + SCAO_BSNBN = 46, /* Bad system nand blocks normalized */ + SCAO_XRC = 48, /* XOR recovery count */ + SCAO_UREC = 56, /* Uncorrectable read error count */ + SCAO_SEEC = 64, /* Soft ecc error count */ + SCAO_EECE = 72, /* End to end corrected errors */ + SCAO_EEDC = 76, /* End to end detected errors */ + SCAO_SDPU = 80, /* System data percent used */ + SCAO_RFSC = 81, /* Refresh counts */ + SCAO_MXUDEC = 88, /* Max User data erase counts */ + SCAO_MNUDEC = 92, /* Min User data erase counts */ + SCAO_NTTE = 96, /* Number of Thermal throttling events */ + SCAO_CTS = 97, /* Current throttling status */ + SCAO_EVF = 98, /* Errata Version Field */ + SCAO_PVF = 99, /* Point Version Field */ + SCAO_MIVF = 101, /* Minor Version Field */ + SCAO_MAVF = 103, /* Major Version Field */ + SCAO_PCEC = 104, /* PCIe correctable error count */ + SCAO_ICS = 112, /* Incomplete shutdowns */ + SCAO_PFB = 120, /* Percent free blocks */ + SCAO_CPH = 128, /* Capacitor health */ + SCAO_NEV = 130, /* NVMe Errata Version */ + SCAO_UIO = 136, /* Unaligned I/O */ + SCAO_SVN = 144, /* Security Version Number */ + SCAO_NUSE = 152, /* NUSE - Namespace utilization */ + SCAO_PSC = 160, /* PLP start count */ + SCAO_EEST = 176, /* Endurance estimate */ + SCAO_PLRC = 192, /* PCIe Link Retraining Count */ + SCAO_LPV = 494, /* Log page version */ + SCAO_LPG = 496, /* Log page GUID */ +} SMART_CLOUD_ATTRIBUTE_OFFSETS; struct __attribute__((__packed__)) ssd_latency_monitor_log { - __u8 feature_status; /* 0x00 */ - __u8 rsvd1; /* 0x01 */ - __le16 active_bucket_timer; /* 0x02 */ - __le16 active_bucket_timer_threshold; /* 0x04 */ - __u8 active_threshold_a; /* 0x06 */ - __u8 active_threshold_b; /* 0x07 */ - __u8 active_threshold_c; /* 0x08 */ - __u8 active_threshold_d; /* 0x09 */ - __le16 active_latency_config; /* 0x0A */ - __u8 active_latency_min_window; /* 0x0C */ - __u8 rsvd2[0x13]; /* 0x0D */ - - __le32 active_bucket_counter[4][4]; /* 0x20 - 0x5F */ - __le64 active_latency_timestamp[4][3]; /* 0x60 - 0xBF */ - __le16 active_measured_latency[4][3]; /* 0xC0 - 0xD7 */ - __le16 active_latency_stamp_units; /* 0xD8 */ - __u8 rsvd3[0x16]; /* 0xDA */ - - __le32 static_bucket_counter[4][4]; /* 0x0F0 - 0x12F */ - __le64 static_latency_timestamp[4][3]; /* 0x130 - 0x18F */ - __le16 static_measured_latency[4][3]; /* 0x190 - 0x1A7 */ - __le16 static_latency_stamp_units; /* 0x1A8 */ - __u8 rsvd4[0x16]; /* 0x1AA */ - - __le16 debug_log_trigger_enable; /* 0x1C0 */ - __le16 debug_log_measured_latency; /* 0x1C2 */ - __le64 debug_log_latency_stamp; /* 0x1C4 */ - __le16 debug_log_ptr; /* 0x1CC */ - __le16 debug_log_counter_trigger; /* 0x1CE */ - __u8 debug_log_stamp_units; /* 0x1D0 */ - __u8 rsvd5[0x1D]; /* 0x1D1 */ - - __le16 log_page_version; /* 0x1EE */ - __u8 log_page_guid[0x10]; /* 0x1F0 */ + __u8 feature_status; /* 0x00 */ + __u8 rsvd1; /* 0x01 */ + __le16 active_bucket_timer; /* 0x02 */ + __le16 active_bucket_timer_threshold; /* 0x04 */ + __u8 active_threshold_a; /* 0x06 */ + __u8 active_threshold_b; /* 0x07 */ + __u8 active_threshold_c; /* 0x08 */ + __u8 active_threshold_d; /* 0x09 */ + __le16 active_latency_config; /* 0x0A */ + __u8 active_latency_min_window; /* 0x0C */ + __u8 rsvd2[0x13]; /* 0x0D */ + + __le32 active_bucket_counter[4][4] ; /* 0x20 - 0x5F */ + __le64 active_latency_timestamp[4][3]; /* 0x60 - 0xBF */ + __le16 active_measured_latency[4][3]; /* 0xC0 - 0xD7 */ + __le16 active_latency_stamp_units; /* 0xD8 */ + __u8 rsvd3[0x16]; /* 0xDA */ + + __le32 static_bucket_counter[4][4] ; /* 0xF0 - 0x12F */ + __le64 static_latency_timestamp[4][3]; /* 0x130 - 0x18F */ + __le16 static_measured_latency[4][3]; /* 0x190 - 0x1A7 */ + __le16 static_latency_stamp_units; /* 0x1A8 */ + __u8 rsvd4[0x16]; /* 0x1AA */ + + __le16 debug_log_trigger_enable; /* 0x1C0 */ + __le16 debug_log_measured_latency; /* 0x1C2 */ + __le64 debug_log_latency_stamp; /* 0x1C4 */ + __le16 debug_log_ptr; /* 0x1CC */ + __le16 debug_log_counter_trigger; /* 0x1CE */ + __u8 debug_log_stamp_units; /* 0x1D0 */ + __u8 rsvd5[0x1D]; /* 0x1D1 */ + + __le16 log_page_version; /* 0x1EE */ + __u8 log_page_guid[0x10]; /* 0x1F0 */ }; -static const __u8 OCP_FID_CLEAR_PCIE_CORRECTABLE_ERROR_COUNTERS = 0xC3; - static int convert_ts(time_t time, char *ts_buf) { - struct tm gmTimeInfo; - time_t time_Human, time_ms; - char buf[80]; + struct tm gmTimeInfo; + time_t time_Human, time_ms; + char buf[80]; - time_Human = time/1000; - time_ms = time % 1000; + time_Human = time/1000; + time_ms = time % 1000; - gmtime_r((const time_t *)&time_Human, &gmTimeInfo); + gmtime_r((const time_t *)&time_Human, &gmTimeInfo); - strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &gmTimeInfo); - sprintf(ts_buf, "%s.%03ld GMT", buf, time_ms); + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &gmTimeInfo); + sprintf(ts_buf, "%s.%03ld GMT", buf, time_ms); - return 0; + return 0; } -static int ocp_print_C3_log_normal(struct nvme_dev *dev, - struct ssd_latency_monitor_log *log_data) +static void ocp_print_C0_log_normal(void *data) { - char ts_buf[128]; - int i, j; - int pos = 0; - - printf("-Latency Monitor/C3 Log Page Data-\n"); - printf(" Controller : %s\n", dev->name); - printf(" Feature Status 0x%x\n", - log_data->feature_status); - printf(" Active Bucket Timer %d min\n", - C0_ACTIVE_BUCKET_TIMER_INCREMENT * - le16_to_cpu(log_data->active_bucket_timer)); - printf(" Active Bucket Timer Threshold %d min\n", - C0_ACTIVE_BUCKET_TIMER_INCREMENT * - le16_to_cpu(log_data->active_bucket_timer_threshold)); - printf(" Active Threshold A %d ms\n", - C0_ACTIVE_THRESHOLD_INCREMENT * - le16_to_cpu(log_data->active_threshold_a+1)); - printf(" Active Threshold B %d ms\n", - C0_ACTIVE_THRESHOLD_INCREMENT * - le16_to_cpu(log_data->active_threshold_b+1)); - printf(" Active Threshold C %d ms\n", - C0_ACTIVE_THRESHOLD_INCREMENT * - le16_to_cpu(log_data->active_threshold_c+1)); - printf(" Active Threshold D %d ms\n", - C0_ACTIVE_THRESHOLD_INCREMENT * - le16_to_cpu(log_data->active_threshold_d+1)); - printf(" Active Latency Minimum Window %d ms\n", - C0_MINIMUM_WINDOW_INCREMENT * - le16_to_cpu(log_data->active_latency_min_window)); - printf(" Active Latency Stamp Units %d\n", - le16_to_cpu(log_data->active_latency_stamp_units)); - printf(" Static Latency Stamp Units %d\n", - le16_to_cpu(log_data->static_latency_stamp_units)); - printf(" Debug Log Trigger Enable %d\n", - le16_to_cpu(log_data->debug_log_trigger_enable)); - - printf(" Read Write Deallocate/Trim \n"); - for (i = 0; i <= 3; i++) { - printf(" Active Latency Mode: Bucket %d %27d %27d %27d\n", - i, - log_data->active_latency_config & (1 << pos), - log_data->active_latency_config & (1 << pos), - log_data->active_latency_config & (1 << pos)); - } - printf("\n"); - - for (i = 0; i <= 3; i++) { - printf(" Active Bucket Counter: Bucket %d %27d %27d %27d \n", - i, - le32_to_cpu(log_data->active_bucket_counter[i][READ]), - le32_to_cpu(log_data->active_bucket_counter[i][WRITE]), - le32_to_cpu(log_data->active_bucket_counter[i][TRIM])); - } - - for (i = 0; i <= 3; i++) { - printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n", - i, - le16_to_cpu(log_data->active_measured_latency[i][READ]), - le16_to_cpu(log_data->active_measured_latency[i][WRITE]), - le16_to_cpu(log_data->active_measured_latency[i][TRIM])); - } - - for (i = 0; i <= 3; i++) { - printf(" Active Latency Time Stamp: Bucket %d ", i); - for (j = 0; j <= 2; j++) { - if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1) - printf(" N/A "); - else { - convert_ts(le64_to_cpu(log_data->active_latency_timestamp[i][j]), ts_buf); - printf("%s ", ts_buf); - } - } - printf("\n"); - } - - for (i = 0; i <= 3; i++) { - printf(" Static Bucket Counter: Bucket %d %27d %27d %27d\n", - i, - le32_to_cpu(log_data->static_bucket_counter[i][READ]), - le32_to_cpu(log_data->static_bucket_counter[i][WRITE]), - le32_to_cpu(log_data->static_bucket_counter[i][TRIM])); - } - - for (i = 0; i <= 3; i++) { - printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n", - i, - le16_to_cpu(log_data->static_measured_latency[i][READ]), - le16_to_cpu(log_data->static_measured_latency[i][WRITE]), - le16_to_cpu(log_data->static_measured_latency[i][TRIM])); - } - - for (i = 0; i <= 3; i++) { - printf(" Static Latency Time Stamp: Bucket %d ", i); - for (j = 0; j <= 2; j++) { - if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1) - printf(" N/A "); - else { - convert_ts(le64_to_cpu(log_data->static_latency_timestamp[i][j]), ts_buf); - printf("%s ", ts_buf); - } - } - printf("\n"); - } - - return 0; + __u8 *log_data = (__u8*)data; + uint16_t smart_log_ver = 0; + + printf("SMART Cloud Attributes :- \n"); + + printf(" Physical media units written - %"PRIu64" %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW+8] & 0xFFFFFFFFFFFFFFFF), + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF)); + printf(" Physical media units read - %"PRIu64" %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR+8] & 0xFFFFFFFFFFFFFFFF), + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF)); + printf(" Bad user nand blocks - Raw %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF)); + printf(" Bad user nand blocks - Normalized %d\n", + (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN])); + printf(" Bad system nand blocks - Raw %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF)); + printf(" Bad system nand blocks - Normalized %d\n", + (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN])); + printf(" XOR recovery count %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC])); + printf(" Uncorrectable read error count %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC])); + printf(" Soft ecc error count %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC])); + printf(" End to end corrected errors %"PRIu32"\n", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE])); + printf(" End to end detected errors %"PRIu32"\n", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC])); + printf(" System data percent used %d\n", + (__u8)log_data[SCAO_SDPU]); + printf(" Refresh counts %"PRIu64"\n", + (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC])& 0x00FFFFFFFFFFFFFF)); + printf(" Max User data erase counts %"PRIu32"\n", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC])); + printf(" Min User data erase counts %"PRIu32"\n", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC])); + printf(" Number of Thermal throttling events %d\n", + (__u8)log_data[SCAO_NTTE]); + printf(" Current throttling status 0x%x\n", + (__u8)log_data[SCAO_CTS]); + printf(" PCIe correctable error count %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC])); + printf(" Incomplete shutdowns %"PRIu32"\n", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS])); + printf(" Percent free blocks %d\n", + (__u8)log_data[SCAO_PFB]); + printf(" Capacitor health %"PRIu16"\n", + (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH])); + printf(" Unaligned I/O %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO])); + printf(" Security Version Number %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN])); + printf(" NUSE - Namespace utilization %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE])); + printf(" PLP start count %s\n", + uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC]))); + printf(" Endurance estimate %s\n", + uint128_t_to_string(le128_to_cpu(&log_data[SCAO_EEST]))); + smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]); + printf(" Log page version %"PRIu16"\n",smart_log_ver); + printf(" Log page GUID 0x"); + printf("%"PRIx64"%"PRIx64"\n",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]), + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG])); + if(smart_log_ver > 2) { + printf(" Errata Version Field %d\n", + (__u8)log_data[SCAO_EVF]); + printf(" Point Version Field %"PRIu16"\n", + (uint16_t)log_data[SCAO_PVF]); + printf(" Minor Version Field %"PRIu16"\n", + (uint16_t)log_data[SCAO_MIVF]); + printf(" Major Version Field %d\n", + (__u8)log_data[SCAO_MAVF]); + printf(" NVMe Errata Version %d\n", + (__u8)log_data[SCAO_NEV]); + printf(" PCIe Link Retraining Count %"PRIu64"\n", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC])); + } + printf("\n"); } -static void ocp_print_C3_log_json(struct ssd_latency_monitor_log *log_data) +static void ocp_print_C0_log_json(void *data) { - struct json_object *root; - char ts_buf[128]; - char buf[128]; - int i, j; - int pos = 0; - char *operation[3] = {"Read", "Write", "Trim"}; - - root = json_create_object(); - - json_object_add_value_uint(root, "Feature Status", - log_data->feature_status); - json_object_add_value_uint(root, "Active Bucket Timer", - C0_ACTIVE_BUCKET_TIMER_INCREMENT * - le16_to_cpu(log_data->active_bucket_timer)); - json_object_add_value_uint(root, "Active Bucket Timer Threshold", - C0_ACTIVE_BUCKET_TIMER_INCREMENT * - le16_to_cpu(log_data->active_bucket_timer_threshold)); - json_object_add_value_uint(root, "Active Threshold A", - C0_ACTIVE_THRESHOLD_INCREMENT * - le16_to_cpu(log_data->active_threshold_a + 1)); - json_object_add_value_uint(root, "Active Threshold B", - C0_ACTIVE_THRESHOLD_INCREMENT * - le16_to_cpu(log_data->active_threshold_b + 1)); - json_object_add_value_uint(root, "Active Threshold C", - C0_ACTIVE_THRESHOLD_INCREMENT * - le16_to_cpu(log_data->active_threshold_c + 1)); - json_object_add_value_uint(root, "Active Threshold D", - C0_ACTIVE_THRESHOLD_INCREMENT * - le16_to_cpu(log_data->active_threshold_d + 1)); - json_object_add_value_uint(root, "Active Lantency Minimum Window", - C0_MINIMUM_WINDOW_INCREMENT * - le16_to_cpu(log_data->active_latency_min_window)); - json_object_add_value_uint(root, "Active Latency Stamp Units", - le16_to_cpu(log_data->active_latency_stamp_units)); - json_object_add_value_uint(root, "Static Latency Stamp Units", - le16_to_cpu(log_data->static_latency_stamp_units)); - json_object_add_value_uint(root, "Debug Log Trigger Enable", - le16_to_cpu(log_data->debug_log_trigger_enable)); - - for (i = 0; i <= 3; i++) { - struct json_object *bucket; - - bucket = json_create_object(); - sprintf(buf, "Active Latency Mode: Bucket %d", i); - for (j = 0; j <= 2; j++) { - json_object_add_value_uint(bucket, operation[j], - log_data->active_latency_config & (1 << pos)); - } - json_object_add_value_object(root, buf, bucket); - } - - for (i = 0; i <= 3; i++) { - struct json_object *bucket; - - bucket = json_create_object(); - sprintf(buf, "Active Bucket Counter: Bucket %d", i); - for (j = 0; j <= 2; j++) { - json_object_add_value_uint(bucket, operation[j], - le32_to_cpu(log_data->active_bucket_counter[i][j])); - } - json_object_add_value_object(root, buf, bucket); - } - - for (i = 0; i <= 3; i++) { - struct json_object *bucket; - - bucket = json_create_object(); - sprintf(buf, "Active Measured Latency: Bucket %d", i); - for (j = 0; j <= 2; j++) { - json_object_add_value_uint(bucket, operation[j], - le16_to_cpu(log_data->active_measured_latency[i][j])); - } - json_object_add_value_object(root, buf, bucket); - } - - for (i = 0; i <= 3; i++) { - struct json_object *bucket; - - bucket = json_create_object(); - sprintf(buf, "Active Latency Time Stamp: Bucket %d", i); - for (j = 0; j <= 2; j++) { - if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1) - json_object_add_value_string(bucket, operation[j], "NA"); - else { - convert_ts(le64_to_cpu(log_data->active_latency_timestamp[i][j]), ts_buf); - json_object_add_value_string(bucket, operation[j], ts_buf); - } - } - json_object_add_value_object(root, buf, bucket); - } - - for (i = 0; i <= 3; i++) { - struct json_object *bucket; - - bucket = json_create_object(); - sprintf(buf, "Static Bucket Counter: Bucket %d", i); - for (j = 0; j <= 2; j++) { - json_object_add_value_uint(bucket, operation[j], - le32_to_cpu(log_data->static_bucket_counter[i][j])); - } - json_object_add_value_object(root, buf, bucket); - } - - for (i = 0; i <= 3; i++) { - struct json_object *bucket; - - bucket = json_create_object(); - sprintf(buf, "Static Measured Latency: Bucket %d", i); - for (j = 0; j <= 2; j++) { - json_object_add_value_uint(bucket, operation[j], - le16_to_cpu(log_data->static_measured_latency[i][j])); - } - json_object_add_value_object(root, buf, bucket); - } - - for (i = 0; i <= 3; i++) { - struct json_object *bucket; - - bucket = json_create_object(); - sprintf(buf, "Static Latency Time Stamp: Bucket %d", i); - for (j = 0; j <= 2; j++) { - if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1) - json_object_add_value_string(bucket, operation[j], "NA"); - else { - convert_ts(le64_to_cpu(log_data->static_latency_timestamp[i][j]), ts_buf); - json_object_add_value_string(bucket, operation[j], ts_buf); - } - } - json_object_add_value_object(root, buf, bucket); - } - - json_print_object(root, NULL); - printf("\n"); - - json_free_object(root); + __u8 *log_data = (__u8*)data; + struct json_object *root; + struct json_object *pmuw; + struct json_object *pmur; + uint16_t smart_log_ver = 0; + + root = json_create_object(); + pmuw = json_create_object(); + pmur = json_create_object(); + + json_object_add_value_uint64(pmuw, "hi", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW+8] & 0xFFFFFFFFFFFFFFFF)); + json_object_add_value_uint64(pmuw, "lo", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF)); + json_object_add_value_object(root, "Physical media units written", pmuw); + json_object_add_value_uint64(pmur, "hi", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR+8] & 0xFFFFFFFFFFFFFFFF)); + json_object_add_value_uint64(pmur, "lo", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF)); + json_object_add_value_object(root, "Physical media units read", pmur); + json_object_add_value_uint64(root, "Bad user nand blocks - Raw", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF)); + json_object_add_value_uint(root, "Bad user nand blocks - Normalized", + (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN])); + json_object_add_value_uint64(root, "Bad system nand blocks - Raw", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF)); + json_object_add_value_uint(root, "Bad system nand blocks - Normalized", + (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN])); + json_object_add_value_uint64(root, "XOR recovery count", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC])); + json_object_add_value_uint64(root, "Uncorrectable read error count", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC])); + json_object_add_value_uint64(root, "Soft ecc error count", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC])); + json_object_add_value_uint(root, "End to end corrected errors", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE])); + json_object_add_value_uint(root, "End to end detected errors", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC])); + json_object_add_value_uint(root, "System data percent used", + (__u8)log_data[SCAO_SDPU]); + json_object_add_value_uint64(root, "Refresh counts", + (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC])& 0x00FFFFFFFFFFFFFF)); + json_object_add_value_uint(root, "Max User data erase counts", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC])); + json_object_add_value_uint(root, "Min User data erase counts", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC])); + json_object_add_value_uint(root, "Number of Thermal throttling events", + (__u8)log_data[SCAO_NTTE]); + json_object_add_value_uint(root, "Current throttling status", + (__u8)log_data[SCAO_CTS]); + json_object_add_value_uint64(root, "PCIe correctable error count", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC])); + json_object_add_value_uint(root, "Incomplete shutdowns", + (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS])); + json_object_add_value_uint(root, "Percent free blocks", + (__u8)log_data[SCAO_PFB]); + json_object_add_value_uint(root, "Capacitor health", + (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH])); + json_object_add_value_uint64(root, "Unaligned I/O", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO])); + json_object_add_value_uint64(root, "Security Version Number", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN])); + json_object_add_value_uint64(root, "NUSE - Namespace utilization", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE])); + json_object_add_value_uint128(root, "PLP start count", + le128_to_cpu(&log_data[SCAO_PSC])); + json_object_add_value_uint128(root, "Endurance estimate", + le128_to_cpu(&log_data[SCAO_EEST])); + smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]); + json_object_add_value_uint(root, "Log page version", smart_log_ver); + char guid[40]; + memset((void*)guid, 0, 40); + sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]), + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG])); + json_object_add_value_string(root, "Log page GUID", guid); + if(smart_log_ver > 2){ + json_object_add_value_uint(root, "Errata Version Field", + (__u8)log_data[SCAO_EVF]); + json_object_add_value_uint(root, "Point Version Field", + (uint16_t)log_data[SCAO_PVF]); + json_object_add_value_uint(root, "Minor Version Field", + (uint16_t)log_data[SCAO_MIVF]); + json_object_add_value_uint(root, "Major Version Field", + (__u8)log_data[SCAO_MAVF]); + json_object_add_value_uint(root, "NVMe Errata Version", + (__u8)log_data[SCAO_NEV]); + json_object_add_value_uint(root, "PCIe Link Retraining Count", + (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC])); + } + json_print_object(root, NULL); + printf("\n"); + json_free_object(root); } -static int get_c3_log_page(struct nvme_dev *dev, char *format) +static int get_c0_log_page(int fd, char *format) { - struct ssd_latency_monitor_log *log_data; - int ret = 0; - int fmt = -1; - __u8 *data; - int i; - - fmt = validate_output_format(format); - if (fmt < 0) { - fprintf(stderr, "ERROR : OCP : invalid output format\n"); - return fmt; - } - - data = malloc(sizeof(__u8) * C3_LATENCY_MON_LOG_BUF_LEN); - if (!data) { - fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno)); - return -1; - } - memset(data, 0, sizeof(__u8) * C3_LATENCY_MON_LOG_BUF_LEN); - - ret = nvme_get_log_simple(dev_fd(dev), C3_LATENCY_MON_OPCODE, - C3_LATENCY_MON_LOG_BUF_LEN, data); - - if (strcmp(format, "json")) - fprintf(stderr, - "NVMe Status:%s(%x)\n", - nvme_status_to_string(ret, false), - ret); - - if (ret == 0) { - log_data = (struct ssd_latency_monitor_log *)data; - - /* check log page version */ - if (log_data->log_page_version != C3_LATENCY_MON_VERSION) { - fprintf(stderr, - "ERROR : OCP : invalid latency monitor version\n"); - ret = -1; - goto out; - } - - /* check log page guid */ - /* Verify GUID matches */ - for (i = 0; i < 16; i++) { - if (lat_mon_guid[i] != log_data->log_page_guid[i]) { - int j; - - fprintf(stderr, "ERROR : OCP : Unknown GUID in C3 Log Page data\n"); - fprintf(stderr, "ERROR : OCP : Expected GUID: 0x"); - for (j = 0; j < 16; j++) { - fprintf(stderr, "%x", lat_mon_guid[j]); - } - - fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x"); - for (j = 0; j < 16; j++) { - fprintf(stderr, "%x", log_data->log_page_guid[j]); - } - fprintf(stderr, "\n"); - - ret = -1; - goto out; - } - } - - switch (fmt) { - case NORMAL: - ocp_print_C3_log_normal(dev, log_data); - break; - case JSON: - ocp_print_C3_log_json(log_data); - break; - } - } else { - fprintf(stderr, - "ERROR : OCP : Unable to read C3 data from buffer\n"); - } + int ret = 0; + int fmt = -1; + __u8 *data; + int i; + + fmt = validate_output_format(format); + if (fmt < 0) { + fprintf(stderr, "ERROR : OCP : invalid output format\n"); + return fmt; + } + + if ((data = (__u8 *) malloc(sizeof(__u8) * C0_SMART_CLOUD_ATTR_LEN)) == NULL) { + fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno)); + return -1; + } + memset(data, 0, sizeof (__u8) * C0_SMART_CLOUD_ATTR_LEN); + + ret = nvme_get_log_simple(fd, C0_SMART_CLOUD_ATTR_OPCODE, + C0_SMART_CLOUD_ATTR_LEN, data); + + if (strcmp(format, "json")) + fprintf(stderr, "NVMe Status:%s(%x)\n", + nvme_status_to_string(ret, false), ret); + + if (ret == 0) { + + /* check log page guid */ + /* Verify GUID matches */ + for (i=0; i<16; i++) { + if (scao_guid[i] != data[SCAO_LPG + i]) { + fprintf(stderr, "ERROR : OCP : Unknown GUID in C0 Log Page data\n"); + int j; + fprintf(stderr, "ERROR : OCP : Expected GUID: 0x"); + for (j = 0; j<16; j++) { + fprintf(stderr, "%x", scao_guid[j]); + } + fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x"); + for (j = 0; j<16; j++) { + fprintf(stderr, "%x", data[SCAO_LPG + j]); + } + fprintf(stderr, "\n"); + + ret = -1; + goto out; + } + } + + /* print the data */ + switch (fmt) { + case NORMAL: + ocp_print_C0_log_normal(data); + break; + case JSON: + ocp_print_C0_log_json(data); + break; + } + } else { + fprintf(stderr, "ERROR : OCP : Unable to read C0 data from buffer\n"); + } out: - free(data); - return ret; -} - -static int smart_add_log(int argc, char **argv, struct command *cmd, - struct plugin *plugin) -{ - return ocp_smart_add_log(argc, argv, cmd, plugin); + free(data); + return ret; } -static int ocp_latency_monitor_log(int argc, char **argv, - struct command *command, - struct plugin *plugin) +static int ocp_smart_add_log(int argc, char **argv, struct command *cmd, + struct plugin *plugin) { - const char *desc = "Retrieve latency monitor log data."; + const char *desc = "Retrieve latency monitor log data."; struct nvme_dev *dev; - int ret = 0; - - struct config { - char *output_format; - }; - - struct config cfg = { - .output_format = "normal", - }; - - OPT_ARGS(opts) = { - OPT_FMT("output-format", 'o', &cfg.output_format, - "output Format: normal|json"), - OPT_END() - }; - - ret = parse_and_open(&dev, argc, argv, desc, opts); - if (ret) - return ret; - - ret = get_c3_log_page(dev, cfg.output_format); - if (ret) - fprintf(stderr, - "ERROR : OCP : Failure reading the C3 Log Page, ret = %d\n", - ret); - - dev_close(dev); - return ret; + int ret = 0; + + struct config { + char *output_format; + }; + + struct config cfg = { + .output_format = "normal", + }; + + OPT_ARGS(opts) = { + OPT_FMT("output-format", 'o', &cfg.output_format, "output Format: normal|json"), + OPT_END() + }; + + ret = parse_and_open(&dev, argc, argv, desc, opts); + if (ret) + return ret; + + ret = get_c0_log_page(dev_fd(dev), cfg.output_format); + if (ret) + fprintf(stderr, "ERROR : OCP : Failure reading the C0 Log Page, ret = %d\n", + ret); + dev_close(dev); + return ret; } -static int clear_fw_update_history(int argc, char **argv, - struct command *cmd, struct plugin *plugin) +static int ocp_print_C3_log_normal(struct nvme_dev *dev, + struct ssd_latency_monitor_log *log_data) { - return ocp_clear_fw_update_history(argc, argv, cmd, plugin); + printf("-Latency Monitor/C3 Log Page Data- \n"); + printf(" Controller : %s\n", dev->name); + int i, j; + int pos = 0; + char ts_buf[128]; + + printf(" Feature Status 0x%x \n", + log_data->feature_status); + printf(" Active Bucket Timer %d min \n", + C0_ACTIVE_BUCKET_TIMER_INCREMENT * + le16_to_cpu(log_data->active_bucket_timer)); + printf(" Active Bucket Timer Threshold %d min \n", + C0_ACTIVE_BUCKET_TIMER_INCREMENT * + le16_to_cpu(log_data->active_bucket_timer_threshold)); + printf(" Active Threshold A %d ms \n", + C0_ACTIVE_THRESHOLD_INCREMENT * + le16_to_cpu(log_data->active_threshold_a+1)); + printf(" Active Threshold B %d ms \n", + C0_ACTIVE_THRESHOLD_INCREMENT * + le16_to_cpu(log_data->active_threshold_b+1)); + printf(" Active Threshold C %d ms \n", + C0_ACTIVE_THRESHOLD_INCREMENT * + le16_to_cpu(log_data->active_threshold_c+1)); + printf(" Active Threshold D %d ms \n", + C0_ACTIVE_THRESHOLD_INCREMENT * + le16_to_cpu(log_data->active_threshold_d+1)); + printf(" Active Latency Minimum Window %d ms \n", + C0_MINIMUM_WINDOW_INCREMENT * + le16_to_cpu(log_data->active_latency_min_window)); + printf(" Active Latency Stamp Units %d \n", + le16_to_cpu(log_data->active_latency_stamp_units)); + printf(" Static Latency Stamp Units %d \n", + le16_to_cpu(log_data->static_latency_stamp_units)); + printf(" Debug Log Trigger Enable %d \n", + le16_to_cpu(log_data->debug_log_trigger_enable)); + + printf(" Read Write Deallocate/Trim \n"); + for (i = 0; i <= 3; i++) { + printf(" Active Latency Mode: Bucket %d %27d %27d %27d \n", + i, + log_data->active_latency_config & (1 << pos), + log_data->active_latency_config & (1 << pos), + log_data->active_latency_config & (1 << pos)); + } + printf("\n"); + for (i = 0; i <= 3; i++) { + printf(" Active Bucket Counter: Bucket %d %27d %27d %27d \n", + i, + le32_to_cpu(log_data->active_bucket_counter[i][READ]), + le32_to_cpu(log_data->active_bucket_counter[i][WRITE]), + le32_to_cpu(log_data->active_bucket_counter[i][TRIM])); + } + + for (i = 0; i <= 3; i++) { + printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n", + i, + le16_to_cpu(log_data->active_measured_latency[i][READ]), + le16_to_cpu(log_data->active_measured_latency[i][WRITE]), + le16_to_cpu(log_data->active_measured_latency[i][TRIM])); + } + + for (i = 0; i <= 3; i++) { + printf(" Active Latency Time Stamp: Bucket %d ", i); + for (j = 0; j <= 2; j++) { + if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1) + printf(" N/A "); + else { + convert_ts(le64_to_cpu(log_data->active_latency_timestamp[i][j]), ts_buf); + printf("%s ", ts_buf); + } + } + printf("\n"); + } + + for (i = 0; i <= 3; i++) { + printf(" Static Bucket Counter: Bucket %d %27d %27d %27d \n", + i, + le32_to_cpu(log_data->static_bucket_counter[i][READ]), + le32_to_cpu(log_data->static_bucket_counter[i][WRITE]), + le32_to_cpu(log_data->static_bucket_counter[i][TRIM])); + } + + for (i = 0; i <= 3; i++) { + printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n", + i, + le16_to_cpu(log_data->static_measured_latency[i][READ]), + le16_to_cpu(log_data->static_measured_latency[i][WRITE]), + le16_to_cpu(log_data->static_measured_latency[i][TRIM])); + } + + for (i = 0; i <= 3; i++) { + printf(" Static Latency Time Stamp: Bucket %d ", i); + for (j = 0; j <= 2; j++) { + if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1) + printf(" N/A "); + else { + convert_ts(le64_to_cpu(log_data->static_latency_timestamp[i][j]), ts_buf); + printf("%s ", ts_buf); + } + } + printf("\n"); + } + + return 0; } -static const char *eol_plp_failure_mode_to_string(__u8 mode) +static void ocp_print_C3_log_json(struct ssd_latency_monitor_log *log_data) { - switch (mode) { - case 1: - return "Read only mode (ROM)"; - case 2: - return "Write through mode (WTM)"; - case 3: - return "Normal mode"; - default: - break; - } - - return "Reserved"; + int i, j; + int pos = 0; + char buf[128]; + char ts_buf[128]; + char *operation[3] = {"Read", "Write", "Trim"}; + struct json_object *root; + root = json_create_object(); + + json_object_add_value_uint(root, "Feature Status", + log_data->feature_status); + json_object_add_value_uint(root, "Active Bucket Timer", + C0_ACTIVE_BUCKET_TIMER_INCREMENT * + le16_to_cpu(log_data->active_bucket_timer)); + json_object_add_value_uint(root, "Active Bucket Timer Threshold", + C0_ACTIVE_BUCKET_TIMER_INCREMENT * + le16_to_cpu(log_data->active_bucket_timer_threshold)); + json_object_add_value_uint(root, "Active Threshold A", + C0_ACTIVE_THRESHOLD_INCREMENT * + le16_to_cpu(log_data->active_threshold_a+1)); + json_object_add_value_uint(root, "Active Threshold B", + C0_ACTIVE_THRESHOLD_INCREMENT * + le16_to_cpu(log_data->active_threshold_b+1)); + json_object_add_value_uint(root, "Active Threshold C", + C0_ACTIVE_THRESHOLD_INCREMENT * + le16_to_cpu(log_data->active_threshold_c+1)); + json_object_add_value_uint(root, "Active Threshold D", + C0_ACTIVE_THRESHOLD_INCREMENT * + le16_to_cpu(log_data->active_threshold_d+1)); + json_object_add_value_uint(root, "Active Lantency Minimum Window", + C0_MINIMUM_WINDOW_INCREMENT * + le16_to_cpu(log_data->active_latency_min_window)); + json_object_add_value_uint(root, "Active Latency Stamp Units", + le16_to_cpu(log_data->active_latency_stamp_units)); + json_object_add_value_uint(root, "Static Latency Stamp Units", + le16_to_cpu(log_data->static_latency_stamp_units)); + json_object_add_value_uint(root, "Debug Log Trigger Enable", + le16_to_cpu(log_data->debug_log_trigger_enable)); + + for (i = 0; i <= 3; i++) { + struct json_object *bucket; + bucket = json_create_object(); + sprintf(buf, "Active Latency Mode: Bucket %d", i); + for (j = 0; j <= 2; j++) { + json_object_add_value_uint(bucket, operation[j], + log_data->active_latency_config & (1 << pos)); + } + json_object_add_value_object(root, buf, bucket); + } + for (i = 0; i <= 3; i++) { + struct json_object *bucket; + bucket = json_create_object(); + sprintf(buf, "Active Bucket Counter: Bucket %d", i); + for (j = 0; j <= 2; j++) { + json_object_add_value_uint(bucket, operation[j], + le32_to_cpu(log_data->active_bucket_counter[i][j])); + } + json_object_add_value_object(root, buf, bucket); + } + for (i = 0; i <= 3; i++) { + struct json_object *bucket; + bucket = json_create_object(); + sprintf(buf, "Active Measured Latency: Bucket %d", i); + for (j = 0; j <= 2; j++) { + json_object_add_value_uint(bucket, operation[j], + le16_to_cpu(log_data->active_measured_latency[i][j])); + } + json_object_add_value_object(root, buf, bucket); + } + for (i = 0; i <= 3; i++) { + struct json_object *bucket; + bucket = json_create_object(); + sprintf(buf, "Active Latency Time Stamp: Bucket %d", i); + for (j = 0; j <= 2; j++) { + if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1) + json_object_add_value_string(bucket, operation[j], "NA"); + else { + convert_ts(le64_to_cpu(log_data->active_latency_timestamp[i][j]), ts_buf); + json_object_add_value_string(bucket, operation[j], ts_buf); + } + } + json_object_add_value_object(root, buf, bucket); + } + for (i = 0; i <= 3; i++) { + struct json_object *bucket; + bucket = json_create_object(); + sprintf(buf, "Static Bucket Counter: Bucket %d", i); + for (j = 0; j <= 2; j++) { + json_object_add_value_uint(bucket, operation[j], + le32_to_cpu(log_data->static_bucket_counter[i][j])); + } + json_object_add_value_object(root, buf, bucket); + } + for (i = 0; i <= 3; i++) { + struct json_object *bucket; + bucket = json_create_object(); + sprintf(buf, "Static Measured Latency: Bucket %d", i); + for (j = 0; j <= 2; j++) { + json_object_add_value_uint(bucket, operation[j], + le16_to_cpu(log_data->static_measured_latency[i][j])); + } + json_object_add_value_object(root, buf, bucket); + } + for (i = 0; i <= 3; i++) { + struct json_object *bucket; + bucket = json_create_object(); + sprintf(buf, "Static Latency Time Stamp: Bucket %d", i); + for (j = 0; j <= 2; j++) { + if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1) + json_object_add_value_string(bucket, operation[j], "NA"); + else { + convert_ts(le64_to_cpu(log_data->static_latency_timestamp[i][j]), ts_buf); + json_object_add_value_string(bucket, operation[j], ts_buf); + } + } + json_object_add_value_object(root, buf, bucket); + } + + json_print_object(root, NULL); + printf("\n"); + + json_free_object(root); } -static int eol_plp_failure_mode_get(struct nvme_dev *dev, const __u32 nsid, - const __u8 fid, __u8 sel) +static int get_c3_log_page(struct nvme_dev *dev, char *format) { - __u32 result; - int err; - - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .sel = sel, - .cdw11 = 0, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&args); - if (!err) { - printf("End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)\n", - fid ? 4 : 2, fid, result ? 10 : 8, result, - nvme_select_to_string(sel), - eol_plp_failure_mode_to_string(result)); - if (sel == NVME_GET_FEATURES_SEL_SUPPORTED) - nvme_show_select_result(result); - } else { - printf("Could not get feature: %#0*x.\n", fid ? 4 : 2, fid); - } - - return err; -} + int ret = 0; + int fmt = -1; + __u8 *data; + int i; + struct ssd_latency_monitor_log *log_data; + + fmt = validate_output_format(format); + if (fmt < 0) { + fprintf(stderr, "ERROR : OCP : invalid output format\n"); + return fmt; + } + + if ((data = (__u8 *) malloc(sizeof(__u8) * C3_LATENCY_MON_LOG_BUF_LEN)) == NULL) { + fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno)); + return -1; + } + memset(data, 0, sizeof (__u8) * C3_LATENCY_MON_LOG_BUF_LEN); + + ret = nvme_get_log_simple(dev_fd(dev), C3_LATENCY_MON_OPCODE, + C3_LATENCY_MON_LOG_BUF_LEN, data); + + if (strcmp(format, "json")) + fprintf(stderr, + "NVMe Status:%s(%x)\n", + nvme_status_to_string(ret, false), + ret); + + if (ret == 0) { + log_data = (struct ssd_latency_monitor_log*)data; + + /* check log page version */ + if (log_data->log_page_version != C3_LATENCY_MON_VERSION) { + fprintf(stderr, + "ERROR : OCP : invalid latency monitor version\n"); + ret = -1; + goto out; + } + + /* check log page guid */ + /* Verify GUID matches */ + for (i=0; i<16; i++) { + if (lat_mon_guid[i] != log_data->log_page_guid[i]) { + fprintf(stderr,"ERROR : OCP : Unknown GUID in C3 Log Page data\n"); + int j; + fprintf(stderr, "ERROR : OCP : Expected GUID: 0x"); + for (j = 0; j<16; j++) { + fprintf(stderr, "%x", lat_mon_guid[j]); + } + fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x"); + for (j = 0; j<16; j++) { + fprintf(stderr, "%x", log_data->log_page_guid[j]); + } + fprintf(stderr, "\n"); + + ret = -1; + goto out; + } + } + + switch (fmt) { + case NORMAL: + ocp_print_C3_log_normal(dev, log_data); + break; + case JSON: + ocp_print_C3_log_json(log_data); + break; + } + } else { + fprintf(stderr, + "ERROR : OCP : Unable to read C3 data from buffer\n"); + } -static int eol_plp_failure_mode_set(struct nvme_dev *dev, const __u32 nsid, - const __u8 fid, __u8 mode, bool save, - bool uuid) -{ - __u32 result; - int err; - int uuid_index = 0; - - if (uuid) { - /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); - if (err || !uuid_index) { - fprintf(stderr, "ERROR: No OCP UUID index found\n"); - return err; - } - } - - - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .cdw11 = mode << 30, - .cdw12 = 0, - .save = save, - .uuidx = uuid_index, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); - if (err > 0) { - nvme_show_status(err); - } else if (err < 0) { - perror("Define EOL/PLP failure mode"); - fprintf(stderr, "Command failed while parsing.\n"); - } else { - printf("Successfully set mode (feature: %#0*x): %#0*x (%s: %s).\n", - fid ? 4 : 2, fid, mode ? 10 : 8, mode, - save ? "Save" : "Not save", - eol_plp_failure_mode_to_string(mode)); - } - - return err; +out: + free(data); + return ret; } -static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd, - struct plugin *plugin) +static int ocp_latency_monitor_log(int argc, char **argv, struct command *command, + struct plugin *plugin) { - const char *desc = "Define EOL or PLP circuitry failure mode.\n"\ - "No argument prints current mode."; - const char *mode = "[0-3]: default/rom/wtm/normal"; - const char *save = "Specifies that the controller shall save the attribute"; - const char *sel = "[0-3,8]: current/default/saved/supported/changed"; - const __u32 nsid = 0; - const __u8 fid = 0xc2; + const char *desc = "Retrieve latency monitor log data."; struct nvme_dev *dev; - int err; - - struct config { - __u8 mode; - bool save; - __u8 sel; - }; - - struct config cfg = { - .mode = 0, - .save = false, - .sel = 0, - }; - - OPT_ARGS(opts) = { - OPT_BYTE("mode", 'm', &cfg.mode, mode), - OPT_FLAG("save", 's', &cfg.save, save), - OPT_BYTE("sel", 'S', &cfg.sel, sel), - OPT_FLAG("no-uuid", 'n', NULL, - "Skip UUID index search (UUID index not required for OCP 1.0)"), - OPT_END() - }; - - err = parse_and_open(&dev, argc, argv, desc, opts); - if (err) - return err; - - if (argconfig_parse_seen(opts, "mode")) - err = eol_plp_failure_mode_set(dev, nsid, fid, cfg.mode, - cfg.save, - !argconfig_parse_seen(opts, "no-uuid")); - else - err = eol_plp_failure_mode_get(dev, nsid, fid, cfg.sel); - - dev_close(dev); - - return err; + int ret = 0; + + struct config { + char *output_format; + }; + + struct config cfg = { + .output_format = "normal", + }; + + OPT_ARGS(opts) = { + OPT_FMT("output-format", 'o', &cfg.output_format, + "output Format: normal|json"), + OPT_END() + }; + + ret = parse_and_open(&dev, argc, argv, desc, opts); + if (ret) + return ret; + + ret = get_c3_log_page(dev, cfg.output_format); + if (ret) + fprintf(stderr, + "ERROR : OCP : Failure reading the C3 Log Page, ret = %d\n", + ret); + dev_close(dev); + return ret; } -static int clear_pcie_corectable_error_counters(int argc, char **argv, - struct command *cmd, - struct plugin *plugin) +static int clear_fw_update_history(int argc, char **argv, struct command *cmd, + struct plugin *plugin) { - const char *desc = "OCP Clear PCIe Correctable Error Counters"; - - return ocp_clear_feature(argc, argv, desc, - OCP_FID_CLEAR_PCIE_CORRECTABLE_ERROR_COUNTERS); + return ocp_clear_fw_update_history(argc, argv, cmd, plugin); } diff --git a/plugins/ocp/ocp-nvme.h b/plugins/ocp/ocp-nvme.h index dc9e154..c20646a 100644 --- a/plugins/ocp/ocp-nvme.h +++ b/plugins/ocp/ocp-nvme.h @@ -3,7 +3,7 @@ * * Authors: Arthur Shau , * Wei Zhang , - * Venkat Ramesh + * Venkat Ramesh */ #undef CMD_INC_FILE #define CMD_INC_FILE plugins/ocp/ocp-nvme @@ -15,11 +15,11 @@ PLUGIN(NAME("ocp", "OCP cloud SSD extensions", NVME_VERSION), COMMAND_LIST( - ENTRY("smart-add-log", "Retrieve extended SMART Information", smart_add_log) - ENTRY("latency-monitor-log", "Get Latency Monitor Log Page", ocp_latency_monitor_log) - ENTRY("clear-fw-activate-history", "Clear firmware update history log", clear_fw_update_history) - ENTRY("eol-plp-failure-mode", "Define EOL or PLP circuitry failure mode.", eol_plp_failure_mode) - ENTRY("clear-pcie-correctable-error-counters", "Clear PCIe correctable error counters", clear_pcie_corectable_error_counters) + ENTRY("smart-add-log", "Retrieve extended SMART Information", ocp_smart_add_log) + ENTRY("latency-monitor-log", "Get Latency Monitor Log Page", + ocp_latency_monitor_log) + ENTRY("clear-fw-activate-history", "Clear firmware update history log", + clear_fw_update_history) ) ); diff --git a/plugins/ocp/ocp-smart-extended-log.c b/plugins/ocp/ocp-smart-extended-log.c deleted file mode 100644 index 37b62e9..0000000 --- a/plugins/ocp/ocp-smart-extended-log.c +++ /dev/null @@ -1,352 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* Copyright (c) 2022 Meta Platforms, Inc. - * - * Authors: Arthur Shau , - * Wei Zhang , - * Venkat Ramesh - */ - -#include "ocp-smart-extended-log.h" - -#include -#include - -#include "common.h" -#include "nvme-print.h" - -/* C0 SCAO Log Page */ -#define C0_SMART_CLOUD_ATTR_LEN 0x200 -#define C0_SMART_CLOUD_ATTR_OPCODE 0xC0 -#define C0_GUID_LENGTH 16 - -static __u8 scao_guid[C0_GUID_LENGTH] = { - 0xC5, 0xAF, 0x10, 0x28, - 0xEA, 0xBF, 0xF2, 0xA4, - 0x9C, 0x4F, 0x6F, 0x7C, - 0xC9, 0x14, 0xD5, 0xAF -}; - -typedef enum { - SCAO_PMUW = 0, /* Physical media units written */ - SCAO_PMUR = 16, /* Physical media units read */ - SCAO_BUNBR = 32, /* Bad user nand blocks raw */ - SCAO_BUNBN = 38, /* Bad user nand blocks normalized */ - SCAO_BSNBR = 40, /* Bad system nand blocks raw */ - SCAO_BSNBN = 46, /* Bad system nand blocks normalized */ - SCAO_XRC = 48, /* XOR recovery count */ - SCAO_UREC = 56, /* Uncorrectable read error count */ - SCAO_SEEC = 64, /* Soft ecc error count */ - SCAO_EEDC = 72, /* End to end detected errors */ - SCAO_EECE = 76, /* End to end corrected errors */ - SCAO_SDPU = 80, /* System data percent used */ - SCAO_RFSC = 81, /* Refresh counts */ - SCAO_MXUDEC = 88, /* Max User data erase counts */ - SCAO_MNUDEC = 92, /* Min User data erase counts */ - SCAO_NTTE = 96, /* Number of Thermal throttling events */ - SCAO_CTS = 97, /* Current throttling status */ - SCAO_EVF = 98, /* Errata Version Field */ - SCAO_PVF = 99, /* Point Version Field */ - SCAO_MIVF = 101, /* Minor Version Field */ - SCAO_MAVF = 103, /* Major Version Field */ - SCAO_PCEC = 104, /* PCIe correctable error count */ - SCAO_ICS = 112, /* Incomplete shutdowns */ - SCAO_PFB = 120, /* Percent free blocks */ - SCAO_CPH = 128, /* Capacitor health */ - SCAO_NEV = 130, /* NVMe Errata Version */ - SCAO_UIO = 136, /* Unaligned I/O */ - SCAO_SVN = 144, /* Security Version Number */ - SCAO_NUSE = 152, /* NUSE - Namespace utilization */ - SCAO_PSC = 160, /* PLP start count */ - SCAO_EEST = 176, /* Endurance estimate */ - SCAO_PLRC = 192, /* PCIe Link Retraining Count */ - SCAO_PSCC = 200, /* Power State Change Count */ - SCAO_LPV = 494, /* Log page version */ - SCAO_LPG = 496, /* Log page GUID */ -} SMART_CLOUD_ATTRIBUTE_OFFSETS; - -static void ocp_print_C0_log_normal(void *data) -{ - uint16_t smart_log_ver = 0; - __u8 *log_data = data; - - printf("SMART Cloud Attributes :-\n"); - - printf(" Physical media units written - %"PRIu64" %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8] & 0xFFFFFFFFFFFFFFFF), - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF)); - printf(" Physical media units read - %"PRIu64" %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8] & 0xFFFFFFFFFFFFFFFF), - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF)); - printf(" Bad user nand blocks - Raw %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF)); - printf(" Bad user nand blocks - Normalized %d\n", - (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN])); - printf(" Bad system nand blocks - Raw %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF)); - printf(" Bad system nand blocks - Normalized %d\n", - (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN])); - printf(" XOR recovery count %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC])); - printf(" Uncorrectable read error count %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC])); - printf(" Soft ecc error count %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC])); - printf(" End to end detected errors %"PRIu32"\n", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC])); - printf(" End to end corrected errors %"PRIu32"\n", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE])); - printf(" System data percent used %d\n", - (__u8)log_data[SCAO_SDPU]); - printf(" Refresh counts %"PRIu64"\n", - (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF)); - printf(" Max User data erase counts %"PRIu32"\n", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC])); - printf(" Min User data erase counts %"PRIu32"\n", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC])); - printf(" Number of Thermal throttling events %d\n", - (__u8)log_data[SCAO_NTTE]); - printf(" Current throttling status 0x%x\n", - (__u8)log_data[SCAO_CTS]); - printf(" PCIe correctable error count %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC])); - printf(" Incomplete shutdowns %"PRIu32"\n", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS])); - printf(" Percent free blocks %d\n", - (__u8)log_data[SCAO_PFB]); - printf(" Capacitor health %"PRIu16"\n", - (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH])); - printf(" Unaligned I/O %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO])); - printf(" Security Version Number %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN])); - printf(" NUSE - Namespace utilization %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE])); - printf(" PLP start count %s\n", - uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC]))); - printf(" Endurance estimate %s\n", - uint128_t_to_string(le128_to_cpu(&log_data[SCAO_EEST]))); - smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]); - printf(" Log page version %"PRIu16"\n", smart_log_ver); - printf(" Log page GUID 0x"); - printf("%"PRIx64"%"PRIx64"\n", (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]), - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG])); - if (smart_log_ver > 2) { - printf(" Errata Version Field %d\n", - (__u8)log_data[SCAO_EVF]); - printf(" Point Version Field %"PRIu16"\n", - le16_to_cpu(*(uint16_t *)&log_data[SCAO_PVF])); - printf(" Minor Version Field %"PRIu16"\n", - le16_to_cpu(*(uint16_t *)&log_data[SCAO_MIVF])); - printf(" Major Version Field %d\n", - (__u8)log_data[SCAO_MAVF]); - printf(" NVMe Errata Version %d\n", - (__u8)log_data[SCAO_NEV]); - printf(" PCIe Link Retraining Count %"PRIu64"\n", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC])); - printf(" Power State Change Count %"PRIu64"\n", - le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC])); - } - printf("\n"); -} - -static void ocp_print_C0_log_json(void *data) -{ - struct json_object *root; - struct json_object *pmuw; - struct json_object *pmur; - uint16_t smart_log_ver = 0; - __u8 *log_data = data; - char guid[40]; - - root = json_create_object(); - pmuw = json_create_object(); - pmur = json_create_object(); - - json_object_add_value_uint64(pmuw, "hi", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8] & 0xFFFFFFFFFFFFFFFF)); - json_object_add_value_uint64(pmuw, "lo", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF)); - json_object_add_value_object(root, "Physical media units written", pmuw); - json_object_add_value_uint64(pmur, "hi", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8] & 0xFFFFFFFFFFFFFFFF)); - json_object_add_value_uint64(pmur, "lo", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF)); - json_object_add_value_object(root, "Physical media units read", pmur); - json_object_add_value_uint64(root, "Bad user nand blocks - Raw", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF)); - json_object_add_value_uint(root, "Bad user nand blocks - Normalized", - (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN])); - json_object_add_value_uint64(root, "Bad system nand blocks - Raw", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF)); - json_object_add_value_uint(root, "Bad system nand blocks - Normalized", - (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN])); - json_object_add_value_uint64(root, "XOR recovery count", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC])); - json_object_add_value_uint64(root, "Uncorrectable read error count", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC])); - json_object_add_value_uint64(root, "Soft ecc error count", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC])); - json_object_add_value_uint(root, "End to end detected errors", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC])); - json_object_add_value_uint(root, "End to end corrected errors", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE])); - json_object_add_value_uint(root, "System data percent used", - (__u8)log_data[SCAO_SDPU]); - json_object_add_value_uint64(root, "Refresh counts", - (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF)); - json_object_add_value_uint(root, "Max User data erase counts", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC])); - json_object_add_value_uint(root, "Min User data erase counts", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC])); - json_object_add_value_uint(root, "Number of Thermal throttling events", - (__u8)log_data[SCAO_NTTE]); - json_object_add_value_uint(root, "Current throttling status", - (__u8)log_data[SCAO_CTS]); - json_object_add_value_uint64(root, "PCIe correctable error count", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC])); - json_object_add_value_uint(root, "Incomplete shutdowns", - (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS])); - json_object_add_value_uint(root, "Percent free blocks", - (__u8)log_data[SCAO_PFB]); - json_object_add_value_uint(root, "Capacitor health", - (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH])); - json_object_add_value_uint64(root, "Unaligned I/O", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO])); - json_object_add_value_uint64(root, "Security Version Number", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN])); - json_object_add_value_uint64(root, "NUSE - Namespace utilization", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE])); - json_object_add_value_uint128(root, "PLP start count", - le128_to_cpu(&log_data[SCAO_PSC])); - json_object_add_value_uint128(root, "Endurance estimate", - le128_to_cpu(&log_data[SCAO_EEST])); - smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]); - - json_object_add_value_uint(root, "Log page version", smart_log_ver); - - memset((void *)guid, 0, 40); - sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"", (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]), - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG])); - json_object_add_value_string(root, "Log page GUID", guid); - - if (smart_log_ver > 2) { - json_object_add_value_uint(root, "Errata Version Field", - (__u8)log_data[SCAO_EVF]); - json_object_add_value_uint(root, "Point Version Field", - le16_to_cpu(*(uint16_t *)&log_data[SCAO_PVF])); - json_object_add_value_uint(root, "Minor Version Field", - le16_to_cpu(*(uint16_t *)&log_data[SCAO_MIVF])); - json_object_add_value_uint(root, "Major Version Field", - (__u8)log_data[SCAO_MAVF]); - json_object_add_value_uint(root, "NVMe Errata Version", - (__u8)log_data[SCAO_NEV]); - json_object_add_value_uint(root, "PCIe Link Retraining Count", - (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC])); - json_object_add_value_uint(root, "Power State Change Count", - le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC])); - } - json_print_object(root, NULL); - printf("\n"); - json_free_object(root); -} - -static int get_c0_log_page(int fd, char *format) -{ - __u8 *data; - int i; - int ret = 0; - int fmt = -1; - - fmt = validate_output_format(format); - if (fmt < 0) { - fprintf(stderr, "ERROR : OCP : invalid output format\n"); - return fmt; - } - - data = malloc(sizeof(__u8) * C0_SMART_CLOUD_ATTR_LEN); - if (!data) { - fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno)); - return -1; - } - memset(data, 0, sizeof(__u8) * C0_SMART_CLOUD_ATTR_LEN); - - ret = nvme_get_log_simple(fd, C0_SMART_CLOUD_ATTR_OPCODE, - C0_SMART_CLOUD_ATTR_LEN, data); - - if (strcmp(format, "json")) - fprintf(stderr, "NVMe Status:%s(%x)\n", - nvme_status_to_string(ret, false), ret); - - if (ret == 0) { - /* check log page guid */ - /* Verify GUID matches */ - for (i = 0; i < 16; i++) { - if (scao_guid[i] != data[SCAO_LPG + i]) { - int j; - - fprintf(stderr, "ERROR : OCP : Unknown GUID in C0 Log Page data\n"); - fprintf(stderr, "ERROR : OCP : Expected GUID: 0x"); - for (j = 0; j < 16; j++) { - fprintf(stderr, "%x", scao_guid[j]); - } - - fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x"); - for (j = 0; j < 16; j++) { - fprintf(stderr, "%x", data[SCAO_LPG + j]); - } - fprintf(stderr, "\n"); - - ret = -1; - goto out; - } - } - - /* print the data */ - switch (fmt) { - case NORMAL: - ocp_print_C0_log_normal(data); - break; - case JSON: - ocp_print_C0_log_json(data); - break; - } - } else { - fprintf(stderr, "ERROR : OCP : Unable to read C0 data from buffer\n"); - } - -out: - free(data); - return ret; -} - -int ocp_smart_add_log(int argc, char **argv, struct command *cmd, - struct plugin *plugin) -{ - const char *desc = "Retrieve the extended SMART health data."; - struct nvme_dev *dev; - int ret = 0; - - struct config { - char *output_format; - }; - - struct config cfg = { - .output_format = "normal", - }; - - OPT_ARGS(opts) = { - OPT_FMT("output-format", 'o', &cfg.output_format, "output Format: normal|json"), - OPT_END() - }; - - ret = parse_and_open(&dev, argc, argv, desc, opts); - if (ret) - return ret; - - ret = get_c0_log_page(dev_fd(dev), cfg.output_format); - if (ret) - fprintf(stderr, "ERROR : OCP : Failure reading the C0 Log Page, ret = %d\n", - ret); - dev_close(dev); - return ret; -} diff --git a/plugins/ocp/ocp-smart-extended-log.h b/plugins/ocp/ocp-smart-extended-log.h deleted file mode 100644 index 42c1f98..0000000 --- a/plugins/ocp/ocp-smart-extended-log.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (c) 2022 Meta Platforms, Inc. - * - * Authors: Arthur Shau , - * Wei Zhang , - * Venkat Ramesh - */ - -#ifndef OCP_SMART_EXTENDED_LOG_H -#define OCP_SMART_EXTENDED_LOG_H - -struct command; -struct plugin; - -int ocp_smart_add_log(int argc, char **argv, struct command *cmd, - struct plugin *plugin); - -#endif diff --git a/plugins/ocp/ocp-utils.c b/plugins/ocp/ocp-utils.c index a37a58c..9294c05 100644 --- a/plugins/ocp/ocp-utils.c +++ b/plugins/ocp/ocp-utils.c @@ -5,13 +5,11 @@ * Author: leonardo.da.cunha@solidigm.com */ -#include #include "ocp-utils.h" -#include "nvme-print.h" const unsigned char ocp_uuid[NVME_UUID_LEN] = { - 0xc1, 0x94, 0xd5, 0x5b, 0xe0, 0x94, 0x47, 0x94, 0xa2, 0x1d, - 0x29, 0x99, 0x8f, 0x56, 0xbe, 0x6f }; + 0x6f, 0xbe, 0x56, 0x8f, 0x99, 0x29, 0x1d, 0xa2, 0x94, 0x47, + 0x94, 0xe0, 0x5b, 0xd5, 0x94, 0xc1 }; int ocp_get_uuid_index(struct nvme_dev *dev, int *index) { @@ -30,66 +28,3 @@ int ocp_get_uuid_index(struct nvme_dev *dev, int *index) } return err; } - -int ocp_clear_feature(int argc, char **argv, const char *desc, const __u8 fid) -{ - __u32 result = 0; - __u32 clear = 1 << 31; - struct nvme_dev *dev; - int uuid_index = 0; - bool uuid = true; - int err; - - OPT_ARGS(opts) = { - OPT_FLAG("no-uuid", 'n', NULL, - "Skip UUID index search (UUID index not required for OCP 1.0)"), - OPT_END() - }; - - err = parse_and_open(&dev, argc, argv, desc, opts); - if (err) - return err; - - if (opts[0].seen) - uuid = false; - - if (uuid) { - /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); - if (err || !uuid_index) { - fprintf(stderr, "ERROR: No OCP UUID index found\n"); - goto close_dev; - } - } - - struct nvme_set_features_args args = { - .result = &result, - .data = NULL, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .nsid = 0, - .cdw11 = clear, - .cdw12 = 0, - .cdw13 = 0, - .cdw15 = 0, - .data_len = 0, - .save = 0, - .uuidx = uuid_index, - .fid = fid, - }; - - err = nvme_set_features(&args); - - if (err == 0) - printf("Success : %s\n", desc); - else if (err > 0) - nvme_show_status(err); - else - printf("Fail : %s\n", desc); -close_dev: - /* Redundant close() to make static code analysis happy */ - close(dev->direct.fd); - dev_close(dev); - return err; -} diff --git a/plugins/ocp/ocp-utils.h b/plugins/ocp/ocp-utils.h index a962169..44d0af4 100644 --- a/plugins/ocp/ocp-utils.h +++ b/plugins/ocp/ocp-utils.h @@ -16,5 +16,3 @@ * Return: Zero if nvme device has UUID list log page, or result of get uuid list otherwise. */ int ocp_get_uuid_index(struct nvme_dev *dev, int *index); - -int ocp_clear_feature(int argc, char **argv, const char *desc, const __u8 fid); diff --git a/plugins/solidigm/meson.build b/plugins/solidigm/meson.build index 526fb02..bca13bb 100644 --- a/plugins/solidigm/meson.build +++ b/plugins/solidigm/meson.build @@ -1,5 +1,4 @@ sources += [ - 'plugins/solidigm/solidigm-util.c', 'plugins/solidigm/solidigm-smart.c', 'plugins/solidigm/solidigm-garbage-collection.c', 'plugins/solidigm/solidigm-latency-tracking.c', diff --git a/plugins/solidigm/solidigm-garbage-collection.c b/plugins/solidigm/solidigm-garbage-collection.c index 3828b9e..8e2eccc 100644 --- a/plugins/solidigm/solidigm-garbage-collection.c +++ b/plugins/solidigm/solidigm-garbage-collection.c @@ -19,7 +19,6 @@ #include "linux/types.h" #include "nvme-print.h" #include "solidigm-garbage-collection.h" -#include "solidigm-util.h" typedef struct __attribute__((packed)) gc_item { __le32 timer_type; @@ -50,11 +49,9 @@ static void vu_gc_log_show_json(garbage_control_collection_log_t *payload, const json_free_object(gc_entries); } -static void vu_gc_log_show(garbage_control_collection_log_t *payload, const char *devname, - __u8 uuid_index) +static void vu_gc_log_show(garbage_control_collection_log_t *payload, const char *devname) { - printf("Solidigm Garbage Collection Log for NVME device:%s UUID-idx:%d\n", devname, - uuid_index); + printf("Solidigm Garbage Collection Log for NVME device: %s\n", devname); printf("Timestamp Timer Type\n"); for (int i = 0; i < VU_GC_MAX_ITEMS; i++) { @@ -68,7 +65,6 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c const char *desc = "Get and parse Solidigm vendor specific garbage collection event log."; struct nvme_dev *dev; int err; - __u8 uuid_index; struct config { char *output_format; @@ -94,36 +90,18 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c return EINVAL; } - uuid_index = solidigm_get_vu_uuid_index(dev); - garbage_control_collection_log_t gc_log; const int solidigm_vu_gc_log_id = 0xfd; - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = &gc_log, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = solidigm_vu_gc_log_id, - .len = sizeof(gc_log), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, - .uuidx = uuid_index, - .rae = false, - .ot = false, - }; - err = nvme_get_log(&args); + err = nvme_get_log_simple(dev_fd(dev), solidigm_vu_gc_log_id, + sizeof(gc_log), &gc_log); if (!err) { if (flags & BINARY) { d_raw((unsigned char *)&gc_log, sizeof(gc_log)); } else if (flags & JSON) { vu_gc_log_show_json(&gc_log, dev->name); } else { - vu_gc_log_show(&gc_log, dev->name, uuid_index); + vu_gc_log_show(&gc_log, dev->name); } } else if (err > 0) { diff --git a/plugins/solidigm/solidigm-latency-tracking.c b/plugins/solidigm/solidigm-latency-tracking.c index 40edcfa..1013ae8 100644 --- a/plugins/solidigm/solidigm-latency-tracking.c +++ b/plugins/solidigm/solidigm-latency-tracking.c @@ -17,7 +17,6 @@ #include "plugin.h" #include "linux/types.h" #include "nvme-print.h" -#include "solidigm-util.h" #define BUCKET_LIST_SIZE_4_0 152 #define BUCKET_LIST_SIZE_4_1 1216 @@ -43,7 +42,6 @@ struct config { struct latency_tracker { int fd; - __u8 uuid_index; struct config cfg; enum nvme_print_flags print_flags; struct latency_statistics stats; @@ -215,7 +213,6 @@ static void latency_tracker_pre_parse(struct latency_tracker *lt) if (lt->print_flags == NORMAL) { printf("Solidigm IO %s Command Latency Tracking Statistics type %d\n", lt->cfg.write ? "Write" : "Read", lt->cfg.type); - printf("UUID-idx: %d\n", lt->uuid_index); printf("Major Revision: %u\nMinor Revision: %u\n", le16_to_cpu(lt->stats.version_major), le16_to_cpu(lt->stats.version_minor)); if (lt->has_average_latency_field) { @@ -279,12 +276,12 @@ static int latency_tracking_is_enable(struct latency_tracker *lt, __u32 * enable { struct nvme_get_features_args args_get = { .args_size = sizeof(args_get), - .fd = lt->fd, - .uuidx = lt->uuid_index, + .fd = lt->fd, .fid = LATENCY_TRACKING_FID, .nsid = 0, .sel = 0, .cdw11 = 0, + .uuidx = 0, .data_len = LATENCY_TRACKING_FID_DATA_LEN, .data = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, @@ -310,12 +307,12 @@ static int latency_tracking_enable(struct latency_tracker *lt) struct nvme_set_features_args args_set = { .args_size = sizeof(args_set), .fd = lt->fd, - .uuidx = lt->uuid_index, .fid = LATENCY_TRACKING_FID, .nsid = 0, .cdw11 = lt->cfg.enable, .cdw12 = 0, .save = 0, + .uuidx = 0, .cdw15 = 0, .data_len = LATENCY_TRACKING_FID_DATA_LEN, .data = NULL, @@ -331,8 +328,8 @@ static int latency_tracking_enable(struct latency_tracker *lt) fprintf(stderr, "Command failed while parsing.\n"); } else { if (lt->print_flags == NORMAL) { - printf("Successfully set enable bit for UUID-idx:%d FID:0x%X, to %i.\n", - lt->uuid_index, LATENCY_TRACKING_FID, lt->cfg.enable); + printf("Successfully set enable bit for FID (0x%X) to %i.\n", + LATENCY_TRACKING_FID, lt->cfg.enable); } } return err; @@ -359,7 +356,6 @@ static int latency_tracker_get_log(struct latency_tracker *lt) .log = <->stats, .args_size = sizeof(args), .fd = lt->fd, - .uuidx = lt->uuid_index, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = lt->cfg.write ? WRITE_LOG_ID : READ_LOG_ID, .len = sizeof(lt->stats), @@ -367,6 +363,7 @@ static int latency_tracker_get_log(struct latency_tracker *lt) .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = lt->cfg.type, + .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, }; @@ -393,7 +390,6 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd int err; struct latency_tracker lt = { - .uuid_index = 0, .cfg = { .output_format = "normal", }, @@ -437,8 +433,6 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd return EINVAL; } - lt.uuid_index = solidigm_get_vu_uuid_index(dev); - err = latency_tracking_enable(<); if (err){ dev_close(dev); @@ -468,8 +462,8 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd putchar(enabled); } else { printf( - "Latency Statistics Tracking (UUID-idx:%d, FID:0x%X) is currently %i.\n", - lt.uuid_index, LATENCY_TRACKING_FID, enabled); + "Latency Statistics Tracking (FID 0x%X) is currently (%i).\n", + LATENCY_TRACKING_FID, enabled); } } else { fprintf(stderr, "Could not read feature id 0xE2.\n"); diff --git a/plugins/solidigm/solidigm-nvme.c b/plugins/solidigm/solidigm-nvme.c index 0e42bd6..b547035 100644 --- a/plugins/solidigm/solidigm-nvme.c +++ b/plugins/solidigm/solidigm-nvme.c @@ -14,9 +14,7 @@ #include "solidigm-garbage-collection.h" #include "solidigm-latency-tracking.h" #include "solidigm-telemetry.h" - #include "plugins/ocp/ocp-clear-fw-update-history.h" -#include "plugins/ocp/ocp-smart-extended-log.h" static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) { @@ -39,13 +37,7 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct } static int clear_fw_update_history(int argc, char **argv, struct command *cmd, - struct plugin *plugin) + struct plugin *plugin) { return ocp_clear_fw_update_history(argc, argv, cmd, plugin); } - -static int smart_cloud(int argc, char **argv, struct command *cmd, - struct plugin *plugin) -{ - return ocp_smart_add_log(argc, argv, cmd, plugin); -} diff --git a/plugins/solidigm/solidigm-nvme.h b/plugins/solidigm/solidigm-nvme.h index 1fdc6a6..778dbf9 100644 --- a/plugins/solidigm/solidigm-nvme.h +++ b/plugins/solidigm/solidigm-nvme.h @@ -13,12 +13,11 @@ #include "cmd.h" -#define SOLIDIGM_PLUGIN_VERSION "0.8" +#define SOLIDIGM_PLUGIN_VERSION "0.7" PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION), COMMAND_LIST( ENTRY("smart-log-add", "Retrieve Solidigm SMART Log", get_additional_smart_log) - ENTRY("vs-smart-add-log", "Get SMART / health extended log (redirects to ocp plug-in)", smart_cloud) ENTRY("garbage-collect-log", "Retrieve Garbage Collection Log", get_garbage_collection_log) ENTRY("latency-tracking-log", "Enable/Retrieve Latency tracking Log", get_latency_tracking_log) ENTRY("parse-telemetry-log", "Parse Telemetry Log binary", get_telemetry_log) diff --git a/plugins/solidigm/solidigm-smart.c b/plugins/solidigm/solidigm-smart.c index 568d3ab..77c26ac 100644 --- a/plugins/solidigm/solidigm-smart.c +++ b/plugins/solidigm/solidigm-smart.c @@ -19,7 +19,6 @@ #include "nvme-print.h" #include "solidigm-smart.h" -#include "solidigm-util.h" struct __attribute__((packed)) nvme_additional_smart_log_item { __u8 id; @@ -180,13 +179,12 @@ static void vu_smart_log_show_json(vu_smart_log_t *payload, unsigned int nsid, c json_free_object(root); } -static void vu_smart_log_show(vu_smart_log_t *payload, unsigned int nsid, const char *devname, - __u8 uuid_index) +static void vu_smart_log_show(vu_smart_log_t *payload, unsigned int nsid, const char *devname) { smart_log_item_t *item = payload->item; - printf("Additional Smart Log for NVMe device:%s namespace-id:%x UUID-idx:%d\n", - devname, nsid, uuid_index); + printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", + devname, nsid); printf("ID KEY Normalized Raw\n"); for (int i = 0; i < VU_SMART_MAX_ITEMS; i++) { @@ -203,7 +201,6 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd enum nvme_print_flags flags; struct nvme_dev *dev; int err; - __u8 uuid_index; struct config { __u32 namespace_id; @@ -232,27 +229,8 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd return flags; } - uuid_index = solidigm_get_vu_uuid_index(dev); - - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = &smart_log_payload, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = solidigm_vu_smart_log_id, - .len = sizeof(smart_log_payload), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, - .uuidx = uuid_index, - .rae = false, - .ot = false, - }; - - err = nvme_get_log(&args); + err = nvme_get_log_simple(dev_fd(dev), solidigm_vu_smart_log_id, + sizeof(smart_log_payload), &smart_log_payload); if (!err) { if (flags & JSON) { vu_smart_log_show_json(&smart_log_payload, @@ -261,7 +239,7 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd d_raw((unsigned char *)&smart_log_payload, sizeof(smart_log_payload)); } else { vu_smart_log_show(&smart_log_payload, cfg.namespace_id, - dev->name, uuid_index); + dev->name); } } else if (err > 0) { nvme_show_status(err); diff --git a/plugins/solidigm/solidigm-telemetry.c b/plugins/solidigm/solidigm-telemetry.c index 9946991..84a4e2a 100644 --- a/plugins/solidigm/solidigm-telemetry.c +++ b/plugins/solidigm/solidigm-telemetry.c @@ -121,7 +121,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc cfg.cfg_file, strerror(err)); goto close_fd; } - struct json_tokener * jstok = json_tokener_new(); + json_tokener * jstok = json_tokener_new(); tl.configuration = json_tokener_parse_ex(jstok, conf_str, length); if (jstok->err != json_tokener_success) { diff --git a/plugins/solidigm/solidigm-telemetry/cod.c b/plugins/solidigm/solidigm-telemetry/cod.c index 7accc53..be5685b 100644 --- a/plugins/solidigm/solidigm-telemetry/cod.c +++ b/plugins/solidigm/solidigm-telemetry/cod.c @@ -110,9 +110,9 @@ void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl) UNKNOWN = 0xFF, }; - struct json_object *telemetry_header = NULL; - struct json_object *COD_offset = NULL; - struct json_object *reason_id = NULL; + json_object *telemetry_header = NULL; + json_object *COD_offset = NULL; + json_object *reason_id = NULL; if (!json_object_object_get_ex(tl->root, "telemetryHeader", &telemetry_header)) return; @@ -144,7 +144,7 @@ void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl) return; } - struct json_object *cod = json_create_object(); + json_object *cod = json_create_object(); json_object_object_add(tl->root, "cod", cod); for (int i =0 ; i < data->header.EntryCount; i++) { diff --git a/plugins/solidigm/solidigm-telemetry/config.c b/plugins/solidigm/solidigm-telemetry/config.c index 5111703..781d786 100644 --- a/plugins/solidigm/solidigm-telemetry/config.c +++ b/plugins/solidigm/solidigm-telemetry/config.c @@ -11,15 +11,15 @@ // max 16 bit unsigned integer nummber 65535 #define MAX_16BIT_NUM_AS_STRING_SIZE 6 -static bool config_get_by_version(const struct json_object *obj, int version_major, - int version_minor, struct json_object **value) +static bool config_get_by_version(const json_object *obj, int version_major, + int version_minor, json_object **value) { char str_key[MAX_16BIT_NUM_AS_STRING_SIZE]; char str_subkey[MAX_16BIT_NUM_AS_STRING_SIZE]; snprintf(str_key, sizeof(str_key), "%d", version_major); snprintf(str_subkey, sizeof(str_subkey), "%d", version_minor); - struct json_object *major_obj = NULL; + json_object *major_obj = NULL; if (!json_object_object_get_ex(obj, str_key, &major_obj)) return false; @@ -28,11 +28,11 @@ static bool config_get_by_version(const struct json_object *obj, int version_maj return value != NULL; } -bool solidigm_config_get_by_token_version(const struct json_object *obj, int token_id, +bool solidigm_config_get_by_token_version(const json_object *obj, int token_id, int version_major, int version_minor, - struct json_object **value) + json_object **value) { - struct json_object *token_obj = NULL; + json_object *token_obj = NULL; char str_key[MAX_16BIT_NUM_AS_STRING_SIZE]; snprintf(str_key, sizeof(str_key), "%d", token_id); diff --git a/plugins/solidigm/solidigm-telemetry/config.h b/plugins/solidigm/solidigm-telemetry/config.h index 30e61ff..bea84fb 100644 --- a/plugins/solidigm/solidigm-telemetry/config.h +++ b/plugins/solidigm/solidigm-telemetry/config.h @@ -7,7 +7,4 @@ #include #include "util/json.h" -bool solidigm_config_get_by_token_version(const struct json_object *obj, - int key, int subkey, - int subsubkey, - struct json_object **value); +bool solidigm_config_get_by_token_version(const json_object *obj, int key, int subkey, int subsubkey, json_object **value); diff --git a/plugins/solidigm/solidigm-telemetry/data-area.c b/plugins/solidigm/solidigm-telemetry/data-area.c index 2f18ea2..7233e8f 100644 --- a/plugins/solidigm/solidigm-telemetry/data-area.c +++ b/plugins/solidigm/solidigm-telemetry/data-area.c @@ -17,7 +17,7 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl, uint32_t offset_bit, uint32_t size_bit, - bool is_signed, struct json_object **val_obj) + bool is_signed, json_object **val_obj) { uint32_t offset_bit_from_byte; uint32_t additional_size_byte; @@ -77,16 +77,16 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl, } static int telemetry_log_structure_parse(const struct telemetry_log *tl, - struct json_object *struct_def, + json_object *struct_def, size_t parent_offset_bit, - struct json_object *output, - struct json_object *metadata) + json_object *output, + json_object *metadata) { - struct json_object *obj_arraySizeArray = NULL; - struct json_object *obj = NULL; - struct json_object *obj_memberList; - struct json_object *major_dimension; - struct json_object *sub_output; + json_object *obj_arraySizeArray = NULL; + json_object *obj = NULL; + json_object *obj_memberList; + json_object *major_dimension; + json_object *sub_output; bool is_enumeration = false; bool has_member_list; const char *type = ""; @@ -155,7 +155,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl, uint32_t array_size_dimension[array_rank]; for (size_t i = 0; i < array_rank; i++) { - struct json_object *dimension = json_object_array_get_idx(obj_arraySizeArray, i); + json_object *dimension = json_object_array_get_idx(obj_arraySizeArray, i); array_size_dimension[i] = json_object_get_uint64(dimension); major_dimension = dimension; @@ -163,7 +163,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl, if (array_rank > 1) { uint32_t linear_pos_per_index = array_size_dimension[0]; uint32_t prev_index_offset_bit = 0; - struct json_object *dimension_output; + json_object *dimension_output; for (int i = 1; i < (array_rank - 1); i++) linear_pos_per_index *= array_size_dimension[i]; @@ -182,7 +182,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl, json_object_array_del_idx(obj_arraySizeArray, array_rank - 1, 1); for (int i = 0 ; i < array_size_dimension[0]; i++) { - struct json_object *sub_array = json_create_array(); + json_object *sub_array = json_create_array(); size_t offset; offset = parent_offset_bit + prev_index_offset_bit; @@ -213,7 +213,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl, for (uint32_t j = 0; j < array_size_dimension[0]; j++) { if (is_enumeration || !has_member_list) { bool is_signed = !strncmp(type, SIGNED_INT_PREFIX, sizeof(SIGNED_INT_PREFIX)-1); - struct json_object *val_obj; + json_object *val_obj; size_t offset; offset = parent_offset_bit + offset_bit + linear_array_pos_bit; @@ -230,7 +230,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl, json_free_object(val_obj); } } else { - struct json_object *sub_sub_output = json_create_object(); + json_object *sub_sub_output = json_object_new_object(); int num_members; if (array_size_dimension[0] > 1) @@ -240,7 +240,7 @@ static int telemetry_log_structure_parse(const struct telemetry_log *tl, num_members = json_object_array_length(obj_memberList); for (int k = 0; k < num_members; k++) { - struct json_object *member = json_object_array_get_idx(obj_memberList, k); + json_object *member = json_object_array_get_idx(obj_memberList, k); size_t offset; offset = parent_offset_bit + offset_bit + linear_array_pos_bit; @@ -322,8 +322,8 @@ struct telemetry_object_header { static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl, enum nvme_telemetry_da da, - struct json_object *toc_array, - struct json_object *tele_obj_array) + json_object *toc_array, + json_object *tele_obj_array) { const struct telemetry_object_header *header; @@ -339,8 +339,8 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl, payload = (char *) tl->log; for (int i = 0; i < toc->header.TableOfContentsCount; i++) { - struct json_object *structure_definition = NULL; - struct json_object *toc_item; + json_object *structure_definition = NULL; + json_object *toc_item; uint32_t obj_offset; bool has_struct; @@ -379,15 +379,15 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl, &structure_definition); if (has_struct) { - struct json_object *tele_obj_item = json_create_object(); + json_object *tele_obj_item = json_create_object(); json_object_array_add(tele_obj_array, tele_obj_item); json_object_get(toc_item); json_object_add_value_object(tele_obj_item, "metadata", toc_item); - struct json_object *parsed_struct = json_create_object(); + json_object *parsed_struct = json_object_new_object(); json_object_add_value_object(tele_obj_item, "objectData", parsed_struct); - struct json_object *obj_hasTelemObjHdr = NULL; + json_object *obj_hasTelemObjHdr = NULL; uint32_t header_offset = sizeof(const struct telemetry_object_header); uint32_t file_offset; @@ -411,8 +411,8 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl, int solidigm_telemetry_log_data_areas_parse(const struct telemetry_log *tl, enum nvme_telemetry_da last_da) { - struct json_object *tele_obj_array = json_create_array(); - struct json_object *toc_array = json_create_array(); + json_object *tele_obj_array = json_create_array(); + json_object *toc_array = json_create_array(); json_object_add_value_array(tl->root, "tableOfContents", toc_array); json_object_add_value_array(tl->root, "telemetryObjects", tele_obj_array); diff --git a/plugins/solidigm/solidigm-telemetry/header.c b/plugins/solidigm/solidigm-telemetry/header.c index d085c24..72b2d97 100644 --- a/plugins/solidigm/solidigm-telemetry/header.c +++ b/plugins/solidigm/solidigm-telemetry/header.c @@ -63,10 +63,10 @@ static_assert(sizeof(const struct reason_indentifier_1_2) == #pragma pack(pop, reason_indentifier) static void telemetry_log_reason_id_parse1_0_ext(const struct telemetry_log *tl, - struct json_object *reason_id) + json_object *reason_id) { const struct reason_indentifier_1_0 *ri; - struct json_object *reserved; + json_object *reserved; ri = (struct reason_indentifier_1_0 *) tl->log->rsnident; json_object_object_add(reason_id, "FirmwareVersion", json_object_new_string_len(ri->FirmwareVersion, sizeof(ri->FirmwareVersion))); @@ -76,16 +76,16 @@ static void telemetry_log_reason_id_parse1_0_ext(const struct telemetry_log *tl, reserved = json_create_array(); json_object_add_value_array(reason_id, "Reserved", reserved); for ( int i=0; i < sizeof(ri->Reserved); i++) { - struct json_object *val = json_object_new_int(ri->Reserved[i]); + json_object *val = json_object_new_int(ri->Reserved[i]); json_object_array_add(reserved, val); } } static void telemetry_log_reason_id_parse1_1_ext(const struct telemetry_log *tl, - struct json_object *reason_id) + json_object *reason_id) { const struct reason_indentifier_1_1 *ri; - struct json_object *reserved; + json_object *reserved; ri = (struct reason_indentifier_1_1 *) tl->log->rsnident; json_object_object_add(reason_id, "FirmwareVersion", json_object_new_string_len(ri->FirmwareVersion, sizeof(ri->FirmwareVersion))); @@ -98,17 +98,17 @@ static void telemetry_log_reason_id_parse1_1_ext(const struct telemetry_log *tl, reserved = json_create_array(); json_object_add_value_array(reason_id, "Reserved", reserved); for (int i = 0; i < sizeof(ri->Reserved); i++) { - struct json_object *val = json_object_new_int(ri->Reserved[i]); + json_object *val = json_object_new_int(ri->Reserved[i]); json_object_array_add(reserved, val); } } static void telemetry_log_reason_id_parse1_2_ext(const struct telemetry_log *tl, - struct json_object *reason_id) + json_object *reason_id) { const struct reason_indentifier_1_2 *ri; - struct json_object *dp_reserved; - struct json_object *reserved; + json_object *dp_reserved; + json_object *reserved; ri = (struct reason_indentifier_1_2 *) tl->log->rsnident; @@ -121,19 +121,19 @@ static void telemetry_log_reason_id_parse1_2_ext(const struct telemetry_log *tl, reserved = json_create_array(); json_object_add_value_array(reason_id, "Reserved2", reserved); for (int i = 0; i < sizeof(ri->Reserved2); i++) { - struct json_object *val = json_object_new_int(ri->Reserved2[i]); + json_object *val = json_object_new_int(ri->Reserved2[i]); json_object_array_add(reserved, val); } dp_reserved = json_create_array(); json_object_add_value_array(reason_id, "DualPortReserved", dp_reserved); for (int i = 0; i < sizeof(ri->DualPortReserved); i++) { - struct json_object *val = json_object_new_int(ri->DualPortReserved[i]); + json_object *val = json_object_new_int(ri->DualPortReserved[i]); json_object_array_add(dp_reserved, val); } } -static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *tl, struct json_object *reason_id) +static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *tl, json_object *reason_id) { const struct reason_indentifier_1_0 *ri1_0 = (struct reason_indentifier_1_0 *) tl->log->rsnident; @@ -161,9 +161,9 @@ static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *t bool solidigm_telemetry_log_header_parse(const struct telemetry_log *tl) { const struct nvme_telemetry_log *log; - struct json_object *ieee_oui_id; - struct json_object *reason_id; - struct json_object *header; + json_object *ieee_oui_id; + json_object *reason_id; + json_object *header; if (tl->log_size < sizeof(const struct nvme_telemetry_log)) { SOLIDIGM_LOG_WARNING("Telemetry log too short."); @@ -180,7 +180,7 @@ bool solidigm_telemetry_log_header_parse(const struct telemetry_log *tl) json_object_object_add(header, "ieeeOuiIdentifier", ieee_oui_id); for (int i = 0; i < sizeof(log->ieee); i++) { - struct json_object *val = json_object_new_int(log->ieee[i]); + json_object *val = json_object_new_int(log->ieee[i]); json_object_array_add(ieee_oui_id, val); } diff --git a/plugins/solidigm/solidigm-telemetry/telemetry-log.h b/plugins/solidigm/solidigm-telemetry/telemetry-log.h index e9eff73..ef4ec5d 100644 --- a/plugins/solidigm/solidigm-telemetry/telemetry-log.h +++ b/plugins/solidigm/solidigm-telemetry/telemetry-log.h @@ -24,8 +24,8 @@ struct telemetry_log { struct nvme_telemetry_log *log; size_t log_size; - struct json_object *root; - struct json_object *configuration; + json_object *root; + json_object *configuration; }; -#endif /* _SOLIDIGM_TELEMETRY_LOG_H */ +#endif /* _SOLIDIGM_TELEMETRY_LOG_H */ \ No newline at end of file diff --git a/plugins/solidigm/solidigm-util.c b/plugins/solidigm/solidigm-util.c deleted file mode 100644 index 0171a49..0000000 --- a/plugins/solidigm/solidigm-util.c +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2023 Solidigm. - * - * Author: leonardo.da.cunha@solidigm.com - */ - -#include "plugins/ocp/ocp-utils.h" -#include "solidigm-util.h" - -__u8 solidigm_get_vu_uuid_index(struct nvme_dev *dev) -{ - int ocp_uuid_index = 0; - - if (ocp_get_uuid_index(dev, &ocp_uuid_index) == 0) - if (ocp_uuid_index == 2) - return 1; - - return 0; -} diff --git a/plugins/solidigm/solidigm-util.h b/plugins/solidigm/solidigm-util.h deleted file mode 100644 index 3a18501..0000000 --- a/plugins/solidigm/solidigm-util.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (c) 2023 Solidigm. - * - * Author: leonardo.da.cunha@solidigm.com - */ - -#include "nvme.h" - -__u8 solidigm_get_vu_uuid_index(struct nvme_dev *dev); diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c index 2d5d173..cf185be 100644 --- a/plugins/wdc/wdc-nvme.c +++ b/plugins/wdc/wdc-nvme.c @@ -996,14 +996,10 @@ struct __attribute__((__packed__)) wdc_bd_ca_log_format { __u8 raw_value[8]; }; -#define LATENCY_LOG_BUCKET_READ 3 -#define LATENCY_LOG_BUCKET_WRITE 2 -#define LATENCY_LOG_BUCKET_TRIM 1 -#define LATENCY_LOG_BUCKET_RESERVED 0 - -#define LATENCY_LOG_MEASURED_LAT_READ 2 -#define LATENCY_LOG_MEASURED_LAT_WRITE 1 -#define LATENCY_LOG_MEASURED_LAT_TRIM 0 +#define READ 0 +#define WRITE 1 +#define TRIM 2 +#define RESERVED 3 struct __attribute__((__packed__)) wdc_ssd_latency_monitor_log { __u8 feature_status; /* 0x00 */ @@ -1018,7 +1014,7 @@ struct __attribute__((__packed__)) wdc_ssd_latency_monitor_log { __u8 active_latency_min_window; /* 0x0C */ __u8 rsvd2[0x13]; /* 0x0D */ - __le32 active_bucket_counter[4][4]; /* 0x20 - 0x5F */ + __le32 active_bucket_counter[4][4] ; /* 0x20 - 0x5F */ __le64 active_latency_timestamp[4][3]; /* 0x60 - 0xBF */ __le16 active_measured_latency[4][3]; /* 0xC0 - 0xD7 */ __le16 active_latency_stamp_units; /* 0xD8 */ @@ -4110,21 +4106,19 @@ static int wdc_print_latency_monitor_log_normal(struct nvme_dev *dev, printf(" Read Write Deallocate/Trim \n"); for (i = 0; i <= 3; i++) { printf(" Active Bucket Counter: Bucket %d %27d %27d %27d \n", - i, le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_READ]), - le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_WRITE]), - le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_TRIM])); + i, le32_to_cpu(log_data->active_bucket_counter[i][READ]), le32_to_cpu(log_data->active_bucket_counter[i][WRITE]), + le32_to_cpu(log_data->active_bucket_counter[i][TRIM])); } - for (i = 3; i >= 0; i--) { + for (i = 0; i <= 3; i++) { printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n", - 3-i, le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_READ]), - le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_WRITE]), - le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_TRIM])); + i, le16_to_cpu(log_data->active_measured_latency[i][READ]), le16_to_cpu(log_data->active_measured_latency[i][WRITE]), + le16_to_cpu(log_data->active_measured_latency[i][TRIM])); } - for (i = 3; i >= 0; i--) { - printf(" Active Latency Time Stamp: Bucket %d ", 3-i); - for (j = 2; j >= 0; j--) { + for (i = 0; i <= 3; i++) { + printf(" Active Latency Time Stamp: Bucket %d ", i); + for (j = 0; j <= 2; j++) { if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1) printf(" N/A "); else { @@ -4137,21 +4131,19 @@ static int wdc_print_latency_monitor_log_normal(struct nvme_dev *dev, for (i = 0; i <= 3; i++) { printf(" Static Bucket Counter: Bucket %d %27d %27d %27d \n", - i, le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_READ]), - le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_WRITE]), - le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_TRIM])); + i, le32_to_cpu(log_data->static_bucket_counter[i][READ]), le32_to_cpu(log_data->static_bucket_counter[i][WRITE]), + le32_to_cpu(log_data->static_bucket_counter[i][TRIM])); } - for (i = 3; i >= 0; i--) { + for (i = 0; i <= 3; i++) { printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n", - 3-i, le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_READ]), - le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_WRITE]), - le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_TRIM])); + i, le16_to_cpu(log_data->static_measured_latency[i][READ]), le16_to_cpu(log_data->static_measured_latency[i][WRITE]), + le16_to_cpu(log_data->static_measured_latency[i][TRIM])); } - for (i = 3; i >= 0; i--) { - printf(" Static Latency Time Stamp: Bucket %d ", 3-i); - for (j = 2; j >= 0; j--) { + for (i = 0; i <= 3; i++) { + printf(" Static Latency Time Stamp: Bucket %d ", i); + for (j = 0; j <= 2; j++) { if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1) printf(" N/A "); else { @@ -4187,38 +4179,38 @@ static void wdc_print_latency_monitor_log_json(struct wdc_ssd_latency_monitor_lo json_object_add_value_int(root, "Debug Log Trigger Enable", le16_to_cpu(log_data->debug_log_trigger_enable)); for (i = 0; i <= 3; i++) { - for (j = 2; j >= 0; j--) { - sprintf(buf, "Active Bucket Counter: Bucket %d %s", i, operation[2-j]); - json_object_add_value_int(root, buf, le32_to_cpu(log_data->active_bucket_counter[i][j+1])); + for (j = 0; j <= 2; j++) { + sprintf(buf, "Active Bucket Counter: Bucket %d %s", i, operation[j]); + json_object_add_value_int(root, buf, le32_to_cpu(log_data->active_bucket_counter[i][j])); } } - for (i = 3; i >= 0; i--) { - for (j = 2; j >= 0; j--) { - sprintf(buf, "Active Measured Latency: Bucket %d %s", 3-i, operation[2-j]); + for (i = 0; i <= 3; i++) { + for (j = 0; j <= 2; j++) { + sprintf(buf, "Active Measured Latency: Bucket %d %s", i, operation[j]); json_object_add_value_int(root, buf, le16_to_cpu(log_data->active_measured_latency[i][j])); } } - for (i = 3; i >= 0; i--) { - for (j = 2; j >= 0; j--) { - sprintf(buf, "Active Latency Time Stamp: Bucket %d %s", 3-i, operation[2-j]); + for (i = 0; i <= 3; i++) { + for (j = 0; j <= 2; j++) { + sprintf(buf, "Active Latency Time Stamp: Bucket %d %s", i, operation[j]); json_object_add_value_int(root, buf, le64_to_cpu(log_data->active_latency_timestamp[i][j])); } } for (i = 0; i <= 3; i++) { - for (j = 2; j >= 0; j--) { - sprintf(buf, "Static Bucket Counter: Bucket %d %s", i, operation[2-j]); - json_object_add_value_int(root, buf, le32_to_cpu(log_data->static_bucket_counter[i][j+1])); + for (j = 0; j <= 2; j++) { + sprintf(buf, "Static Bucket Counter: Bucket %d %s", i, operation[j]); + json_object_add_value_int(root, buf, le32_to_cpu(log_data->static_bucket_counter[i][j])); } } - for (i = 3; i >= 0; i--) { - for (j = 2; j >= 0; j--) { - sprintf(buf, "Static Measured Latency: Bucket %d %s", 3-i, operation[2-j]); + for (i = 0; i <= 3; i++) { + for (j = 0; j <= 2; j++) { + sprintf(buf, "Static Measured Latency: Bucket %d %s", i, operation[j]); json_object_add_value_int(root, buf, le16_to_cpu(log_data->static_measured_latency[i][j])); } } - for (i = 3; i >= 0; i--) { - for (j = 2; j >= 0; j--) { - sprintf(buf, "Static Latency Time Stamp: Bucket %d %s", 3-i, operation[2-j]); + for (i = 0; i <= 3; i++) { + for (j = 0; j <= 2; j++) { + sprintf(buf, "Static Latency Time Stamp: Bucket %d %s", i, operation[j]); json_object_add_value_int(root, buf, le64_to_cpu(log_data->static_latency_timestamp[i][j])); } } @@ -10576,7 +10568,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv, if (ret != 0) goto out; - /* convert from kelvins to degrees Celsius */ + /* convert from Kelvin to degrees Celsius */ temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]) - 273; /* retrieve HCTM Thermal Management Temperatures */ diff --git a/plugins/wdc/wdc-nvme.h b/plugins/wdc/wdc-nvme.h index cdd9615..242cf9a 100644 --- a/plugins/wdc/wdc-nvme.h +++ b/plugins/wdc/wdc-nvme.h @@ -5,7 +5,7 @@ #if !defined(WDC_NVME) || defined(CMD_HEADER_MULTI_READ) #define WDC_NVME -#define WDC_PLUGIN_VERSION "2.3.1" +#define WDC_PLUGIN_VERSION "2.1.2" #include "cmd.h" PLUGIN(NAME("wdc", "Western Digital vendor specific extensions", WDC_PLUGIN_VERSION), -- cgit v1.2.3