Merging upstream version 2.12.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
078c0dbcc0
commit
635faa7346
571 changed files with 10718 additions and 2738 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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--)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
13
plugins/ocp/ocp-types.h
Normal 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 */
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue