1
0
Fork 0

Merging upstream version 2.13.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-04-13 11:50:38 +02:00
parent adb2e5e05d
commit 8599c7290c
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
579 changed files with 6165 additions and 1687 deletions

108
plugins/feat/feat-nvme.c Normal file
View file

@ -0,0 +1,108 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "nvme.h"
#include "plugin.h"
#include "nvme-print.h"
#define CREATE_CMD
#include "feat-nvme.h"
static const char *power_mgmt_feat = "power management feature";
static const char *sel = "[0-3]: current/default/saved/supported";
static const char *save = "Specifies that the controller shall save the attribute";
static int power_mgmt_get(struct nvme_dev *dev, const __u8 fid, __u8 sel)
{
__u32 result;
int err;
struct nvme_get_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = fid,
.sel = sel,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = &result,
};
err = nvme_get_features(&args);
if (!err) {
if (NVME_CHECK(sel, GET_FEATURES_SEL, SUPPORTED))
nvme_show_select_result(fid, result);
else
nvme_feature_show_fields(fid, result, NULL);
} else {
nvme_show_error("Get %s", power_mgmt_feat);
}
return err;
}
static int power_mgmt_set(struct nvme_dev *dev, const __u8 fid, __u8 ps, __u8 wh, bool save)
{
__u32 result;
int err;
struct nvme_set_features_args args = {
.args_size = sizeof(args),
.fd = dev_fd(dev),
.fid = fid,
.cdw11 = NVME_SET(ps, FEAT_PWRMGMT_PS) | NVME_SET(wh, FEAT_PWRMGMT_WH),
.save = save,
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
.result = &result,
};
err = nvme_set_features(&args);
nvme_show_init();
if (err > 0) {
nvme_show_status(err);
} else if (err < 0) {
nvme_show_perror("Set %s", power_mgmt_feat);
} else {
nvme_show_result("Set %s: 0x%04x (%s)", power_mgmt_feat, args.cdw11,
save ? "Save" : "Not save");
nvme_feature_show_fields(fid, args.cdw11, NULL);
}
nvme_show_finish();
return err;
}
static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *ps = "power state";
const char *wh = "workload hint";
const __u8 fid = NVME_FEAT_FID_POWER_MGMT;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
struct config {
__u8 ps;
__u8 wh;
bool save;
__u8 sel;
};
struct config cfg = { 0 };
NVME_ARGS(opts,
OPT_BYTE("ps", 'p', &cfg.ps, ps),
OPT_BYTE("wh", 'w', &cfg.wh, wh),
OPT_FLAG("save", 's', &cfg.save, save),
OPT_BYTE("sel", 'S', &cfg.sel, sel));
err = parse_and_open(&dev, argc, argv, POWER_MGMT_DESC, opts);
if (err)
return err;
if (argconfig_parse_seen(opts, "ps"))
err = power_mgmt_set(dev, fid, cfg.ps, cfg.wh, cfg.save);
else
err = power_mgmt_get(dev, fid, cfg.sel);
return err;
}

25
plugins/feat/feat-nvme.h Normal file
View file

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "cmd.h"
#undef CMD_INC_FILE
#define CMD_INC_FILE plugins/feat/feat-nvme
#include "define_cmd.h"
#if !defined(FEAT_NVME) || defined(CMD_HEADER_MULTI_READ)
#define FEAT_NVME
#define FEAT_PLUGIN_VERSION "1.0"
#define POWER_MGMT_DESC "Get and set power management feature"
PLUGIN(NAME("feat", "NVMe feature extensions", FEAT_PLUGIN_VERSION),
COMMAND_LIST(
ENTRY("power-mgmt", POWER_MGMT_DESC, feat_power_mgmt)
)
);
#endif /* !FEAT_NVME || CMD_HEADER_MULTI_READ */
#ifndef FEAT_NVME_H
#define FEAT_NVME_H
#endif /* FEAT_NVME_H */

3
plugins/feat/meson.build Normal file
View file

@ -0,0 +1,3 @@
sources += [
'plugins/feat/feat-nvme.c',
]

View file

@ -280,7 +280,7 @@ static int lm_migration_send(int argc, char **argv, struct command *command, str
" 1h = Suspend";
const char *dudmq = "Delete user data migration queue (DUDMQ) as part of suspend operation "
"(CDW11[31])";
const char *seqind = "Sequence Indicator (CDW11[17:16])\n"
const char *seqind = "Sequence Indicator (CDW10[17:16])\n"
" 0h = Not first not last\n"
" 1h = First in two or more\n"
" 2h = Last in two or more\n"
@ -394,7 +394,7 @@ static int lm_migration_send(int argc, char **argv, struct command *command, str
.args_size = sizeof(args),
.fd = dev_fd(dev),
.sel = cfg.sel,
.mos = NVME_SET(cfg.seqind, LM_MIGRATION_SEND_MOS),
.mos = NVME_SET(cfg.seqind, LM_SEQIND),
.cntlid = cfg.cntlid,
.csuuidi = cfg.csuuidi,
.uidx = cfg.uidx,
@ -521,6 +521,7 @@ static int lm_migration_recv(int argc, char **argv, struct command *command, str
.csuuidi = cfg.csuuidi,
.offset = cfg.offset,
.cntlid = cfg.cntlid,
.numd = cfg.numd,
.data = data,
.result = &result,
};

View file

@ -1,12 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later
if json_c_dep.found()
sources += [
'plugins/solidigm/solidigm-nvme.c',
]
subdir('solidigm')
endif
sources += [
'plugins/amzn/amzn-nvme.c',
'plugins/dapustor/dapustor-nvme.c',
@ -22,6 +15,8 @@ sources += [
'plugins/nbft/nbft-plugin.c',
'plugins/netapp/netapp-nvme.c',
'plugins/nvidia/nvidia-nvme.c',
'plugins/sandisk/sandisk-nvme.c',
'plugins/sandisk/sandisk-utils.c',
'plugins/scaleflux/sfx-nvme.c',
'plugins/seagate/seagate-nvme.c',
'plugins/shannon/shannon-nvme.c',
@ -35,9 +30,14 @@ sources += [
'plugins/zns/zns.c',
]
subdir('ocp')
subdir('feat')
subdir('lm')
subdir('ocp')
if conf.get('HAVE_SED_OPAL') != 0
subdir('sed')
endif
if json_c_dep.found()
subdir('solidigm')
endif

View file

@ -156,6 +156,31 @@ static void netapp_get_ns_attrs(char *size, char *used, char *blk_size,
version[i] = '\0';
}
static void ontap_get_subsysname(char *subnqn, char *subsysname,
struct nvme_id_ctrl *ctrl)
{
char *subname;
int i, len = sizeof(ctrl->subnqn);
/* get the target NQN */
memcpy(subnqn, ctrl->subnqn, len);
subnqn[len] = '\0';
/* strip trailing whitespaces */
for (i = len - 1; i >= 0 && subnqn[i] == ' '; i--)
subnqn[i] = '\0';
/* get the subsysname from the target NQN */
subname = strrchr(subnqn, '.');
if (subname) {
subname++;
len = strlen(subname);
memcpy(subsysname, subname, len);
subsysname[len] = '\0';
} else
fprintf(stderr, "Unable to fetch ONTAP subsystem name\n");
}
static void ontap_labels_to_str(char *dst, char *src, int count)
{
int i;
@ -272,8 +297,8 @@ static void netapp_smdevice_json(struct json_object *devices, char *devname,
}
static void netapp_ontapdevice_json(struct json_object *devices, char *devname,
char *vsname, char *nspath, int nsid, char *uuid,
unsigned long long lba, char *version,
char *vsname, char *subsysname, char *nspath, int nsid,
char *uuid, unsigned long long lba, char *version,
unsigned long long nsze, unsigned long long nuse)
{
struct json_object *device_attrs;
@ -283,6 +308,7 @@ static void netapp_ontapdevice_json(struct json_object *devices, char *devname,
device_attrs = json_create_object();
json_object_add_value_string(device_attrs, "Device", devname);
json_object_add_value_string(device_attrs, "Vserver", vsname);
json_object_add_value_string(device_attrs, "Subsystem", subsysname);
json_object_add_value_string(device_attrs, "Namespace_Path", nspath);
json_object_add_value_int(device_attrs, "NSID", nsid);
json_object_add_value_string(device_attrs, "UUID", uuid);
@ -519,23 +545,25 @@ static void netapp_ontapdevices_print_verbose(struct ontapdevice_info *devices,
char size[128], used[128];
char blk_size[128], version[9];
char uuid_str[37] = " ";
char subnqn[257], subsysname[65];
int i;
char *formatstr = NULL;
char basestr[] =
"%s, Vserver %s, Namespace Path %s, NSID %d, UUID %s, "
"Size %s, Used %s, Format %s, Version %s\n";
char columnstr[] = "%-16s %-25s %-50s %-4d %-38s %-9s %-9s %-9s %-9s\n";
"%s, Vserver %s, Subsystem %s, Namespace Path %s, NSID %d, "
"UUID %s, Size %s, Used %s, Format %s, Version %s\n";
char columnstr[] = "%-16s %-25s %-25s %-50s %-4d %-38s %-9s %-9s %-9s %-9s\n";
if (format == NNORMAL)
formatstr = basestr;
else if (format == NCOLUMN) {
printf("%-16s %-25s %-50s %-4s %-38s %-9s %-9s %-9s %-9s\n",
"Device", "Vserver", "Namespace Path",
printf("%-16s %-25s %-25s %-50s %-4s %-38s %-9s %-9s %-9s %-9s\n",
"Device", "Vserver", "Subsystem", "Namespace Path",
"NSID", "UUID", "Size", "Used",
"Format", "Version");
printf("%-16s %-25s %-50s %-4s %-38s %-9s %-9s %-9s %-9s\n",
printf("%-16s %-25s %-25s %-50s %-4s %-38s %-9s %-9s %-9s %-9s\n",
"----------------", "-------------------------",
"-------------------------",
"--------------------------------------------------",
"----", "--------------------------------------",
"---------", "---------", "---------", "---------");
@ -547,13 +575,15 @@ static void netapp_ontapdevices_print_verbose(struct ontapdevice_info *devices,
/* found the device, fetch and print for that alone */
netapp_get_ns_attrs(size, used, blk_size, version,
&lba, &devices[i].ctrl, &devices[i].ns);
ontap_get_subsysname(subnqn, subsysname,
&devices[i].ctrl);
nvme_uuid_to_string(devices[i].uuid, uuid_str);
netapp_get_ontap_labels(vsname, nspath,
devices[i].log_data);
printf(formatstr, devices[i].dev, vsname, nspath,
devices[i].nsid, uuid_str, size, used,
blk_size, version);
printf(formatstr, devices[i].dev, vsname, subsysname,
nspath, devices[i].nsid, uuid_str,
size, used, blk_size, version);
return;
}
}
@ -562,12 +592,14 @@ static void netapp_ontapdevices_print_verbose(struct ontapdevice_info *devices,
/* fetch info and print for all devices */
netapp_get_ns_attrs(size, used, blk_size, version,
&lba, &devices[i].ctrl, &devices[i].ns);
ontap_get_subsysname(subnqn, subsysname,
&devices[i].ctrl);
nvme_uuid_to_string(devices[i].uuid, uuid_str);
netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
printf(formatstr, devices[i].dev, vsname, nspath,
devices[i].nsid, uuid_str, size, used,
blk_size, version);
printf(formatstr, devices[i].dev, vsname, subsysname,
nspath, devices[i].nsid, uuid_str,
size, used, blk_size, version);
}
}
@ -579,21 +611,23 @@ static void netapp_ontapdevices_print_regular(struct ontapdevice_info *devices,
unsigned long long lba;
char size[128];
char uuid_str[37] = " ";
char subnqn[257], subsysname[65];
int i;
char *formatstr = NULL;
char basestr[] =
"%s, Vserver %s, Namespace Path %s, NSID %d, UUID %s, %s\n";
char columnstr[] = "%-16s %-25s %-50s %-4d %-38s %-9s\n";
"%s, Vserver %s, Subsystem %s, Namespace Path %s, NSID %d, UUID %s, %s\n";
char columnstr[] = "%-16s %-25s %-25s %-50s %-4d %-38s %-9s\n";
if (format == NNORMAL)
formatstr = basestr;
else if (format == NCOLUMN) {
printf("%-16s %-25s %-50s %-4s %-38s %-9s\n",
"Device", "Vserver", "Namespace Path",
printf("%-16s %-25s %-25s %-50s %-4s %-38s %-9s\n",
"Device", "Vserver", "Subsystem", "Namespace Path",
"NSID", "UUID", "Size");
printf("%-16s %-25s %-50s %-4s %-38s %-9s\n",
printf("%-16s %-25s %-25s %-50s %-4s %-38s %-9s\n",
"----------------", "-------------------------",
"-------------------------",
"--------------------------------------------------",
"----", "--------------------------------------",
"---------");
@ -607,9 +641,11 @@ static void netapp_ontapdevices_print_regular(struct ontapdevice_info *devices,
nvme_uuid_to_string(devices[i].uuid, uuid_str);
netapp_get_ontap_labels(vsname, nspath,
devices[i].log_data);
ontap_get_subsysname(subnqn, subsysname,
&devices[i].ctrl);
printf(formatstr, devices[i].dev, vsname, nspath,
devices[i].nsid, uuid_str, size);
printf(formatstr, devices[i].dev, vsname, subsysname,
nspath, devices[i].nsid, uuid_str, size);
return;
}
}
@ -619,9 +655,10 @@ static void netapp_ontapdevices_print_regular(struct ontapdevice_info *devices,
netapp_get_ns_size(size, &lba, &devices[i].ns);
nvme_uuid_to_string(devices[i].uuid, uuid_str);
netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
ontap_get_subsysname(subnqn, subsysname, &devices[i].ctrl);
printf(formatstr, devices[i].dev, vsname, nspath,
devices[i].nsid, uuid_str, size);
printf(formatstr, devices[i].dev, vsname, subsysname,
nspath, devices[i].nsid, uuid_str, size);
}
}
@ -636,6 +673,7 @@ static void netapp_ontapdevices_print_json(struct ontapdevice_info *devices,
char size[128], used[128];
char blk_size[128], version[9];
char uuid_str[37] = " ";
char subnqn[257], subsysname[65];
int i;
/* prepare for the json output */
@ -647,13 +685,15 @@ static void netapp_ontapdevices_print_json(struct ontapdevice_info *devices,
/* found the device, fetch info for that alone */
netapp_get_ns_attrs(size, used, blk_size, version,
&lba, &devices[i].ctrl, &devices[i].ns);
ontap_get_subsysname(subnqn, subsysname,
&devices[i].ctrl);
nvme_uuid_to_string(devices[i].uuid, uuid_str);
netapp_get_ontap_labels(vsname, nspath,
devices[i].log_data);
netapp_ontapdevice_json(json_devices, devices[i].dev,
vsname, nspath, devices[i].nsid,
uuid_str, lba, version,
vsname, subsysname, nspath,
devices[i].nsid, uuid_str, lba, version,
le64_to_cpu(devices[i].ns.nsze),
le64_to_cpu(devices[i].ns.nuse));
goto out;
@ -664,12 +704,14 @@ static void netapp_ontapdevices_print_json(struct ontapdevice_info *devices,
/* fetch info for all devices */
netapp_get_ns_attrs(size, used, blk_size, version,
&lba, &devices[i].ctrl, &devices[i].ns);
ontap_get_subsysname(subnqn, subsysname,
&devices[i].ctrl);
nvme_uuid_to_string(devices[i].uuid, uuid_str);
netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
netapp_ontapdevice_json(json_devices, devices[i].dev,
vsname, nspath, devices[i].nsid,
uuid_str, lba, version,
vsname, subsysname, nspath,
devices[i].nsid, uuid_str, lba, version,
le64_to_cpu(devices[i].ns.nsze),
le64_to_cpu(devices[i].ns.nuse));
}

View file

@ -565,8 +565,7 @@ static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd,
OPT_BYTE("mode", 'm', &cfg.mode, mode),
OPT_FLAG("save", 's', &cfg.save, save),
OPT_BYTE("sel", 'S', &cfg.sel, sel),
OPT_FLAG("no-uuid", 'n', NULL,
"Skip UUID index search (UUID index not required for OCP 1.0)"));
OPT_FLAG("no-uuid", 'n', NULL, no_uuid));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
@ -2026,8 +2025,7 @@ static int set_dssd_power_state_feature(int argc, char **argv, struct command *c
OPT_ARGS(opts) = {
OPT_BYTE("power-state", 'p', &cfg.power_state, power_state),
OPT_FLAG("save", 's', &cfg.save, save),
OPT_FLAG("no-uuid", 'n', NULL,
"Skip UUID index search (UUID index not required for OCP 1.0)"),
OPT_FLAG("no-uuid", 'n', NULL, no_uuid),
OPT_END()
};
@ -2117,8 +2115,7 @@ static int get_dssd_power_state_feature(int argc, char **argv, struct command *c
OPT_ARGS(opts) = {
OPT_BYTE("sel", 'S', &cfg.sel, sel),
OPT_FLAG("all", 'a', NULL, all),
OPT_FLAG("no-uuid", 'n', NULL,
"Skip UUID index search (UUID index not required for OCP 1.0)"),
OPT_FLAG("no-uuid", 'n', NULL, no_uuid),
OPT_END()
};
@ -2176,8 +2173,7 @@ static int set_plp_health_check_interval(int argc, char **argv, struct command *
OPT_ARGS(opts) = {
OPT_BYTE("plp_health_interval", 'p', &cfg.plp_health_interval, plp_health_interval),
OPT_FLAG("save", 's', &cfg.save, save),
OPT_FLAG("no-uuid", 'n', NULL,
"Skip UUID index search (UUID index not required for OCP 1.0)"),
OPT_FLAG("no-uuid", 'n', NULL, no_uuid),
OPT_END()
};

View file

@ -11,7 +11,7 @@
#if !defined(OCP_NVME) || defined(CMD_HEADER_MULTI_READ)
#define OCP_NVME
#define OCP_PLUGIN_VERSION "2.11.0"
#define OCP_PLUGIN_VERSION "2.12.0"
#include "cmd.h"
PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),

View file

@ -464,15 +464,19 @@ void json_add_formatted_u32_str(struct json_object *pobject, const char *msg, un
void json_add_formatted_var_size_str(struct json_object *pobject, const char *msg, __u8 *pdata,
unsigned int data_size)
{
char description_str[256] = "";
char *description_str = NULL;
char temp_buffer[3] = { 0 };
/* Allocate 2 chars for each value in the data + 2 bytes for the null terminator */
description_str = (char *) calloc(1, data_size*2 + 2);
for (size_t i = 0; i < data_size; ++i) {
sprintf(temp_buffer, "%02X", pdata[i]);
strcat(description_str, temp_buffer);
}
json_object_add_value_string(pobject, msg, description_str);
free(description_str);
}
#endif /* CONFIG_JSONC */

View file

@ -0,0 +1,307 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2025 Sandisk Corporation or its affiliates.
*
* Author: Jeff Lien <jeff.lien@sandisk.com>
* Brandon Paupore <brandon.paupore@sandisk.com>
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <errno.h>
#include <limits.h>
#include <fcntl.h>
#include <unistd.h>
#include "common.h"
#include "nvme.h"
#include "libnvme.h"
#include "plugin.h"
#include "linux/types.h"
#include "util/cleanup.h"
#include "util/types.h"
#include "nvme-print.h"
#define CREATE_CMD
#include "sandisk-nvme.h"
#include "sandisk-utils.h"
#include "plugins/wdc/wdc-nvme-cmds.h"
static int sndk_vs_internal_fw_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_internal_fw_log(argc, argv, command, plugin);
}
static int sndk_vs_nand_stats(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_nand_stats(argc, argv, command, plugin);
}
static int sndk_vs_smart_add_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_smart_add_log(argc, argv, command, plugin);
}
static int sndk_clear_pcie_correctable_errors(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_clear_pcie_correctable_errors(argc, argv, command, plugin);
}
static int sndk_drive_status(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_drive_status(argc, argv, command, plugin);
}
static int sndk_clear_assert_dump(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_clear_assert_dump(argc, argv, command, plugin);
}
static int sndk_drive_resize(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_drive_resize(argc, argv, command, plugin);
}
static int sndk_vs_fw_activate_history(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_fw_activate_history(argc, argv, command, plugin);
}
static int sndk_clear_fw_activate_history(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_clear_fw_activate_history(argc, argv, command, plugin);
}
static int sndk_vs_telemetry_controller_option(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_telemetry_controller_option(argc, argv, command, plugin);
}
static int sndk_reason_identifier(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_reason_identifier(argc, argv, command, plugin);
}
static int sndk_log_page_directory(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_log_page_directory(argc, argv, command, plugin);
}
static int sndk_namespace_resize(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_namespace_resize(argc, argv, command, plugin);
}
static int sndk_vs_drive_info(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_drive_info(argc, argv, command, plugin);
}
static int sndk_capabilities(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
const char *desc = "Send a capabilities command.";
uint64_t capabilities = 0;
struct nvme_dev *dev;
nvme_root_t r;
int ret;
OPT_ARGS(opts) = {
OPT_END()
};
ret = parse_and_open(&dev, argc, argv, desc, opts);
if (ret)
return ret;
/* get capabilities */
r = nvme_scan(NULL);
sndk_check_device(r, dev);
capabilities = sndk_get_drive_capabilities(r, dev);
/* print command and supported status */
printf("Sandisk Plugin Capabilities for NVME device:%s\n", dev->name);
printf("vs-internal-log : %s\n",
capabilities & SNDK_DRIVE_CAP_INTERNAL_LOG_MASK ? "Supported" : "Not Supported");
printf("vs-nand-stats : %s\n",
capabilities & SNDK_DRIVE_CAP_NAND_STATS ? "Supported" : "Not Supported");
printf("vs-smart-add-log : %s\n",
capabilities & SNDK_DRIVE_CAP_SMART_LOG_MASK ? "Supported" : "Not Supported");
printf("--C0 Log Page : %s\n",
capabilities & SNDK_DRIVE_CAP_C0_LOG_PAGE ? "Supported" : "Not Supported");
printf("--C1 Log Page : %s\n",
capabilities & SNDK_DRIVE_CAP_C1_LOG_PAGE ? "Supported" : "Not Supported");
printf("--C3 Log Page : %s\n",
capabilities & SNDK_DRIVE_CAP_C3_LOG_PAGE ? "Supported" : "Not Supported");
printf("--CA Log Page : %s\n",
capabilities & SNDK_DRIVE_CAP_CA_LOG_PAGE ? "Supported" : "Not Supported");
printf("--D0 Log Page : %s\n",
capabilities & SNDK_DRIVE_CAP_D0_LOG_PAGE ? "Supported" : "Not Supported");
printf("clear-pcie-correctable-errors : %s\n",
capabilities & SNDK_DRIVE_CAP_CLEAR_PCIE_MASK ? "Supported" : "Not Supported");
printf("get-drive-status : %s\n",
capabilities & SNDK_DRIVE_CAP_DRIVE_STATUS ? "Supported" : "Not Supported");
printf("drive-resize : %s\n",
capabilities & SNDK_DRIVE_CAP_RESIZE ? "Supported" : "Not Supported");
printf("vs-fw-activate-history : %s\n",
capabilities & SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK ? "Supported" :
"Not Supported");
printf("clear-fw-activate-history : %s\n",
capabilities & SNDK_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK ? "Supported" :
"Not Supported");
printf("vs-telemetry-controller-option: %s\n",
capabilities & SNDK_DRIVE_CAP_DISABLE_CTLR_TELE_LOG ? "Supported" : "Not Supported");
printf("vs-error-reason-identifier : %s\n",
capabilities & SNDK_DRIVE_CAP_REASON_ID ? "Supported" : "Not Supported");
printf("log-page-directory : %s\n",
capabilities & SNDK_DRIVE_CAP_LOG_PAGE_DIR ? "Supported" : "Not Supported");
printf("namespace-resize : %s\n",
capabilities & SNDK_DRIVE_CAP_NS_RESIZE ? "Supported" : "Not Supported");
printf("vs-drive-info : %s\n",
capabilities & SNDK_DRIVE_CAP_INFO ? "Supported" : "Not Supported");
printf("vs-temperature-stats : %s\n",
capabilities & SNDK_DRIVE_CAP_TEMP_STATS ? "Supported" : "Not Supported");
printf("cloud-SSD-plugin-version : %s\n",
capabilities & SNDK_DRIVE_CAP_CLOUD_SSD_VERSION ? "Supported" : "Not Supported");
printf("vs-pcie-stats : %s\n",
capabilities & SNDK_DRIVE_CAP_PCIE_STATS ? "Supported" : "Not Supported");
printf("get-error-recovery-log : %s\n",
capabilities & SNDK_DRIVE_CAP_OCP_C1_LOG_PAGE ? "Supported" : "Not Supported");
printf("get-dev-capabilities-log : %s\n",
capabilities & SNDK_DRIVE_CAP_OCP_C4_LOG_PAGE ? "Supported" : "Not Supported");
printf("get-unsupported-reqs-log : %s\n",
capabilities & SNDK_DRIVE_CAP_OCP_C5_LOG_PAGE ? "Supported" : "Not Supported");
printf("get-latency-monitor-log : %s\n",
capabilities & SNDK_DRIVE_CAP_C3_LOG_PAGE ? "Supported" : "Not Supported");
printf("cloud-boot-SSD-version : %s\n",
capabilities & SNDK_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION ? "Supported" :
"Not Supported");
printf("vs-cloud-log : %s\n",
capabilities & SNDK_DRIVE_CAP_CLOUD_LOG_PAGE ? "Supported" : "Not Supported");
printf("vs-hw-rev-log : %s\n",
capabilities & SNDK_DRIVE_CAP_HW_REV_LOG_PAGE ? "Supported" : "Not Supported");
printf("vs-device_waf : %s\n",
capabilities & SNDK_DRIVE_CAP_DEVICE_WAF ? "Supported" : "Not Supported");
printf("set-latency-monitor-feature : %s\n",
capabilities & SNDK_DRIVE_CAP_SET_LATENCY_MONITOR ? "Supported" : "Not Supported");
printf("capabilities : Supported\n");
nvme_free_tree(r);
dev_close(dev);
return 0;
}
static int sndk_cloud_ssd_plugin_version(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_cloud_ssd_plugin_version(argc, argv, command, plugin);
}
static int sndk_vs_pcie_stats(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_pcie_stats(argc, argv, command, plugin);
}
static int sndk_get_latency_monitor_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_get_latency_monitor_log(argc, argv, command, plugin);
}
static int sndk_get_error_recovery_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_get_error_recovery_log(argc, argv, command, plugin);
}
static int sndk_get_dev_capabilities_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_get_dev_capabilities_log(argc, argv, command, plugin);
}
static int sndk_get_unsupported_reqs_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_get_unsupported_reqs_log(argc, argv, command, plugin);
}
static int sndk_cloud_boot_SSD_version(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_cloud_boot_SSD_version(argc, argv, command, plugin);
}
static int sndk_vs_cloud_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_cloud_log(argc, argv, command, plugin);
}
static int sndk_vs_hw_rev_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_hw_rev_log(argc, argv, command, plugin);
}
static int sndk_vs_device_waf(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_device_waf(argc, argv, command, plugin);
}
static int sndk_set_latency_monitor_feature(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_set_latency_monitor_feature(argc, argv, command, plugin);
}
static int sndk_vs_temperature_stats(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return run_wdc_vs_temperature_stats(argc, argv, command, plugin);
}

View file

@ -0,0 +1,81 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#undef CMD_INC_FILE
#define CMD_INC_FILE plugins/sandisk/sandisk-nvme
#if !defined(SANDISK_NVME) || defined(CMD_HEADER_MULTI_READ)
#define SANDISK_NVME
#define SANDISK_PLUGIN_VERSION "2.12.0"
#include "cmd.h"
PLUGIN(NAME("sndk", "Sandisk vendor specific extensions", SANDISK_PLUGIN_VERSION),
COMMAND_LIST(
ENTRY("vs-internal-log", "Sandisk Internal Firmware Log",
sndk_vs_internal_fw_log)
ENTRY("vs-nand-stats", "Sandisk NAND Statistics", sndk_vs_nand_stats)
ENTRY("vs-smart-add-log", "Sandisk Additional Smart Log",
sndk_vs_smart_add_log)
ENTRY("clear-pcie-correctable-errors",
"Sandisk Clear PCIe Correctable Error Count",
sndk_clear_pcie_correctable_errors)
ENTRY("get-drive-status", "Sandisk Get Drive Status",
sndk_drive_status)
ENTRY("clear-assert-dump", "Sandisk Clear Assert Dump",
sndk_clear_assert_dump)
ENTRY("drive-resize", "Sandisk Drive Resize", sndk_drive_resize)
ENTRY("vs-fw-activate-history", "Sandisk Get FW Activate History",
sndk_vs_fw_activate_history)
ENTRY("clear-fw-activate-history",
"Sandisk Clear FW Activate History",
sndk_clear_fw_activate_history)
ENTRY("vs-telemetry-controller-option",
"Sandisk Enable/Disable Controller Initiated Telemetry Log",
sndk_vs_telemetry_controller_option)
ENTRY("vs-error-reason-identifier",
"Sandisk Telemetry Reason Identifier",
sndk_reason_identifier)
ENTRY("log-page-directory", "Sandisk Get Log Page Directory",
sndk_log_page_directory)
ENTRY("namespace-resize", "Sandisk NamespaceDrive Resize",
sndk_namespace_resize)
ENTRY("vs-drive-info", "Sandisk Get Drive Info", sndk_vs_drive_info)
ENTRY("vs-temperature-stats", "Sandisk Get Temperature Stats",
sndk_vs_temperature_stats)
ENTRY("capabilities", "Sandisk Device Capabilities",
sndk_capabilities)
ENTRY("cloud-SSD-plugin-version",
"Sandisk Cloud SSD Plugin Version",
sndk_cloud_ssd_plugin_version)
ENTRY("vs-pcie-stats", "Sandisk VS PCIE Statistics",
sndk_vs_pcie_stats)
ENTRY("get-latency-monitor-log",
"Sandisk Get Latency Monitor Log Page",
sndk_get_latency_monitor_log)
ENTRY("get-error-recovery-log",
"Sandisk Get Error Recovery Log Page",
sndk_get_error_recovery_log)
ENTRY("get-dev-capabilities-log",
"Sandisk Get Device Capabilities Log Page",
sndk_get_dev_capabilities_log)
ENTRY("get-unsupported-reqs-log",
"Sandisk Get Unsupported Requirements Log Page",
sndk_get_unsupported_reqs_log)
ENTRY("cloud-boot-SSD-version",
"Sandisk Get the Cloud Boot SSD Version",
sndk_cloud_boot_SSD_version)
ENTRY("vs-cloud-log", "Sandisk Get the Cloud Log Page",
sndk_vs_cloud_log)
ENTRY("vs-hw-rev-log", "Sandisk Get the Hardware Revision Log Page",
sndk_vs_hw_rev_log)
ENTRY("vs-device-waf",
"Sandisk Calculate Device Write Amplication Factor",
sndk_vs_device_waf)
ENTRY("set-latency-monitor-feature",
"Sandisk set Latency Monitor feature",
sndk_set_latency_monitor_feature)
)
);
#endif
#include "define_cmd.h"

View file

@ -0,0 +1,534 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2025 Sandisk Corporation or its affiliates.
*
* Author: Jeff Lien <jeff.lien@sandisk.com>
* Brandon Paupore <brandon.paupore@sandisk.com>
*/
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include "nvme.h"
#include "libnvme.h"
#include "nvme-print.h"
#include "sandisk-utils.h"
#include "plugins/wdc/wdc-nvme-cmds.h"
int sndk_get_pci_ids(nvme_root_t r, struct nvme_dev *dev,
uint32_t *device_id, uint32_t *vendor_id)
{
char vid[256], did[256], id[32];
nvme_ctrl_t c = NULL;
nvme_ns_t n = NULL;
int fd, ret;
c = nvme_scan_ctrl(r, dev->name);
if (c) {
snprintf(vid, sizeof(vid), "%s/device/vendor",
nvme_ctrl_get_sysfs_dir(c));
snprintf(did, sizeof(did), "%s/device/device",
nvme_ctrl_get_sysfs_dir(c));
nvme_free_ctrl(c);
} else {
n = nvme_scan_namespace(dev->name);
if (!n) {
fprintf(stderr, "Unable to find %s\n", dev->name);
return -1;
}
snprintf(vid, sizeof(vid), "%s/device/device/vendor",
nvme_ns_get_sysfs_dir(n));
snprintf(did, sizeof(did), "%s/device/device/device",
nvme_ns_get_sysfs_dir(n));
nvme_free_ns(n);
}
fd = open(vid, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "ERROR: SNDK: %s : Open vendor file failed\n", __func__);
return -1;
}
ret = read(fd, id, 32);
close(fd);
if (ret < 0) {
fprintf(stderr, "%s: Read of pci vendor id failed\n", __func__);
return -1;
}
id[ret < 32 ? ret : 31] = '\0';
if (id[strlen(id) - 1] == '\n')
id[strlen(id) - 1] = '\0';
*vendor_id = strtol(id, NULL, 0);
ret = 0;
fd = open(did, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "ERROR: SNDK: %s : Open device file failed\n", __func__);
return -1;
}
ret = read(fd, id, 32);
close(fd);
if (ret < 0) {
fprintf(stderr, "ERROR: SNDK: %s: Read of pci device id failed\n", __func__);
return -1;
}
id[ret < 32 ? ret : 31] = '\0';
if (id[strlen(id) - 1] == '\n')
id[strlen(id) - 1] = '\0';
*device_id = strtol(id, NULL, 0);
return 0;
}
int sndk_get_vendor_id(struct nvme_dev *dev, uint32_t *vendor_id)
{
int ret;
struct nvme_id_ctrl ctrl;
memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
fprintf(stderr, "ERROR: SNDK: nvme_identify_ctrl() failed 0x%x\n", ret);
return -1;
}
*vendor_id = (uint32_t) ctrl.vid;
return ret;
}
bool sndk_check_device(nvme_root_t r, struct nvme_dev *dev)
{
int ret;
bool supported;
uint32_t read_device_id = -1, read_vendor_id = -1;
ret = sndk_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
if (ret < 0) {
/* Use the identify nvme command to get vendor id due to NVMeOF device. */
if (sndk_get_vendor_id(dev, &read_vendor_id) < 0)
return false;
}
supported = false;
if (read_vendor_id == SNDK_NVME_SNDK_VID ||
read_vendor_id == SNDK_NVME_WDC_VID)
supported = true;
else
fprintf(stderr,
"ERROR: SNDK: unsupported Sandisk device, Vendor ID = 0x%x, Device ID = 0x%x\n",
read_vendor_id, read_device_id);
return supported;
}
__u64 sndk_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
{
__u64 capabilities = 0;
int ret;
uint32_t read_device_id = -1, read_vendor_id = -1;
__u32 cust_id;
ret = sndk_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
if (ret < 0) {
if (sndk_get_vendor_id(dev, &read_vendor_id) < 0)
return capabilities;
}
/*
* Below check condition is added due in NVMeOF device
* We aren't able to read the device_id in this case
* so we can only use the vendor_id
*/
if (read_device_id == -1 && read_vendor_id != -1) {
capabilities = sndk_get_enc_drive_capabilities(r, dev);
return capabilities;
}
switch (read_vendor_id) {
case SNDK_NVME_WDC_VID:
switch (read_device_id) {
case SNDK_NVME_SN630_DEV_ID:
case SNDK_NVME_SN630_DEV_ID_1:
capabilities = (SNDK_DRIVE_CAP_INTERNAL_LOG |
SNDK_DRIVE_CAP_DRIVE_STATUS |
SNDK_DRIVE_CAP_CLEAR_ASSERT |
SNDK_DRIVE_CAP_RESIZE |
SNDK_DRIVE_CAP_CLEAR_PCIE);
/* verify the 0xCA log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_DEVICE_INFO_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_VU_SMART_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_D0_LOG_PAGE;
break;
case SNDK_NVME_SN640_DEV_ID:
case SNDK_NVME_SN640_DEV_ID_1:
case SNDK_NVME_SN640_DEV_ID_2:
case SNDK_NVME_SN640_DEV_ID_3:
/* verify the 0xC0 log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_SMART_CLOUD_ATTR_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_C0_LOG_PAGE;
capabilities |= (SNDK_DRIVE_CAP_INTERNAL_LOG |
SNDK_DRIVE_CAP_DRIVE_STATUS |
SNDK_DRIVE_CAP_CLEAR_ASSERT |
SNDK_DRIVE_CAP_RESIZE |
SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY |
SNDK_DRIVE_CAP_DISABLE_CTLR_TELE_LOG |
SNDK_DRIVE_CAP_REASON_ID |
SNDK_DRIVE_CAP_LOG_PAGE_DIR);
/* verify the 0xC1 (OCP Error Recovery) log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_ERROR_REC_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_OCP_C1_LOG_PAGE;
/* verify the 0xC3 (OCP Latency Monitor) log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_LATENCY_MON_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_C3_LOG_PAGE;
/* verify the 0xC4 (OCP Device Capabilities) log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_DEV_CAP_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_OCP_C4_LOG_PAGE;
/* verify the 0xC5 (OCP Unsupported Requirements) log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_UNSUPPORTED_REQS_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_OCP_C5_LOG_PAGE;
/* verify the 0xCA log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_DEVICE_INFO_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_VU_SMART_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_D0_LOG_PAGE;
cust_id = run_wdc_get_fw_cust_id(r, dev);
if (cust_id == SNDK_INVALID_CUSTOMER_ID) {
fprintf(stderr, "%s: ERROR: SNDK: invalid customer id\n", __func__);
return -1;
}
if ((cust_id == SNDK_CUSTOMER_ID_0x1004) ||
(cust_id == SNDK_CUSTOMER_ID_0x1008) ||
(cust_id == SNDK_CUSTOMER_ID_0x1005) ||
(cust_id == SNDK_CUSTOMER_ID_0x1304))
capabilities |= (SNDK_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE |
SNDK_DRIVE_CAP_INFO |
SNDK_DRIVE_CAP_CLOUD_SSD_VERSION);
else
capabilities |= (SNDK_DRIVE_CAP_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_CLEAR_PCIE);
break;
case SNDK_NVME_SN840_DEV_ID:
case SNDK_NVME_SN840_DEV_ID_1:
/* verify the 0xC0 log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_EOL_STATUS_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_C0_LOG_PAGE;
capabilities |= (SNDK_DRIVE_CAP_INTERNAL_LOG |
SNDK_DRIVE_CAP_DRIVE_STATUS |
SNDK_DRIVE_CAP_CLEAR_ASSERT |
SNDK_DRIVE_CAP_RESIZE |
SNDK_DRIVE_CAP_CLEAR_PCIE |
SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY |
SNDK_DRIVE_CAP_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_DISABLE_CTLR_TELE_LOG |
SNDK_DRIVE_CAP_REASON_ID |
SNDK_DRIVE_CAP_LOG_PAGE_DIR);
/* verify the 0xCA log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_DEVICE_INFO_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_VU_SMART_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_D0_LOG_PAGE;
break;
case SNDK_NVME_SN650_DEV_ID:
case SNDK_NVME_SN650_DEV_ID_1:
case SNDK_NVME_SN650_DEV_ID_2:
case SNDK_NVME_SN650_DEV_ID_3:
case SNDK_NVME_SN650_DEV_ID_4:
case SNDK_NVME_SN655_DEV_ID:
case SNDK_NVME_SN655_DEV_ID_1:
/* verify the 0xC0 log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_SMART_CLOUD_ATTR_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_C0_LOG_PAGE;
/* verify the 0xC1 (OCP Error Recovery) log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_ERROR_REC_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_OCP_C1_LOG_PAGE;
/* verify the 0xC3 (OCP Latency Monitor) log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_LATENCY_MON_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_C3_LOG_PAGE;
/* verify the 0xC4 (OCP Device Capabilities) log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_DEV_CAP_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_OCP_C4_LOG_PAGE;
/* verify the 0xC5 (OCP Unsupported Requirements) log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_UNSUPPORTED_REQS_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_OCP_C5_LOG_PAGE;
capabilities |= (SNDK_DRIVE_CAP_INTERNAL_LOG |
SNDK_DRIVE_CAP_DRIVE_STATUS |
SNDK_DRIVE_CAP_CLEAR_ASSERT |
SNDK_DRIVE_CAP_RESIZE |
SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY |
SNDK_DRIVE_CAP_DISABLE_CTLR_TELE_LOG |
SNDK_DRIVE_CAP_REASON_ID |
SNDK_DRIVE_CAP_LOG_PAGE_DIR);
cust_id = run_wdc_get_fw_cust_id(r, dev);
if (cust_id == SNDK_INVALID_CUSTOMER_ID) {
fprintf(stderr, "%s: ERROR: SNDK: invalid customer id\n", __func__);
return -1;
}
if ((cust_id == SNDK_CUSTOMER_ID_0x1004) ||
(cust_id == SNDK_CUSTOMER_ID_0x1008) ||
(cust_id == SNDK_CUSTOMER_ID_0x1005) ||
(cust_id == SNDK_CUSTOMER_ID_0x1304))
capabilities |= (SNDK_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE |
SNDK_DRIVE_CAP_INFO |
SNDK_DRIVE_CAP_CLOUD_SSD_VERSION);
else
capabilities |= (SNDK_DRIVE_CAP_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_CLEAR_PCIE);
break;
case SNDK_NVME_SN861_DEV_ID:
case SNDK_NVME_SN861_DEV_ID_1:
case SNDK_NVME_SN861_DEV_ID_2:
capabilities |= (SNDK_DRIVE_CAP_C0_LOG_PAGE |
SNDK_DRIVE_CAP_C3_LOG_PAGE |
SNDK_DRIVE_CAP_CA_LOG_PAGE |
SNDK_DRIVE_CAP_OCP_C4_LOG_PAGE |
SNDK_DRIVE_CAP_OCP_C5_LOG_PAGE |
SNDK_DRIVE_CAP_INTERNAL_LOG |
SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2 |
SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE |
SNDK_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_INFO |
SNDK_DRIVE_CAP_CLOUD_SSD_VERSION |
SNDK_DRIVE_CAP_LOG_PAGE_DIR |
SNDK_DRIVE_CAP_DRIVE_STATUS |
SNDK_DRIVE_CAP_SET_LATENCY_MONITOR);
break;
case SNDK_NVME_SNTMP_DEV_ID:
capabilities |= (SNDK_DRIVE_CAP_C0_LOG_PAGE |
SNDK_DRIVE_CAP_C3_LOG_PAGE |
SNDK_DRIVE_CAP_CA_LOG_PAGE |
SNDK_DRIVE_CAP_OCP_C4_LOG_PAGE |
SNDK_DRIVE_CAP_OCP_C5_LOG_PAGE |
SNDK_DRIVE_CAP_DUI |
SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2 |
SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE |
SNDK_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_INFO |
SNDK_DRIVE_CAP_CLOUD_SSD_VERSION |
SNDK_DRIVE_CAP_LOG_PAGE_DIR |
SNDK_DRIVE_CAP_DRIVE_STATUS |
SNDK_DRIVE_CAP_SET_LATENCY_MONITOR);
break;
default:
capabilities = 0;
}
break;
case SNDK_NVME_SNDK_VID:
switch (read_device_id) {
case SNDK_NVME_SN520_DEV_ID:
case SNDK_NVME_SN520_DEV_ID_1:
case SNDK_NVME_SN520_DEV_ID_2:
case SNDK_NVME_SN810_DEV_ID:
capabilities = SNDK_DRIVE_CAP_DUI_DATA;
break;
case SNDK_NVME_SN820CL_DEV_ID:
capabilities = SNDK_DRIVE_CAP_DUI_DATA |
SNDK_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION |
SNDK_DRIVE_CAP_CLOUD_LOG_PAGE |
SNDK_DRIVE_CAP_C0_LOG_PAGE |
SNDK_DRIVE_CAP_HW_REV_LOG_PAGE |
SNDK_DRIVE_CAP_INFO |
SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE |
SNDK_DRIVE_CAP_NAND_STATS |
SNDK_DRIVE_CAP_DEVICE_WAF |
SNDK_DRIVE_CAP_TEMP_STATS;
break;
case SNDK_NVME_SN720_DEV_ID:
capabilities = SNDK_DRIVE_CAP_DUI_DATA |
SNDK_DRIVE_CAP_NAND_STATS |
SNDK_DRIVE_CAP_NS_RESIZE;
break;
case SNDK_NVME_SN730_DEV_ID:
capabilities = SNDK_DRIVE_CAP_DUI |
SNDK_DRIVE_CAP_NAND_STATS |
SNDK_DRIVE_CAP_INFO |
SNDK_DRIVE_CAP_TEMP_STATS |
SNDK_DRIVE_CAP_VUC_CLEAR_PCIE |
SNDK_DRIVE_CAP_PCIE_STATS;
break;
case SNDK_NVME_SN530_DEV_ID_1:
case SNDK_NVME_SN530_DEV_ID_2:
case SNDK_NVME_SN530_DEV_ID_3:
case SNDK_NVME_SN530_DEV_ID_4:
case SNDK_NVME_SN530_DEV_ID_5:
case SNDK_NVME_SN350_DEV_ID:
case SNDK_NVME_SN570_DEV_ID:
case SNDK_NVME_SN850X_DEV_ID:
case SNDK_NVME_SN5000_DEV_ID_1:
case SNDK_NVME_SN5000_DEV_ID_2:
case SNDK_NVME_SN5000_DEV_ID_3:
case SNDK_NVME_SN5000_DEV_ID_4:
case SNDK_NVME_SN7000S_DEV_ID_1:
case SNDK_NVME_SN7150_DEV_ID_1:
case SNDK_NVME_SN7150_DEV_ID_2:
case SNDK_NVME_SN7150_DEV_ID_3:
case SNDK_NVME_SN7150_DEV_ID_4:
case SNDK_NVME_SN7150_DEV_ID_5:
case SNDK_NVME_SN7100_DEV_ID_1:
case SNDK_NVME_SN7100_DEV_ID_2:
case SNDK_NVME_SN7100_DEV_ID_3:
case SNDK_NVME_SN8000S_DEV_ID:
case SNDK_NVME_SN5100S_DEV_ID_1:
case SNDK_NVME_SN5100S_DEV_ID_2:
case SNDK_NVME_SN5100S_DEV_ID_3:
case SNDK_NVME_SN740_DEV_ID:
case SNDK_NVME_SN740_DEV_ID_1:
case SNDK_NVME_SN740_DEV_ID_2:
case SNDK_NVME_SN740_DEV_ID_3:
case SNDK_NVME_SN340_DEV_ID:
capabilities = SNDK_DRIVE_CAP_DUI;
break;
case SNDK_NVME_ZN350_DEV_ID:
case SNDK_NVME_ZN350_DEV_ID_1:
capabilities = SNDK_DRIVE_CAP_DUI_DATA |
SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE |
SNDK_DRIVE_CAP_C0_LOG_PAGE |
SNDK_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2 |
SNDK_DRIVE_CAP_INFO |
SNDK_DRIVE_CAP_CLOUD_SSD_VERSION |
SNDK_DRIVE_CAP_LOG_PAGE_DIR;
break;
default:
capabilities = 0;
}
break;
default:
capabilities = 0;
}
return capabilities;
}
__u64 sndk_get_enc_drive_capabilities(nvme_root_t r,
struct nvme_dev *dev)
{
int ret;
uint32_t read_vendor_id;
__u64 capabilities = 0;
__u32 cust_id;
ret = sndk_get_vendor_id(dev, &read_vendor_id);
if (ret < 0)
return capabilities;
switch (read_vendor_id) {
case SNDK_NVME_WDC_VID:
capabilities = (SNDK_DRIVE_CAP_INTERNAL_LOG |
SNDK_DRIVE_CAP_DRIVE_STATUS |
SNDK_DRIVE_CAP_CLEAR_ASSERT |
SNDK_DRIVE_CAP_RESIZE);
/* verify the 0xC3 log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_LATENCY_MON_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_C3_LOG_PAGE;
/* verify the 0xCB log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_FW_ACT_HISTORY_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY;
/* verify the 0xCA log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_DEVICE_INFO_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
if (run_wdc_nvme_check_supported_log_page(r, dev,
SNDK_NVME_GET_VU_SMART_LOG_ID))
capabilities |= SNDK_DRIVE_CAP_D0_LOG_PAGE;
cust_id = run_wdc_get_fw_cust_id(r, dev);
if (cust_id == SNDK_INVALID_CUSTOMER_ID) {
fprintf(stderr, "%s: ERROR: SNDK: invalid customer id\n", __func__);
return -1;
}
if ((cust_id == SNDK_CUSTOMER_ID_0x1004) ||
(cust_id == SNDK_CUSTOMER_ID_0x1008) ||
(cust_id == SNDK_CUSTOMER_ID_0x1005) ||
(cust_id == SNDK_CUSTOMER_ID_0x1304))
capabilities |= (SNDK_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE);
else
capabilities |= (SNDK_DRIVE_CAP_CLEAR_FW_ACT_HISTORY |
SNDK_DRIVE_CAP_CLEAR_PCIE);
break;
default:
capabilities = 0;
}
return capabilities;
}

View file

@ -0,0 +1,192 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2025 Sandisk Corporation or its affiliates.
*
* Author: Jeff Lien <jeff.lien@sandisk.com>
* Brandon Paupore <brandon.paupore@sandisk.com>
*/
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
/* Device Config */
#define SNDK_NVME_WDC_VID 0x1b96
#define SNDK_NVME_SNDK_VID 0x15b7
#define SNDK_NVME_SN630_DEV_ID 0x2200
#define SNDK_NVME_SN630_DEV_ID_1 0x2201
#define SNDK_NVME_SN840_DEV_ID 0x2300
#define SNDK_NVME_SN840_DEV_ID_1 0x2500
#define SNDK_NVME_SN640_DEV_ID 0x2400
#define SNDK_NVME_SN640_DEV_ID_1 0x2401
#define SNDK_NVME_SN640_DEV_ID_2 0x2402
#define SNDK_NVME_SN640_DEV_ID_3 0x2404
#define SNDK_NVME_SN650_DEV_ID 0x2700
#define SNDK_NVME_SN650_DEV_ID_1 0x2701
#define SNDK_NVME_SN650_DEV_ID_2 0x2702
#define SNDK_NVME_SN650_DEV_ID_3 0x2720
#define SNDK_NVME_SN650_DEV_ID_4 0x2721
#define SNDK_NVME_SN655_DEV_ID 0x2722
#define SNDK_NVME_SN655_DEV_ID_1 0x2723
#define SNDK_NVME_SN861_DEV_ID 0x2750
#define SNDK_NVME_SN861_DEV_ID_1 0x2751
#define SNDK_NVME_SN861_DEV_ID_2 0x2752
#define SNDK_NVME_SNTMP_DEV_ID 0x2761
#define SNDK_NVME_SN520_DEV_ID 0x5003
#define SNDK_NVME_SN520_DEV_ID_1 0x5004
#define SNDK_NVME_SN520_DEV_ID_2 0x5005
#define SNDK_NVME_SN530_DEV_ID_1 0x5007
#define SNDK_NVME_SN530_DEV_ID_2 0x5008
#define SNDK_NVME_SN530_DEV_ID_3 0x5009
#define SNDK_NVME_SN530_DEV_ID_4 0x500b
#define SNDK_NVME_SN530_DEV_ID_5 0x501d
#define SNDK_NVME_SN350_DEV_ID 0x5019
#define SNDK_NVME_SN570_DEV_ID 0x501A
#define SNDK_NVME_SN850X_DEV_ID 0x5030
#define SNDK_NVME_SN5000_DEV_ID_1 0x5034
#define SNDK_NVME_SN5000_DEV_ID_2 0x5035
#define SNDK_NVME_SN5000_DEV_ID_3 0x5036
#define SNDK_NVME_SN5000_DEV_ID_4 0x504A
#define SNDK_NVME_SN7000S_DEV_ID_1 0x5039
#define SNDK_NVME_SN7150_DEV_ID_1 0x503b
#define SNDK_NVME_SN7150_DEV_ID_2 0x503c
#define SNDK_NVME_SN7150_DEV_ID_3 0x503d
#define SNDK_NVME_SN7150_DEV_ID_4 0x503e
#define SNDK_NVME_SN7150_DEV_ID_5 0x503f
#define SNDK_NVME_SN7100_DEV_ID_1 0x5043
#define SNDK_NVME_SN7100_DEV_ID_2 0x5044
#define SNDK_NVME_SN7100_DEV_ID_3 0x5045
#define SNDK_NVME_SN8000S_DEV_ID 0x5049
#define SNDK_NVME_SN720_DEV_ID 0x5002
#define SNDK_NVME_SN730_DEV_ID 0x5006
#define SNDK_NVME_SN740_DEV_ID 0x5015
#define SNDK_NVME_SN740_DEV_ID_1 0x5016
#define SNDK_NVME_SN740_DEV_ID_2 0x5017
#define SNDK_NVME_SN740_DEV_ID_3 0x5025
#define SNDK_NVME_SN340_DEV_ID 0x500d
#define SNDK_NVME_ZN350_DEV_ID 0x5010
#define SNDK_NVME_ZN350_DEV_ID_1 0x5018
#define SNDK_NVME_SN810_DEV_ID 0x5011
#define SNDK_NVME_SN820CL_DEV_ID 0x5037
#define SNDK_NVME_SN5100S_DEV_ID_1 0x5061
#define SNDK_NVME_SN5100S_DEV_ID_2 0x5062
#define SNDK_NVME_SN5100S_DEV_ID_3 0x5063
#define SNDK_DRIVE_CAP_INTERNAL_LOG 0x0000000000000001
#define SNDK_DRIVE_CAP_C1_LOG_PAGE 0x0000000000000002
#define SNDK_DRIVE_CAP_CA_LOG_PAGE 0x0000000000000004
#define SNDK_DRIVE_CAP_D0_LOG_PAGE 0x0000000000000008
#define SNDK_DRIVE_CAP_DRIVE_STATUS 0x0000000000000010
#define SNDK_DRIVE_CAP_CLEAR_ASSERT 0x0000000000000020
#define SNDK_DRIVE_CAP_CLEAR_PCIE 0x0000000000000040
#define SNDK_DRIVE_CAP_RESIZE 0x0000000000000080
#define SNDK_DRIVE_CAP_NAND_STATS 0x0000000000000100
#define SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY 0x0000000000000200
#define SNDK_DRIVE_CAP_CLEAR_FW_ACT_HISTORY 0x0000000000000400
#define SNDK_DRIVE_CAP_DISABLE_CTLR_TELE_LOG 0x0000000000000800
#define SNDK_DRIVE_CAP_REASON_ID 0x0000000000001000
#define SNDK_DRIVE_CAP_LOG_PAGE_DIR 0x0000000000002000
#define SNDK_DRIVE_CAP_NS_RESIZE 0x0000000000004000
#define SNDK_DRIVE_CAP_INFO 0x0000000000008000
#define SNDK_DRIVE_CAP_C0_LOG_PAGE 0x0000000000010000
#define SNDK_DRIVE_CAP_TEMP_STATS 0x0000000000020000
#define SNDK_DRIVE_CAP_VUC_CLEAR_PCIE 0x0000000000040000
#define SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE 0x0000000000080000
#define SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2 0x0000000000100000
#define SNDK_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY 0x0000000000200000
#define SNDK_DRIVE_CAP_CLOUD_SSD_VERSION 0x0000000000400000
#define SNDK_DRIVE_CAP_PCIE_STATS 0x0000000000800000
#define SNDK_DRIVE_CAP_HW_REV_LOG_PAGE 0x0000000001000000
#define SNDK_DRIVE_CAP_C3_LOG_PAGE 0x0000000002000000
#define SNDK_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION 0x0000000004000000
#define SNDK_DRIVE_CAP_CLOUD_LOG_PAGE 0x0000000008000000
#define SNDK_DRIVE_CAP_DUI_DATA 0x0000000010000000
#define SNDK_DRIVE_CAP_VUC_LOG 0x0000000020000000
#define SNDK_DRIVE_CAP_DUI 0x0000000040000000
#define SNDK_DRIVE_CAP_OCP_C1_LOG_PAGE 0x0000000080000000
#define SNDK_DRIVE_CAP_OCP_C4_LOG_PAGE 0x0000000100000000
#define SNDK_DRIVE_CAP_OCP_C5_LOG_PAGE 0x0000000200000000
#define SNDK_DRIVE_CAP_DEVICE_WAF 0x0000000400000000
#define SNDK_DRIVE_CAP_SET_LATENCY_MONITOR 0x0000000800000000
#define SNDK_DRIVE_CAP_SMART_LOG_MASK (SNDK_DRIVE_CAP_C0_LOG_PAGE | \
SNDK_DRIVE_CAP_C1_LOG_PAGE | \
SNDK_DRIVE_CAP_CA_LOG_PAGE | \
SNDK_DRIVE_CAP_D0_LOG_PAGE)
#define SNDK_DRIVE_CAP_CLEAR_PCIE_MASK (SNDK_DRIVE_CAP_CLEAR_PCIE | \
SNDK_DRIVE_CAP_VUC_CLEAR_PCIE | \
SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE)
#define SNDK_DRIVE_CAP_INTERNAL_LOG_MASK (SNDK_DRIVE_CAP_INTERNAL_LOG | \
SNDK_DRIVE_CAP_DUI | \
SNDK_DRIVE_CAP_DUI_DATA | \
SNDK_DRIVE_CAP_VUC_LOG)
#define SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK (SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY | \
SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2)
#define SNDK_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK (SNDK_DRIVE_CAP_CLEAR_FW_ACT_HISTORY | \
SNDK_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY)
/* Vendor defined Log Page IDs */
#define SNDK_NVME_GET_SMART_CLOUD_ATTR_LOG_ID 0xC0
#define SNDK_NVME_GET_EOL_STATUS_LOG_ID 0xC0
#define SNDK_ERROR_REC_LOG_ID 0xC1
#define SNDK_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID 0xC2
#define SNDK_LATENCY_MON_LOG_ID 0xC3
#define SNDK_DEV_CAP_LOG_ID 0xC4
#define SNDK_UNSUPPORTED_REQS_LOG_ID 0xC5
#define SNDK_NVME_GET_DEVICE_INFO_LOG_ID 0xCA
#define SNDK_NVME_GET_FW_ACT_HISTORY_LOG_ID 0xCB
#define SNDK_NVME_GET_VU_SMART_LOG_ID 0xD0
/* Customer ID's */
#define SNDK_CUSTOMER_ID_GN 0x0001
#define SNDK_CUSTOMER_ID_GD 0x0101
#define SNDK_CUSTOMER_ID_BD 0x1009
#define SNDK_CUSTOMER_ID_0x1004 0x1004
#define SNDK_CUSTOMER_ID_0x1005 0x1005
#define SNDK_CUSTOMER_ID_0x1008 0x1008
#define SNDK_CUSTOMER_ID_0x1304 0x1304
#define SNDK_INVALID_CUSTOMER_ID -1
int sndk_get_pci_ids(nvme_root_t r,
struct nvme_dev *dev,
uint32_t *device_id,
uint32_t *vendor_id);
int sndk_get_vendor_id(struct nvme_dev *dev,
uint32_t *vendor_id);
bool sndk_check_device(nvme_root_t r,
struct nvme_dev *dev);
__u64 sndk_get_drive_capabilities(nvme_root_t r,
struct nvme_dev *dev);
__u64 sndk_get_enc_drive_capabilities(nvme_root_t r,
struct nvme_dev *dev);

View file

@ -1,4 +1,5 @@
sources += [
'plugins/solidigm/solidigm-nvme.c',
'plugins/solidigm/solidigm-id-ctrl.c',
'plugins/solidigm/solidigm-util.c',
'plugins/solidigm/solidigm-smart.c',

View file

@ -13,7 +13,7 @@
#include "cmd.h"
#define SOLIDIGM_PLUGIN_VERSION "1.9"
#define SOLIDIGM_PLUGIN_VERSION "1.11"
PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION),
COMMAND_LIST(

View file

@ -41,6 +41,19 @@ struct __packed nvme_additional_smart_log_item {
__u8 _rp;
};
struct __packed smart_ref_clk {
__u8 id;
__u8 _kp[2];
__u8 normalized;
__le16 gainCount0;
__le16 lossCount0;
__le16 gainCount1;
__le16 lossCount1;
};
_Static_assert(sizeof(struct nvme_additional_smart_log_item) == sizeof(struct smart_ref_clk),
"Size mismatch for smart_ref_clk");
#define VU_SMART_PAGE_SIZE 512
#define VU_SMART_MAX_ITEMS (VU_SMART_PAGE_SIZE / sizeof(struct nvme_additional_smart_log_item))
struct vu_smart_log {
@ -113,6 +126,8 @@ static char *id_to_name(__u8 id)
static void smart_log_item_print(struct nvme_additional_smart_log_item *item)
{
struct smart_ref_clk *pll_item = (struct smart_ref_clk *)item;
if (!item->id)
return;
@ -131,6 +146,14 @@ static void smart_log_item_print(struct nvme_additional_smart_log_item *item)
item->thermal_throttle.pct,
le32_to_cpu(item->thermal_throttle.count));
return;
case 0xF3:
printf("gain0: %u, loss0: %u, gain1: %u, loss1: %u, legacy:%lu\n",
le16_to_cpu(pll_item->gainCount0),
le16_to_cpu(pll_item->lossCount0),
le16_to_cpu(pll_item->gainCount1),
le16_to_cpu(pll_item->lossCount1),
int48_to_long(item->raw));
return;
default:
printf("%"PRIu64"\n", int48_to_long(item->raw));
}
@ -138,6 +161,7 @@ static void smart_log_item_print(struct nvme_additional_smart_log_item *item)
static void smart_log_item_add_json(struct nvme_additional_smart_log_item *item, struct json_object *dev_stats)
{
struct smart_ref_clk *pll_item = (struct smart_ref_clk *)item;
struct json_object *entry_stats = json_create_object();
if (!item->id)
@ -155,6 +179,13 @@ static void smart_log_item_add_json(struct nvme_additional_smart_log_item *item,
json_object_add_value_int(entry_stats, "percentage", item->thermal_throttle.pct);
json_object_add_value_int(entry_stats, "count", le32_to_cpu(item->thermal_throttle.count));
break;
case 0xF3:
json_object_add_value_int(entry_stats, "gain0", le16_to_cpu(pll_item->gainCount0));
json_object_add_value_int(entry_stats, "loss0", le16_to_cpu(pll_item->lossCount0));
json_object_add_value_int(entry_stats, "gain1", le16_to_cpu(pll_item->gainCount1));
json_object_add_value_int(entry_stats, "loss1", le16_to_cpu(pll_item->lossCount1));
json_object_add_value_int(entry_stats, "legacy", int48_to_long(item->raw));
break;
default:
json_object_add_value_int(entry_stats, "raw", int48_to_long(item->raw));
}
@ -198,7 +229,7 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
const int solidigm_vu_smart_log_id = 0xCA;
struct vu_smart_log smart_log_payload;
nvme_print_flags_t flags;
struct nvme_dev *dev;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
int err;
__u8 uuid_index;
@ -215,6 +246,7 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, "(optional) desired namespace"),
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
OPT_INCR("verbose", 'v', &nvme_cfg.verbose, verbose),
OPT_END()
};
@ -263,9 +295,6 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
nvme_show_status(err);
}
/* Redundant close() to make static code analysis happy */
close(dev->direct.fd);
dev_close(dev);
return err;
}

View file

@ -29,7 +29,7 @@ static int read_file2buffer(char *file_name, char **buffer, size_t *length)
FILE *fd = fopen(file_name, "rb");
if (!fd)
return errno;
return -errno;
fseek(fd, 0, SEEK_END);
size_t length_bytes = ftell(fd);
@ -39,7 +39,7 @@ static int read_file2buffer(char *file_name, char **buffer, size_t *length)
*buffer = malloc(length_bytes);
if (!*buffer) {
fclose(fd);
return errno;
return -errno;
}
*length = fread(*buffer, 1, length_bytes, fd);
fclose(fd);
@ -51,9 +51,15 @@ struct config {
bool ctrl_init;
int data_area;
char *cfg_file;
bool is_input_file;
char *binary_file;
};
static void cleanup_json_object(struct json_object **jobj_ptr)
{
json_free_object(*jobj_ptr);
*jobj_ptr = NULL;
}
int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Parse Solidigm Telemetry log";
@ -61,20 +67,25 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
const char *cgen = "Gather report generated by the controller.";
const char *dgen = "Pick which telemetry data area to report. Default is 3 to fetch areas 1-3. Valid options are 1, 2, 3, 4.";
const char *cfile = "JSON configuration file";
const char *sfile = "data source <device> is binary file containing log dump instead of block or character device";
struct nvme_dev *dev;
const char *sfile = "binary file containing log dump";
bool has_binary_file = false;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
_cleanup_free_ struct nvme_telemetry_log *tlog = NULL;
__attribute__((cleanup(cleanup_json_object))) struct json_object *configuration = NULL;
__attribute__((cleanup(cleanup_json_object))) struct json_object *root =
json_create_object();
struct telemetry_log tl = {
.root = json_create_object(),
.log = NULL,
.root = root,
};
struct config cfg = {
.host_gen = 1,
.ctrl_init = false,
.data_area = -1,
.cfg_file = NULL,
.is_input_file = false,
};
OPT_ARGS(opts) = {
@ -82,54 +93,61 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
OPT_FLAG("controller-init", 'c', &cfg.ctrl_init, cgen),
OPT_UINT("data-area", 'd', &cfg.data_area, dgen),
OPT_FILE("config-file", 'j', &cfg.cfg_file, cfile),
OPT_FLAG("source-file", 's', &cfg.is_input_file, sfile),
OPT_FILE("source-file", 's', &cfg.binary_file, sfile),
OPT_INCR("verbose", 'v', &nvme_cfg.verbose, verbose),
OPT_END()
};
int err = argconfig_parse(argc, argv, desc, opts);
if (err)
goto ret;
if (err) {
nvme_show_status(err);
return err;
}
/* When not selected on the command line, get minimum data area required */
if (cfg.data_area == -1)
cfg.data_area = cfg.cfg_file ? 3 : 1;
if (!argconfig_parse_seen(opts, "data-area"))
cfg.data_area = argconfig_parse_seen(opts, "config-file") ? 3 : 1;
if (cfg.is_input_file) {
if (optind >= argc) {
err = errno = EINVAL;
perror(argv[0]);
goto ret;
has_binary_file = argconfig_parse_seen(opts, "source-file");
if (has_binary_file) {
// If a binary file is provided, we don't want to open a device.
// GNU getopt() permutes the contents of argv as it scans,
// so that eventually all the nonoptions are at the end.
if (argc > optind) {
errno = EINVAL;
err = -errno;
nvme_show_status(err);
return err;
}
char *binary_file_name = argv[optind];
err = read_file2buffer(binary_file_name, (char **)&tl.log, &tl.log_size);
err = read_file2buffer(cfg.binary_file, (char **)&tlog, &tl.log_size);
} else {
err = parse_and_open(&dev, argc, argv, desc, opts);
}
if (err)
goto ret;
if (err) {
nvme_show_status(err);
return err;
}
if (cfg.host_gen > 1) {
SOLIDIGM_LOG_WARNING("Invalid host-generate value '%d'", cfg.host_gen);
err = EINVAL;
goto close_fd;
err = -EINVAL;
nvme_show_status(err);
return err;
}
if (cfg.cfg_file) {
char *conf_str = NULL;
if (argconfig_parse_seen(opts, "config-file")) {
_cleanup_free_ char *conf_str = NULL;
size_t length = 0;
err = read_file2buffer(cfg.cfg_file, &conf_str, &length);
if (err) {
SOLIDIGM_LOG_WARNING("Failed to open JSON configuration file %s: %s!",
cfg.cfg_file, strerror(err));
goto close_fd;
nvme_show_status(err);
return err;
}
struct json_tokener *jstok = json_tokener_new();
tl.configuration = json_tokener_parse_ex(jstok, conf_str, length);
free(conf_str);
configuration = json_tokener_parse_ex(jstok, conf_str, length);
if (jstok->err != json_tokener_success) {
SOLIDIGM_LOG_WARNING("Parsing error on JSON configuration file %s: %s (at offset %d)",
cfg.cfg_file,
@ -137,12 +155,13 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
jstok->char_offset);
json_tokener_free(jstok);
err = EINVAL;
goto close_fd;
return err;
}
json_tokener_free(jstok);
tl.configuration = configuration;
}
if (!cfg.is_input_file) {
if (!has_binary_file) {
size_t max_data_tx;
size_t power2;
__u8 mdts = 0;
@ -151,11 +170,11 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
if (err < 0) {
SOLIDIGM_LOG_WARNING("identify_ctrl: %s",
nvme_strerror(errno));
goto close_fd;
return err;
} else if (err > 0) {
nvme_show_status(err);
SOLIDIGM_LOG_WARNING("Failed to acquire identify ctrl %d!", err);
goto close_fd;
return err;
}
power2 = max_data_tx / NVME_LOG_PAGE_PDU_SIZE;
while (power2 && !(1 & power2)) {
@ -164,31 +183,22 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
}
err = sldgm_dynamic_telemetry(dev_fd(dev), cfg.host_gen, cfg.ctrl_init, true,
mdts, cfg.data_area, &tl.log, &tl.log_size);
mdts, cfg.data_area, &tlog, &tl.log_size);
if (err < 0) {
SOLIDIGM_LOG_WARNING("get-telemetry-log: %s",
nvme_strerror(errno));
goto close_fd;
return err;
} else if (err > 0) {
nvme_show_status(err);
SOLIDIGM_LOG_WARNING("Failed to acquire telemetry log %d!", err);
goto close_fd;
return err;
}
}
tl.log = tlog;
solidigm_telemetry_log_data_areas_parse(&tl, cfg.data_area);
json_print_object(tl.root, NULL);
json_free_object(tl.root);
printf("\n");
close_fd:
if (!cfg.is_input_file) {
/* Redundant close() to make static code analysis happy */
close(dev->direct.fd);
dev_close(dev);
}
ret:
json_free_object(tl.configuration);
free(tl.log);
return err;
}

View file

@ -18,6 +18,23 @@
#define MAX_WARNING_SIZE 1024
#define MAX_ARRAY_RANK 16
#define NLOG_HEADER_ID 101
static void reverse_string(char *buff, size_t len)
{
char *start = buff;
char *end = buff + len - 1;
char temp;
while (end > start) {
temp = *end;
*end = *start;
*start = temp;
start++;
end--;
}
}
static bool telemetry_log_get_value(const struct telemetry_log *tl,
uint64_t offset_bit, uint32_t size_bit,
@ -418,6 +435,13 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
header->Token);
if (!nlog_name)
continue;
// NLOGs have different parser from other Telemetry objects
has_struct = solidigm_config_get_struct_by_token_version(tl->configuration,
NLOG_HEADER_ID,
header->versionMajor,
header->versionMinor,
&structure_definition);
}
struct json_object *tele_obj_item = json_create_object();
@ -443,29 +467,72 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
telemetry_log_structure_parse(tl, structure_definition,
BITS_IN_BYTE * object_file_offset,
parsed_struct, toc_item);
} else if (nlog_formats) {
}
// NLOGs have different parser from other Telemetry objects
if (nlog_name) {
if (has_struct) {
struct json_object *header_sizeBits = NULL;
struct json_object *header_nlogSelect = NULL;
struct json_object *header_nlogName = NULL;
if (json_object_object_get_ex(structure_definition, "sizeBit",
&header_sizeBits))
header_offset = json_object_get_int(header_sizeBits) /
BITS_IN_BYTE;
// Overwrite nlogName with correct type
if (json_object_object_get_ex(parsed_struct, "nlogSelect",
&header_nlogSelect) &&
json_object_object_get_ex(header_nlogSelect, "nlogName",
&header_nlogName)) {
int nlogName = json_object_get_int(header_nlogName);
char *name = (char *)&nlogName;
reverse_string(name, sizeof(uint32_t));
json_object_object_add(header_nlogSelect, "nlogName",
json_object_new_string_len(name,
sizeof(uint32_t)));
}
}
// Overwrite the object name
json_object_object_add(toc_item, "objName",
json_object_new_string(nlog_name));
telemetry_log_nlog_parse(tl, nlog_formats, object_file_offset,
telemetry_log_nlog_parse(tl, nlog_formats,
object_file_offset + header_offset,
toc->items[i].ContentSizeBytes - header_offset,
parsed_struct, toc_item);
}
}
}
void solidigm_telemetry_log_da1_check_ocp(struct telemetry_log *tl)
{
const uint64_t ocp_telemetry_uuid[] = {0xBC73719D87E64EFA, 0xBA560A9C3043424C};
const uint64_t *log_uuid = (uint64_t *) &tl->log->data_area[16];
tl->is_ocp = tl->log_size >= (&tl->log->data_area[32] - (uint8_t *) tl->log) &&
log_uuid[0] == ocp_telemetry_uuid[0] && log_uuid[1] == ocp_telemetry_uuid[1];
}
int solidigm_telemetry_log_data_areas_parse(struct telemetry_log *tl,
enum nvme_telemetry_da last_da)
{
struct json_object *tele_obj_array = json_create_array();
struct json_object *toc_array = json_create_array();
solidigm_telemetry_log_da1_check_ocp(tl);
solidigm_telemetry_log_header_parse(tl);
solidigm_telemetry_log_cod_parse(tl);
if (tl->configuration) {
enum nvme_telemetry_da first_da = NVME_TELEMETRY_DA_1;
if (tl->is_ocp)
first_da = NVME_TELEMETRY_DA_3;
json_object_add_value_array(tl->root, "tableOfContents", toc_array);
json_object_add_value_array(tl->root, "telemetryObjects", tele_obj_array);
for (enum nvme_telemetry_da da = NVME_TELEMETRY_DA_1; da <= last_da; da++)
for (enum nvme_telemetry_da da = first_da; da <= last_da; da++)
telemetry_log_data_area_toc_parse(tl, da, toc_array, tele_obj_array);
}
return 0;

View file

@ -8,3 +8,4 @@
int solidigm_telemetry_log_data_areas_parse(struct telemetry_log *tl,
enum nvme_telemetry_da last_da);
void solidigm_telemetry_log_da1_check_ocp(struct telemetry_log *tl);

View file

@ -57,6 +57,28 @@ struct reason_indentifier_1_2 {
static_assert(sizeof(const struct reason_indentifier_1_2) ==
MEMBER_SIZE(struct nvme_telemetry_log, rsnident),
"Size mismatch for reason_indentifier_1_2");
struct reason_identifier_ocp_2_5 {
char errorId[64];
char fileId[8];
uint16_t lineNum;
union {
struct {
uint8_t validLineNum:1;
uint8_t validFileId:1;
uint8_t validErrorId:1;
uint8_t validVuExtension:1;
uint8_t reservedBits:4;
};
uint8_t raw;
} validFlags;
uint8_t reserved[21];
uint8_t vuExtension[32];
};
static_assert(sizeof(const struct reason_identifier_ocp_2_5) ==
MEMBER_SIZE(struct nvme_telemetry_log, rsnident),
"Size mismatch for reason_identifier_ocp_2_5");
#pragma pack(pop, reason_indentifier)
static void telemetry_log_reason_id_parse1_0_ext(const struct telemetry_log *tl,
@ -153,6 +175,43 @@ static void telemetry_log_reason_id_parse1_2_ext(const struct telemetry_log *tl,
json_object_array_add(dp_reserved, val);
}
}
static void telemetry_log_reason_id_parse_ocp_2_5(const struct telemetry_log *tl,
struct json_object *reason_id)
{
const struct reason_identifier_ocp_2_5 *ri;
struct json_object *reserved;
struct json_object *vu_extension;
ri = (struct reason_identifier_ocp_2_5 *) tl->log->rsnident;
json_object_object_add(reason_id, "errorId",
json_object_new_string_len(ri->errorId,
sizeof(ri->errorId)));
json_object_object_add(reason_id, "fileId",
json_object_new_string_len(ri->fileId,
sizeof(ri->fileId)));
json_object_add_value_uint(reason_id, "lineNum", le16_to_cpu(ri->lineNum));
json_object_add_value_uint(reason_id, "validLineNum", ri->validFlags.validLineNum);
json_object_add_value_uint(reason_id, "validFileId", ri->validFlags.validFileId);
json_object_add_value_uint(reason_id, "validErrorId", ri->validFlags.validErrorId);
json_object_add_value_uint(reason_id, "validVuExtension", ri->validFlags.validVuExtension);
reserved = json_create_array();
json_object_add_value_array(reason_id, "reserved", reserved);
for (int i = 0; i < sizeof(ri->reserved); i++) {
struct json_object *val = json_object_new_int(ri->reserved[i]);
json_object_array_add(reserved, val);
}
vu_extension = json_create_array();
json_object_add_value_array(reason_id, "vuExtension", vu_extension);
for (int i = 0; i < sizeof(ri->vuExtension); i++) {
struct json_object *val = json_object_new_int(ri->vuExtension[i]);
json_object_array_add(vu_extension, val);
}
}
static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *tl, struct json_object *reason_id)
{
@ -161,12 +220,18 @@ static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *t
uint16_t version_major = le16_to_cpu(ri1_0->versionMajor);
uint16_t version_minor = le16_to_cpu(ri1_0->versionMinor);
if (tl->is_ocp) {
telemetry_log_reason_id_parse_ocp_2_5(tl, reason_id);
return;
}
json_object_add_value_uint(reason_id, "versionMajor", version_major);
json_object_add_value_uint(reason_id, "versionMinor", version_minor);
json_object_add_value_uint(reason_id, "reasonCode", le32_to_cpu(ri1_0->reasonCode));
json_object_add_value_object(reason_id, "driveStatus",
json_object_new_string_len(ri1_0->DriveStatus,
sizeof(ri1_0->DriveStatus)));
if (version_major == 1) {
switch (version_minor) {
case 0:
@ -211,6 +276,7 @@ bool solidigm_telemetry_log_header_parse(const struct telemetry_log *tl)
json_object_add_value_uint(header, "dataArea1LastBlock", log->dalb1);
json_object_add_value_uint(header, "dataArea2LastBlock", log->dalb2);
json_object_add_value_uint(header, "dataArea3LastBlock", log->dalb3);
json_object_add_value_uint(header, "dataArea4LastBlock", log->dalb4);
json_object_add_value_uint(header, "hostInitiatedDataGeneration", log->hostdgn);
json_object_add_value_uint(header, "controllerInitiatedDataAvailable", log->ctrlavail);
json_object_add_value_uint(header, "controllerInitiatedDataGeneration", log->ctrldgn);

View file

@ -10,14 +10,12 @@
#include <string.h>
#include <stdio.h>
#include "ccan/ilog/ilog.h"
#define LOG_ENTRY_HEADER_SIZE 1
#define LOG_ENTRY_TIMESTAMP_SIZE 2
#define LOG_ENTRY_NUM_ARGS_MAX 8
#define LOG_ENTRY_NUM_ARGS_MASK 0xF
#define LOG_ENTRY_MAX_SIZE (LOG_ENTRY_HEADER_SIZE + LOG_ENTRY_TIMESTAMP_SIZE + \
LOG_ENTRY_NUM_ARGS_MAX)
#define NUM_ARGS_MASK ((1 << ((int)STATIC_ILOG_32(LOG_ENTRY_NUM_ARGS_MAX))) - 1)
#define MAX_HEADER_MISMATCH_TRACK 10
static int formats_find(struct json_object *formats, uint32_t val, struct json_object **format)
@ -41,13 +39,13 @@ static uint32_t nlog_get_events(const uint32_t *nlog, const uint32_t nlog_size,
uint32_t tail_count = 0;
for (int i = nlog_size - start_offset - 1; i >= -start_offset; i--) {
struct json_object *format;
struct json_object *format = NULL;
uint32_t header = nlog_get_pos(nlog, nlog_size, i);
uint32_t num_data;
if (header == 0 || !formats_find(formats, header, &format)) {
if (event_count > 0) {
//check if fould circular buffer tail
//check if found circular buffer tail
if (i != (last_bad_header_pos - 1)) {
if (tail_mismatches &&
(tail_count < MAX_HEADER_MISMATCH_TRACK))
@ -58,7 +56,7 @@ static uint32_t nlog_get_events(const uint32_t *nlog, const uint32_t nlog_size,
}
continue;
}
num_data = header & NUM_ARGS_MASK;
num_data = header & LOG_ENTRY_NUM_ARGS_MASK;
if (events) {
struct json_object *event = json_object_new_array();
struct json_object *param = json_object_new_array();

View file

@ -11,6 +11,7 @@
#include "libnvme.h"
#include "util/json.h"
#include <assert.h>
#include <stdbool.h>
#if !defined __cplusplus
#define static_assert _Static_assert
@ -26,6 +27,7 @@ struct telemetry_log {
size_t log_size;
struct json_object *root;
struct json_object *configuration;
bool is_ocp;
};
#endif /* _SOLIDIGM_TELEMETRY_LOG_H */

121
plugins/wdc/wdc-nvme-cmds.h Normal file
View file

@ -0,0 +1,121 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2025 Western Digital Corporation or its affiliates.
*
* Author: Jeff Lien <jeff.lien@wdc.com>,
*/
int run_wdc_cloud_ssd_plugin_version(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_internal_fw_log(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_nand_stats(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_smart_add_log(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_clear_pcie_correctable_errors(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_drive_status(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_clear_assert_dump(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_drive_resize(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_fw_activate_history(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_clear_fw_activate_history(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_telemetry_controller_option(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_reason_identifier(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_log_page_directory(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_namespace_resize(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_drive_info(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_cloud_ssd_plugin_version(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_pcie_stats(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_get_latency_monitor_log(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_get_error_recovery_log(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_get_dev_capabilities_log(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_get_unsupported_reqs_log(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_cloud_boot_SSD_version(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_cloud_log(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_hw_rev_log(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_vs_device_waf(int argc, char **argv,
struct command *command,
struct plugin *plugin);
int run_wdc_set_latency_monitor_feature(int argc, char **argv,
struct command *cmd,
struct plugin *plugin);
int run_wdc_vs_temperature_stats(int argc, char **argv,
struct command *command,
struct plugin *plugin);
bool run_wdc_nvme_check_supported_log_page(nvme_root_t r,
struct nvme_dev *dev,
__u8 log_id);
__u32 run_wdc_get_fw_cust_id(nvme_root_t r,
struct nvme_dev *dev);

View file

@ -43,6 +43,7 @@
#define CREATE_CMD
#include "wdc-nvme.h"
#include "wdc-utils.h"
#include "wdc-nvme-cmds.h"
#define WRITE_SIZE (sizeof(__u8) * 4096)
@ -12625,3 +12626,200 @@ int wdc_set_latency_monitor_feature(int argc, char **argv, struct command *cmd,
return ret;
}
/*
* Externally available functions used to call the WDC Plugin commands
*/
int run_wdc_cloud_ssd_plugin_version(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_cloud_ssd_plugin_version(argc, argv, command, plugin);
}
int run_wdc_vs_internal_fw_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_internal_fw_log(argc, argv, command, plugin);
}
int run_wdc_vs_nand_stats(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_nand_stats(argc, argv, command, plugin);
}
int run_wdc_vs_smart_add_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_smart_add_log(argc, argv, command, plugin);
}
int run_wdc_clear_pcie_correctable_errors(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_clear_pcie_correctable_errors(argc, argv, command, plugin);
}
int run_wdc_drive_status(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_drive_status(argc, argv, command, plugin);
}
int run_wdc_clear_assert_dump(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_clear_assert_dump(argc, argv, command, plugin);
}
int run_wdc_drive_resize(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_drive_resize(argc, argv, command, plugin);
}
int run_wdc_vs_fw_activate_history(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_fw_activate_history(argc, argv, command, plugin);
}
int run_wdc_clear_fw_activate_history(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_clear_fw_activate_history(argc, argv, command, plugin);
}
int run_wdc_vs_telemetry_controller_option(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_telemetry_controller_option(argc, argv, command, plugin);
}
int run_wdc_reason_identifier(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_reason_identifier(argc, argv, command, plugin);
}
int run_wdc_log_page_directory(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_log_page_directory(argc, argv, command, plugin);
}
int run_wdc_namespace_resize(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_namespace_resize(argc, argv, command, plugin);
}
int run_wdc_vs_drive_info(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_drive_info(argc, argv, command, plugin);
}
int run_wdc_vs_pcie_stats(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_pcie_stats(argc, argv, command, plugin);
}
int run_wdc_get_latency_monitor_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_get_latency_monitor_log(argc, argv, command, plugin);
}
int run_wdc_get_error_recovery_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_get_error_recovery_log(argc, argv, command, plugin);
}
int run_wdc_get_dev_capabilities_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_get_dev_capabilities_log(argc, argv, command, plugin);
}
int run_wdc_get_unsupported_reqs_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_get_unsupported_reqs_log(argc, argv, command, plugin);
}
int run_wdc_cloud_boot_SSD_version(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_cloud_boot_SSD_version(argc, argv, command, plugin);
}
int run_wdc_vs_cloud_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_cloud_log(argc, argv, command, plugin);
}
int run_wdc_vs_hw_rev_log(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_hw_rev_log(argc, argv, command, plugin);
}
int run_wdc_vs_device_waf(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_device_waf(argc, argv, command, plugin);
}
int run_wdc_set_latency_monitor_feature(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_set_latency_monitor_feature(argc, argv, command, plugin);
}
int run_wdc_vs_temperature_stats(int argc, char **argv,
struct command *command,
struct plugin *plugin)
{
return wdc_vs_temperature_stats(argc, argv, command, plugin);
}
__u32 run_wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev)
{
return wdc_get_fw_cust_id(r, dev);
}
bool run_wdc_nvme_check_supported_log_page(nvme_root_t r,
struct nvme_dev *dev,
__u8 log_id)
{
return wdc_nvme_check_supported_log_page(r, dev, log_id);
}