1
0
Fork 0

Merging upstream version 2.12.

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

View file

@ -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);