summaryrefslogtreecommitdiffstats
path: root/plugins/solidigm
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/solidigm')
-rw-r--r--plugins/solidigm/meson.build3
-rw-r--r--plugins/solidigm/solidigm-garbage-collection.c6
-rw-r--r--plugins/solidigm/solidigm-get-drive-info.c79
-rw-r--r--plugins/solidigm/solidigm-get-drive-info.h8
-rw-r--r--plugins/solidigm/solidigm-internal-logs.c34
-rw-r--r--plugins/solidigm/solidigm-latency-tracking.c4
-rw-r--r--plugins/solidigm/solidigm-log-page-dir.c46
-rw-r--r--plugins/solidigm/solidigm-nvme.c27
-rw-r--r--plugins/solidigm/solidigm-nvme.h6
-rw-r--r--plugins/solidigm/solidigm-ocp-version.c25
-rw-r--r--plugins/solidigm/solidigm-ocp-version.h8
-rw-r--r--plugins/solidigm/solidigm-smart.c12
-rw-r--r--plugins/solidigm/solidigm-telemetry.c35
-rw-r--r--plugins/solidigm/solidigm-telemetry/config.c2
-rw-r--r--plugins/solidigm/solidigm-telemetry/data-area.c2
-rw-r--r--plugins/solidigm/solidigm-telemetry/nlog.c5
-rw-r--r--plugins/solidigm/solidigm-temp-stats.c108
-rw-r--r--plugins/solidigm/solidigm-temp-stats.h8
-rw-r--r--plugins/solidigm/solidigm-util.h2
19 files changed, 348 insertions, 72 deletions
diff --git a/plugins/solidigm/meson.build b/plugins/solidigm/meson.build
index 84495a1..052afa1 100644
--- a/plugins/solidigm/meson.build
+++ b/plugins/solidigm/meson.build
@@ -8,6 +8,9 @@ sources += [
'plugins/solidigm/solidigm-telemetry.c',
'plugins/solidigm/solidigm-internal-logs.c',
'plugins/solidigm/solidigm-market-log.c',
+ 'plugins/solidigm/solidigm-temp-stats.c',
+ 'plugins/solidigm/solidigm-get-drive-info.c',
+ 'plugins/solidigm/solidigm-ocp-version.c',
]
subdir('solidigm-telemetry')
diff --git a/plugins/solidigm/solidigm-garbage-collection.c b/plugins/solidigm/solidigm-garbage-collection.c
index b26d754..a37e9c5 100644
--- a/plugins/solidigm/solidigm-garbage-collection.c
+++ b/plugins/solidigm/solidigm-garbage-collection.c
@@ -68,6 +68,7 @@ static void vu_gc_log_show(struct garbage_control_collection_log *payload, const
int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Get and parse Solidigm vendor specific garbage collection event log.";
+ enum nvme_print_flags flags;
struct nvme_dev *dev;
int err;
__u8 uuid_index;
@@ -89,9 +90,8 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c
if (err)
return err;
- enum nvme_print_flags flags = validate_output_format(cfg.output_format);
-
- if (flags == -EINVAL) {
+ err = validate_output_format(cfg.output_format, &flags);
+ if (err) {
fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format);
dev_close(dev);
return -EINVAL;
diff --git a/plugins/solidigm/solidigm-get-drive-info.c b/plugins/solidigm/solidigm-get-drive-info.c
new file mode 100644
index 0000000..21f59bb
--- /dev/null
+++ b/plugins/solidigm/solidigm-get-drive-info.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Authors: leonardo.da.cunha@solidigm.com
+ */
+
+#include <errno.h>
+#include "nvme-print.h"
+#include "nvme-wrap.h"
+#include "common.h"
+
+int sldgm_get_drive_info(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ const char *desc = "Get drive HW information";
+ const char *FTL_unit_size_str = "FTL_unit_size";
+ char *output_format = "normal";
+ enum nvme_print_flags flags;
+ nvme_root_t r;
+ nvme_ctrl_t c;
+ nvme_ns_t n;
+ struct nvme_id_ns ns = { 0 };
+ __u8 flbaf_inUse;
+ __u16 lba_size;
+ __u16 ftl_unit_size;
+ int err;
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &output_format, "normal|json"),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ err = validate_output_format(output_format, &flags);
+ if ((err < 0) || !(flags == NORMAL || flags == JSON)) {
+ nvme_show_error("Invalid output format");
+ return err;
+ }
+
+ r = nvme_scan(NULL);
+ c = nvme_scan_ctrl(r, dev->name);
+ n = c ? nvme_ctrl_first_ns(c) : nvme_scan_namespace(dev->name);
+ if (!n) {
+ nvme_show_error("solidigm-vs-drive-info: drive missing namespace");
+ return -EINVAL;
+ }
+
+ err = nvme_ns_identify(n, &ns);
+ if (err) {
+ nvme_show_error("identify namespace: %s", nvme_strerror(errno));
+ return err;
+ }
+
+ if (!(ns.nsfeat & 0x10)) {
+ nvme_show_error("solidigm-vs-drive-info: performance options not available");
+ return -EINVAL;
+ }
+
+ nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &flbaf_inUse);
+ lba_size = 1 << ns.lbaf[flbaf_inUse].ds;
+ ftl_unit_size = (le16_to_cpu(ns.npwg) + 1) * lba_size / 1024;
+
+ if (flags == JSON) {
+ struct json_object *root = json_create_object();
+
+ json_object_add_value_int(root, FTL_unit_size_str, ftl_unit_size);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ } else {
+ printf("%s: %d\n", FTL_unit_size_str, ftl_unit_size);
+ }
+
+ return err;
+}
diff --git a/plugins/solidigm/solidigm-get-drive-info.h b/plugins/solidigm/solidigm-get-drive-info.h
new file mode 100644
index 0000000..ffc1bd2
--- /dev/null
+++ b/plugins/solidigm/solidigm-get-drive-info.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+int sldgm_get_drive_info(int argc, char **argv, struct command *cmd, struct plugin *plugin);
diff --git a/plugins/solidigm/solidigm-internal-logs.c b/plugins/solidigm/solidigm-internal-logs.c
index 4730443..236652a 100644
--- a/plugins/solidigm/solidigm-internal-logs.c
+++ b/plugins/solidigm/solidigm-internal-logs.c
@@ -19,6 +19,7 @@
#include "libnvme.h"
#include "plugin.h"
#include "nvme-print.h"
+#include "solidigm-util.h"
#define DWORD_SIZE 4
@@ -427,7 +428,8 @@ static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetr
int err = 0, output;
__u8 *buffer = NULL;
size_t bytes_remaining = 0;
- int data_area = NVME_TELEMETRY_DA_3;
+ enum nvme_telemetry_da da;
+ size_t max_data_tx;
char file_path[PATH_MAX];
char *log_name;
@@ -444,6 +446,12 @@ static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetr
default:
return -EINVAL;
}
+ err = nvme_get_telemetry_max(dev_fd(dev), &da, &max_data_tx);
+ if (err)
+ return err;
+
+ if (max_data_tx > DRIVER_MAX_TX_256K)
+ max_data_tx = DRIVER_MAX_TX_256K;
sprintf(file_path, "%s_%s.bin", cfg.file_prefix, log_name);
output = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
@@ -452,16 +460,16 @@ static int dump_telemetry(struct nvme_dev *dev, struct config cfg, enum telemetr
switch (ttype) {
case HOSTGENNEW:
- err = nvme_get_new_host_telemetry(dev_fd(dev), &log,
- data_area, &log_size);
+ err = nvme_get_telemetry_log(dev_fd(dev), true, false, false, max_data_tx, da,
+ &log, &log_size);
break;
case HOSTGENOLD:
- err = nvme_get_host_telemetry(dev_fd(dev), &log,
- data_area, &log_size);
+ err = nvme_get_telemetry_log(dev_fd(dev), false, false, false, max_data_tx, da,
+ &log, &log_size);
break;
case CONTROLLER:
- err = nvme_get_ctrl_telemetry(dev_fd(dev), true, &log,
- data_area, &log_size);
+ err = nvme_get_telemetry_log(dev_fd(dev), false, true, true, max_data_tx, da, &log,
+ &log_size);
break;
}
@@ -546,42 +554,42 @@ int solidigm_get_internal_log(int argc, char **argv, struct command *command,
if (err == 0)
log_count++;
else if (err < 0)
- perror("Assert log");
+ perror("Error retrieving Assert log");
}
if (all || !strcmp(cfg.type, "EVENT")) {
err = dump_event_logs(dev, cfg);
if (err == 0)
log_count++;
else if (err < 0)
- perror("Eventt log");
+ perror("Error retrieving Event log");
}
if (all || !strcmp(cfg.type, "NLOG")) {
err = dump_nlogs(dev, cfg, -1);
if (err == 0)
log_count++;
else if (err < 0)
- perror("Nlog");
+ perror("Error retrieving Nlog");
}
if (all || !strcmp(cfg.type, "CONTROLLERINITTELEMETRY")) {
err = dump_telemetry(dev, cfg, CONTROLLER);
if (err == 0)
log_count++;
else if (err < 0)
- perror("Telemetry Controller Initated");
+ perror("Error retrieving Telemetry Controller Initiated");
}
if (all || !strcmp(cfg.type, "HOSTINITTELEMETRYNOGEN")) {
err = dump_telemetry(dev, cfg, HOSTGENOLD);
if (err == 0)
log_count++;
else if (err < 0)
- perror("Previously existing Telemetry Host Initated");
+ perror("Error retrieving previously existing Telemetry Host Initiated");
}
if (all || !strcmp(cfg.type, "HOSTINITTELEMETRY")) {
err = dump_telemetry(dev, cfg, HOSTGENNEW);
if (err == 0)
log_count++;
else if (err < 0)
- perror("Telemetry Host Initated");
+ perror("Error retrieving Telemetry Host Initiated");
}
if (log_count == 0) {
diff --git a/plugins/solidigm/solidigm-latency-tracking.c b/plugins/solidigm/solidigm-latency-tracking.c
index 481a831..66f3c56 100644
--- a/plugins/solidigm/solidigm-latency-tracking.c
+++ b/plugins/solidigm/solidigm-latency-tracking.c
@@ -411,8 +411,8 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd
lt.fd = dev_fd(dev);
- lt.print_flags = validate_output_format(lt.cfg.output_format);
- if (lt.print_flags == -EINVAL) {
+ err = validate_output_format(lt.cfg.output_format, &lt.print_flags);
+ if (err < 0) {
fprintf(stderr, "Invalid output format '%s'\n", lt.cfg.output_format);
dev_close(dev);
return -EINVAL;
diff --git a/plugins/solidigm/solidigm-log-page-dir.c b/plugins/solidigm/solidigm-log-page-dir.c
index 111a433..bf272f8 100644
--- a/plugins/solidigm/solidigm-log-page-dir.c
+++ b/plugins/solidigm/solidigm-log-page-dir.c
@@ -100,38 +100,13 @@ static struct lid_dir *get_standard_lids(struct nvme_supported_log_pages *suppor
static struct lid_dir standard_dir = { 0 };
init_lid_dir(&standard_dir);
- standard_dir.lid[0x00].str = "Supported Log Pages";
- standard_dir.lid[0x01].str = "Error Information";
- standard_dir.lid[0x02].str = "SMART / Health Information";
- standard_dir.lid[0x03].str = "Firmware Slot Information";
- standard_dir.lid[0x04].str = "Changed Namespace List";
- standard_dir.lid[0x05].str = "Commands Supported and Effects";
- standard_dir.lid[0x06].str = "Device Self Test";
- standard_dir.lid[0x07].str = "Telemetry Host-Initiated";
- standard_dir.lid[0x08].str = "Telemetry Controller-Initiated";
- standard_dir.lid[0x09].str = "Endurance Group Information";
- standard_dir.lid[0x0A].str = "Predictable Latency Per NVM Set";
- standard_dir.lid[0x0B].str = "Predictable Latency Event Aggregate";
- standard_dir.lid[0x0C].str = "Asymmetric Namespace Access";
- standard_dir.lid[0x0D].str = "Persistent Event Log";
- standard_dir.lid[0x0E].str = "Predictable Latency Event Aggregate";
- standard_dir.lid[0x0F].str = "Endurance Group Event Aggregate";
- standard_dir.lid[0x10].str = "Media Unit Status";
- standard_dir.lid[0x11].str = "Supported Capacity Configuration List";
- standard_dir.lid[0x12].str = "Feature Identifiers Supported and Effects";
- standard_dir.lid[0x13].str = "NVMe-MI Commands Supported and Effects";
- standard_dir.lid[0x14].str = "Command and Feature lockdown";
- standard_dir.lid[0x15].str = "Boot Partition";
- standard_dir.lid[0x16].str = "Rotational Media Information";
- standard_dir.lid[0x70].str = "Discovery";
- standard_dir.lid[0x80].str = "Reservation Notification";
- standard_dir.lid[0x81].str = "Sanitize Status";
for (int lid = 0; lid < NVME_LOG_SUPPORTED_LOG_PAGES_MAX; lid++) {
if (!supported->lid_support[lid] || lid >= MIN_VENDOR_LID)
continue;
standard_dir.lid[lid].supported = true;
+ standard_dir.lid[lid].str = nvme_log_to_string(lid);
}
return &standard_dir;
@@ -158,6 +133,14 @@ static struct lid_dir *get_solidigm_lids(struct nvme_supported_log_pages *suppor
solidigm_dir.lid[0xC4].str = "Endurance Manager Statistics";
solidigm_dir.lid[0xC5].str = "Temperature Statistics";
solidigm_dir.lid[0xCA].str = "SMART Attributes";
+ solidigm_dir.lid[0xCB].str = "VU NVMe IO Queue Metrics Log Page";
+ solidigm_dir.lid[0xDD].str = "VU Marketing Description Log Page";
+ solidigm_dir.lid[0xEF].str = "Performance Rating and LBA Access Histogram";
+ solidigm_dir.lid[0xF2].str = "Get Power Usage Log Page";
+ solidigm_dir.lid[0xF6].str = "Vt Histo Get Log Page";
+ solidigm_dir.lid[0xF9].str = "Workload Tracker Get Log Page";
+ solidigm_dir.lid[0xFD].str = "Garbage Control Collection Log Page";
+ solidigm_dir.lid[0xFE].str = "Latency Outlier Log Page";
update_vendor_lid_supported(supported, &solidigm_dir);
@@ -281,15 +264,18 @@ int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *c
}
if (!err) {
- const enum nvme_print_flags print_flag = validate_output_format(format);
+ enum nvme_print_flags print_flag;
+
+ err = validate_output_format(format, &print_flag);
+ if (err < 0) {
+ fprintf(stderr, "Error: Invalid output format specified: %s.\n", format);
+ return err;
+ }
if (print_flag == NORMAL) {
supported_log_pages_normal(lid_dirs);
} else if (print_flag == JSON) {
supported_log_pages_json(lid_dirs);
- } else {
- fprintf(stderr, "Error: Invalid output format specified: %s.\n", format);
- err = -EINVAL;
}
}
diff --git a/plugins/solidigm/solidigm-nvme.c b/plugins/solidigm/solidigm-nvme.c
index b0db1ea..3fb86f5 100644
--- a/plugins/solidigm/solidigm-nvme.c
+++ b/plugins/solidigm/solidigm-nvme.c
@@ -18,8 +18,11 @@
#include "solidigm-telemetry.h"
#include "solidigm-log-page-dir.h"
#include "solidigm-market-log.h"
+#include "solidigm-temp-stats.h"
+#include "solidigm-get-drive-info.h"
+#include "solidigm-ocp-version.h"
-#include "plugins/ocp/ocp-clear-fw-update-history.h"
+#include "plugins/ocp/ocp-clear-features.h"
#include "plugins/ocp/ocp-smart-extended-log.h"
#include "plugins/ocp/ocp-fw-activation-history.h"
@@ -59,6 +62,12 @@ static int clear_fw_update_history(int argc, char **argv, struct command *cmd,
return ocp_clear_fw_update_history(argc, argv, cmd, plugin);
}
+static int clear_pcie_correctable_error_counters(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ return ocp_clear_pcie_correctable_errors(argc, argv, cmd, plugin);
+}
+
static int smart_cloud(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
@@ -82,3 +91,19 @@ static int get_market_log(int argc, char **argv, struct command *cmd,
{
return sldgm_get_market_log(argc, argv, cmd, plugin);
}
+
+static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ return sldgm_get_temp_stats_log(argc, argv, cmd, plugin);
+}
+
+static int get_drive_info(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ return sldgm_get_drive_info(argc, argv, cmd, plugin);
+}
+
+static int get_cloud_SSDplugin_version(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ return sldgm_ocp_version(argc, argv, cmd, plugin);
+}
diff --git a/plugins/solidigm/solidigm-nvme.h b/plugins/solidigm/solidigm-nvme.h
index 69b63e5..a984a38 100644
--- a/plugins/solidigm/solidigm-nvme.h
+++ b/plugins/solidigm/solidigm-nvme.h
@@ -13,7 +13,7 @@
#include "cmd.h"
-#define SOLIDIGM_PLUGIN_VERSION "0.14"
+#define SOLIDIGM_PLUGIN_VERSION "1.0"
PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION),
COMMAND_LIST(
@@ -25,9 +25,13 @@ PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_V
ENTRY("market-log", "Retrieve Market Log", get_market_log)
ENTRY("latency-tracking-log", "Enable/Retrieve Latency tracking Log", get_latency_tracking_log)
ENTRY("parse-telemetry-log", "Parse Telemetry Log binary", get_telemetry_log)
+ ENTRY("clear-pcie-correctable-errors ", "Clear PCIe Correctable Error Counters (redirects to ocp plug-in)", clear_pcie_correctable_error_counters)
ENTRY("clear-fw-activate-history", "Clear firmware update history log (redirects to ocp plug-in)", clear_fw_update_history)
ENTRY("vs-fw-activate-history", "Get firmware activation history log (redirects to ocp plug-in)", fw_activation_history)
ENTRY("log-page-directory", "Retrieve log page directory", get_log_page_directory_log)
+ ENTRY("temp-stats", "Retrieve Temperature Statistics log", get_temp_stats_log)
+ ENTRY("vs-drive-info", "Retrieve drive information", get_drive_info)
+ ENTRY("cloud-SSDplugin-version", "Prints plug-in OCP version", get_cloud_SSDplugin_version)
)
);
diff --git a/plugins/solidigm/solidigm-ocp-version.c b/plugins/solidigm/solidigm-ocp-version.c
new file mode 100644
index 0000000..4048cc1
--- /dev/null
+++ b/plugins/solidigm/solidigm-ocp-version.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include <stdio.h>
+#include "nvme.h"
+
+int sldgm_ocp_version(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc = "Prints OCP extensions version of Solidigm plugin";
+
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
+
+ int err = argconfig_parse(argc, argv, desc, opts);
+
+ if (!err)
+ printf("1.0\n");
+
+ return err;
+}
diff --git a/plugins/solidigm/solidigm-ocp-version.h b/plugins/solidigm/solidigm-ocp-version.h
new file mode 100644
index 0000000..d79452c
--- /dev/null
+++ b/plugins/solidigm/solidigm-ocp-version.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+int sldgm_ocp_version(int argc, char **argv, struct command *cmd, struct plugin *plugin);
diff --git a/plugins/solidigm/solidigm-smart.c b/plugins/solidigm/solidigm-smart.c
index e3d468a..62245fa 100644
--- a/plugins/solidigm/solidigm-smart.c
+++ b/plugins/solidigm/solidigm-smart.c
@@ -69,15 +69,17 @@ static char *id_to_name(__u8 id)
case 0xE2:
return "media_wear_percentage";
case 0xE3:
- return "host_reads";
+ return "timed_work_load_host_reads";
case 0xE4:
- return "timed_work_load";
+ return "timed_work_load_timer";
case 0xE5:
return "read_commands_in_flight_counter";
case 0xE6:
return "write_commands_in_flight_counter";
case 0xEA:
return "thermal_throttle_status";
+ case 0xEE:
+ return "re_sku_count";
case 0xF0:
return "retry_buffer_overflow_counter";
case 0xF3:
@@ -220,11 +222,11 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
if (err)
return err;
- flags = validate_output_format(cfg.output_format);
- if (flags == -EINVAL) {
+ err = validate_output_format(cfg.output_format, &flags);
+ if (err < 0) {
fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format);
dev_close(dev);
- return flags;
+ return err;
}
uuid_index = solidigm_get_vu_uuid_index(dev);
diff --git a/plugins/solidigm/solidigm-telemetry.c b/plugins/solidigm/solidigm-telemetry.c
index 472284a..2bebccc 100644
--- a/plugins/solidigm/solidigm-telemetry.c
+++ b/plugins/solidigm/solidigm-telemetry.c
@@ -22,6 +22,7 @@
#include "solidigm-telemetry/header.h"
#include "solidigm-telemetry/config.h"
#include "solidigm-telemetry/data-area.h"
+#include "solidigm-util.h"
static int read_file2buffer(char *file_name, char **buffer, size_t *length)
{
@@ -71,7 +72,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
struct config cfg = {
.host_gen = 1,
.ctrl_init = false,
- .data_area = 3,
+ .data_area = -1,
.cfg_file = NULL,
.is_input_file = false,
};
@@ -90,6 +91,10 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
if (err)
goto ret;
+ /* 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 (cfg.is_input_file) {
if (optind >= argc) {
err = errno = EINVAL;
@@ -138,19 +143,23 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
}
if (!cfg.is_input_file) {
- if (cfg.ctrl_init)
- err = nvme_get_ctrl_telemetry(dev_fd(dev), true,
- &tl.log, cfg.data_area,
- &tl.log_size);
- else if (cfg.host_gen)
- err = nvme_get_new_host_telemetry(dev_fd(dev), &tl.log,
- cfg.data_area,
- &tl.log_size);
- else
- err = nvme_get_host_telemetry(dev_fd(dev), &tl.log,
- cfg.data_area,
- &tl.log_size);
+ size_t max_data_tx;
+
+ err = nvme_get_telemetry_max(dev_fd(dev), NULL, &max_data_tx);
+ if (err < 0) {
+ SOLIDIGM_LOG_WARNING("identify_ctrl: %s",
+ nvme_strerror(errno));
+ goto close_fd;
+ } else if (err > 0) {
+ nvme_show_status(err);
+ SOLIDIGM_LOG_WARNING("Failed to acquire identify ctrl %d!", err);
+ goto close_fd;
+ }
+ if (max_data_tx > DRIVER_MAX_TX_256K)
+ max_data_tx = DRIVER_MAX_TX_256K;
+ err = nvme_get_telemetry_log(dev_fd(dev), cfg.host_gen, cfg.ctrl_init, true,
+ max_data_tx, cfg.data_area, &tl.log, &tl.log_size);
if (err < 0) {
SOLIDIGM_LOG_WARNING("get-telemetry-log: %s",
nvme_strerror(errno));
diff --git a/plugins/solidigm/solidigm-telemetry/config.c b/plugins/solidigm/solidigm-telemetry/config.c
index cc2a8bb..eceeede 100644
--- a/plugins/solidigm/solidigm-telemetry/config.c
+++ b/plugins/solidigm/solidigm-telemetry/config.c
@@ -9,7 +9,7 @@
#include <string.h>
#include "config.h"
-// max 16 bit unsigned integer nummber 65535
+// max 16 bit unsigned integer number 65535
#define MAX_16BIT_NUM_AS_STRING_SIZE 6
#define OBJ_NAME_PREFIX "UID_"
diff --git a/plugins/solidigm/solidigm-telemetry/data-area.c b/plugins/solidigm/solidigm-telemetry/data-area.c
index 0cfa56c..14d612b 100644
--- a/plugins/solidigm/solidigm-telemetry/data-area.c
+++ b/plugins/solidigm/solidigm-telemetry/data-area.c
@@ -57,7 +57,7 @@ static bool telemetry_log_get_value(const struct telemetry_log *tl,
char err_msg[MAX_WARNING_SIZE];
snprintf(err_msg, MAX_WARNING_SIZE,
- "Value crossing 64 bit, byte aligned bounday, not supported. size_bit=%u, offset_bit_from_byte=%u.",
+ "Value crossing 64 bit, byte aligned boundary, not supported. size_bit=%u, offset_bit_from_byte=%u.",
size_bit, offset_bit_from_byte);
*val_obj = json_object_new_string(err_msg);
diff --git a/plugins/solidigm/solidigm-telemetry/nlog.c b/plugins/solidigm/solidigm-telemetry/nlog.c
index 43b8918..926772b 100644
--- a/plugins/solidigm/solidigm-telemetry/nlog.c
+++ b/plugins/solidigm/solidigm-telemetry/nlog.c
@@ -8,15 +8,16 @@
#include "nlog.h"
#include "config.h"
#include <string.h>
-#include <math.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_MAX_SIZE (LOG_ENTRY_HEADER_SIZE + LOG_ENTRY_TIMESTAMP_SIZE + \
LOG_ENTRY_NUM_ARGS_MAX)
-#define NUM_ARGS_MASK ((1 << ((int)log2(LOG_ENTRY_NUM_ARGS_MAX)+1)) - 1)
+#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)
diff --git a/plugins/solidigm/solidigm-temp-stats.c b/plugins/solidigm/solidigm-temp-stats.c
new file mode 100644
index 0000000..85a3c37
--- /dev/null
+++ b/plugins/solidigm/solidigm-temp-stats.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include <errno.h>
+
+#include "common.h"
+#include "nvme-print.h"
+#include "solidigm-util.h"
+
+#define SLDGM_TEMP_STATS_LID 0xC5
+
+struct temp_stats {
+ __le64 curr;
+ __le64 last_overtemp;
+ __le64 life_overtemp;
+ __le64 highest_temp;
+ __le64 lowest_temp;
+ __u8 rsvd[40];
+ __le64 max_operating_temp;
+ __le64 min_operating_temp;
+ __le64 est_offset;
+};
+
+static void show_temp_stats(struct temp_stats *stats)
+{
+ printf("Current temperature : %"PRIu64"\n", le64_to_cpu(stats->curr));
+ printf("Last critical overtemp flag : %"PRIu64"\n", le64_to_cpu(stats->last_overtemp));
+ printf("Life critical overtemp flag : %"PRIu64"\n", le64_to_cpu(stats->life_overtemp));
+ printf("Highest temperature : %"PRIu64"\n", le64_to_cpu(stats->highest_temp));
+ printf("Lowest temperature : %"PRIu64"\n", le64_to_cpu(stats->lowest_temp));
+ printf("Max operating temperature : %"PRIu64"\n", le64_to_cpu(stats->max_operating_temp));
+ printf("Min operating temperature : %"PRIu64"\n", le64_to_cpu(stats->min_operating_temp));
+ printf("Estimated offset : %"PRIu64"\n", le64_to_cpu(stats->est_offset));
+}
+
+int sldgm_get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ unsigned char buffer[4096] = {0};
+ struct nvme_dev *dev;
+ __u8 uuid_idx;
+ int err;
+
+ const char *desc = "Get/show Temperature Statistics log.";
+ const char *raw = "dump output in binary format";
+ struct config {
+ bool raw_binary;
+ };
+
+ struct config cfg = {
+ .raw_binary = false,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ uuid_idx = solidigm_get_vu_uuid_index(dev);
+
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = buffer,
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .uuidx = uuid_idx,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .lid = SLDGM_TEMP_STATS_LID,
+ .len = sizeof(buffer),
+ .nsid = NVME_NSID_ALL,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .rae = false,
+ .ot = false,
+ };
+
+ err = nvme_get_log(&args);
+ if (!err) {
+ uint64_t *guid = (uint64_t *)&buffer[4080];
+
+ if (guid[1] == 0xC7BB98B7D0324863 && guid[0] == 0xBB2C23990E9C722F) {
+ fprintf(stderr, "Error: Log page has 'OCP unsupported Requirements' GUID\n");
+ err = -EBADMSG;
+ goto closefd;
+ }
+ if (!cfg.raw_binary)
+ show_temp_stats((struct temp_stats *) buffer);
+ else
+ d_raw(buffer, sizeof(struct temp_stats));
+ } else if (err > 0) {
+ nvme_show_status(err);
+ }
+
+closefd:
+ /* Redundant close() to make static code analysis happy */
+ close(dev->direct.fd);
+ dev_close(dev);
+ return err;
+}
diff --git a/plugins/solidigm/solidigm-temp-stats.h b/plugins/solidigm/solidigm-temp-stats.h
new file mode 100644
index 0000000..58d5a86
--- /dev/null
+++ b/plugins/solidigm/solidigm-temp-stats.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+int sldgm_get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin);
diff --git a/plugins/solidigm/solidigm-util.h b/plugins/solidigm/solidigm-util.h
index 3a18501..fa5032f 100644
--- a/plugins/solidigm/solidigm-util.h
+++ b/plugins/solidigm/solidigm-util.h
@@ -7,4 +7,6 @@
#include "nvme.h"
+#define DRIVER_MAX_TX_256K (256 * 1024)
+
__u8 solidigm_get_vu_uuid_index(struct nvme_dev *dev);