Adding upstream version 2.13.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
c0fbec1eb4
commit
94a061187a
579 changed files with 6165 additions and 1687 deletions
108
plugins/feat/feat-nvme.c
Normal file
108
plugins/feat/feat-nvme.c
Normal 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
25
plugins/feat/feat-nvme.h
Normal 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
3
plugins/feat/meson.build
Normal file
|
@ -0,0 +1,3 @@
|
|||
sources += [
|
||||
'plugins/feat/feat-nvme.c',
|
||||
]
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
307
plugins/sandisk/sandisk-nvme.c
Normal file
307
plugins/sandisk/sandisk-nvme.c
Normal 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);
|
||||
}
|
81
plugins/sandisk/sandisk-nvme.h
Normal file
81
plugins/sandisk/sandisk-nvme.h
Normal 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"
|
534
plugins/sandisk/sandisk-utils.c
Normal file
534
plugins/sandisk/sandisk-utils.c
Normal 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;
|
||||
}
|
||||
|
||||
|
192
plugins/sandisk/sandisk-utils.h
Normal file
192
plugins/sandisk/sandisk-utils.h
Normal 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);
|
||||
|
|
@ -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',
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
121
plugins/wdc/wdc-nvme-cmds.h
Normal 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);
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue