1
0
Fork 0

Merging upstream version 2.12.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-03-20 08:10:44 +01:00
parent 078c0dbcc0
commit 635faa7346
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
571 changed files with 10718 additions and 2738 deletions

View file

@ -7,12 +7,11 @@
*/
#include <unistd.h>
#include "util/types.h"
#include "ocp-nvme.h"
#include "ocp-utils.h"
#include "nvme-print.h"
static const __u8 OCP_FID_CLEAR_FW_ACTIVATION_HISTORY = 0xC1;
static const __u8 OCP_FID_CLEAR_PCIE_CORRECTABLE_ERROR_COUNTERS = 0xC3;
static int ocp_clear_feature(int argc, char **argv, const char *desc, const __u8 fid)
{
__u32 result = 0;
@ -80,14 +79,13 @@ int ocp_clear_fw_update_history(int argc, char **argv, struct command *cmd, stru
{
const char *desc = "OCP Clear Firmware Update History";
return ocp_clear_feature(argc, argv, desc, OCP_FID_CLEAR_FW_ACTIVATION_HISTORY);
return ocp_clear_feature(argc, argv, desc, OCP_FID_CFUH);
}
int ocp_clear_pcie_correctable_errors(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
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_feature(argc, argv, desc, OCP_FID_CPCIE);
}

View file

@ -13,6 +13,7 @@
#include "common.h"
#include "nvme-print.h"
#include "ocp-nvme.h"
#include "ocp-utils.h"
#include "ocp-print.h"
@ -26,7 +27,6 @@ static const unsigned char ocp_fw_activation_history_guid[GUID_LEN] = {
int ocp_fw_activation_history_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
const __u8 log_id = 0xC2;
const char *description = "Retrieves the OCP firmware activation history log.";
char *format = "normal";
@ -59,7 +59,7 @@ int ocp_fw_activation_history_log(int argc, char **argv, struct command *cmd,
.args_size = sizeof(args),
.fd = dev_fd(dev),
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.lid = log_id,
.lid = (enum nvme_cmd_get_log_lid)OCP_LID_FAHL_OBSOLETE,
.len = sizeof(fw_history),
.nsid = NVME_NSID_ALL,
.csi = NVME_CSI_NVM,

View file

@ -4,6 +4,7 @@
*
* Authors: karl.dedow@solidigm.com
*/
#include <libnvme.h>
#include "common.h"
#include "linux/types.h"
@ -18,7 +19,7 @@ struct __packed fw_activation_history_entry {
__u8 entry_length;
__le16 reserved1;
__le16 activation_count;
__le64 timestamp;
struct nvme_timestamp ts;
__le64 reserved2;
__le64 power_cycle_count;
char previous_fw[8];

View file

@ -11,6 +11,7 @@
#include "nvme-print.h"
#include "ocp-hardware-component-log.h"
#include "ocp-print.h"
#include "ocp-utils.h"
//#define HWCOMP_DUMMY
@ -154,6 +155,8 @@ const char *hwcomp_id_to_string(__u32 id)
return "Country of Origin";
case HWCOMP_ID_HW_REV:
return "Global Device Hardware Revision";
case HWCOMP_ID_BORN_ON_DATE:
return "Born on Date";
case HWCOMP_ID_VENDOR ... HWCOMP_ID_MAX:
return "Vendor Unique Component";
case HWCOMP_ID_RSVD:
@ -168,39 +171,59 @@ static int get_hwcomp_log_data(struct nvme_dev *dev, struct hwcomp_log *log)
{
int ret = 0;
size_t desc_offset = offsetof(struct hwcomp_log, desc);
long double log_bytes;
nvme_uint128_t log_size;
struct nvme_get_log_args args = {
.lpo = desc_offset,
.args_size = sizeof(args),
.fd = dev_fd(dev),
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.lid = LID_HWCOMP,
.lid = (enum nvme_cmd_get_log_lid)OCP_LID_HWCOMP,
.nsid = NVME_NSID_ALL,
.log = log,
.len = desc_offset,
};
ocp_get_uuid_index(dev, &args.uuidx);
#ifdef HWCOMP_DUMMY
memcpy(log, hwcomp_dummy, desc_offset);
#else /* HWCOMP_DUMMY */
ret = nvme_get_log_simple(dev_fd(dev), LID_HWCOMP, desc_offset, log);
ret = nvme_get_log_page(dev_fd(dev), NVME_LOG_PAGE_PDU_SIZE, &args);
if (ret) {
print_info_error("error: ocp: failed to get log simple (hwcomp: %02X, ret: %d)\n",
LID_HWCOMP, ret);
print_info_error("error: ocp: failed to get hwcomp log size (ret: %d)\n", ret);
return ret;
}
#endif /* HWCOMP_DUMMY */
print_info("id: %02Xh\n", LID_HWCOMP);
log_size = le128_to_cpu(log->size);
print_info("id: %02Xh\n", OCP_LID_HWCOMP);
print_info("version: %04Xh\n", log->ver);
print_info_array("guid", log->guid, ARRAY_SIZE(log->guid));
print_info("size: %s\n", uint128_t_to_string(le128_to_cpu(log->size)));
print_info("size: %s\n", uint128_t_to_string(log_size));
log_bytes = uint128_t_to_double(log_size);
if (log->ver == 1)
log_bytes *= sizeof(__le32);
if (log_bytes <= desc_offset) {
print_info_error("error: ocp: invalid hwcomp log size bytes: %.0Lf\n", log_bytes);
return -EINVAL;
}
args.len = log_bytes - desc_offset;
print_info("args.len: %u\n", args.len);
args.len = uint128_t_to_double(le128_to_cpu(log->size)) * sizeof(__le32);
log->desc = calloc(1, args.len);
if (!log->desc) {
fprintf(stderr, "error: ocp: calloc: %s\n", strerror(errno));
return -1;
return -errno;
}
args.log = log->desc,
args.lpo = desc_offset,
#ifdef HWCOMP_DUMMY
memcpy(log->desc, &hwcomp_dummy[desc_offset], args.len);
@ -208,7 +231,8 @@ static int get_hwcomp_log_data(struct nvme_dev *dev, struct hwcomp_log *log)
ret = nvme_get_log_page(dev_fd(dev), NVME_LOG_PAGE_PDU_SIZE, &args);
if (ret) {
print_info_error("error: ocp: failed to get log page (hwcomp: %02X, ret: %d)\n",
LID_HWCOMP, ret);
OCP_LID_HWCOMP, ret);
free(log->desc);
return ret;
}
#endif /* HWCOMP_DUMMY */
@ -218,12 +242,10 @@ static int get_hwcomp_log_data(struct nvme_dev *dev, struct hwcomp_log *log)
static int get_hwcomp_log(struct nvme_dev *dev, __u32 id, bool list)
{
_cleanup_free_ __u8 *desc = NULL;
int ret;
nvme_print_flags_t fmt;
struct hwcomp_log log = {
.desc = (struct hwcomp_desc *)desc,
.desc = NULL,
};
ret = validate_output_format(nvme_cfg.output_format, &fmt);
@ -235,12 +257,14 @@ static int get_hwcomp_log(struct nvme_dev *dev, __u32 id, bool list)
ret = get_hwcomp_log_data(dev, &log);
if (ret) {
print_info_error("error: ocp: failed get hwcomp log: %02X data, ret: %d\n",
LID_HWCOMP, ret);
OCP_LID_HWCOMP, ret);
return ret;
}
ocp_show_hwcomp_log(&log, id, list, fmt);
free(log.desc);
return 0;
}
@ -268,6 +292,7 @@ int ocp_hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *pl
VAL_LONG("sn", HWCOMP_ID_SN),
VAL_LONG("country", HWCOMP_ID_COUNTRY),
VAL_LONG("hw-rev", HWCOMP_ID_HW_REV),
VAL_LONG("born-on-date", HWCOMP_ID_BORN_ON_DATE),
VAL_LONG("vendor", HWCOMP_ID_VENDOR),
VAL_END()
};
@ -281,8 +306,8 @@ int ocp_hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *pl
ret = get_hwcomp_log(dev, cfg.id, cfg.list);
if (ret)
fprintf(stderr, "error: ocp: failed to get hwcomp log: %02X, ret: %d\n", LID_HWCOMP,
ret);
fprintf(stderr, "error: ocp: failed to get hwcomp log: %02X, ret: %d\n",
OCP_LID_HWCOMP, ret);
return ret;
}

View file

@ -9,7 +9,6 @@
#ifndef OCP_HARDWARE_COMPONENT_LOG_H
#define OCP_HARDWARE_COMPONENT_LOG_H
#define LID_HWCOMP 0xc6
#define HWCOMP_RSVD2_LEN 14
#define HWCOMP_SIZE_LEN 16
#define HWCOMP_RSVD48_LEN 16
@ -54,6 +53,7 @@ enum hwcomp_id {
HWCOMP_ID_SN,
HWCOMP_ID_COUNTRY,
HWCOMP_ID_HW_REV,
HWCOMP_ID_BORN_ON_DATE,
HWCOMP_ID_VENDOR = 0x8000,
HWCOMP_ID_MAX = 0xffff,
};

View file

@ -32,6 +32,7 @@
#include "ocp-telemetry-decode.h"
#include "ocp-hardware-component-log.h"
#include "ocp-print.h"
#include "ocp-types.h"
#define CREATE_CMD
#include "ocp-nvme.h"
@ -44,8 +45,6 @@
/// Latency Monitor Log
#define C3_LATENCY_MON_LOG_BUF_LEN 0x200
#define C3_LATENCY_MON_OPCODE 0xC3
#define NVME_FEAT_OCP_LATENCY_MONITOR 0xC5
static __u8 lat_mon_guid[GUID_LEN] = {
0x92, 0x7a, 0xc0, 0x8c,
@ -104,6 +103,17 @@ enum erri_type {
ERRI_TYPE_HW_MALFUNCTION,
ERRI_TYPE_NO_MORE_NAND_SPARES,
ERRI_TYPE_INCOMPLETE_SHUTDOWN,
ERRI_TYPE_METADATA_CORRUPTION,
ERRI_TYPE_CRITICAL_GC,
ERRI_TYPE_LATENCY_SPIKE,
ERRI_TYPE_IO_CMD_FAILURE,
ERRI_TYPE_IO_CMD_TIMEOUT,
ERRI_TYPE_ADMIN_CMD_FAILURE,
ERRI_TYPE_ADMIN_CMD_TIMEOUT,
ERRI_TYPE_THERMAL_THROTTLE_ENGAGED,
ERRI_TYPE_THERMAL_THROTTLE_DISENGAGED,
ERRI_TYPE_CRITICAL_TEMPERATURE_EVENT,
ERRI_TYPE_DIE_OFFLINE,
};
const char *erri_type_to_string(__le16 type)
@ -131,6 +141,28 @@ const char *erri_type_to_string(__le16 type)
return "no more NAND spares available";
case ERRI_TYPE_INCOMPLETE_SHUTDOWN:
return "incomplete shutdown";
case ERRI_TYPE_METADATA_CORRUPTION:
return "Metadata Corruption";
case ERRI_TYPE_CRITICAL_GC:
return "Critical Garbage Collection";
case ERRI_TYPE_LATENCY_SPIKE:
return "Latency Spike";
case ERRI_TYPE_IO_CMD_FAILURE:
return "I/O command failure";
case ERRI_TYPE_IO_CMD_TIMEOUT:
return "I/O command timeout";
case ERRI_TYPE_ADMIN_CMD_FAILURE:
return "Admin command failure";
case ERRI_TYPE_ADMIN_CMD_TIMEOUT:
return "Admin command timeout";
case ERRI_TYPE_THERMAL_THROTTLE_ENGAGED:
return "Thermal Throttle Engaged";
case ERRI_TYPE_THERMAL_THROTTLE_DISENGAGED:
return "Thermal Throttle Disengaged";
case ERRI_TYPE_CRITICAL_TEMPERATURE_EVENT:
return "Critical Temperature Event";
case ERRI_TYPE_DIE_OFFLINE:
return "Die Offline";
default:
break;
}
@ -161,6 +193,8 @@ const char *data = "Error injection data structure entries";
const char *number = "Number of valid error injection data entries";
static const char *type = "Error injection type";
static const char *nrtdp = "Number of reads to trigger device panic";
static const char *save = "Specifies that the controller shall save the attribute";
static const char *enable_ieee1667_silo = "enable IEEE1667 silo";
static int get_c3_log_page(struct nvme_dev *dev, char *format)
{
@ -183,8 +217,7 @@ static int get_c3_log_page(struct nvme_dev *dev, char *format)
}
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);
ret = ocp_get_log_simple(dev, OCP_LID_LMLOG, 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);
@ -305,7 +338,7 @@ int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd,
.active_latency_minimum_window = 0xA,
.debug_log_trigger_enable = 0,
.discard_debug_log = 0,
.latency_monitor_feature_enable = 0x7,
.latency_monitor_feature_enable = 0x1,
};
OPT_ARGS(opts) = {
@ -356,7 +389,7 @@ int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd,
struct nvme_set_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = NVME_FEAT_OCP_LATENCY_MONITOR,
.fid = OCP_FID_LM,
.nsid = 0,
.cdw12 = 0,
.save = 1,
@ -370,7 +403,7 @@ int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd,
if (err < 0) {
perror("set-feature");
} else if (!err) {
printf("NVME_FEAT_OCP_LATENCY_MONITOR: 0x%02x\n", NVME_FEAT_OCP_LATENCY_MONITOR);
printf("NVME_FEAT_OCP_LATENCY_MONITOR: 0x%02x\n", OCP_FID_LM);
printf("active bucket timer threshold: 0x%x\n",
le16_to_cpu(buf.active_bucket_timer_threshold));
printf("active threshold a: 0x%x\n", buf.active_threshold_a);
@ -511,10 +544,8 @@ static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd,
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]: current/default/saved/supported";
const __u32 nsid = 0;
const __u8 fid = 0xc2;
const __u8 fid = OCP_FID_ROWTM;
struct nvme_dev *dev;
int err;
@ -1252,8 +1283,7 @@ static int get_c9_log_page_data(struct nvme_dev *dev, int print_data, int save_b
}
memset(header_data, 0, sizeof(__u8) * C9_TELEMETRY_STR_LOG_LEN);
ret = nvme_get_log_simple(dev_fd(dev), C9_TELEMETRY_STRING_LOG_ENABLE_OPCODE,
C9_TELEMETRY_STR_LOG_LEN, header_data);
ret = ocp_get_log_simple(dev, OCP_LID_TELSLG, C9_TELEMETRY_STR_LOG_LEN, header_data);
if (!ret) {
log_data = (struct telemetry_str_log_format *)header_data;
@ -1295,8 +1325,7 @@ static int get_c9_log_page_data(struct nvme_dev *dev, int print_data, int save_b
}
memset(pC9_string_buffer, 0, sizeof(__u8) * total_log_page_sz);
ret = nvme_get_log_simple(dev_fd(dev), C9_TELEMETRY_STRING_LOG_ENABLE_OPCODE,
total_log_page_sz, pC9_string_buffer);
ret = ocp_get_log_simple(dev, OCP_LID_TELSLG, total_log_page_sz, pC9_string_buffer);
} else {
fprintf(stderr, "ERROR : OCP : Unable to read C9 data.\n");
}
@ -1385,7 +1414,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct
const char *output_format = "output format normal|json";
const char *data_area = "Telemetry Data Area; 1 or 2;\n"
"e.g. '-a 1 for Data Area 1.'\n'-a 2 for Data Areas 1 and 2.';\n";
const char *telemetry_type = "Telemetry Type; 'host' or 'controller'";
const char *telemetry_type = "Telemetry Type; 'host', 'host0', 'host1' or 'controller'";
struct nvme_dev *dev;
int err = 0;
@ -1453,7 +1482,8 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct
else if (!strcmp(opt.telemetry_type, "controller"))
tele_type = TELEMETRY_TYPE_CONTROLLER;
else {
nvme_show_error("telemetry-type should be host or controller.\n");
nvme_show_error(
"telemetry-type should be host, host0, host1 or controller.\n");
goto out;
}
} else {
@ -1504,60 +1534,6 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct
nvme_show_result("Status:(%x)\n", err);
}
break;
case TELEMETRY_TYPE_NONE:
printf("\n-------------------------------------------------------------\n");
/* Host 0 (lsp == 0) must be executed before Host 1 (lsp == 1). */
printf("\nExtracting Telemetry Host 0 Dump (Data Area 1)...\n");
err = get_telemetry_dump(dev, opt.output_file, sn,
TELEMETRY_TYPE_HOST_0, 1, true);
if (err)
fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false),
err);
printf("\n-------------------------------------------------------------\n");
printf("\nExtracting Telemetry Host 0 Dump (Data Area 3)...\n");
err = get_telemetry_dump(dev, opt.output_file, sn,
TELEMETRY_TYPE_HOST_0, 3, false);
if (err)
fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false),
err);
printf("\n-------------------------------------------------------------\n");
printf("\nExtracting Telemetry Host 1 Dump (Data Area 1)...\n");
err = get_telemetry_dump(dev, opt.output_file, sn,
TELEMETRY_TYPE_HOST_1, 1, true);
if (err)
fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false),
err);
printf("\n-------------------------------------------------------------\n");
printf("\nExtracting Telemetry Host 1 Dump (Data Area 3)...\n");
err = get_telemetry_dump(dev, opt.output_file, sn,
TELEMETRY_TYPE_HOST_1, 3, false);
if (err)
fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false),
err);
printf("\n-------------------------------------------------------------\n");
printf("\nExtracting Telemetry Controller Dump (Data Area 3)...\n");
if (is_support_telemetry_controller == true) {
err = get_telemetry_dump(dev, opt.output_file, sn,
TELEMETRY_TYPE_CONTROLLER, 3, true);
if (err)
fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
}
printf("\n-------------------------------------------------------------\n");
break;
case TELEMETRY_TYPE_HOST_0:
case TELEMETRY_TYPE_HOST_1:
default:
@ -1585,7 +1561,6 @@ out:
/* C5 Unsupported Requirement Log Page */
#define C5_UNSUPPORTED_REQS_LEN 4096
#define C5_UNSUPPORTED_REQS_OPCODE 0xC5
static __u8 unsupported_req_guid[GUID_LEN] = {
0x2F, 0x72, 0x9C, 0x0E,
@ -1620,8 +1595,7 @@ static int get_c5_log_page(struct nvme_dev *dev, char *format)
}
memset(data, 0, sizeof(__u8) * C5_UNSUPPORTED_REQS_LEN);
ret = nvme_get_log_simple(dev_fd(dev), C5_UNSUPPORTED_REQS_OPCODE,
C5_UNSUPPORTED_REQS_LEN, data);
ret = ocp_get_log_simple(dev, OCP_LID_URLP, C5_UNSUPPORTED_REQS_LEN, data);
if (!ret) {
log_data = (struct unsupported_requirement_log *)data;
@ -1693,7 +1667,6 @@ static int ocp_unsupported_requirements_log(int argc, char **argv, struct comman
/// Error Recovery Log Page(0xC1)
#define C1_ERROR_RECOVERY_LOG_BUF_LEN 0x200
#define C1_ERROR_RECOVERY_OPCODE 0xC1
static __u8 error_recovery_guid[GUID_LEN] = {
0x44, 0xd9, 0x31, 0x21,
@ -1726,7 +1699,7 @@ static int get_c1_log_page(struct nvme_dev *dev, char *format)
}
memset(data, 0, sizeof(__u8) * C1_ERROR_RECOVERY_LOG_BUF_LEN);
ret = nvme_get_log_simple(dev_fd(dev), C1_ERROR_RECOVERY_OPCODE, C1_ERROR_RECOVERY_LOG_BUF_LEN, data);
ret = ocp_get_log_simple(dev, OCP_LID_EREC, C1_ERROR_RECOVERY_LOG_BUF_LEN, data);
if (!ret) {
log_data = (struct ocp_error_recovery_log_page *)data;
@ -1797,7 +1770,6 @@ static int ocp_error_recovery_log(int argc, char **argv, struct command *cmd, st
/// Device Capabilities (Log Identifier C4h) Requirements
#define C4_DEV_CAP_REQ_LEN 0x1000
#define C4_DEV_CAP_REQ_OPCODE 0xC4
static __u8 dev_cap_req_guid[GUID_LEN] = {
0x97, 0x42, 0x05, 0x0d,
0xd1, 0xe1, 0xc9, 0x98,
@ -1829,7 +1801,7 @@ static int get_c4_log_page(struct nvme_dev *dev, char *format)
}
memset(data, 0, sizeof(__u8) * C4_DEV_CAP_REQ_LEN);
ret = nvme_get_log_simple(dev_fd(dev), C4_DEV_CAP_REQ_OPCODE, C4_DEV_CAP_REQ_LEN, data);
ret = ocp_get_log_simple(dev, OCP_LID_DCLP, C4_DEV_CAP_REQ_LEN, data);
if (!ret) {
log_data = (struct ocp_device_capabilities_log_page *)data;
@ -1915,7 +1887,7 @@ static int ocp_set_telemetry_profile(struct nvme_dev *dev, __u8 tps)
struct nvme_set_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = 0xC8,
.fid = OCP_FID_TEL_CFG,
.nsid = 0xFFFFFFFF,
.cdw11 = tps,
.cdw12 = 0,
@ -2038,7 +2010,6 @@ static int set_dssd_power_state_feature(int argc, char **argv, struct command *c
const char *power_state = "DSSD Power State to set in watts";
const char *save = "Specifies that the controller shall save the attribute";
const __u32 nsid = 0;
const __u8 fid = 0xC7;
struct nvme_dev *dev;
int err;
@ -2065,9 +2036,8 @@ static int set_dssd_power_state_feature(int argc, char **argv, struct command *c
return err;
if (argconfig_parse_seen(opts, "power-state"))
err = set_dssd_power_state(dev, nsid, fid, cfg.power_state,
cfg.save,
!argconfig_parse_seen(opts, "no-uuid"));
err = set_dssd_power_state(dev, nsid, OCP_FID_DSSDPS, cfg.power_state, cfg.save,
!argconfig_parse_seen(opts, "no-uuid"));
dev_close(dev);
@ -2130,7 +2100,7 @@ static int get_dssd_power_state_feature(int argc, char **argv, struct command *c
const char *all = "Print out all 3 values at once - Current, Default, and Saved";
const char *sel = "[0-3]: current/default/saved/supported/";
const __u32 nsid = 0;
const __u8 fid = 0xC7;
const __u8 fid = OCP_FID_DSSDPS;
struct nvme_dev *dev;
int i, err;
@ -2188,7 +2158,6 @@ static int set_plp_health_check_interval(int argc, char **argv, struct command *
const char *plp_health_interval = "[31:16]:PLP Health Check Interval";
const char *save = "Specifies that the controller shall save the attribute";
const __u32 nsid = 0;
const __u8 fid = 0xc6;
struct nvme_dev *dev;
int err;
__u32 result;
@ -2230,7 +2199,7 @@ static int set_plp_health_check_interval(int argc, char **argv, struct command *
struct nvme_set_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = fid,
.fid = OCP_FID_PLPI,
.nsid = nsid,
.cdw11 = cfg.plp_health_interval << 16,
.cdw12 = 0,
@ -2262,7 +2231,6 @@ static int get_plp_health_check_interval(int argc, char **argv, struct command *
{
const char *desc = "Define Issue Get Feature command (FID : 0xC6) PLP Health Check Interval";
const char *sel = "[0-3,8]: current/default/saved/supported/changed";
const __u32 nsid = 0;
const __u8 fid = 0xc6;
struct nvme_dev *dev;
@ -2290,7 +2258,7 @@ static int get_plp_health_check_interval(int argc, char **argv, struct command *
struct nvme_get_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = fid,
.fid = OCP_FID_PLPI,
.nsid = nsid,
.sel = cfg.sel,
.cdw11 = 0,
@ -2328,7 +2296,6 @@ static int set_dssd_async_event_config(int argc, char **argv, struct command *cm
const char *epn = "[0]:Enable Panic Notices";
const char *save = "Specifies that the controller shall save the attribute";
const __u32 nsid = 0;
const __u8 fid = 0xc9;
struct nvme_dev *dev;
int err;
__u32 result;
@ -2364,7 +2331,7 @@ static int set_dssd_async_event_config(int argc, char **argv, struct command *cm
struct nvme_set_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = fid,
.fid = OCP_FID_DAEC,
.nsid = nsid,
.cdw11 = cfg.epn ? 1 : 0,
.cdw12 = 0,
@ -2398,7 +2365,7 @@ static int get_dssd_async_event_config(int argc, char **argv, struct command *cm
const char *desc = "Issue Get Feature command (FID : 0xC9) DSSD Async Event Config";
const char *sel = "[0-3]: current/default/saved/supported";
const __u32 nsid = 0;
const __u8 fid = 0xc9;
const __u8 fid = OCP_FID_DAEC;
struct nvme_dev *dev;
__u32 result;
int err;
@ -2469,7 +2436,11 @@ static int get_c9_log_page(struct nvme_dev *dev, char *format)
return ret;
}
ret = get_c9_log_page_data(dev, 1, 0);
if (fmt == BINARY)
ret = get_c9_log_page_data(dev, 0, 1);
else
ret = get_c9_log_page_data(dev, 0, 0);
if (!ret) {
ocp_c9_log(log_data, pC9_string_buffer, total_log_page_sz, fmt);
} else {
@ -2496,7 +2467,8 @@ static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *c
};
OPT_ARGS(opts) = {
OPT_FMT("output-format", 'o', &cfg.output_format, "output Format: normal|json"),
OPT_FMT("output-format", 'o', &cfg.output_format,
"output Format:normal|json|binary"),
OPT_END()
};
@ -2521,7 +2493,6 @@ static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *c
/* C7 TCG Configuration Log Page */
#define C7_TCG_CONFIGURATION_LEN 512
#define C7_TCG_CONFIGURATION_OPCODE 0xC7
static __u8 tcg_configuration_guid[GUID_LEN] = {
0x06, 0x40, 0x24, 0xBD,
@ -2556,8 +2527,7 @@ static int get_c7_log_page(struct nvme_dev *dev, char *format)
}
memset(data, 0, sizeof(__u8) * C7_TCG_CONFIGURATION_LEN);
ret = nvme_get_log_simple(dev_fd(dev), C7_TCG_CONFIGURATION_OPCODE,
C7_TCG_CONFIGURATION_LEN, data);
ret = ocp_get_log_simple(dev, OCP_LID_TCGL, C7_TCG_CONFIGURATION_LEN, data);
if (!ret) {
log_data = (struct tcg_configuration_log *)data;
@ -2657,7 +2627,7 @@ static int error_injection_get(struct nvme_dev *dev, const __u8 sel, bool uuid)
struct erri_get_cq_entry cq_entry;
int err;
int i;
const __u8 fid = 0xc0;
const __u8 fid = OCP_FID_ERRI;
_cleanup_free_ struct erri_entry *entry = NULL;
@ -2738,7 +2708,7 @@ static int error_injection_set(struct nvme_dev *dev, struct erri_config *cfg, bo
struct nvme_set_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = 0xc0,
.fid = OCP_FID_ERRI,
.cdw11 = cfg->number,
.data_len = cfg->number * sizeof(struct erri_entry),
.timeout = nvme_cfg.timeout,
@ -2830,7 +2800,7 @@ static int enable_ieee1667_silo_get(struct nvme_dev *dev, const __u8 sel, bool u
{
struct ieee1667_get_cq_entry cq_entry;
int err;
const __u8 fid = 0xc4;
const __u8 fid = OCP_FID_1667;
struct nvme_get_features_args args = {
.result = (__u32 *)&cq_entry,
@ -2890,6 +2860,70 @@ static int get_enable_ieee1667_silo(int argc, char **argv, struct command *cmd,
return enable_ieee1667_silo_get(dev, cfg.sel, !argconfig_parse_seen(opts, "no-uuid"));
}
static int enable_ieee1667_silo_set(struct nvme_dev *dev,
struct argconfig_commandline_options *opts)
{
struct ieee1667_get_cq_entry cq_entry;
int err;
const __u8 fid = OCP_FID_1667;
bool enable = argconfig_parse_seen(opts, "enable");
struct nvme_set_features_args args = {
.result = (__u32 *)&cq_entry,
.args_size = sizeof(args),
.fd = dev_fd(dev),
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.cdw11 = OCP_SET(enable, ENABLE_IEEE1667_SILO),
.save = argconfig_parse_seen(opts, "save"),
.fid = fid,
};
if (!argconfig_parse_seen(opts, "no-uuid")) {
/* OCP 2.0 requires UUID index support */
err = ocp_get_uuid_index(dev, &args.uuidx);
if (err || !args.uuidx) {
nvme_show_error("ERROR: No OCP UUID index found");
return err;
}
}
err = nvme_cli_set_features(dev, &args);
if (err > 0) {
nvme_show_status(err);
} else if (err < 0) {
nvme_show_perror(enable_ieee1667_silo);
fprintf(stderr, "Command failed while parsing.\n");
} else {
enable = OCP_GET(args.cdw11, ENABLE_IEEE1667_SILO);
nvme_show_result("Successfully set enable (feature: 0x%02x): %d (%s: %s).", fid,
enable, args.save ? "Save" : "Not save",
enable ? "Enabled" : "Disabled");
}
return err;
}
static int set_enable_ieee1667_silo(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
int err;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
OPT_ARGS(opts) = {
OPT_FLAG("enable", 'e', NULL, no_uuid),
OPT_FLAG("save", 's', NULL, save),
OPT_FLAG("no-uuid", 'n', NULL, no_uuid),
OPT_END()
};
err = parse_and_open(&dev, argc, argv, enable_ieee1667_silo, opts);
if (err)
return err;
return enable_ieee1667_silo_set(dev, opts);
}
static int hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
return ocp_hwcomp_log(argc, argv, cmd, plugin);

View file

@ -11,7 +11,7 @@
#if !defined(OCP_NVME) || defined(CMD_HEADER_MULTI_READ)
#define OCP_NVME
#define OCP_PLUGIN_VERSION "2.9.2"
#define OCP_PLUGIN_VERSION "2.11.0"
#include "cmd.h"
PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),
@ -40,6 +40,7 @@ PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),
ENTRY("set-error-injection", "Inject error conditions", set_error_injection)
ENTRY("get-enable-ieee1667-silo", "return set of enable IEEE1667 silo",
get_enable_ieee1667_silo)
ENTRY("set-enable-ieee1667-silo", "enable IEEE1667 silo", set_enable_ieee1667_silo)
ENTRY("hardware-component-log", "retrieve hardware component log", hwcomp_log)
)
);
@ -50,6 +51,8 @@ PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),
#ifndef OCP_NVME_H
#define OCP_NVME_H
#include "common.h"
struct __packed ssd_latency_monitor_log {
__u8 feature_status; /* 0x00 */
__u8 rsvd1; /* 0x01 */
@ -73,8 +76,9 @@ struct __packed ssd_latency_monitor_log {
__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 */
__u8 rsvd4[0x0A]; /* 0x1AA */
__u8 latency_monitor_debug_log_size[0x0C]; /* 0x1B4 */
__le16 debug_log_trigger_enable; /* 0x1C0 */
__le16 debug_log_measured_latency; /* 0x1C2 */
__le64 debug_log_latency_stamp; /* 0x1C4 */
@ -195,7 +199,7 @@ struct __packed ocp_device_capabilities_log_page {
/*
* struct tcg_configuration_log - TCG Configuration Log Page Structure
* @state: state
* @rsvd1: Reserved1
* @rsvd1: Reserved
* @locking_sp_act_count: Locking SP Activation Count
* @type_rev_count: Tper Revert Count
* @locking_sp_rev_count: Locking SP Revert Count.
@ -207,13 +211,14 @@ struct __packed ocp_device_capabilities_log_page {
* @no_of_write_lock_locking_obj: Number of Write Locked Locking Objects
* @no_of_read_unlock_locking_obj: Number of Read Unlocked Locking Objects
* @no_of_read_unlock_locking_obj: Number of Write Unlocked Locking Objects
* @rsvd2: Reserved2
* @rsvd15: Reserved
* @sid_auth_try_count: SID Authentication Try Count
* @sid_auth_try_limit: SID Authentication Try Limit
* @pro_tcg_rc: Programmatic TCG Reset Count
* @pro_rlc: Programmatic Reset Lock Count
* @tcg_ec: TCG Error Count
* @rsvd3: Reserved3
* @no_of_ns_prov_locking_obj_ext: Number of Namespace Provisioned Locking Objects Extended
* @rsvd38: Reserved
* @log_page_version: Log Page Version
*/
struct __packed tcg_configuration_log {
@ -230,15 +235,43 @@ struct __packed tcg_configuration_log {
__u8 no_of_write_lock_locking_obj;
__u8 no_of_read_unlock_locking_obj;
__u8 no_of_write_unlock_locking_obj;
__u8 rsvd2;
__u8 rsvd15;
__le32 sid_auth_try_count;
__le32 sid_auth_try_limit;
__le32 pro_tcg_rc;
__le32 pro_rlc;
__le32 tcg_ec;
__u8 rsvd3[458];
__le16 no_of_ns_prov_locking_obj_ext;
__u8 rsvd38[456];
__le16 log_page_version;
__u8 log_page_guid[GUID_LEN];
};
enum ocp_dssd_log_id {
OCP_LID_SMART = 0xc0, /* SMART / Helth Information Extended */
OCP_LID_EREC, /* Error Recovery */
OCP_LID_FAHL_OBSOLETE, /* Firmware Activation History (Obsolete) */
OCP_LID_LMLOG, /* Latency Monitor */
OCP_LID_DCLP, /* Device Capabilities */
OCP_LID_URLP, /* Unsupported Requirements */
OCP_LID_HWCOMP, /* Hardware Component */
OCP_LID_TCGL, /* TCG Configuration */
OCP_LID_RESERVED, /* Reserved for future use */
OCP_LID_TELSLG, /* Telemetry String */
OCP_LID_LMLOG_DEBUG, /* Latency Monitor Debug Telemetry */
};
enum ocp_dssd_feature_id {
OCP_FID_ERRI = 0xc0, /* Error Injection */
OCP_FID_CFUH, /* Clear Firmware Update History (Obsolete) */
OCP_FID_ROWTM, /* EOL/PLP Failure Mode */
OCP_FID_CPCIE, /* Clear PCIe Correctable Error Counters */
OCP_FID_1667, /* Enable IEEE1667 Silo */
OCP_FID_LM, /* Latency Monitor */
OCP_FID_PLPI, /* PLP Health Check Interval */
OCP_FID_DSSDPS, /* DSSD Power State */
OCP_FID_TEL_CFG, /* Telemetry Profile */
OCP_FID_DAEC, /* DSSD Asynchronous Event Configuration */
};
#endif /* OCP_NVME_H */

View file

@ -7,9 +7,12 @@
static void binary_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list)
{
long double desc_len = uint128_t_to_double(le128_to_cpu(log->size)) * sizeof(__le32);
long double log_bytes = uint128_t_to_double(le128_to_cpu(log->size));
d_raw((unsigned char *)log, offsetof(struct hwcomp_log, desc) + desc_len);
if (log->ver == 1)
log_bytes *= sizeof(__le32);
d_raw((unsigned char *)log, log_bytes);
}
static void binary_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data)

View file

@ -11,15 +11,16 @@
static void print_hwcomp_desc_json(struct hwcomp_desc_entry *e, struct json_object *r)
{
obj_add_str(r, "Description", hwcomp_id_to_string(le32_to_cpu(e->desc->id)));
obj_add_nprix64(r, "Date/Lot Size", e->date_lot_size);
obj_add_nprix64(r, "Additional Information Size", e->add_info_size);
obj_add_uint_0nx(r, "Identifier", le32_to_cpu(e->desc->id), 8);
obj_add_0nprix64(r, "Manufacture", le64_to_cpu(e->desc->mfg), 16);
obj_add_0nprix64(r, "Revision", le64_to_cpu(e->desc->rev), 16);
obj_add_0nprix64(r, "Manufacture Code", le64_to_cpu(e->desc->mfg_code), 16);
obj_add_byte_array(r, "Date/Lot Code", e->date_lot_code, e->date_lot_size);
obj_add_byte_array(r, "Additional Information", e->add_info, e->add_info_size);
json_object_add_value_string(r, "Description",
hwcomp_id_to_string(le32_to_cpu(e->desc->id)));
json_object_add_nprix64(r, "Date/Lot Size", e->date_lot_size);
json_object_add_nprix64(r, "Additional Information Size", e->add_info_size);
json_object_add_uint_0nx(r, "Identifier", le32_to_cpu(e->desc->id), 8);
json_object_add_0nprix64(r, "Manufacture", le64_to_cpu(e->desc->mfg), 16);
json_object_add_0nprix64(r, "Revision", le64_to_cpu(e->desc->rev), 16);
json_object_add_0nprix64(r, "Manufacture Code", le64_to_cpu(e->desc->mfg_code), 16);
json_object_add_byte_array(r, "Date/Lot Code", e->date_lot_code, e->date_lot_size);
json_object_add_byte_array(r, "Additional Information", e->add_info, e->add_info_size);
}
static void print_hwcomp_desc_list_json(struct json_object *r, struct hwcomp_desc_entry *e,
@ -31,7 +32,8 @@ static void print_hwcomp_desc_list_json(struct json_object *r, struct hwcomp_des
return;
if (list) {
obj_add_str(r, k, hwcomp_id_to_string(le32_to_cpu(e->desc->id)));
json_object_add_value_string(r, k,
hwcomp_id_to_string(le32_to_cpu(e->desc->id)));
return;
}
@ -63,17 +65,19 @@ static void print_hwcomp_descs_json(struct hwcomp_desc *desc, long double log_si
static void json_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list)
{
long double log_bytes = uint128_t_to_double(le128_to_cpu(log->size));
struct json_object *r = json_create_object();
long double log_size = uint128_t_to_double(le128_to_cpu(log->size)) * sizeof(__le32);
if (log->ver == 1)
log_bytes *= sizeof(__le32);
obj_add_uint_02x(r, "Log Identifier", LID_HWCOMP);
obj_add_uint_0x(r, "Log Page Version", le16_to_cpu(log->ver));
obj_add_byte_array(r, "Reserved2", log->rsvd2, ARRAY_SIZE(log->rsvd2));
obj_add_byte_array(r, "Log page GUID", log->guid, ARRAY_SIZE(log->guid));
obj_add_nprix64(r, "Hardware Component Log Size", (unsigned long long)log_size);
obj_add_byte_array(r, "Reserved48", log->rsvd48, ARRAY_SIZE(log->rsvd48));
print_hwcomp_descs_json(log->desc, log_size, id, list,
json_object_add_uint_02x(r, "Log Identifier", OCP_LID_HWCOMP);
json_object_add_uint_0x(r, "Log Page Version", le16_to_cpu(log->ver));
json_object_add_byte_array(r, "Reserved2", log->rsvd2, ARRAY_SIZE(log->rsvd2));
json_object_add_byte_array(r, "Log page GUID", log->guid, ARRAY_SIZE(log->guid));
json_object_add_nprix64(r, "Hardware Component Log Size", (unsigned long long)log_bytes);
json_object_add_byte_array(r, "Reserved48", log->rsvd48, ARRAY_SIZE(log->rsvd48));
print_hwcomp_descs_json(log->desc, log_bytes - offsetof(struct hwcomp_log, desc), id, list,
obj_create_array_obj(r, "Component Descriptions"));
json_print(r);
@ -97,7 +101,7 @@ static void json_fw_activation_history(const struct fw_activation_history *fw_hi
json_object_add_value_uint(entry_obj, "activation count",
le16_to_cpu(entry->activation_count));
json_object_add_value_uint64(entry_obj, "timestamp",
(0x0000FFFFFFFFFFFF & le64_to_cpu(entry->timestamp)));
int48_to_long(entry->ts.timestamp));
json_object_add_value_uint(entry_obj, "power cycle count",
le64_to_cpu(entry->power_cycle_count));
@ -134,85 +138,88 @@ static void json_fw_activation_history(const struct fw_activation_history *fw_hi
printf("\n");
}
static void json_smart_extended_log(void *data)
static void json_smart_extended_log_v1(struct ocp_smart_extended_log *log)
{
struct json_object *root;
struct json_object *pmuw;
struct json_object *pmur;
uint16_t smart_log_ver = 0;
__u8 *log_data = data;
uint16_t dssd_version = 0;
int i = 0;
char guid[40];
char ascii_arr[65];
char *ascii = ascii_arr;
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));
le64_to_cpu(*(uint64_t *)&log->physical_media_units_written[8]));
json_object_add_value_uint64(pmuw, "lo",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
le64_to_cpu(*(uint64_t *)&log->physical_media_units_written));
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));
le64_to_cpu(*(uint64_t *)&log->physical_media_units_read[8]));
json_object_add_value_uint64(pmur, "lo",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
le64_to_cpu(*(uint64_t *)&log->physical_media_units_read));
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));
int48_to_long(log->bad_user_nand_blocks_raw));
json_object_add_value_uint(root, "Bad user nand blocks - Normalized",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
le16_to_cpu(log->bad_user_nand_blocks_normalized));
json_object_add_value_uint64(root, "Bad system nand blocks - Raw",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
int48_to_long(log->bad_system_nand_blocks_raw));
json_object_add_value_uint(root, "Bad system nand blocks - Normalized",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
le16_to_cpu(log->bad_system_nand_blocks_normalized));
json_object_add_value_uint64(root, "XOR recovery count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
le64_to_cpu(log->xor_recovery_count));
json_object_add_value_uint64(root, "Uncorrectable read error count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
le64_to_cpu(log->uncorrectable_read_err_count));
json_object_add_value_uint64(root, "Soft ecc error count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
le64_to_cpu(log->soft_ecc_err_count));
json_object_add_value_uint(root, "End to end detected errors",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
le32_to_cpu(log->end_to_end_detected_err));
json_object_add_value_uint(root, "End to end corrected errors",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
le32_to_cpu(log->end_to_end_corrected_err));
json_object_add_value_uint(root, "System data percent used",
(__u8)log_data[SCAO_SDPU]);
log->system_data_used_percent);
json_object_add_value_uint64(root, "Refresh counts",
(uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
int56_to_long(log->refresh_counts));
json_object_add_value_uint(root, "Max User data erase counts",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
le32_to_cpu(log->user_data_erase_count_max));
json_object_add_value_uint(root, "Min User data erase counts",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
le32_to_cpu(log->user_data_erase_count_min));
json_object_add_value_uint(root, "Number of Thermal throttling events",
(__u8)log_data[SCAO_NTTE]);
log->thermal_throttling_event_count);
json_object_add_value_uint(root, "Current throttling status",
(__u8)log_data[SCAO_CTS]);
log->thermal_throttling_current_status);
json_object_add_value_uint64(root, "PCIe correctable error count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
le64_to_cpu(log->pcie_correctable_err_count));
json_object_add_value_uint(root, "Incomplete shutdowns",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
le32_to_cpu(log->incomplete_shoutdowns));
json_object_add_value_uint(root, "Percent free blocks",
(__u8)log_data[SCAO_PFB]);
log->percent_free_blocks);
json_object_add_value_uint(root, "Capacitor health",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
le16_to_cpu(log->capacitor_health));
json_object_add_value_uint64(root, "Unaligned I/O",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
le64_to_cpu(log->unaligned_io));
json_object_add_value_uint64(root, "Security Version Number",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
le64_to_cpu(log->security_version));
json_object_add_value_uint64(root, "NUSE - Namespace utilization",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
le64_to_cpu(log->total_nuse));
json_object_add_value_uint128(root, "PLP start count",
le128_to_cpu(&log_data[SCAO_PSC]));
le128_to_cpu(log->plp_start_count));
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]);
le128_to_cpu(log->endurance_estimate));
smart_log_ver = le16_to_cpu(log->log_page_version);
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]));
le64_to_cpu(*(uint64_t *)&log->log_page_guid[8]),
le64_to_cpu(*(uint64_t *)&log->log_page_guid));
json_object_add_value_string(root, "Log page GUID", guid);
switch (smart_log_ver) {
@ -221,31 +228,251 @@ static void json_smart_extended_log(void *data)
default:
case 4:
json_object_add_value_uint(root, "NVMe Command Set Errata Version",
(__u8)log_data[SCAO_NCSEV]);
log->nvme_cmdset_errata_version);
json_object_add_value_uint(root, "Lowest Permitted Firmware Revision",
le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
le64_to_cpu(log->lowest_permitted_fw_rev));
json_object_add_value_uint(root, "NVMe Over Pcie Errata Version",
log->nvme_over_pcie_errate_version);
json_object_add_value_uint(root, "NVMe Mi Errata Version",
log->nvme_mi_errata_version);
json_object_add_value_uint(root, "Total media dies",
le16_to_cpu(log->total_media_dies));
json_object_add_value_uint(root, "Total die failure tolerance",
le16_to_cpu(log->total_die_failure_tolerance));
json_object_add_value_uint(root, "Media dies offline",
le16_to_cpu(log->media_dies_offline));
json_object_add_value_uint(root, "Max temperature recorded",
log->max_temperature_recorded);
json_object_add_value_uint64(root, "Nand avg erase count",
le64_to_cpu(log->nand_avg_erase_count));
json_object_add_value_uint(root, "Command timeouts",
le32_to_cpu(log->command_timeouts));
json_object_add_value_uint(root, "Sys area program fail count raw",
le32_to_cpu(log->sys_area_program_fail_count_raw));
json_object_add_value_uint(root, "Sys area program fail count noralized",
log->sys_area_program_fail_count_normalized);
json_object_add_value_uint(root, "Sys area uncorrectable read count raw",
le32_to_cpu(log->sys_area_uncorr_read_count_raw));
json_object_add_value_uint(root, "Sys area uncorrectable read count noralized",
log->sys_area_uncorr_read_count_normalized);
json_object_add_value_uint(root, "Sys area erase fail count raw",
le32_to_cpu(log->sys_area_erase_fail_count_raw));
json_object_add_value_uint(root, "Sys area erase fail count noralized",
log->sys_area_erase_fail_count_normalized);
json_object_add_value_uint(root, "Max peak power capability",
le16_to_cpu(log->max_peak_power_capability));
json_object_add_value_uint(root, "Current max avg power",
le16_to_cpu(log->current_max_avg_power));
json_object_add_value_uint64(root, "Lifetime power consumed",
int48_to_long(log->lifetime_power_consumed));
memset((void *)ascii, 0, 65);
for (i = 0; i < 8; i++)
ascii += sprintf(ascii, "%c", log->dssd_firmware_revision[i]);
json_object_add_value_string(root, "Dssd firmware revision", ascii_arr);
json_object_add_value_string(root, "Dssd firmware build UUID",
util_uuid_to_string(log->dssd_firmware_build_uuid));
ascii = ascii_arr;
memset((void *)ascii, 0, 65);
for (i = 0; i < 64; i++)
ascii += sprintf(ascii, "%c", log->dssd_firmware_build_label[i]);
json_object_add_value_string(root, "Dssd firmware build label", ascii_arr);
fallthrough;
case 2 ... 3:
json_object_add_value_uint(root, "Errata Version Field",
(__u8)log_data[SCAO_EVF]);
log->dssd_errata_version);
memcpy(&dssd_version, log->dssd_point_version, sizeof(dssd_version));
json_object_add_value_uint(root, "Point Version Field",
le16_to_cpu(*(uint16_t *)&log_data[SCAO_PVF]));
le16_to_cpu(dssd_version));
memcpy(&dssd_version, log->dssd_minor_version, sizeof(dssd_version));
json_object_add_value_uint(root, "Minor Version Field",
le16_to_cpu(*(uint16_t *)&log_data[SCAO_MIVF]));
le16_to_cpu(dssd_version));
json_object_add_value_uint(root, "Major Version Field",
(__u8)log_data[SCAO_MAVF]);
log->dssd_major_version);
json_object_add_value_uint(root, "NVMe Base Errata Version",
(__u8)log_data[SCAO_NBEV]);
log->nvme_base_errata_version);
json_object_add_value_uint(root, "PCIe Link Retraining Count",
le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
le64_to_cpu(log->pcie_link_retaining_count));
json_object_add_value_uint(root, "Power State Change Count",
le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
le64_to_cpu(log->power_state_change_count));
}
json_print_object(root, NULL);
printf("\n");
json_free_object(root);
}
static void json_smart_extended_log_v2(struct ocp_smart_extended_log *log)
{
struct json_object *root;
struct json_object *pmuw;
struct json_object *pmur;
int i = 0;
uint16_t smart_log_ver = 0;
uint16_t dssd_version = 0;
char guid[40];
char ascii_arr[65];
char *ascii = ascii_arr;
root = json_create_object();
pmuw = json_create_object();
pmur = json_create_object();
json_object_add_value_uint64(pmuw, "hi",
le64_to_cpu(*(uint64_t *)&log->physical_media_units_written[8]));
json_object_add_value_uint64(pmuw, "lo",
le64_to_cpu(*(uint64_t *)&log->physical_media_units_written));
json_object_add_value_object(root, "physical_media_units_written", pmuw);
json_object_add_value_uint64(pmur, "hi",
le64_to_cpu(*(uint64_t *)&log->physical_media_units_read[8]));
json_object_add_value_uint64(pmur, "lo",
le64_to_cpu(*(uint64_t *)&log->physical_media_units_read));
json_object_add_value_object(root, "physical_media_units_read", pmur);
json_object_add_value_uint64(root, "bad_user_nand_blocks_raw",
int48_to_long(log->bad_user_nand_blocks_raw));
json_object_add_value_uint(root, "bad_user_nand_blocks_normalized",
le16_to_cpu(log->bad_user_nand_blocks_normalized));
json_object_add_value_uint64(root, "bad_system_nand_blocks_raw",
int48_to_long(log->bad_system_nand_blocks_raw));
json_object_add_value_uint(root, "bad_system_nand_blocks_normalized",
le16_to_cpu(log->bad_system_nand_blocks_normalized));
json_object_add_value_uint64(root, "xor_recovery_count",
le64_to_cpu(log->xor_recovery_count));
json_object_add_value_uint64(root, "uncorrectable_read_errors",
le64_to_cpu(log->uncorrectable_read_err_count));
json_object_add_value_uint64(root, "soft_ecc_error_count",
le64_to_cpu(log->soft_ecc_err_count));
json_object_add_value_uint(root, "end_to_end_detected_errors",
le32_to_cpu(log->end_to_end_detected_err));
json_object_add_value_uint(root, "end_to_end_corrected_errors",
le32_to_cpu(log->end_to_end_corrected_err));
json_object_add_value_uint(root, "system_data_percent_used",
log->system_data_used_percent);
json_object_add_value_uint64(root, "refresh_count",
int56_to_long(log->refresh_counts));
json_object_add_value_uint(root, "max_user_data_erase_count",
le32_to_cpu(log->user_data_erase_count_max));
json_object_add_value_uint(root, "min_user_data_erase_count",
le32_to_cpu(log->user_data_erase_count_min));
json_object_add_value_uint(root, "thermal_throttling_events",
log->thermal_throttling_event_count);
json_object_add_value_uint(root, "current_throttling_status",
log->thermal_throttling_current_status);
json_object_add_value_uint64(root, "pcie_correctable_errors",
le64_to_cpu(log->pcie_correctable_err_count));
json_object_add_value_uint(root, "incomplete_shutdowns",
le32_to_cpu(log->incomplete_shoutdowns));
json_object_add_value_uint(root, "percent_free_blocks",
log->percent_free_blocks);
json_object_add_value_uint(root, "capacitor_health",
le16_to_cpu(log->capacitor_health));
json_object_add_value_uint64(root, "unaligned_io",
le64_to_cpu(log->unaligned_io));
json_object_add_value_uint64(root, "security_version_number",
le64_to_cpu(log->security_version));
json_object_add_value_uint64(root, "nuse_namespace_utilization",
le64_to_cpu(log->total_nuse));
json_object_add_value_uint128(root, "plp_start_count",
le128_to_cpu(log->plp_start_count));
json_object_add_value_uint128(root, "endurance_estimate",
le128_to_cpu(log->endurance_estimate));
smart_log_ver = le16_to_cpu(log->log_page_version);
json_object_add_value_uint(root, "log_page_version", smart_log_ver);
memset((void *)guid, 0, 40);
sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
le64_to_cpu(*(uint64_t *)&log->log_page_guid[8]),
le64_to_cpu(*(uint64_t *)&log->log_page_guid));
json_object_add_value_string(root, "log_page_guid", guid);
switch (smart_log_ver) {
case 0 ... 1:
break;
default:
case 4:
json_object_add_value_uint(root, "nvme_command_set_errata_version",
log->nvme_cmdset_errata_version);
json_object_add_value_uint(root, "lowest_permitted_firmware_revision",
le64_to_cpu(log->lowest_permitted_fw_rev));
json_object_add_value_uint(root, "nvme_over_pcie_errata_version",
log->nvme_over_pcie_errate_version);
json_object_add_value_uint(root, "nvme_mi_errata_version",
log->nvme_mi_errata_version);
json_object_add_value_uint(root, "total_media_dies",
le16_to_cpu(log->total_media_dies));
json_object_add_value_uint(root, "total_die_failure_tolerance",
le16_to_cpu(log->total_die_failure_tolerance));
json_object_add_value_uint(root, "media_dies_offline",
le16_to_cpu(log->media_dies_offline));
json_object_add_value_uint(root, "max_temperature_recorded",
log->max_temperature_recorded);
json_object_add_value_uint64(root, "nand_avg_erase_count",
le64_to_cpu(log->nand_avg_erase_count));
json_object_add_value_uint(root, "command_timeouts",
le32_to_cpu(log->command_timeouts));
json_object_add_value_uint(root, "sys_area_program_fail_count_raw",
le32_to_cpu(log->sys_area_program_fail_count_raw));
json_object_add_value_uint(root, "sys_area_program_fail_count_noralized",
log->sys_area_program_fail_count_normalized);
json_object_add_value_uint(root, "sys_area_uncorrectable_read_count_raw",
le32_to_cpu(log->sys_area_uncorr_read_count_raw));
json_object_add_value_uint(root, "sys_area_uncorrectable_read_count_noralized",
log->sys_area_uncorr_read_count_normalized);
json_object_add_value_uint(root, "sys_area_erase_fail_count_raw",
le32_to_cpu(log->sys_area_erase_fail_count_raw));
json_object_add_value_uint(root, "sys_area_erase_fail_count_noralized",
log->sys_area_erase_fail_count_normalized);
json_object_add_value_uint(root, "max_peak_power_capability",
le16_to_cpu(log->max_peak_power_capability));
json_object_add_value_uint(root, "current_max_avg_power",
le16_to_cpu(log->current_max_avg_power));
json_object_add_value_uint64(root, "lifetime_power_consumed",
int48_to_long(log->lifetime_power_consumed));
memset((void *)ascii, 0, 65);
for (i = 0; i < 8; i++)
ascii += sprintf(ascii, "%c", log->dssd_firmware_revision[i]);
json_object_add_value_string(root, "dssd_firmware_revision", ascii_arr);
json_object_add_value_string(root, "dssd_firmware_build_uuid",
util_uuid_to_string(log->dssd_firmware_build_uuid));
ascii = ascii_arr;
memset((void *)ascii, 0, 65);
for (i = 0; i < 64; i++)
ascii += sprintf(ascii, "%c", log->dssd_firmware_build_label[i]);
json_object_add_value_string(root, "dssd_firmware_build_label", ascii_arr);
fallthrough;
case 2 ... 3:
json_object_add_value_uint(root, "errata_version_field",
log->dssd_errata_version);
memcpy(&dssd_version, log->dssd_point_version, sizeof(dssd_version));
json_object_add_value_uint(root, "point_version_field",
le16_to_cpu(dssd_version));
memcpy(&dssd_version, log->dssd_minor_version, sizeof(dssd_version));
json_object_add_value_uint(root, "minor_version_field",
le16_to_cpu(dssd_version));
json_object_add_value_uint(root, "major_version_field",
log->dssd_major_version);
json_object_add_value_uint(root, "nvme_base_errata_version",
log->nvme_base_errata_version);
json_object_add_value_uint(root, "pcie_link_retraining_count",
le64_to_cpu(log->pcie_link_retaining_count));
json_object_add_value_uint(root, "power_state_change_count",
le64_to_cpu(log->power_state_change_count));
}
json_print_object(root, NULL);
printf("\n");
json_free_object(root);
}
static void json_smart_extended_log(struct ocp_smart_extended_log *log, unsigned int version)
{
switch (version) {
default:
case 1:
json_smart_extended_log_v1(log);
break;
case 2:
json_smart_extended_log_v2(log);
}
}
static void json_telemetry_log(struct ocp_telemetry_parse_options *options)
{
print_ocp_telemetry_json(options);
@ -258,6 +485,7 @@ static void json_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *lo
char buf[128];
int i, j;
char *operation[3] = {"Trim", "Write", "Read"};
__u16 log_page_version = le16_to_cpu(log_data->log_page_version);
root = json_create_object();
@ -374,6 +602,21 @@ static void json_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *lo
json_object_add_value_uint(root, "Static Latency Stamp Units",
le16_to_cpu(log_data->static_latency_stamp_units));
if (log_page_version >= 0x4) {
strcpy(buf, "0x");
for (i = ARRAY_SIZE(log_data->latency_monitor_debug_log_size) - 1;
i > 0 && (log_data->latency_monitor_debug_log_size[i] == 0); i--)
;
while (i >= 0) {
char hex_string[3];
sprintf(hex_string, "%02x", log_data->latency_monitor_debug_log_size[i--]);
strcat(buf, hex_string);
}
json_object_add_value_string(root, "Debug Telemetry Log Size", buf);
}
json_object_add_value_uint(root, "Debug Log Trigger Enable",
le16_to_cpu(log_data->debug_log_trigger_enable));
json_object_add_value_uint(root, "Debug Log Measured Latency",
@ -390,8 +633,7 @@ static void json_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *lo
le16_to_cpu(log_data->debug_log_counter_trigger));
json_object_add_value_uint(root, "Debug Log Stamp Units",
le16_to_cpu(log_data->debug_log_stamp_units));
json_object_add_value_uint(root, "Log Page Version",
le16_to_cpu(log_data->log_page_version));
json_object_add_value_uint(root, "Log Page Version", log_page_version);
char guid[(GUID_LEN * 2) + 1];
char *ptr = &guid[0];
@ -552,7 +794,7 @@ static void json_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_dat
json_object_add_value_int(root, "Log Page Version",
le16_to_cpu(log_data->log_page_version));
memset((__u8 *)res, 0, 15);
memset((__u8 *)res, 0, 48);
for (j = 0; j < 15; j++)
res += sprintf(res, "%d", log_data->reserved1[j]);
json_object_add_value_string(root, "Reserved", res_arr);
@ -564,7 +806,8 @@ static void json_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_dat
json_object_add_value_int(root, "Telemetry String Log Size", le64_to_cpu(log_data->sls));
memset((__u8 *)res, 0, 24);
res = res_arr;
memset((__u8 *)res, 0, 48);
for (j = 0; j < 24; j++)
res += sprintf(res, "%d", log_data->reserved2[j]);
json_object_add_value_string(root, "Reserved", res_arr);
@ -587,81 +830,97 @@ static void json_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_dat
fifo += sprintf(fifo, "%c", log_data->fifo1[j]);
json_object_add_value_string(root, "FIFO 1 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo2[j]);
json_object_add_value_string(root, "FIFO 2 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo3[j]);
json_object_add_value_string(root, "FIFO 3 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo4[j]);
json_object_add_value_string(root, "FIFO 4 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo5[j]);
json_object_add_value_string(root, "FIFO 5 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo6[j]);
json_object_add_value_string(root, "FIFO 6 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo7[j]);
json_object_add_value_string(root, "FIFO 7 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo8[j]);
json_object_add_value_string(root, "FIFO 8 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo9[j]);
json_object_add_value_string(root, "FIFO 9 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo10[j]);
json_object_add_value_string(root, "FIFO 10 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo11[j]);
json_object_add_value_string(root, "FIFO 11 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo12[j]);
json_object_add_value_string(root, "FIFO 12 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo13[j]);
json_object_add_value_string(root, "FIFO 13 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo14[j]);
json_object_add_value_string(root, "FIFO 14 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo15[j]);
json_object_add_value_string(root, "FIFO 15 ASCII String", fifo_arr);
fifo = fifo_arr;
memset((void *)fifo, 0, 16);
for (j = 0; j < 16; j++)
fifo += sprintf(fifo, "%c", log_data->fifo16[j]);
json_object_add_value_string(root, "FIFO 16 ASCII String", fifo_arr);
res = res_arr;
memset((__u8 *)res, 0, 48);
for (j = 0; j < 48; j++)
res += sprintf(res, "%d", log_data->reserved3[j]);
@ -772,6 +1031,7 @@ static void json_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_
char *guid = guid_buf;
char res_arr[458];
char *res = res_arr;
__u16 log_page_version = le16_to_cpu(log_data->log_page_version);
root = json_create_object();
@ -800,7 +1060,7 @@ static void json_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_
log_data->no_of_read_unlock_locking_obj);
json_object_add_value_int(root, "Number of Write Unlocked Locking Objects",
log_data->no_of_write_unlock_locking_obj);
json_object_add_value_int(root, "Reserved2", log_data->rsvd2);
json_object_add_value_int(root, "Reserved2", log_data->rsvd15);
json_object_add_value_int(root, "SID Authentication Try Count",
le32_to_cpu(log_data->sid_auth_try_count));
@ -813,12 +1073,20 @@ static void json_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_
json_object_add_value_int(root, "TCG Error Count", le32_to_cpu(log_data->tcg_ec));
memset((__u8 *)res, 0, 458);
for (j = 0; j < 458; j++)
res += sprintf(res, "%d", log_data->rsvd3[j]);
if (log_page_version == 1) {
res += sprintf(res, "%d%d", *(__u8 *)&log_data->no_of_ns_prov_locking_obj_ext,
*((__u8 *)&log_data->no_of_ns_prov_locking_obj_ext + 1));
} else {
json_object_add_value_int(root,
"Number of Namespace Provisioned Locking Objects Extended",
log_data->no_of_ns_prov_locking_obj_ext);
}
for (j = 0; j < 456; j++)
res += sprintf(res, "%d", log_data->rsvd38[j]);
json_object_add_value_string(root, "Reserved3", res_arr);
json_object_add_value_int(root, "Log Page Version",
le16_to_cpu(log_data->log_page_version));
json_object_add_value_int(root, "Log Page Version", log_page_version);
memset((void *)guid, 0, GUID_LEN);
for (j = GUID_LEN - 1; j >= 0; j--)

View file

@ -30,18 +30,21 @@ static void stdout_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list)
{
size_t date_lot_code_offset = sizeof(struct hwcomp_desc);
int num = 1;
long double log_bytes = uint128_t_to_double(le128_to_cpu(log->size));
struct hwcomp_desc_entry e = { log->desc };
long double log_size = uint128_t_to_double(le128_to_cpu(log->size)) * sizeof(__le32);
if (log->ver == 1)
log_bytes *= sizeof(__le32);
printf("Log Identifier: 0x%02xh\n", LID_HWCOMP);
printf("Log Identifier: 0x%02xh\n", OCP_LID_HWCOMP);
printf("Log Page Version: 0x%x\n", le16_to_cpu(log->ver));
print_array("Reserved2", log->rsvd2, ARRAY_SIZE(log->rsvd2));
print_array("Log page GUID", log->guid, ARRAY_SIZE(log->guid));
printf("Hardware Component Log Size: 0x%"PRIx64"\n", (uint64_t)log_size);
printf("Hardware Component Log Size: 0x%"PRIx64"\n", (uint64_t)log_bytes);
print_array("Reserved48", log->rsvd48, ARRAY_SIZE(log->rsvd48));
printf("Component Descriptions\n");
while (log_size > 0) {
log_bytes -= offsetof(struct hwcomp_log, desc);
while (log_bytes > 0) {
e.date_lot_size = le64_to_cpu(e.desc->date_lot_size) * sizeof(__le32);
e.date_lot_code = e.date_lot_size ? (__u8 *)e.desc + date_lot_code_offset : NULL;
e.add_info_size = le64_to_cpu(e.desc->add_info_size) * sizeof(__le32);
@ -51,7 +54,7 @@ static void stdout_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list)
print_hwcomp_desc(&e, list, num++);
e.desc_size = date_lot_code_offset + e.date_lot_size + e.add_info_size;
e.desc = (struct hwcomp_desc *)((__u8 *)e.desc + e.desc_size);
log_size -= e.desc_size;
log_bytes -= e.desc_size;
}
}
@ -72,8 +75,7 @@ static void stdout_fw_activation_history(const struct fw_activation_history *fw_
printf(" %-22s%d\n", "entry length:", entry->entry_length);
printf(" %-22s%d\n", "activation count:",
le16_to_cpu(entry->activation_count));
printf(" %-22s%"PRIu64"\n", "timestamp:",
(0x0000FFFFFFFFFFFF & le64_to_cpu(entry->timestamp)));
printf(" %-22s%"PRIu64"\n", "timestamp:", int48_to_long(entry->ts.timestamp));
printf(" %-22s%"PRIu64"\n", "power cycle count:",
le64_to_cpu(entry->power_cycle_count));
printf(" %-22s%.*s\n", "previous firmware:", (int)sizeof(entry->previous_fw),
@ -95,101 +97,144 @@ static void stdout_fw_activation_history(const struct fw_activation_history *fw_
printf("\n");
}
static void stdout_smart_extended_log(void *data)
static void stdout_smart_extended_log(struct ocp_smart_extended_log *log, unsigned int version)
{
uint16_t smart_log_ver = 0;
__u8 *log_data = data;
uint16_t dssd_version = 0;
int i = 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));
le64_to_cpu(*(uint64_t *)&log->physical_media_units_written[8]),
le64_to_cpu(*(uint64_t *)&log->physical_media_units_written));
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));
le64_to_cpu(*(uint64_t *)&log->physical_media_units_read[8]),
le64_to_cpu(*(uint64_t *)&log->physical_media_units_read));
printf(" Bad user nand blocks - Raw %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
int48_to_long(log->bad_user_nand_blocks_raw));
printf(" Bad user nand blocks - Normalized %d\n",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
le16_to_cpu(log->bad_user_nand_blocks_normalized));
printf(" Bad system nand blocks - Raw %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
int48_to_long(log->bad_system_nand_blocks_raw));
printf(" Bad system nand blocks - Normalized %d\n",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
le16_to_cpu(log->bad_system_nand_blocks_normalized));
printf(" XOR recovery count %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
le64_to_cpu(log->xor_recovery_count));
printf(" Uncorrectable read error count %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
le64_to_cpu(log->uncorrectable_read_err_count));
printf(" Soft ecc error count %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
le64_to_cpu(log->soft_ecc_err_count));
printf(" End to end detected errors %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
le32_to_cpu(log->end_to_end_detected_err));
printf(" End to end corrected errors %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
le32_to_cpu(log->end_to_end_corrected_err));
printf(" System data percent used %d\n",
(__u8)log_data[SCAO_SDPU]);
log->system_data_used_percent);
printf(" Refresh counts %"PRIu64"\n",
(uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
int56_to_long(log->refresh_counts));
printf(" Max User data erase counts %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
le32_to_cpu(log->user_data_erase_count_max));
printf(" Min User data erase counts %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
le32_to_cpu(log->user_data_erase_count_min));
printf(" Number of Thermal throttling events %d\n",
(__u8)log_data[SCAO_NTTE]);
log->thermal_throttling_event_count);
printf(" Current throttling status 0x%x\n",
(__u8)log_data[SCAO_CTS]);
log->thermal_throttling_current_status);
printf(" PCIe correctable error count %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
le64_to_cpu(log->pcie_correctable_err_count));
printf(" Incomplete shutdowns %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
le32_to_cpu(log->incomplete_shoutdowns));
printf(" Percent free blocks %d\n",
(__u8)log_data[SCAO_PFB]);
log->percent_free_blocks);
printf(" Capacitor health %"PRIu16"\n",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
printf(" NVMe base errata version %c\n",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
printf(" NVMe command set errata version %c\n",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
le16_to_cpu(log->capacitor_health));
printf(" Unaligned I/O %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
le64_to_cpu(log->unaligned_io));
printf(" Security Version Number %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
le64_to_cpu(log->security_version));
printf(" NUSE - Namespace utilization %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
le64_to_cpu(log->total_nuse));
printf(" PLP start count %s\n",
uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC])));
uint128_t_to_string(le128_to_cpu(log->plp_start_count)));
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]);
uint128_t_to_string(le128_to_cpu(log->endurance_estimate)));
smart_log_ver = le16_to_cpu(log->log_page_version);
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]));
printf("%"PRIx64"%"PRIx64"\n", le64_to_cpu(*(uint64_t *)&log->log_page_guid[8]),
le64_to_cpu(*(uint64_t *)&log->log_page_guid));
switch (smart_log_ver) {
case 0 ... 1:
break;
default:
case 4:
printf(" NVMe Command Set Errata Version %d\n",
(__u8)log_data[SCAO_NCSEV]);
log->nvme_cmdset_errata_version);
printf(" Lowest Permitted Firmware Revision %"PRIu64"\n",
le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
le64_to_cpu(log->lowest_permitted_fw_rev));
printf(" NVMe Over Pcie Errata Version %d\n",
log->nvme_over_pcie_errate_version);
printf(" NVMe Mi Errata Version %d\n",
log->nvme_mi_errata_version);
printf(" Total media dies %"PRIu16"\n",
le16_to_cpu(log->total_media_dies));
printf(" Total die failure tolerance %"PRIu16"\n",
le16_to_cpu(log->total_die_failure_tolerance));
printf(" Media dies offline %"PRIu16"\n",
le16_to_cpu(log->media_dies_offline));
printf(" Max temperature recorded %d\n",
log->max_temperature_recorded);
printf(" Nand avg erase count %"PRIu64"\n",
le64_to_cpu(log->nand_avg_erase_count));
printf(" Command timeouts %"PRIu32"\n",
le32_to_cpu(log->command_timeouts));
printf(" Sys area program fail count raw %"PRIu32"\n",
le32_to_cpu(log->sys_area_program_fail_count_raw));
printf(" Sys area program fail count noralized %d\n",
le32_to_cpu(log->sys_area_program_fail_count_normalized));
printf(" Sys area uncorrectable read count raw %"PRIu32"\n",
le32_to_cpu(log->sys_area_uncorr_read_count_raw));
printf(" Sys area uncorrectable read count noralized %d\n",
le32_to_cpu(log->sys_area_uncorr_read_count_normalized));
printf(" Sys area erase fail count raw %"PRIu32"\n",
le32_to_cpu(log->sys_area_erase_fail_count_raw));
printf(" Sys area erase fail count noralized %d\n",
le32_to_cpu(log->sys_area_erase_fail_count_normalized));
printf(" Max peak power capability %"PRIu16"\n",
le16_to_cpu(log->max_peak_power_capability));
printf(" Current max avg power %"PRIu16"\n",
le16_to_cpu(log->current_max_avg_power));
printf(" Lifetime power consumed %"PRIu64"\n",
int48_to_long(log->lifetime_power_consumed));
printf(" Dssd firmware revision ");
for (i = 0; i < sizeof(log->dssd_firmware_revision); i++)
printf("%c", log->dssd_firmware_revision[i]);
printf("\n");
printf(" Dssd firmware build UUID %s\n",
util_uuid_to_string(log->dssd_firmware_build_uuid));
printf(" Dssd firmware build label ");
for (i = 0; i < sizeof(log->dssd_firmware_build_label); i++)
printf("%c", log->dssd_firmware_build_label[i]);
printf("\n");
fallthrough;
case 2 ... 3:
printf(" Errata Version Field %d\n",
(__u8)log_data[SCAO_EVF]);
log->dssd_errata_version);
memcpy(&dssd_version, log->dssd_point_version, sizeof(dssd_version));
printf(" Point Version Field %"PRIu16"\n",
le16_to_cpu(*(uint16_t *)&log_data[SCAO_PVF]));
le16_to_cpu(dssd_version));
memcpy(&dssd_version, log->dssd_minor_version, sizeof(dssd_version));
printf(" Minor Version Field %"PRIu16"\n",
le16_to_cpu(*(uint16_t *)&log_data[SCAO_MIVF]));
le16_to_cpu(dssd_version));
printf(" Major Version Field %d\n",
(__u8)log_data[SCAO_MAVF]);
log->dssd_major_version);
printf(" NVMe Base Errata Version %d\n",
(__u8)log_data[SCAO_NBEV]);
log->nvme_base_errata_version);
printf(" PCIe Link Retraining Count %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
le64_to_cpu(log->pcie_link_retaining_count));
printf(" Power State Change Count %"PRIu64"\n",
le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
le64_to_cpu(log->power_state_change_count));
}
printf("\n");
}
@ -205,6 +250,7 @@ static void stdout_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *
{
char ts_buf[128];
int i, j;
__u16 log_page_version = le16_to_cpu(log_data->log_page_version);
printf("-Latency Monitor/C3 Log Page Data-\n");
printf(" Controller : %s\n", dev->name);
@ -237,6 +283,17 @@ static void stdout_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *
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));
if (log_page_version >= 0x4) {
printf(" Debug Telemetry Log Size 0x");
for (i = ARRAY_SIZE(log_data->latency_monitor_debug_log_size) - 1;
i > 0 && (log_data->latency_monitor_debug_log_size[i] == 0); i--)
;
while (i >= 0)
printf("%02x", log_data->latency_monitor_debug_log_size[i--]);
printf("\n");
}
printf(" Debug Log Trigger Enable %d\n",
le16_to_cpu(log_data->debug_log_trigger_enable));
printf(" Debug Log Measured Latency %d\n",
@ -253,8 +310,7 @@ static void stdout_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *
le16_to_cpu(log_data->debug_log_counter_trigger));
printf(" Debug Log Stamp Units %d\n",
le16_to_cpu(log_data->debug_log_stamp_units));
printf(" Log Page Version %d\n",
le16_to_cpu(log_data->log_page_version));
printf(" Log Page Version %d\n", log_page_version);
char guid[(GUID_LEN * 2) + 1];
char *ptr = &guid[0];
@ -632,59 +688,67 @@ static void stdout_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_d
static void stdout_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data)
{
int j;
__u16 log_page_version = le16_to_cpu(log_data->log_page_version);
printf("TCG Configuration C7 Log Page Data-\n");
printf(" State : 0x%x\n",
log_data->state);
printf(" Reserved1 : 0x");
printf(" State : 0x%x\n",
log_data->state);
printf(" Reserved1 : ");
for (j = 0; j < 3; j++)
printf("%d", log_data->rsvd1[j]);
printf("\n");
printf(" Locking SP Activation Count : 0x%x\n",
printf(" Locking SP Activation Count : 0x%x\n",
log_data->locking_sp_act_count);
printf(" Tper Revert Count : 0x%x\n",
printf(" Tper Revert Count : 0x%x\n",
log_data->type_rev_count);
printf(" Locking SP Revert Count : 0x%x\n",
printf(" Locking SP Revert Count : 0x%x\n",
log_data->locking_sp_rev_count);
printf(" Number of Locking Objects : 0x%x\n",
printf(" Number of Locking Objects : 0x%x\n",
log_data->no_of_locking_obj);
printf(" Number of Single User Mode Locking Objects : 0x%x\n",
printf(" Number of Single User Mode Locking Objects : 0x%x\n",
log_data->no_of_single_um_locking_obj);
printf(" Number of Range Provisioned Locking Objects : 0x%x\n",
printf(" Number of Range Provisioned Locking Objects : 0x%x\n",
log_data->no_of_range_prov_locking_obj);
printf(" Number of Namespace Provisioned Locking Objects : 0x%x\n",
printf(" Number of Namespace Provisioned Locking Objects : 0x%x\n",
log_data->no_of_ns_prov_locking_obj);
printf(" Number of Read Locked Locking Objects : 0x%x\n",
printf(" Number of Read Locked Locking Objects : 0x%x\n",
log_data->no_of_read_lock_locking_obj);
printf(" Number of Write Locked Locking Objects : 0x%x\n",
printf(" Number of Write Locked Locking Objects : 0x%x\n",
log_data->no_of_write_lock_locking_obj);
printf(" Number of Read Unlocked Locking Objects : 0x%x\n",
printf(" Number of Read Unlocked Locking Objects : 0x%x\n",
log_data->no_of_read_unlock_locking_obj);
printf(" Number of Write Unlocked Locking Objects : 0x%x\n",
printf(" Number of Write Unlocked Locking Objects : 0x%x\n",
log_data->no_of_write_unlock_locking_obj);
printf(" Reserved2 : 0x%x\n",
log_data->rsvd2);
printf(" SID Authentication Try Count : 0x%x\n",
printf(" Reserved2 : %x\n",
log_data->rsvd15);
printf(" SID Authentication Try Count : 0x%x\n",
le32_to_cpu(log_data->sid_auth_try_count));
printf(" SID Authentication Try Limit : 0x%x\n",
printf(" SID Authentication Try Limit : 0x%x\n",
le32_to_cpu(log_data->sid_auth_try_limit));
printf(" Programmatic TCG Reset Count : 0x%x\n",
printf(" Programmatic TCG Reset Count : 0x%x\n",
le32_to_cpu(log_data->pro_tcg_rc));
printf(" Programmatic Reset Lock Count : 0x%x\n",
printf(" Programmatic Reset Lock Count : 0x%x\n",
le32_to_cpu(log_data->pro_rlc));
printf(" TCG Error Count : 0x%x\n",
printf(" TCG Error Count : 0x%x\n",
le32_to_cpu(log_data->tcg_ec));
printf(" Reserved3 : 0x");
for (j = 0; j < 458; j++)
printf("%d", log_data->rsvd3[j]);
if (log_page_version == 1) {
printf(" Reserved3 : %d%d",
*(__u8 *)&log_data->no_of_ns_prov_locking_obj_ext,
*((__u8 *)&log_data->no_of_ns_prov_locking_obj_ext + 1));
} else {
printf(" Number of Namespace Provisioned Locking Objects Extended : 0x%x\n",
le16_to_cpu(log_data->no_of_ns_prov_locking_obj_ext));
printf(" Reserved3 : ");
}
for (j = 0; j < 456; j++)
printf("%d", log_data->rsvd38[j]);
printf("\n");
printf(" Log Page Version : 0x%x\n",
le16_to_cpu(log_data->log_page_version));
printf(" Log page GUID : 0x");
printf(" Log Page Version : 0x%x\n",
log_page_version);
printf(" Log page GUID : 0x");
for (j = GUID_LEN - 1; j >= 0; j--)
printf("%02x", log_data->log_page_guid[j]);
printf("\n");

View file

@ -36,9 +36,10 @@ void ocp_fw_act_history(const struct fw_activation_history *fw_history, nvme_pri
ocp_print(fw_act_history, flags, fw_history);
}
void ocp_smart_extended_log(void *data, nvme_print_flags_t flags)
void ocp_smart_extended_log(struct ocp_smart_extended_log *log, unsigned int version,
nvme_print_flags_t flags)
{
ocp_print(smart_extended_log, flags, data);
ocp_print(smart_extended_log, flags, log, version);
}
void ocp_show_telemetry_log(struct ocp_telemetry_parse_options *options, nvme_print_flags_t flags)

View file

@ -4,13 +4,14 @@
#include "ocp-hardware-component-log.h"
#include "ocp-fw-activation-history.h"
#include "ocp-smart-extended-log.h"
#include "ocp-telemetry-decode.h"
#include "ocp-nvme.h"
struct ocp_print_ops {
void (*hwcomp_log)(struct hwcomp_log *log, __u32 id, bool list);
void (*fw_act_history)(const struct fw_activation_history *fw_history);
void (*smart_extended_log)(void *data);
void (*smart_extended_log)(struct ocp_smart_extended_log *log, unsigned int version);
void (*telemetry_log)(struct ocp_telemetry_parse_options *options);
void (*c3_log)(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data);
void (*c5_log)(struct nvme_dev *dev, struct unsupported_requirement_log *log_data);
@ -36,7 +37,8 @@ static inline struct ocp_print_ops *ocp_get_json_print_ops(nvme_print_flags_t fl
void ocp_show_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list, nvme_print_flags_t flags);
void ocp_fw_act_history(const struct fw_activation_history *fw_history, nvme_print_flags_t flags);
void ocp_smart_extended_log(void *data, nvme_print_flags_t flags);
void ocp_smart_extended_log(struct ocp_smart_extended_log *log, unsigned int version,
nvme_print_flags_t flags);
void ocp_show_telemetry_log(struct ocp_telemetry_parse_options *options, nvme_print_flags_t flags);
void ocp_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data,
nvme_print_flags_t flags);

View file

@ -14,10 +14,10 @@
#include "common.h"
#include "nvme-print.h"
#include "ocp-print.h"
#include "ocp-utils.h"
/* C0 SCAO Log Page */
#define C0_SMART_CLOUD_ATTR_LEN 0x200
#define C0_SMART_CLOUD_ATTR_OPCODE 0xC0
static __u8 scao_guid[GUID_LEN] = {
0xC5, 0xAF, 0x10, 0x28,
@ -26,12 +26,21 @@ static __u8 scao_guid[GUID_LEN] = {
0xC9, 0x14, 0xD5, 0xAF
};
static int get_c0_log_page(int fd, char *format)
static int get_c0_log_page(struct nvme_dev *dev, char *format,
unsigned int format_version)
{
nvme_print_flags_t fmt;
__u8 *data;
struct ocp_smart_extended_log *data;
int i;
int ret;
int fd = dev_fd(dev);
struct nvme_get_log_args args = {
.args_size = sizeof(args),
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.lid = (enum nvme_cmd_get_log_lid)OCP_LID_SMART,
.nsid = NVME_NSID_ALL,
.len = C0_SMART_CLOUD_ATTR_LEN,
};
ret = validate_output_format(format, &fmt);
if (ret < 0) {
@ -46,8 +55,9 @@ static int get_c0_log_page(int fd, char *format)
}
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);
args.log = data;
ocp_get_uuid_index(dev, &args.uuidx);
ret = nvme_get_log_page(fd, NVME_LOG_PAGE_PDU_SIZE, &args);
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n",
@ -57,7 +67,7 @@ static int get_c0_log_page(int fd, char *format)
/* check log page guid */
/* Verify GUID matches */
for (i = 0; i < 16; i++) {
if (scao_guid[i] != data[SCAO_LPG + i]) {
if (scao_guid[i] != data->log_page_guid[i]) {
int j;
fprintf(stderr, "ERROR : OCP : Unknown GUID in C0 Log Page data\n");
@ -67,7 +77,7 @@ static int get_c0_log_page(int fd, char *format)
fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
for (j = 0; j < 16; j++)
fprintf(stderr, "%x", data[SCAO_LPG + j]);
fprintf(stderr, "%x", data->log_page_guid[j]);
fprintf(stderr, "\n");
ret = -1;
@ -76,7 +86,7 @@ static int get_c0_log_page(int fd, char *format)
}
/* print the data */
ocp_smart_extended_log(data, fmt);
ocp_smart_extended_log(data, format_version, fmt);
} else {
fprintf(stderr, "ERROR : OCP : Unable to read C0 data from buffer\n");
}
@ -95,14 +105,17 @@ int ocp_smart_add_log(int argc, char **argv, struct command *cmd,
struct config {
char *output_format;
unsigned int output_format_version;
};
struct config cfg = {
.output_format = "normal",
.output_format_version = 1,
};
OPT_ARGS(opts) = {
OPT_FMT("output-format", 'o', &cfg.output_format, "output Format: normal|json"),
OPT_UINT("output-format-version", 0, &cfg.output_format_version, "output Format version: 1|2"),
OPT_END()
};
@ -110,7 +123,8 @@ int ocp_smart_add_log(int argc, char **argv, struct command *cmd,
if (ret)
return ret;
ret = get_c0_log_page(dev_fd(dev), cfg.output_format);
ret = get_c0_log_page(dev, cfg.output_format,
cfg.output_format_version);
if (ret)
fprintf(stderr, "ERROR : OCP : Failure reading the C0 Log Page, ret = %d\n",
ret);

View file

@ -6,50 +6,149 @@
* Venkat Ramesh <venkatraghavan@fb.com>
*/
#include "common.h"
#include "linux/types.h"
#ifndef OCP_SMART_EXTENDED_LOG_H
#define OCP_SMART_EXTENDED_LOG_H
struct command;
struct plugin;
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_NBEV = 130, /* NVMe Base Errata Version */
SCAO_NCSEV = 131, /* NVMe Command Set 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_LPFR = 208, /* Lowest Permitted Firmware Revision */
SCAO_LPV = 494, /* Log page version */
SCAO_LPG = 496, /* Log page GUID */
/**
* struct ocp_smart_extended_log - SMART / Health Information Extended
* @physical_media_units_written: Physical Media Units Written
* @physical_media_units_read: Physical Media Units Read
* @bad_user_nand_blocks_raw: Bad User NAND Blocks raw
* @bad_user_nand_blocks_normalized: Bad User NAND Blocks normalized
* @bad_system_nand_blocks_raw: Bad System NAND Blocks raw
* @bad_system_nand_blocks_normalized: Bad System NAND Blocks normalized
* @xor_recovery_count: XOR Recovery Count
* @uncorrectable_read_err_count: Uncorrectable Read Error Count
* @soft_ecc_err_count: Soft ECC Error Count
* @end_to_end_detected_err: End to End detected errors
* @end_to_end_corrected_err: End to End corrected errors
* @system_data_used_percent: System data percent used
* @refresh_counts: Refresh Counts
* @user_data_erase_count_max: Max User data erase counts
* @user_data_erase_count_min: Min User data erase counts
* @thermal_throttling_event_count: Number of Thermal throttling events
* @dssd_errata_version: DSSD Errata Version
* @dssd_point_version: DSSD Point Version
* @dssd_minor_version: DSSD Minor Version
* @dssd_major_version: DSSD Major Version
* @pcie_correctable_err_count: PCIe Correctable Error Count
* @incomplete_shoutdowns: Incomplete Shutdowns
* @rsvd116: Reserved
* @percent_free_blocks: Percent free blocks
* @rsvd121: Reserved
* @capacitor_health: Capacitor health
* @nvme_base_errata_version: NVM Express Base Errata Version
* @nvme_cmdset_errata_version: NVMe Command Set Errata Version
* @rsvd132: Reserved
* @nvme_over_pcie_errate_version: NVMe Over Pcie Errata Version
* @nvme_mi_errata_version: NVMe MI Errata Version
* @unaligned_io: Unaligned I/O
* @security_version: Security Version Number
* @total_nuse: Total NUSE - Namespace utilization
* @plp_start_count: PLP start count
* @endurance_estimate: Endurance Estimate
* @pcie_link_retaining_count: PCIe Link Retraining Count
* @power_state_change_count: Power State Change Count
* @lowest_permitted_fw_rev: Lowest Permitted Firmware Revision -------------
* @rsvd216: Reserved
* @total_media_dies: Total media dies
* @total_die_failure_tolerance: Total die failure tolerance
* @media_dies_offline: Media dies offline
* @max_temperature_recorded: Max temperature recorded
* @rsvd223: Reserved
* @nand_avg_erase_count: Nand avg erase count
* @command_timeouts: Command timeouts
* @sys_area_program_fail_count_raw: Sys area program fail count raw
* @sys_area_program_fail_count_normalized: Sys area program fail count noralized
* @revd241: Reserved
* @sys_area_uncorr_read_count_raw: Sys area uncorrectable read count raw
* @sys_area_uncorr_read_count_normalized: Sys area uncorrectable read count noralized
* @revd249: Reserved
* @sys_area_erase_fail_count_raw: Sys area erase fail count raw
* @sys_area_erase_fail_count_normalized: Sys area erase fail count noralized
* @revd257: Reserved
* @max_peak_power_capability: Max peak power capability
* @current_max_avg_power: Current max avg power
* @lifetime_power_consumed: Lifetime power consumed
* @dssd_firmware_revision: Dssd firmware revision
* @dssd_firmware_build_uuid: Dssd firmware build UUID
* @dssd_firmware_build_label: Dssd firmware build label
* @revd358: Reserved
* @log_page_version: Log page version
* @log_page_guid: Log page GUID
*/
struct ocp_smart_extended_log {
__u8 physical_media_units_written[16]; /* [15:0] */
__u8 physical_media_units_read[16]; /* [31:16] */
__u8 bad_user_nand_blocks_raw[6]; /* [37:32] */
__le16 bad_user_nand_blocks_normalized; /* [39:38] */
__u8 bad_system_nand_blocks_raw[6]; /* [45:40] */
__le16 bad_system_nand_blocks_normalized; /* [47:46] */
__le64 xor_recovery_count; /* [55:48] */
__le64 uncorrectable_read_err_count; /* [63:56] */
__le64 soft_ecc_err_count; /* [71:64] */
__le32 end_to_end_detected_err; /* [75:72] */
__le32 end_to_end_corrected_err; /* [79:76] */
__u8 system_data_used_percent; /* [80] */
__u8 refresh_counts[7]; /* [87:81] */
__le32 user_data_erase_count_max; /* [91:88] */
__le32 user_data_erase_count_min; /* [95:92] */
__u8 thermal_throttling_event_count; /* [96] */
__u8 thermal_throttling_current_status; /* [97] */
__u8 dssd_errata_version; /* [98] */
__u8 dssd_point_version[2]; /* [100:99] */
__u8 dssd_minor_version[2]; /* [102:101] */
__u8 dssd_major_version; /* [103] */
__le64 pcie_correctable_err_count; /* [111:104] */
__le32 incomplete_shoutdowns; /* [115:112] */
__u8 rsvd116[4]; /* [119:116] */
__u8 percent_free_blocks; /* [120] */
__u8 rsvd121[7]; /* [127:121] */
__le16 capacitor_health; /* [129:128] */
__u8 nvme_base_errata_version; /* [130] */
__u8 nvme_cmdset_errata_version; /* [131] */
__u8 nvme_over_pcie_errate_version; /* [132] */
__u8 nvme_mi_errata_version; /* [133] */
__u8 rsvd134[2]; /* [135:134] */
__le64 unaligned_io; /* [143:136] */
__le64 security_version; /* [151:144] */
__le64 total_nuse; /* [159:152] */
__u8 plp_start_count[16]; /* [175:160] */
__u8 endurance_estimate[16]; /* [191:176] */
__le64 pcie_link_retaining_count; /* [199:192] */
__le64 power_state_change_count; /* [207:200] */
__le64 lowest_permitted_fw_rev; /* [215:208] */
__le16 total_media_dies; /* [217:216] */
__le16 total_die_failure_tolerance; /* [219:218] */
__le16 media_dies_offline; /* [221:220] */
__u8 max_temperature_recorded; /* [222] */
__u8 rsvd223; /* [223] */
__le64 nand_avg_erase_count; /* [231:224] */
__le32 command_timeouts; /* [235:232] */
__le32 sys_area_program_fail_count_raw; /* [239:236] */
__u8 sys_area_program_fail_count_normalized; /* [240] */
__u8 rsvd241[3]; /* [243:241] */
__le32 sys_area_uncorr_read_count_raw; /* [247:244] */
__u8 sys_area_uncorr_read_count_normalized; /* [248] */
__u8 rsvd249[3]; /* [251:249] */
__le32 sys_area_erase_fail_count_raw; /* [255:252] */
__u8 sys_area_erase_fail_count_normalized; /* [256] */
__u8 rsvd257[3]; /* [259:257] */
__le16 max_peak_power_capability; /* [261:260] */
__le16 current_max_avg_power; /* [263:262] */
__u8 lifetime_power_consumed[6]; /* [269:264] */
__u8 dssd_firmware_revision[8]; /* [277:270] */
__u8 dssd_firmware_build_uuid[16]; /* [293:278] */
__u8 dssd_firmware_build_label[64]; /* [375:294] */
__u8 rsvd358[136]; /* [493:358] */
__le16 log_page_version; /* [495:494] */
__u8 log_page_guid[16]; /* [511:496] */
};
int ocp_smart_add_log(int argc, char **argv, struct command *cmd,

View file

@ -39,6 +39,7 @@ void print_stats_desc(struct telemetry_stats_desc *stat_desc)
printf("Statistics info : 0x%x\n", stat_desc->info);
printf("NS info : 0x%x\n", stat_desc->ns_info);
printf("Statistic Data Size : 0x%x\n", le16_to_cpu(stat_data_sz));
printf("Namespace ID[15:0] : 0x%x\n", stat_desc->nsid);
if (stat_data_sz > 0) {
printf("%s : 0x",
@ -109,13 +110,18 @@ void print_telemetry_fifo_event(__u8 class_type,
if ((id == ADMIN_QUEUE_NONZERO_STATUS) ||
(id == IO_QUEUE_NONZERO_STATUS)) {
printf(" Cmd Op Code : 0x%02x\n", data[0]);
__u16 status = *(__u16 *)&data[1];
__u16 cmd_id = *(__u16 *)&data[3];
__u16 sq_id = *(__u16 *)&data[5];
__u16 status;
__u16 cmd_id;
__u16 sq_id;
memcpy(&status, &data[1], sizeof(status));
memcpy(&cmd_id, &data[3], sizeof(cmd_id));
memcpy(&sq_id, &data[5], sizeof(sq_id));
printf(" Status Code : 0x%04x\n", le16_to_cpu(status));
printf(" Cmd ID : 0x%04x\n", le16_to_cpu(cmd_id));
printf(" SQ ID : 0x%04x\n", le16_to_cpu(sq_id));
printf(" LID,FID,Other Cmd Reserved : 0x%02x\n", data[7]);
} else if (id == CC_REGISTER_CHANGED) {
__u32 cc_reg_data = *(__u32 *)data;
@ -126,6 +132,20 @@ void print_telemetry_fifo_event(__u8 class_type,
printf(" CSTS Reg Data : 0x%08x\n",
le32_to_cpu(csts_reg_data));
} else if (id == OOB_COMMAND) {
printf(" Cmd Op Code : 0x%02x\n", data[0]);
__u16 status;
memcpy(&status, &data[1], sizeof(status));
printf(" Admin Cmd Status : 0x%04x\n", le16_to_cpu(status));
printf(" NVMe MI SC : 0x%02x\n", data[3]);
printf(" Byte1 Req Msg : 0x%02x\n", data[4]);
printf(" Byte2 Req Msg : 0x%02x\n", data[5]);
} else if (id == OOB_AER_EVENT_MSG_TRANS) {
__u64 aem = *(__u64 *)data;
printf(" AEM : 0x%016"PRIx64"\n",
le64_to_cpu(aem));
}
if (size > 8)
print_vu_event_data((size-8), (__u8 *)&data[8]);
@ -168,7 +188,7 @@ void print_telemetry_fifo_event(__u8 class_type,
case TELEMETRY_MEDIA_WEAR_CLASS:
printf(" Event ID : 0x%04x %s\n",
id, telemetry_media_debug_event_id_to_string(id));
id, telemetry_media_wear_event_id_to_string(id));
__u32 host_tb_written = *(__u32 *)&data[0];
__u32 media_tb_written = *(__u32 *)&data[4];
__u32 media_tb_erased = *(__u32 *)&data[8];
@ -190,6 +210,16 @@ void print_telemetry_fifo_event(__u8 class_type,
print_stats_desc((struct telemetry_stats_desc *)data);
break;
case TELEMETRY_VIRTUAL_FIFO_EVENT_CLASS:
printf(" Event ID : 0x%04x %s\n",
id, telemetry_virtual_fifo_event_id_to_string(id));
__u16 vu_event_id = *(__u16 *)data;
printf(" VU Virtual FIFO Event ID : 0x%02x\n", le16_to_cpu(vu_event_id));
printf("\n");
break;
default:
/*
* printf("Unknown Event Class Type\n");
@ -489,9 +519,9 @@ int get_telemetry_das_offset_and_size(
return 0;
}
int get_static_id_ascii_string(int identifier, char *description)
int get_statistic_id_ascii_string(int identifier, char *description)
{
if (pstring_buffer == NULL)
if (!pstring_buffer || !description)
return -1;
struct nvme_ocp_telemetry_string_header *pocp_ts_header =
@ -522,16 +552,17 @@ int get_static_id_ascii_string(int identifier, char *description)
memcpy(description, pdescription,
peach_statistic_entry->ascii_id_length + 1);
// If ASCII string isn't found, see in our internal Map
// for 2.5 Spec defined strings (id < 0x1D).
if ((description == NULL) && (identifier < 0x1D))
memcpy(description,
statistic_identifiers_map[identifier].description,
peach_statistic_entry->ascii_id_length + 1);
return 0;
}
}
// If ASCII string isn't found, see in our internal Map
// for 2.5 Spec defined strings
if (identifier <= 0x1D) {
strcpy(description, statistic_identifiers_map[identifier].description);
return 0;
}
return -1;
}
@ -629,10 +660,10 @@ int parse_ocp_telemetry_string_log(int event_fifo_num, int identifier, int debug
}
if (string_table == STATISTICS_IDENTIFIER_STRING)
get_static_id_ascii_string(identifier, description);
else if (string_table == EVENT_STRING)
get_statistic_id_ascii_string(identifier, description);
else if (string_table == EVENT_STRING && debug_event_class < 0x80)
get_event_id_ascii_string(identifier, debug_event_class, description);
else if (string_table == VU_EVENT_STRING)
else if (string_table == VU_EVENT_STRING || debug_event_class >= 0x80)
get_vu_event_id_ascii_string(identifier, debug_event_class, description);
return 0;
@ -1204,10 +1235,15 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
struct json_object *pstats_array, FILE *fp)
{
if (pstatistic_entry == NULL) {
nvme_show_error("Input buffer was NULL");
nvme_show_error("Statistics Input buffer was NULL");
return -1;
}
if (pstatistic_entry->statistic_id == STATISTICS_RESERVED_ID)
/* End of statistics entries, return -1 to stop processing the buffer */
return -1;
unsigned int data_size = pstatistic_entry->statistic_data_size * SIZE_OF_DWORD;
__u8 *pdata = (__u8 *)pstatistic_entry +
sizeof(struct nvme_ocp_telemetry_statistic_descriptor);
@ -1236,8 +1272,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
pstatistic_entry->statistic_data_size);
json_add_formatted_u32_str(pstatistics_object, STR_RESERVED,
pstatistic_entry->reserved);
json_add_formatted_var_size_str(pstatistics_object, STR_STATISTICS_SPECIFIC_DATA,
pdata, data_size);
if (pstatistic_entry->statistic_id == MAX_DIE_BAD_BLOCK_ID) {
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_WORST_DIE_PERCENT,
pdata[0]);
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_WORST_DIE_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id == MAX_NAND_CHANNEL_BAD_BLOCK_ID) {
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT,
pdata[0]);
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_WORST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id == MIN_NAND_CHANNEL_BAD_BLOCK_ID) {
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT,
pdata[0]);
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_BEST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else {
json_add_formatted_var_size_str(pstatistics_object,
STR_STATISTICS_SPECIFIC_DATA,
pdata,
data_size);
}
if (pstatistics_object != NULL)
json_array_add_value_object(pstats_array, pstatistics_object);
@ -1257,8 +1318,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
pstatistic_entry->statistic_data_size);
fprintf(fp, "%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
data_size, fp);
if (pstatistic_entry->statistic_id == MAX_DIE_BAD_BLOCK_ID) {
fprintf(fp, "%s: 0x%02x\n", STR_STATISTICS_WORST_DIE_PERCENT,
pdata[0]);
fprintf(fp, "%s: 0x%04x\n", STR_STATISTICS_WORST_DIE_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id ==
MAX_NAND_CHANNEL_BAD_BLOCK_ID) {
fprintf(fp, "%s: 0x%02x\n",
STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT,
pdata[0]);
fprintf(fp, "%s: 0x%04x\n",
STR_STATISTICS_WORST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id ==
MIN_NAND_CHANNEL_BAD_BLOCK_ID) {
fprintf(fp, "%s: 0x%02x\n",
STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT,
pdata[0]);
fprintf(fp, "%s: 0x%04x\n",
STR_STATISTICS_BEST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else {
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA,
pdata,
data_size,
fp);
}
fprintf(fp, STR_LINE2);
} else {
printf("%s: 0x%x\n", STR_STATISTICS_IDENTIFIER,
@ -1275,8 +1361,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
printf("%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
pstatistic_entry->statistic_data_size);
printf("%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
data_size, fp);
if (pstatistic_entry->statistic_id == MAX_DIE_BAD_BLOCK_ID) {
printf("%s: 0x%02x\n", STR_STATISTICS_WORST_DIE_PERCENT,
pdata[0]);
printf("%s: 0x%04x\n", STR_STATISTICS_WORST_DIE_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id ==
MAX_NAND_CHANNEL_BAD_BLOCK_ID) {
printf("%s: 0x%02x\n",
STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT,
pdata[0]);
printf("%s: 0x%04x\n",
STR_STATISTICS_WORST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id ==
MIN_NAND_CHANNEL_BAD_BLOCK_ID) {
printf("%s: 0x%02x\n",
STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT,
pdata[0]);
printf("%s: 0x%04x\n",
STR_STATISTICS_BEST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else {
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA,
pdata,
data_size,
fp);
}
printf(STR_LINE2);
}
}
@ -1297,6 +1408,7 @@ int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets
__u32 stats_da_1_start_dw = 0, stats_da_1_size_dw = 0;
__u32 stats_da_2_start_dw = 0, stats_da_2_size_dw = 0;
__u8 *pstats_offset = NULL;
int parse_rc = 0;
if (poffsets->data_area == 1) {
__u32 stats_da_1_start = *(__u32 *)(pda1_ocp_header_offset +
@ -1336,7 +1448,11 @@ int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets
(struct nvme_ocp_telemetry_statistic_descriptor *)
(pstats_offset + offset_to_move);
parse_statistic(pstatistic_entry, pstats_array, fp);
parse_rc = parse_statistic(pstatistic_entry, pstats_array, fp);
if (parse_rc < 0)
/* end of stats entries or null pointer, so break */
break;
offset_to_move += (pstatistic_entry->statistic_data_size * SIZE_OF_DWORD +
stat_des_size);
}

View file

@ -48,6 +48,83 @@ enum TELEMETRY_STATISTIC_ID {
TELEMETRY_STAT_ID_MAXDBB = 0x1B, /* Max Die Bad Block */
TELEMETRY_STAT_ID_MAXCBB = 0x1C, /* Max NAND Channel Bad Block */
TELEMETRY_STAT_ID_MINCBB = 0x1D, /* Min NAND Channel Bad Block */
TELEMETRY_STAT_ID_PMUW = 0x1E, /* Physical Media Units Written */
TELEMETRY_STAT_ID_PMUR = 0x1F, /* Physical Media Units Read */
TELEMETRY_STAT_ID_BUNB = 0x20, /* Bad User NAND Blocks */
TELEMETRY_STAT_ID_BSNB = 0x21, /* Bad System NAND Blocks */
TELEMETRY_STAT_ID_XORRC = 0x22, /* XOR Recovery Count */
TELEMETRY_STAT_ID_UNREC = 0x23, /* Uncorrectable Read Error Count */
TELEMETRY_STAT_ID_SECCEC = 0x24, /* Soft ECC Error Count */
TELEMETRY_STAT_ID_ETOECC = 0x25, /* End To End Correction Counts */
TELEMETRY_STAT_ID_SDU = 0x26, /* System Data % Used */
TELEMETRY_STAT_ID_RC = 0x27, /* Refresh Count */
TELEMETRY_STAT_ID_UDEC = 0x28, /* User Data Erase Counts */
TELEMETRY_STAT_ID_TTSC = 0x29, /* Thremal Throttling Status and Count */
TELEMETRY_STAT_ID_DSSDSV = 0x2A, /* DSSD Specification Version */
TELEMETRY_STAT_ID_PCIECEC = 0x2B, /* PCIe Correctable Error Count */
TELEMETRY_STAT_ID_IS = 0x2C, /* Incomplete Shutdown */
TELEMETRY_STAT_ID_FB = 0x2D, /* % Free Block */
TELEMETRY_STAT_ID_CH = 0x2E, /* Capacitor Health */
TELEMETRY_STAT_ID_NVMEBEV = 0x2F, /* NVM Express Base Errata Version */
TELEMETRY_STAT_ID_NVMCSEV = 0x30, /* NVM Command Set Errata Version */
TELEMETRY_STAT_ID_NVMEMIEV = 0x31, /* NVM Exp Mgmt Interface Err Version */
TELEMETRY_STAT_ID_UIO = 0x32, /* Unaligned IO */
TELEMETRY_STAT_ID_SVN = 0x33, /* Security Version Number */
TELEMETRY_STAT_ID_TNUSE = 0x34, /* Total NUSE */
TELEMETRY_STAT_ID_PLPSC = 0x35, /* PLP Start Count */
TELEMETRY_STAT_ID_EE = 0x36, /* Endurance Estimate */
TELEMETRY_STAT_ID_PCIELRC = 0x37, /* PCIe Link Retraining Count */
TELEMETRY_STAT_ID_PSCC = 0x38, /* Power State Change Count */
TELEMETRY_STAT_ID_LPFR = 0x39, /* Lowest Permitted Firmware Revision */
TELEMETRY_STAT_ID_LPV = 0x3A, /* Log Page Version */
TELEMETRY_STAT_ID_MDO = 0x3B, /* Media Dies Offline */
TELEMETRY_STAT_ID_MTR = 0x3C, /* Max Temperature Recorded */
TELEMETRY_STAT_ID_NAEC = 0x3D, /* Nand Avg Erase Count */
TELEMETRY_STAT_ID_CT = 0x3E, /* Command Timeout */
TELEMETRY_STAT_ID_SAPFC = 0x3F, /* System Area Program Fail Count */
TELEMETRY_STAT_ID_SARFC = 0x40, /* System Area Read Fail Count */
TELEMETRY_STAT_ID_SAEFC = 0x41, /* System Area Erase Fail Count */
TELEMETRY_STAT_ID_MPPC = 0x42, /* Max Peak Power Capability */
TELEMETRY_STAT_ID_CMAP = 0x43, /* Current Max Average Power */
TELEMETRY_STAT_ID_LPC = 0x44, /* Lifetime Power Consumed */
TELEMETRY_STAT_ID_PAC = 0x45, /* Panic Asset Count */
TELEMETRY_STAT_ID_DBT = 0x46, /* Device Busy Time */
TELEMETRY_STAT_ID_CW = 0x47, /* Critical Warning */
TELEMETRY_STAT_ID_COMTEMP = 0x48, /* Composite Temperature */
TELEMETRY_STAT_ID_AS = 0x49, /* Available Spare */
TELEMETRY_STAT_ID_AST = 0x4A, /* Available Spare Threshold */
TELEMETRY_STAT_ID_PU = 0x4B, /* Percentage Used */
TELEMETRY_STAT_ID_EGCWS = 0x4C, /* Endurance Gp CW Summary */
TELEMETRY_STAT_ID_DUR = 0x4D, /* Data Units Read */
TELEMETRY_STAT_ID_DUW = 0x4E, /* Data Units Written */
TELEMETRY_STAT_ID_HRC = 0x4F, /* Host Read Commands */
TELEMETRY_STAT_ID_HWC = 0x50, /* Host Write Commands */
TELEMETRY_STAT_ID_CBT = 0x51, /* Controller Busy Time */
TELEMETRY_STAT_ID_PC = 0x52, /* Power Cycles */
TELEMETRY_STAT_ID_POH = 0x53, /* Power On Hours */
TELEMETRY_STAT_ID_US = 0x54, /* Unsafe Shutdowns */
TELEMETRY_STAT_ID_MDIE = 0x55, /* Media and Data Integrity Er */
TELEMETRY_STAT_ID_NEILE = 0x56, /* No of Error Info Entries */
TELEMETRY_STAT_ID_WCTT = 0x57, /* Warning Composite Temp Time */
TELEMETRY_STAT_ID_CCTT = 0x58, /* Critical Comp Temp Time */
TELEMETRY_STAT_ID_TS1 = 0x59, /* Temperature Sensor 1 */
TELEMETRY_STAT_ID_TS2 = 0x5A, /* Temperature Sensor 2 */
TELEMETRY_STAT_ID_TS3 = 0x5B, /* Temperature Sensor 3 */
TELEMETRY_STAT_ID_TS4 = 0x5C, /* Temperature Sensor 4 */
TELEMETRY_STAT_ID_TS5 = 0x5D, /* Temperature Sensor 5 */
TELEMETRY_STAT_ID_TS6 = 0x5E, /* Temperature Sensor 6 */
TELEMETRY_STAT_ID_TS7 = 0x5F, /* Temperature Sensor 7 */
TELEMETRY_STAT_ID_TS8 = 0x60, /* Temperature Sensor 8 */
TELEMETRY_STAT_ID_TMT1TC = 0x61, /* Thermal Mgmt Temp1 TC */
TELEMETRY_STAT_ID_TMT2TC = 0x62, /* Thermal Mgmt Temp2 TC */
TELEMETRY_STAT_ID_TTTMT1 = 0x63, /* Total Time TMT1 */
TELEMETRY_STAT_ID_TTTMT2 = 0x64, /* Total Time TMT2 */
TELEMETRY_STAT_ID_EEE = 0x65, /* Endurance Estimate */
TELEMETRY_STAT_ID_EDUR = 0x66, /* Endurance Data Units Read */
TELEMETRY_STAT_ID_EDUW = 0x67, /* Endurance Data Units Written */
TELEMETRY_STAT_ID_EMUW = 0x68, /* Endurance Media Units Written */
TELEMETRY_STAT_ID_ENEILE = 0x69, /* Endurance No Of Err Info Log Entries */
};
static const char * const telemetry_stat_id_str[] = {
@ -80,50 +157,128 @@ static const char * const telemetry_stat_id_str[] = {
[TELEMETRY_STAT_ID_MAXDBB] = "Max Die Bad Block",
[TELEMETRY_STAT_ID_MAXCBB] = "Max NAND Channel Bad Block",
[TELEMETRY_STAT_ID_MINCBB] = "Min NAND Channel Bad Block",
[TELEMETRY_STAT_ID_PMUW] = "Physical Media Units Written",
[TELEMETRY_STAT_ID_PMUR] = "Physical Media Units Read",
[TELEMETRY_STAT_ID_BUNB] = "Bad User NAND Blocks",
[TELEMETRY_STAT_ID_BSNB] = "Bad System NAND Blocks",
[TELEMETRY_STAT_ID_XORRC] = "XOR Recovery Count",
[TELEMETRY_STAT_ID_UNREC] = "Uncorrectable Read Error Count",
[TELEMETRY_STAT_ID_SECCEC] = "Soft ECC Error Count",
[TELEMETRY_STAT_ID_ETOECC] = "End To End Correction Counts",
[TELEMETRY_STAT_ID_SDU] = "System Data Used",
[TELEMETRY_STAT_ID_RC] = "Refresh Count",
[TELEMETRY_STAT_ID_UDEC] = "User Data Erase Counts",
[TELEMETRY_STAT_ID_TTSC] = "Thremal Throttling Status and Count",
[TELEMETRY_STAT_ID_DSSDSV] = "DSSD Specification Version",
[TELEMETRY_STAT_ID_PCIECEC] = "PCIe Correctable Error Count",
[TELEMETRY_STAT_ID_IS] = "Incomplete Shutdown",
[TELEMETRY_STAT_ID_FB] = "Free Block",
[TELEMETRY_STAT_ID_CH] = "Capacitor Health",
[TELEMETRY_STAT_ID_NVMEBEV] = "NVM Express Base Errata Version",
[TELEMETRY_STAT_ID_NVMCSEV] = "NVM Command Set Errata Version",
[TELEMETRY_STAT_ID_NVMEMIEV] = "NVM Express Management Interface Errata Version",
[TELEMETRY_STAT_ID_UIO] = "Unaligned IO",
[TELEMETRY_STAT_ID_SVN] = "Security Version Number",
[TELEMETRY_STAT_ID_TNUSE] = "Total NUSE",
[TELEMETRY_STAT_ID_PLPSC] = "PLP Start Count",
[TELEMETRY_STAT_ID_EE] = "Endurance Estimate",
[TELEMETRY_STAT_ID_PCIELRC] = "PCIe Link Retraining Count",
[TELEMETRY_STAT_ID_PSCC] = "Power State Change Count",
[TELEMETRY_STAT_ID_LPFR] = "Lowest Permitted Firmware Revision",
[TELEMETRY_STAT_ID_LPV] = "Log Page Version",
[TELEMETRY_STAT_ID_MDO] = "Media Dies Offline",
[TELEMETRY_STAT_ID_MTR] = "Max Temperature Recorded",
[TELEMETRY_STAT_ID_NAEC] = "Nand Avg Erase Count",
[TELEMETRY_STAT_ID_CT] = "Command Timeout",
[TELEMETRY_STAT_ID_SAPFC] = "System Area Program Fail Count",
[TELEMETRY_STAT_ID_SARFC] = "System Area Read Fail Count",
[TELEMETRY_STAT_ID_SAEFC] = "System Area Erase Fail Count",
[TELEMETRY_STAT_ID_MPPC] = "Max Peak Power Capability",
[TELEMETRY_STAT_ID_CMAP] = "Current Max Average Power",
[TELEMETRY_STAT_ID_LPC] = "Lifetime Power Consumed",
[TELEMETRY_STAT_ID_PAC] = "Panic Asset Count",
[TELEMETRY_STAT_ID_DBT] = "Device Busy Time",
[TELEMETRY_STAT_ID_CW] = "Critical Warning",
[TELEMETRY_STAT_ID_COMTEMP] = "Composite Temperature",
[TELEMETRY_STAT_ID_AS] = "Available Spare",
[TELEMETRY_STAT_ID_AST] = "Available Spare Threshold",
[TELEMETRY_STAT_ID_PU] = "Percentage Used",
[TELEMETRY_STAT_ID_EGCWS] = "Endurance Gp CW Summary",
[TELEMETRY_STAT_ID_DUR] = "Data Units Read",
[TELEMETRY_STAT_ID_DUW] = "Data Units Written",
[TELEMETRY_STAT_ID_HRC] = "Host Read Commands",
[TELEMETRY_STAT_ID_HWC] = "Host Write Commands",
[TELEMETRY_STAT_ID_CBT] = "Controller Busy Time",
[TELEMETRY_STAT_ID_PC] = "Power Cycles",
[TELEMETRY_STAT_ID_POH] = "Power On Hours",
[TELEMETRY_STAT_ID_US] = "Unsafe Shutdowns",
[TELEMETRY_STAT_ID_MDIE] = "Media and Data Integrity Er",
[TELEMETRY_STAT_ID_NEILE] = "No of Error Info Entries",
[TELEMETRY_STAT_ID_WCTT] = "Warning Composite Temp Time",
[TELEMETRY_STAT_ID_CCTT] = "Critical Comp Temp Time",
[TELEMETRY_STAT_ID_TS1] = "Temperature Sensor 1",
[TELEMETRY_STAT_ID_TS2] = "Temperature Sensor 2",
[TELEMETRY_STAT_ID_TS3] = "Temperature Sensor 3",
[TELEMETRY_STAT_ID_TS4] = "Temperature Sensor 4",
[TELEMETRY_STAT_ID_TS5] = "Temperature Sensor 5",
[TELEMETRY_STAT_ID_TS6] = "Temperature Sensor 6",
[TELEMETRY_STAT_ID_TS7] = "Temperature Sensor 7",
[TELEMETRY_STAT_ID_TS8] = "Temperature Sensor 8",
[TELEMETRY_STAT_ID_TMT1TC] = "Thermal Mgmt Temp1 TC",
[TELEMETRY_STAT_ID_TMT2TC] = "Thermal Mgmt Temp2 TC",
[TELEMETRY_STAT_ID_TTTMT1] = "Total Time TMT1",
[TELEMETRY_STAT_ID_TTTMT2] = "Total Time TMT2",
[TELEMETRY_STAT_ID_EEE] = "Endurance Estimate",
[TELEMETRY_STAT_ID_EDUR] = "Endurance Data Units Read",
[TELEMETRY_STAT_ID_EDUW] = "Endurance Data Units Written",
[TELEMETRY_STAT_ID_EMUW] = "Endurance Media Units Written",
[TELEMETRY_STAT_ID_ENEILE] = "Endurance No Of Err Info Log Entries",
};
/*****************************************************************************
* Telemetry FIFO Event Class ID's and Strings
*****************************************************************************/
enum TELEMETRY_EVENT_CLASS_TYPE {
TELEMETRY_TIMESTAMP_CLASS = 0x1,
TELEMETRY_PCIE_CLASS = 0x2,
TELEMETRY_NVME_CLASS = 0x3,
TELEMETRY_RESET_CLASS = 0x4,
TELEMETRY_BOOT_SEQ_CLASS = 0x5,
TELEMETRY_FW_ASSERT_CLASS = 0x6,
TELEMETRY_TEMPERATURE_CLASS = 0x7,
TELEMETRY_MEDIA_DBG_CLASS = 0x8,
TELEMETRY_MEDIA_WEAR_CLASS = 0x9,
TELEMETRY_STAT_SNAPSHOT_CLASS = 0xA,
TELEMETRY_TIMESTAMP_CLASS = 0x1,
TELEMETRY_PCIE_CLASS = 0x2,
TELEMETRY_NVME_CLASS = 0x3,
TELEMETRY_RESET_CLASS = 0x4,
TELEMETRY_BOOT_SEQ_CLASS = 0x5,
TELEMETRY_FW_ASSERT_CLASS = 0x6,
TELEMETRY_TEMPERATURE_CLASS = 0x7,
TELEMETRY_MEDIA_DBG_CLASS = 0x8,
TELEMETRY_MEDIA_WEAR_CLASS = 0x9,
TELEMETRY_STAT_SNAPSHOT_CLASS = 0xA,
TELEMETRY_VIRTUAL_FIFO_EVENT_CLASS = 0xB,
};
static const char * const telemetry_event_class_str[] = {
[TELEMETRY_TIMESTAMP_CLASS] = "Timestamp Class",
[TELEMETRY_PCIE_CLASS] = "PCIe Class",
[TELEMETRY_NVME_CLASS] = "NVMe Class",
[TELEMETRY_RESET_CLASS] = "Reset Class",
[TELEMETRY_BOOT_SEQ_CLASS] = "Boot Sequence Class",
[TELEMETRY_FW_ASSERT_CLASS] = "FW Assert Class",
[TELEMETRY_TEMPERATURE_CLASS] = "Temperature Class",
[TELEMETRY_MEDIA_DBG_CLASS] = "Media Debug Class",
[TELEMETRY_MEDIA_WEAR_CLASS] = "Media Wear Class",
[TELEMETRY_STAT_SNAPSHOT_CLASS] = "Statistic Snapshot Class",
[TELEMETRY_TIMESTAMP_CLASS] = "Timestamp Class",
[TELEMETRY_PCIE_CLASS] = "PCIe Class",
[TELEMETRY_NVME_CLASS] = "NVMe Class",
[TELEMETRY_RESET_CLASS] = "Reset Class",
[TELEMETRY_BOOT_SEQ_CLASS] = "Boot Sequence Class",
[TELEMETRY_FW_ASSERT_CLASS] = "FW Assert Class",
[TELEMETRY_TEMPERATURE_CLASS] = "Temperature Class",
[TELEMETRY_MEDIA_DBG_CLASS] = "Media Debug Class",
[TELEMETRY_MEDIA_WEAR_CLASS] = "Media Wear Class",
[TELEMETRY_STAT_SNAPSHOT_CLASS] = "Statistic Snapshot Class",
[TELEMETRY_VIRTUAL_FIFO_EVENT_CLASS] = "Virtual FIFO Event Class",
};
/*****************************************************************************
* Telemetry Timestamp Class (01h) Event ID's and Strings
*****************************************************************************/
enum TELEMETRY_TIMESTAMP_EVENT_ID {
TIMESTAMP_HOST_CMD_ISSUED = 0x0000,
TIMESTAMP_SNAPSHOT = 0x0001,
TIMESTAMP_POWER_ON_HOURS = 0x0002,
TIMESTAMP_FEATURE_HOST_ISSUED = 0x0000,
TIMESTAMP_FW_INTIATED_SNAPSHOT = 0x0001,
TIMESTAMP_OBSOLETE = 0x0002,
};
static const char * const telemetry_timestamp_event_id_str[] = {
[TIMESTAMP_HOST_CMD_ISSUED] = "Timestamp Host Cmd Issued",
[TIMESTAMP_SNAPSHOT] = "Timestamp Snapshot",
[TIMESTAMP_POWER_ON_HOURS] = "Timestamp Power on Hours",
[TIMESTAMP_FEATURE_HOST_ISSUED] = "Host Issued Timestamp Set Feature Cmd",
[TIMESTAMP_FW_INTIATED_SNAPSHOT] = "Fw Initiated Timestamp Snapshot",
[TIMESTAMP_OBSOLETE] = "TimeStamp Obsolete",
};
/*****************************************************************************
@ -217,6 +372,8 @@ enum TELEMETRY_NVME_EVENT_ID {
CC_REGISTER_CHANGED = 0x000B,
CSTS_REGISTER_CHANGED = 0x000C,
DELETE_IO_QUEUE_PROCESSED = 0x000D,
OOB_COMMAND = 0x000E,
OOB_AER_EVENT_MSG_TRANS = 0x000F
};
static const char * const telemetry_nvme_event_id_str[] = {
@ -226,14 +383,16 @@ static const char * const telemetry_nvme_event_id_str[] = {
[CSTS_RDY_1_TO_0] = "CSTS.RDY Transitions from 1 to 0",
[NVME_EVENT_ID_RESERVED] = "Reserved NVMe Event ID",
[CREATE_IO_QUEUE_PROCESSED] = "Create IO SQ or CQ Command Processed",
[ADMIN_QUEUE_CMD_PROCESSED] = "Other Admin Queue Command Processed",
[ADMIN_QUEUE_CMD_PROCESSED] = "Inb-Admin Que Cmd Proc other than Cr IO SQ/CQ",
[ADMIN_QUEUE_NONZERO_STATUS] = "Admin Command Returned Non-zero Status",
[IO_QUEUE_NONZERO_STATUS] = "IO Command Returned Non-zero Status",
[CSTS_CFS_0_TO_1] = "CSTS.CFS Transitions from 0 to 1",
[ADMIN_QUEUE_BASE_WRITTEN] = "Admin SQ or CQ Base Address Written",
[CC_REGISTER_CHANGED] = "CC Register Changed",
[CSTS_REGISTER_CHANGED] = "CTS Register Changed",
[CSTS_REGISTER_CHANGED] = "CSTS Register Changed",
[DELETE_IO_QUEUE_PROCESSED] = "Delete IO SQ or CQ Command Processed",
[OOB_COMMAND] = "Out of Band Command Process",
[OOB_AER_EVENT_MSG_TRANS] = "Out of Band AER Event Msg Transition"
};
/*****************************************************************************
@ -292,7 +451,7 @@ static const char * const telemetry_fw_assert_event_id_str[] = {
[ASSERT_BACKGROUND_CODE] = "Assert in Background Services Code",
[FTL_REBUILD_FAILED] = "FTL Rebuild Failed",
[FTL_DATA_MISMATCH] = "FTL Data Mismatch",
[ASSERT_OTHER_CODE] = "FTL Other Code",
[ASSERT_OTHER_CODE] = "Assert in Other Code",
};
/*****************************************************************************
@ -342,6 +501,19 @@ static const char * const telemetry_media_wear_event_id_str[] = {
[MEDIA_WEAR] = "Media Wear",
};
/*****************************************************************************
* Telemetry Virtual FIFO (0Bh) Event ID's and Strings
*****************************************************************************/
enum TELEMETRY_VIRTUAL_FIFO_EVENT_ID {
VIRTUAL_FIFO_START = 0x0000,
VIRTUAL_FIFO_END = 0x0002,
};
static const char * const telemetry_virtual_fifo_event_id_str[] = {
[VIRTUAL_FIFO_START] = "Virtual FIFO Start",
[VIRTUAL_FIFO_END] = "Virtual FIFO End",
};
/*****************************************************************************
* Telemetry Data Structures
@ -353,7 +525,6 @@ static const char * const telemetry_media_wear_event_id_str[] = {
#define FILE_NAME_SIZE 2048
enum TELEMETRY_TYPE {
TELEMETRY_TYPE_NONE = 0,
TELEMETRY_TYPE_HOST = 7,
TELEMETRY_TYPE_CONTROLLER = 8,
TELEMETRY_TYPE_HOST_0 = 9,
@ -381,7 +552,7 @@ struct telemetry_stats_desc {
__u8 info;
__u8 ns_info;
__le16 size;
__le16 rsvd1;
__le16 nsid;
__u8 data[];
};
@ -438,7 +609,6 @@ struct telemetry_data_area_1 {
#define DEFAULT_OUTPUT_FORMAT_JSON "json"
/* C9 Telemetry String Log Format Log Page */
#define C9_TELEMETRY_STRING_LOG_ENABLE_OPCODE 0xC9
#define C9_TELEMETRY_STR_LOG_LEN 432
#define C9_TELEMETRY_STR_LOG_SIST_OFST 431
@ -460,6 +630,12 @@ struct telemetry_data_area_1 {
#define STR_STATISTICS_DATA_SIZE "Statistic Data Size"
#define STR_RESERVED "Reserved"
#define STR_STATISTICS_SPECIFIC_DATA "Statistic Specific Data"
#define STR_STATISTICS_WORST_DIE_PERCENT "Worst die % of bad blocks"
#define STR_STATISTICS_WORST_DIE_RAW "Worst die raw number of bad blocks"
#define STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT "Worst NAND channel % of bad blocks"
#define STR_STATISTICS_WORST_NAND_CHANNEL_RAW "Worst NAND channel number of bad blocks"
#define STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT "Best NAND channel % of bad blocks"
#define STR_STATISTICS_BEST_NAND_CHANNEL_RAW "Best NAND channel number of bad blocks"
#define STR_CLASS_SPECIFIC_DATA "Class Specific Data"
#define STR_DBG_EVENT_CLASS_TYPE "Debug Event Class type"
#define STR_EVENT_IDENTIFIER "Event Identifier"
@ -497,6 +673,47 @@ enum ocp_telemetry_string_tables {
VU_EVENT_STRING
};
/**
* enum ocp_telemetry_statistics_identifiers - OCP Statistics Identifiers
*/
enum ocp_telemetry_statistic_identifiers {
STATISTICS_RESERVED_ID = 0x00,
OUTSTANDING_ADMIN_CMDS_ID = 0x01,
HOST_WRTIE_BANDWIDTH_ID = 0x02,
GW_WRITE_BANDWITH_ID = 0x03,
ACTIVE_NAMESPACES_ID = 0x04,
INTERNAL_WRITE_WORKLOAD_ID = 0x05,
INTERNAL_READ_WORKLOAD_ID = 0x06,
INTERNAL_WRITE_QUEUE_DEPTH_ID = 0x07,
INTERNAL_READ_QUEUE_DEPTH_ID = 0x08,
PENDING_TRIM_LBA_COUNT_ID = 0x09,
HOST_TRIM_LBA_REQUEST_COUNT_ID = 0x0A,
CURRENT_NVME_POWER_STATE_ID = 0x0B,
CURRENT_DSSD_POWER_STATE_ID = 0x0C,
PROGRAM_FAIL_COUNT_ID = 0x0D,
ERASE_FAIL_COUNT_ID = 0x0E,
READ_DISTURB_WRITES_ID = 0x0F,
RETENTION_WRITES_ID = 0x10,
WEAR_LEVELING_WRITES_ID = 0x11,
READ_RECOVERY_WRITES_ID = 0x12,
GC_WRITES_ID = 0x13,
SRAM_CORRECTABLE_COUNT_ID = 0x14,
DRAM_CORRECTABLE_COUNT_ID = 0x15,
SRAM_UNCORRECTABLE_COUNT_ID = 0x16,
DRAM_UNCORRECTABLE_COUNT_ID = 0x17,
DATA_INTEGRITY_ERROR_COUNT_ID = 0x18,
READ_RETRY_ERROR_COUNT_ID = 0x19,
PERST_EVENTS_COUNT_ID = 0x1A,
MAX_DIE_BAD_BLOCK_ID = 0x1B,
MAX_NAND_CHANNEL_BAD_BLOCK_ID = 0x1C,
MIN_NAND_CHANNEL_BAD_BLOCK_ID = 0x1D,
//RESERVED = 7FFFh-1Eh,
//VENDOR_UNIQUE_CLASS_TYPE = FFFFh-8000h,
};
/**
* enum ocp_telemetry_debug_event_class_types - OCP Debug Event Class types
* @RESERVED_CLASS_TYPE: Reserved class
@ -1018,6 +1235,10 @@ static inline const char *telemetry_media_wear_event_id_to_string(int event_id)
{
return ARGSTR(telemetry_media_wear_event_id_str, event_id);
}
static inline const char *telemetry_virtual_fifo_event_id_to_string(int event_id)
{
return ARGSTR(telemetry_virtual_fifo_event_id_str, event_id);
}
/**
* @brief parse the ocp telemetry host or controller log binary file
@ -1129,7 +1350,7 @@ int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options);
*
* @return 0 success
*/
int get_static_id_ascii_string(int identifier, char *description);
int get_statistic_id_ascii_string(int identifier, char *description);
/**
* @brief gets event id ascii string

13
plugins/ocp/ocp-types.h Normal file
View file

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef OCP_TYPES_H
#define OCP_TYPES_H
#define OCP_GET(value, name) NVME_GET(value, OCP_##name)
#define OCP_SET(value, name) NVME_SET(value, OCP_##name)
enum nvme_ocp_enable_ieee1667_silo {
NVME_OCP_ENABLE_IEEE1667_SILO_SHIFT = 31,
NVME_OCP_ENABLE_IEEE1667_SILO_MASK = 1,
};
#endif /* OCP_TYPES_H */

View file

@ -7,6 +7,8 @@
#include <unistd.h>
#include <errno.h>
#include "util/types.h"
#include "ocp-nvme.h"
#include "ocp-utils.h"
const unsigned char ocp_uuid[NVME_UUID_LEN] = {
@ -37,3 +39,23 @@ int ocp_get_uuid_index(struct nvme_dev *dev, __u8 *index)
return ocp_find_uuid_index(&uuid_list, index);
}
int ocp_get_log_simple(struct nvme_dev *dev, enum ocp_dssd_log_id lid, __u32 len, void *log)
{
int fd = dev_fd(dev);
struct nvme_get_log_args args = {
.log = log,
.args_size = sizeof(args),
.fd = fd,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.lid = (enum nvme_cmd_get_log_lid)lid,
.len = len,
.nsid = NVME_NSID_ALL,
.lsi = NVME_LOG_LSI_NONE,
.lsp = NVME_LOG_LSP_NONE,
};
ocp_get_uuid_index(dev, &args.uuidx);
return nvme_get_log_page(fd, NVME_LOG_PAGE_PDU_SIZE, &args);
}

View file

@ -4,7 +4,6 @@
*
* Author: leonardo.da.cunha@solidigm.com
*/
#include "nvme.h"
/*
@ -30,3 +29,5 @@ int ocp_get_uuid_index(struct nvme_dev *dev, __u8 *index);
* Return: Zero if nvme device has UUID list log page, Negative POSIX error code otherwise.
*/
int ocp_find_uuid_index(struct nvme_id_uuid_list *uuid_list, __u8 *index);
int ocp_get_log_simple(struct nvme_dev *dev, enum ocp_dssd_log_id lid, __u32 len, void *log);