Adding upstream version 2.4+really2.3.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
69f45f5c7c
commit
85727a4155
458 changed files with 5141 additions and 7138 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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',
|
||||
]
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Authors: Arthur Shau <arthurshau@fb.com>,
|
||||
* Wei Zhang <wzhang@fb.com>,
|
||||
* Venkat Ramesh <venkatraghavan@fb.com>
|
||||
* Venkat Ramesh <venkatraghavan@fb.com>
|
||||
*/
|
||||
#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)
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -1,352 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/* Copyright (c) 2022 Meta Platforms, Inc.
|
||||
*
|
||||
* Authors: Arthur Shau <arthurshau@fb.com>,
|
||||
* Wei Zhang <wzhang@fb.com>,
|
||||
* Venkat Ramesh <venkatraghavan@fb.com>
|
||||
*/
|
||||
|
||||
#include "ocp-smart-extended-log.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* Copyright (c) 2022 Meta Platforms, Inc.
|
||||
*
|
||||
* Authors: Arthur Shau <arthurshau@fb.com>,
|
||||
* Wei Zhang <wzhang@fb.com>,
|
||||
* Venkat Ramesh <venkatraghavan@fb.com>
|
||||
*/
|
||||
|
||||
#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
|
|
@ -5,13 +5,11 @@
|
|||
* Author: leonardo.da.cunha@solidigm.com
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -7,7 +7,4 @@
|
|||
#include <stdbool.h>
|
||||
#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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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 */
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue