summaryrefslogtreecommitdiffstats
path: root/plugins/ocp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-11-09 08:09:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-11-09 08:09:59 +0000
commit3a023e2f691f3679889da0d63f377704e395e58a (patch)
tree90bcede47e76472c15225259d858ceb7987c9ff1 /plugins/ocp
parentReleasing debian version 2.10.2-1. (diff)
downloadnvme-cli-3a023e2f691f3679889da0d63f377704e395e58a.tar.xz
nvme-cli-3a023e2f691f3679889da0d63f377704e395e58a.zip
Merging upstream version 2.11.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins/ocp')
-rw-r--r--plugins/ocp/meson.build9
-rw-r--r--plugins/ocp/ocp-fw-activation-history.c129
-rw-r--r--plugins/ocp/ocp-fw-activation-history.h32
-rw-r--r--plugins/ocp/ocp-hardware-component-log.c288
-rw-r--r--plugins/ocp/ocp-hardware-component-log.h64
-rw-r--r--plugins/ocp/ocp-nvme.c1809
-rw-r--r--plugins/ocp/ocp-nvme.h200
-rw-r--r--plugins/ocp/ocp-print-binary.c54
-rw-r--r--plugins/ocp/ocp-print-json.c851
-rw-r--r--plugins/ocp/ocp-print-stdout.c710
-rw-r--r--plugins/ocp/ocp-print.c81
-rw-r--r--plugins/ocp/ocp-print.h51
-rw-r--r--plugins/ocp/ocp-smart-extended-log.c239
-rw-r--r--plugins/ocp/ocp-smart-extended-log.h40
-rw-r--r--plugins/ocp/ocp-telemetry-decode.c471
-rw-r--r--plugins/ocp/ocp-telemetry-decode.h32
16 files changed, 2983 insertions, 2077 deletions
diff --git a/plugins/ocp/meson.build b/plugins/ocp/meson.build
index 7835444..55b9966 100644
--- a/plugins/ocp/meson.build
+++ b/plugins/ocp/meson.build
@@ -5,5 +5,14 @@ sources += [
'plugins/ocp/ocp-smart-extended-log.c',
'plugins/ocp/ocp-fw-activation-history.c',
'plugins/ocp/ocp-telemetry-decode.c',
+ 'plugins/ocp/ocp-hardware-component-log.c',
+ 'plugins/ocp/ocp-print.c',
+ 'plugins/ocp/ocp-print-stdout.c',
+ 'plugins/ocp/ocp-print-binary.c',
]
+if json_c_dep.found()
+ sources += [
+ 'plugins/ocp/ocp-print-json.c',
+ ]
+endif
diff --git a/plugins/ocp/ocp-fw-activation-history.c b/plugins/ocp/ocp-fw-activation-history.c
index 543042f..79c03b2 100644
--- a/plugins/ocp/ocp-fw-activation-history.c
+++ b/plugins/ocp/ocp-fw-activation-history.c
@@ -14,135 +14,15 @@
#include "nvme-print.h"
#include "ocp-utils.h"
+#include "ocp-print.h"
-static const unsigned char ocp_fw_activation_history_guid[16] = {
+static const unsigned char ocp_fw_activation_history_guid[GUID_LEN] = {
0x6D, 0x79, 0x9a, 0x76,
0xb4, 0xda, 0xf6, 0xa3,
0xe2, 0x4d, 0xb2, 0x8a,
0xac, 0xf3, 0x1c, 0xd1
};
-struct __packed fw_activation_history_entry {
- __u8 ver_num;
- __u8 entry_length;
- __u16 reserved1;
- __u16 activation_count;
- __u64 timestamp;
- __u64 reserved2;
- __u64 power_cycle_count;
- char previous_fw[8];
- char new_fw[8];
- __u8 slot_number;
- __u8 commit_action;
- __u16 result;
- __u8 reserved3[14];
-};
-
-struct __packed fw_activation_history {
- __u8 log_id;
- __u8 reserved1[3];
- __u32 valid_entries;
- struct fw_activation_history_entry entries[20];
- __u8 reserved2[2790];
- __u16 log_page_version;
- __u64 log_page_guid[2];
-};
-
-static void ocp_fw_activation_history_normal(const struct fw_activation_history *fw_history)
-{
- printf("Firmware History Log:\n");
-
- printf(" %-26s%d\n", "log identifier:", fw_history->log_id);
- printf(" %-26s%d\n", "valid entries:", le32_to_cpu(fw_history->valid_entries));
-
- printf(" entries:\n");
-
- for (int index = 0; index < fw_history->valid_entries; index++) {
- const struct fw_activation_history_entry *entry = &fw_history->entries[index];
-
- printf(" entry[%d]:\n", le32_to_cpu(index));
- printf(" %-22s%d\n", "version number:", entry->ver_num);
- printf(" %-22s%d\n", "entry length:", entry->entry_length);
- printf(" %-22s%d\n", "activation count:",
- le16_to_cpu(entry->activation_count));
- printf(" %-22s%"PRIu64"\n", "timestamp:",
- (0x0000FFFFFFFFFFFF & le64_to_cpu(entry->timestamp)));
- printf(" %-22s%"PRIu64"\n", "power cycle count:",
- le64_to_cpu(entry->power_cycle_count));
- printf(" %-22s%.*s\n", "previous firmware:", (int)sizeof(entry->previous_fw),
- entry->previous_fw);
- printf(" %-22s%.*s\n", "new firmware:", (int)sizeof(entry->new_fw),
- entry->new_fw);
- printf(" %-22s%d\n", "slot number:", entry->slot_number);
- printf(" %-22s%d\n", "commit action type:", entry->commit_action);
- printf(" %-22s%d\n", "result:", le16_to_cpu(entry->result));
- }
-
- printf(" %-26s%d\n", "log page version:",
- le16_to_cpu(fw_history->log_page_version));
-
- printf(" %-26s0x%"PRIx64"%"PRIx64"\n", "log page guid:",
- le64_to_cpu(fw_history->log_page_guid[1]),
- le64_to_cpu(fw_history->log_page_guid[0]));
-
- printf("\n");
-}
-
-static void ocp_fw_activation_history_json(const struct fw_activation_history *fw_history)
-{
- struct json_object *root = json_create_object();
-
- json_object_add_value_uint(root, "log identifier", fw_history->log_id);
- json_object_add_value_uint(root, "valid entries", le32_to_cpu(fw_history->valid_entries));
-
- struct json_object *entries = json_create_array();
-
- for (int index = 0; index < fw_history->valid_entries; index++) {
- const struct fw_activation_history_entry *entry = &fw_history->entries[index];
- struct json_object *entry_obj = json_create_object();
-
- json_object_add_value_uint(entry_obj, "version number", entry->ver_num);
- json_object_add_value_uint(entry_obj, "entry length", entry->entry_length);
- json_object_add_value_uint(entry_obj, "activation count",
- le16_to_cpu(entry->activation_count));
- json_object_add_value_uint64(entry_obj, "timestamp",
- (0x0000FFFFFFFFFFFF & le64_to_cpu(entry->timestamp)));
- json_object_add_value_uint(entry_obj, "power cycle count",
- le64_to_cpu(entry->power_cycle_count));
-
- struct json_object *fw = json_object_new_string_len(entry->previous_fw,
- sizeof(entry->previous_fw));
-
- json_object_add_value_object(entry_obj, "previous firmware", fw);
-
- fw = json_object_new_string_len(entry->new_fw, sizeof(entry->new_fw));
-
- json_object_add_value_object(entry_obj, "new firmware", fw);
- json_object_add_value_uint(entry_obj, "slot number", entry->slot_number);
- json_object_add_value_uint(entry_obj, "commit action type", entry->commit_action);
- json_object_add_value_uint(entry_obj, "result", le16_to_cpu(entry->result));
-
- json_array_add_value_object(entries, entry_obj);
- }
-
- json_object_add_value_array(root, "entries", entries);
-
- json_object_add_value_uint(root, "log page version",
- le16_to_cpu(fw_history->log_page_version));
-
- char guid[2 * sizeof(fw_history->log_page_guid) + 3] = { 0 };
-
- sprintf(guid, "0x%"PRIx64"%"PRIx64"",
- le64_to_cpu(fw_history->log_page_guid[1]),
- le64_to_cpu(fw_history->log_page_guid[0]));
- json_object_add_value_string(root, "log page guid", guid);
-
- json_print_object(root, NULL);
- json_free_object(root);
-
- printf("\n");
-}
-
int ocp_fw_activation_history_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
@@ -215,10 +95,7 @@ int ocp_fw_activation_history_log(int argc, char **argv, struct command *cmd,
return err;
}
- if (print_flag == JSON)
- ocp_fw_activation_history_json(&fw_history);
- else if (print_flag == NORMAL)
- ocp_fw_activation_history_normal(&fw_history);
+ ocp_fw_act_history(&fw_history, print_flag);
}
return err;
diff --git a/plugins/ocp/ocp-fw-activation-history.h b/plugins/ocp/ocp-fw-activation-history.h
index a7f9058..15733a3 100644
--- a/plugins/ocp/ocp-fw-activation-history.h
+++ b/plugins/ocp/ocp-fw-activation-history.h
@@ -4,6 +4,8 @@
*
* Authors: karl.dedow@solidigm.com
*/
+#include "common.h"
+#include "linux/types.h"
#ifndef OCP_FIRMWARE_ACTIVATION_HISTORY_H
#define OCP_FIRMWARE_ACTIVATION_HISTORY_H
@@ -11,7 +13,33 @@
struct command;
struct plugin;
-int ocp_fw_activation_history_log(int argc, char **argv,
- struct command *cmd, struct plugin *plugin);
+struct __packed fw_activation_history_entry {
+ __u8 ver_num;
+ __u8 entry_length;
+ __le16 reserved1;
+ __le16 activation_count;
+ __le64 timestamp;
+ __le64 reserved2;
+ __le64 power_cycle_count;
+ char previous_fw[8];
+ char new_fw[8];
+ __u8 slot_number;
+ __u8 commit_action;
+ __le16 result;
+ __u8 reserved3[14];
+};
+
+struct __packed fw_activation_history {
+ __u8 log_id;
+ __u8 reserved1[3];
+ __le32 valid_entries;
+ struct fw_activation_history_entry entries[20];
+ __u8 reserved2[2790];
+ __le16 log_page_version;
+ __le64 log_page_guid[2];
+};
+
+int ocp_fw_activation_history_log(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin);
#endif
diff --git a/plugins/ocp/ocp-hardware-component-log.c b/plugins/ocp/ocp-hardware-component-log.c
new file mode 100644
index 0000000..73f1452
--- /dev/null
+++ b/plugins/ocp/ocp-hardware-component-log.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2024
+ */
+#include <stdio.h>
+#include <errno.h>
+
+#include "common.h"
+#include "util/types.h"
+#include "util/logging.h"
+#include "nvme-print.h"
+#include "ocp-hardware-component-log.h"
+#include "ocp-print.h"
+
+//#define HWCOMP_DUMMY
+
+#define print_info_array(...) \
+ do { \
+ if (log_level >= LOG_INFO) \
+ print_array(__VA_ARGS__); \
+ } while (false)
+
+#define print_info_error(...) \
+ do { \
+ if (log_level >= LOG_INFO) \
+ fprintf(stderr, __VA_ARGS__); \
+ } while (false)
+
+#ifdef HWCOMP_DUMMY
+static __u8 hwcomp_dummy[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xdc, 0x57, 0x0f, 0x9f, 0xb9, 0x31, 0x6b, 0xb7,
+ 0xd0, 0x4e, 0xcd, 0x30, 0x1f, 0x82, 0xb6, 0xbc,
+ 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+};
+#endif /* HWCOMP_DUMMY */
+
+const char *hwcomp_id_to_string(__u32 id)
+{
+ switch (id) {
+ case HWCOMP_ID_ASIC:
+ return "Controller ASIC component";
+ case HWCOMP_ID_NAND:
+ return "NAND Component";
+ case HWCOMP_ID_DRAM:
+ return "DRAM Component";
+ case HWCOMP_ID_PMIC:
+ return "PMIC Component";
+ case HWCOMP_ID_PCB:
+ return "PCB Component";
+ case HWCOMP_ID_CAP:
+ return "capacitor component";
+ case HWCOMP_ID_REG:
+ return "registor component";
+ case HWCOMP_ID_CASE:
+ return "case component";
+ case HWCOMP_ID_SN:
+ return "Device Serial Number";
+ case HWCOMP_ID_COUNTRY:
+ return "Country of Origin";
+ case HWCOMP_ID_HW_REV:
+ return "Global Device Hardware Revision";
+ case HWCOMP_ID_VENDOR ... HWCOMP_ID_MAX:
+ return "Vendor Unique Component";
+ case HWCOMP_ID_RSVD:
+ default:
+ break;
+ }
+
+ return "Reserved";
+}
+
+static int get_hwcomp_log_data(struct nvme_dev *dev, struct hwcomp_log *log)
+{
+ int ret = 0;
+ size_t desc_offset = offsetof(struct hwcomp_log, desc);
+ struct nvme_get_log_args args = {
+ .lpo = desc_offset,
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .lid = LID_HWCOMP,
+ .nsid = NVME_NSID_ALL,
+ };
+
+#ifdef HWCOMP_DUMMY
+ memcpy(log, hwcomp_dummy, desc_offset);
+#else /* HWCOMP_DUMMY */
+ ret = nvme_get_log_simple(dev_fd(dev), LID_HWCOMP, desc_offset, log);
+ if (ret) {
+ print_info_error("error: ocp: failed to get log simple (hwcomp: %02X, ret: %d)\n",
+ LID_HWCOMP, ret);
+ return ret;
+ }
+#endif /* HWCOMP_DUMMY */
+
+ print_info("id: %02Xh\n", LID_HWCOMP);
+ print_info("version: %04Xh\n", log->ver);
+ print_info_array("guid", log->guid, ARRAY_SIZE(log->guid));
+ print_info("size: %s\n", uint128_t_to_string(le128_to_cpu(log->size)));
+
+ args.len = uint128_t_to_double(le128_to_cpu(log->size)) * sizeof(__le32);
+ log->desc = calloc(1, args.len);
+ if (!log->desc) {
+ fprintf(stderr, "error: ocp: calloc: %s\n", strerror(errno));
+ return -1;
+ }
+
+ args.log = log->desc,
+
+#ifdef HWCOMP_DUMMY
+ memcpy(log->desc, &hwcomp_dummy[desc_offset], args.len);
+#else /* HWCOMP_DUMMY */
+ ret = nvme_get_log_page(dev_fd(dev), NVME_LOG_PAGE_PDU_SIZE, &args);
+ if (ret) {
+ print_info_error("error: ocp: failed to get log page (hwcomp: %02X, ret: %d)\n",
+ LID_HWCOMP, ret);
+ return ret;
+ }
+#endif /* HWCOMP_DUMMY */
+
+ return ret;
+}
+
+static int get_hwcomp_log(struct nvme_dev *dev, __u32 id, bool list)
+{
+ _cleanup_free_ __u8 *desc = NULL;
+
+ int ret;
+ nvme_print_flags_t fmt;
+ struct hwcomp_log log = {
+ .desc = (struct hwcomp_desc *)desc,
+ };
+
+ ret = validate_output_format(nvme_cfg.output_format, &fmt);
+ if (ret < 0) {
+ fprintf(stderr, "error: ocp: invalid output format\n");
+ return ret;
+ }
+
+ ret = get_hwcomp_log_data(dev, &log);
+ if (ret) {
+ print_info_error("error: ocp: failed get hwcomp log: %02X data, ret: %d\n",
+ LID_HWCOMP, ret);
+ return ret;
+ }
+
+ ocp_show_hwcomp_log(&log, id, list, fmt);
+
+ return 0;
+}
+
+int ocp_hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+ int ret = 0;
+ const char *desc = "retrieve hardware component log";
+ struct config {
+ __u64 id;
+ bool list;
+ } cfg = { 0 };
+ const char *id_desc = "component identifier";
+ const char *list_desc = "list component descriptions";
+
+ OPT_VALS(id) = {
+ VAL_LONG("asic", HWCOMP_ID_ASIC),
+ VAL_LONG("nand", HWCOMP_ID_NAND),
+ VAL_LONG("dram", HWCOMP_ID_DRAM),
+ VAL_LONG("pmic", HWCOMP_ID_PMIC),
+ VAL_LONG("pcb", HWCOMP_ID_PCB),
+ VAL_LONG("cap", HWCOMP_ID_CAP),
+ VAL_LONG("reg", HWCOMP_ID_REG),
+ VAL_LONG("case", HWCOMP_ID_CASE),
+ VAL_LONG("sn", HWCOMP_ID_SN),
+ VAL_LONG("country", HWCOMP_ID_COUNTRY),
+ VAL_LONG("hw-rev", HWCOMP_ID_HW_REV),
+ VAL_LONG("vendor", HWCOMP_ID_VENDOR),
+ VAL_END()
+ };
+
+ NVME_ARGS(opts, OPT_LONG("comp-id", 'i', &cfg.id, id_desc, id),
+ OPT_FLAG("list", 'l', &cfg.list, list_desc));
+
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
+
+ ret = get_hwcomp_log(dev, cfg.id, cfg.list);
+ if (ret)
+ fprintf(stderr, "error: ocp: failed to get hwcomp log: %02X, ret: %d\n", LID_HWCOMP,
+ ret);
+
+ return ret;
+}
diff --git a/plugins/ocp/ocp-hardware-component-log.h b/plugins/ocp/ocp-hardware-component-log.h
new file mode 100644
index 0000000..f5e5162
--- /dev/null
+++ b/plugins/ocp/ocp-hardware-component-log.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2024
+ */
+#include "cmd.h"
+#include "common.h"
+#include "ocp-nvme.h"
+
+#ifndef OCP_HARDWARE_COMPONENT_LOG_H
+#define OCP_HARDWARE_COMPONENT_LOG_H
+
+#define LID_HWCOMP 0xc6
+#define HWCOMP_RSVD2_LEN 14
+#define HWCOMP_SIZE_LEN 16
+#define HWCOMP_RSVD48_LEN 16
+
+struct __packed hwcomp_desc {
+ __le64 date_lot_size;
+ __le64 add_info_size;
+ __le32 id;
+ __le64 mfg;
+ __le64 rev;
+ __le64 mfg_code;
+};
+
+struct __packed hwcomp_log {
+ __le16 ver;
+ __u8 rsvd2[HWCOMP_RSVD2_LEN];
+ __u8 guid[GUID_LEN];
+ __u8 size[HWCOMP_SIZE_LEN];
+ __u8 rsvd48[HWCOMP_RSVD48_LEN];
+ struct hwcomp_desc *desc;
+};
+
+struct hwcomp_desc_entry {
+ struct hwcomp_desc *desc;
+ __u64 date_lot_size;
+ __u8 *date_lot_code;
+ __u64 add_info_size;
+ __u8 *add_info;
+ __u64 desc_size;
+};
+
+enum hwcomp_id {
+ HWCOMP_ID_RSVD,
+ HWCOMP_ID_ASIC,
+ HWCOMP_ID_NAND,
+ HWCOMP_ID_DRAM,
+ HWCOMP_ID_PMIC,
+ HWCOMP_ID_PCB,
+ HWCOMP_ID_CAP,
+ HWCOMP_ID_REG,
+ HWCOMP_ID_CASE,
+ HWCOMP_ID_SN,
+ HWCOMP_ID_COUNTRY,
+ HWCOMP_ID_HW_REV,
+ HWCOMP_ID_VENDOR = 0x8000,
+ HWCOMP_ID_MAX = 0xffff,
+};
+
+int ocp_hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *plugin);
+const char *hwcomp_id_to_string(__u32 id);
+
+#endif /* OCP_HARDWARE_COMPONENT_LOG_H */
diff --git a/plugins/ocp/ocp-nvme.c b/plugins/ocp/ocp-nvme.c
index 91f4083..6f05750 100644
--- a/plugins/ocp/ocp-nvme.c
+++ b/plugins/ocp/ocp-nvme.c
@@ -22,6 +22,7 @@
#include "plugin.h"
#include "linux/types.h"
#include "util/types.h"
+#include "util/logging.h"
#include "nvme-print.h"
#include "nvme-wrap.h"
@@ -29,6 +30,8 @@
#include "ocp-clear-features.h"
#include "ocp-fw-activation-history.h"
#include "ocp-telemetry-decode.h"
+#include "ocp-hardware-component-log.h"
+#include "ocp-print.h"
#define CREATE_CMD
#include "ocp-nvme.h"
@@ -42,76 +45,29 @@
#define C3_LATENCY_MON_LOG_BUF_LEN 0x200
#define C3_LATENCY_MON_OPCODE 0xC3
-#define C3_LATENCY_MON_VERSION 0x0001
-#define C3_GUID_LENGTH 16
#define NVME_FEAT_OCP_LATENCY_MONITOR 0xC5
-#define C3_ACTIVE_BUCKET_TIMER_INCREMENT 5
-#define C3_ACTIVE_THRESHOLD_INCREMENT 5
-#define C3_MINIMUM_WINDOW_INCREMENT 100
-#define C3_BUCKET_NUM 4
-
-static __u8 lat_mon_guid[C3_GUID_LENGTH] = {
+static __u8 lat_mon_guid[GUID_LEN] = {
0x92, 0x7a, 0xc0, 0x8c,
0xd0, 0x84, 0x6c, 0x9c,
0x70, 0x43, 0xe6, 0xd4,
0x58, 0x5e, 0xd4, 0x85
};
-#define READ 3
-#define WRITE 2
-#define TRIM 1
#define RESERVED 0
-struct __packed ssd_latency_monitor_log {
- __u8 feature_status; /* 0x00 */
- __u8 rsvd1; /* 0x01 */
- __le16 active_bucket_timer; /* 0x02 */
- __le16 active_bucket_timer_threshold; /* 0x04 */
- __u8 active_threshold_a; /* 0x06 */
- __u8 active_threshold_b; /* 0x07 */
- __u8 active_threshold_c; /* 0x08 */
- __u8 active_threshold_d; /* 0x09 */
- __le16 active_latency_config; /* 0x0A */
- __u8 active_latency_min_window; /* 0x0C */
- __u8 rsvd2[0x13]; /* 0x0D */
-
- __le32 active_bucket_counter[4][4]; /* 0x20 - 0x5F */
- __le64 active_latency_timestamp[4][3]; /* 0x60 - 0xBF */
- __le16 active_measured_latency[4][3]; /* 0xC0 - 0xD7 */
- __le16 active_latency_stamp_units; /* 0xD8 */
- __u8 rsvd3[0x16]; /* 0xDA */
-
- __le32 static_bucket_counter[4][4]; /* 0x0F0 - 0x12F */
- __le64 static_latency_timestamp[4][3]; /* 0x130 - 0x18F */
- __le16 static_measured_latency[4][3]; /* 0x190 - 0x1A7 */
- __le16 static_latency_stamp_units; /* 0x1A8 */
- __u8 rsvd4[0x16]; /* 0x1AA */
-
- __le16 debug_log_trigger_enable; /* 0x1C0 */
- __le16 debug_log_measured_latency; /* 0x1C2 */
- __le64 debug_log_latency_stamp; /* 0x1C4 */
- __le16 debug_log_ptr; /* 0x1CC */
- __le16 debug_log_counter_trigger; /* 0x1CE */
- __u8 debug_log_stamp_units; /* 0x1D0 */
- __u8 rsvd5[0x1D]; /* 0x1D1 */
-
- __le16 log_page_version; /* 0x1EE */
- __u8 log_page_guid[0x10]; /* 0x1F0 */
-};
-
struct __packed feature_latency_monitor {
- __u16 active_bucket_timer_threshold;
- __u8 active_threshold_a;
- __u8 active_threshold_b;
- __u8 active_threshold_c;
- __u8 active_threshold_d;
- __u16 active_latency_config;
- __u8 active_latency_minimum_window;
- __u16 debug_log_trigger_enable;
- __u8 discard_debug_log;
- __u8 latency_monitor_feature_enable;
- __u8 reserved[4083];
+ __le16 active_bucket_timer_threshold;
+ __u8 active_threshold_a;
+ __u8 active_threshold_b;
+ __u8 active_threshold_c;
+ __u8 active_threshold_d;
+ __le16 active_latency_config;
+ __u8 active_latency_minimum_window;
+ __le16 debug_log_trigger_enable;
+ __u8 discard_debug_log;
+ __u8 latency_monitor_feature_enable;
+ __u8 reserved[4083];
};
struct erri_entry {
@@ -194,6 +150,11 @@ struct erri_config {
__u16 nrtdp;
};
+struct ieee1667_get_cq_entry {
+ __u32 enabled:3;
+ __u32 rsvd3:29;
+};
+
static const char *sel = "[0-3]: current/default/saved/supported";
static const char *no_uuid = "Skip UUID index search (UUID index not required for OCP 1.0)";
const char *data = "Error injection data structure entries";
@@ -201,288 +162,6 @@ const char *number = "Number of valid error injection data entries";
static const char *type = "Error injection type";
static const char *nrtdp = "Number of reads to trigger device panic";
-static int ocp_print_C3_log_normal(struct nvme_dev *dev,
- struct ssd_latency_monitor_log *log_data)
-{
- char ts_buf[128];
- int i, j;
-
- printf("-Latency Monitor/C3 Log Page Data-\n");
- printf(" Controller : %s\n", dev->name);
- printf(" Feature Status 0x%x\n",
- log_data->feature_status);
- printf(" Active Bucket Timer %d min\n",
- C3_ACTIVE_BUCKET_TIMER_INCREMENT *
- le16_to_cpu(log_data->active_bucket_timer));
- printf(" Active Bucket Timer Threshold %d min\n",
- C3_ACTIVE_BUCKET_TIMER_INCREMENT *
- le16_to_cpu(log_data->active_bucket_timer_threshold));
- printf(" Active Threshold A %d ms\n",
- C3_ACTIVE_THRESHOLD_INCREMENT *
- le16_to_cpu(log_data->active_threshold_a+1));
- printf(" Active Threshold B %d ms\n",
- C3_ACTIVE_THRESHOLD_INCREMENT *
- le16_to_cpu(log_data->active_threshold_b+1));
- printf(" Active Threshold C %d ms\n",
- C3_ACTIVE_THRESHOLD_INCREMENT *
- le16_to_cpu(log_data->active_threshold_c+1));
- printf(" Active Threshold D %d ms\n",
- C3_ACTIVE_THRESHOLD_INCREMENT *
- le16_to_cpu(log_data->active_threshold_d+1));
- printf(" Active Latency Configuration 0x%x\n",
- le16_to_cpu(log_data->active_latency_config));
- printf(" Active Latency Minimum Window %d ms\n",
- C3_MINIMUM_WINDOW_INCREMENT *
- le16_to_cpu(log_data->active_latency_min_window));
- printf(" Active Latency Stamp Units %d\n",
- le16_to_cpu(log_data->active_latency_stamp_units));
- printf(" Static Latency Stamp Units %d\n",
- le16_to_cpu(log_data->static_latency_stamp_units));
- printf(" Debug Log Trigger Enable %d\n",
- le16_to_cpu(log_data->debug_log_trigger_enable));
- printf(" Debug Log Measured Latency %d\n",
- le16_to_cpu(log_data->debug_log_measured_latency));
- if (le64_to_cpu(log_data->debug_log_latency_stamp) == -1) {
- printf(" Debug Log Latency Time Stamp N/A\n");
- } else {
- convert_ts(le64_to_cpu(log_data->debug_log_latency_stamp), ts_buf);
- printf(" Debug Log Latency Time Stamp %s\n", ts_buf);
- }
- printf(" Debug Log Pointer %d\n",
- le16_to_cpu(log_data->debug_log_ptr));
- printf(" Debug Counter Trigger Source %d\n",
- le16_to_cpu(log_data->debug_log_counter_trigger));
- printf(" Debug Log Stamp Units %d\n",
- le16_to_cpu(log_data->debug_log_stamp_units));
- printf(" Log Page Version %d\n",
- le16_to_cpu(log_data->log_page_version));
-
- char guid[(C3_GUID_LENGTH * 2) + 1];
- char *ptr = &guid[0];
-
- for (i = C3_GUID_LENGTH - 1; i >= 0; i--)
- ptr += sprintf(ptr, "%02X", log_data->log_page_guid[i]);
-
- printf(" Log Page GUID %s\n", guid);
- printf("\n");
-
- printf(" Read Write Deallocate/Trim\n");
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- printf(" Active Bucket Counter: Bucket %d %27d %27d %27d\n",
- i,
- le32_to_cpu(log_data->active_bucket_counter[i][READ]),
- le32_to_cpu(log_data->active_bucket_counter[i][WRITE]),
- le32_to_cpu(log_data->active_bucket_counter[i][TRIM]));
- }
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- printf(" Active Latency Time Stamp: Bucket %d ", i);
- for (j = 2; j >= 0; j--) {
- if (le64_to_cpu(log_data->active_latency_timestamp[3-i][j]) == -1) {
- printf(" N/A ");
- } else {
- convert_ts(le64_to_cpu(log_data->active_latency_timestamp[3-i][j]), ts_buf);
- printf("%s ", ts_buf);
- }
- }
- printf("\n");
- }
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
- i,
- le16_to_cpu(log_data->active_measured_latency[3-i][READ-1]),
- le16_to_cpu(log_data->active_measured_latency[3-i][WRITE-1]),
- le16_to_cpu(log_data->active_measured_latency[3-i][TRIM-1]));
- }
-
- printf("\n");
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- printf(" Static Bucket Counter: Bucket %d %27d %27d %27d\n",
- i,
- le32_to_cpu(log_data->static_bucket_counter[i][READ]),
- le32_to_cpu(log_data->static_bucket_counter[i][WRITE]),
- le32_to_cpu(log_data->static_bucket_counter[i][TRIM]));
- }
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- printf(" Static Latency Time Stamp: Bucket %d ", i);
- for (j = 2; j >= 0; j--) {
- if (le64_to_cpu(log_data->static_latency_timestamp[3-i][j]) == -1) {
- printf(" N/A ");
- } else {
- convert_ts(le64_to_cpu(log_data->static_latency_timestamp[3-i][j]), ts_buf);
- printf("%s ", ts_buf);
- }
- }
- printf("\n");
- }
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
- i,
- le16_to_cpu(log_data->static_measured_latency[3-i][READ-1]),
- le16_to_cpu(log_data->static_measured_latency[3-i][WRITE-1]),
- le16_to_cpu(log_data->static_measured_latency[3-i][TRIM-1]));
- }
-
- return 0;
-}
-
-static void ocp_print_C3_log_json(struct ssd_latency_monitor_log *log_data)
-{
- struct json_object *root;
- char ts_buf[128];
- char buf[128];
- int i, j;
- char *operation[3] = {"Trim", "Write", "Read"};
-
- root = json_create_object();
-
- json_object_add_value_uint(root, "Feature Status",
- log_data->feature_status);
- json_object_add_value_uint(root, "Active Bucket Timer",
- C3_ACTIVE_BUCKET_TIMER_INCREMENT *
- le16_to_cpu(log_data->active_bucket_timer));
- json_object_add_value_uint(root, "Active Bucket Timer Threshold",
- C3_ACTIVE_BUCKET_TIMER_INCREMENT *
- le16_to_cpu(log_data->active_bucket_timer_threshold));
- json_object_add_value_uint(root, "Active Threshold A",
- C3_ACTIVE_THRESHOLD_INCREMENT *
- le16_to_cpu(log_data->active_threshold_a + 1));
- json_object_add_value_uint(root, "Active Threshold B",
- C3_ACTIVE_THRESHOLD_INCREMENT *
- le16_to_cpu(log_data->active_threshold_b + 1));
- json_object_add_value_uint(root, "Active Threshold C",
- C3_ACTIVE_THRESHOLD_INCREMENT *
- le16_to_cpu(log_data->active_threshold_c + 1));
- json_object_add_value_uint(root, "Active Threshold D",
- C3_ACTIVE_THRESHOLD_INCREMENT *
- le16_to_cpu(log_data->active_threshold_d + 1));
- json_object_add_value_uint(root, "Active Latency Configuration",
- le16_to_cpu(log_data->active_latency_config));
- json_object_add_value_uint(root, "Active Latency Minimum Window",
- C3_MINIMUM_WINDOW_INCREMENT *
- le16_to_cpu(log_data->active_latency_min_window));
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- struct json_object *bucket;
-
- bucket = json_create_object();
- sprintf(buf, "Active Bucket Counter: Bucket %d", i);
- for (j = 2; j >= 0; j--) {
- json_object_add_value_uint(bucket, operation[j],
- le32_to_cpu(log_data->active_bucket_counter[i][j+1]));
- }
- json_object_add_value_object(root, buf, bucket);
- }
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- struct json_object *bucket;
-
- bucket = json_create_object();
- sprintf(buf, "Active Latency Time Stamp: Bucket %d", i);
- for (j = 2; j >= 0; j--) {
- if (le64_to_cpu(log_data->active_latency_timestamp[3-i][j]) == -1) {
- json_object_add_value_string(bucket, operation[j], "NA");
- } else {
- convert_ts(le64_to_cpu(log_data->active_latency_timestamp[3-i][j]), ts_buf);
- json_object_add_value_string(bucket, operation[j], ts_buf);
- }
- }
- json_object_add_value_object(root, buf, bucket);
- }
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- struct json_object *bucket;
-
- bucket = json_create_object();
- sprintf(buf, "Active Measured Latency: Bucket %d", i);
- for (j = 2; j >= 0; j--) {
- json_object_add_value_uint(bucket, operation[j],
- le16_to_cpu(log_data->active_measured_latency[3-i][j]));
- }
- json_object_add_value_object(root, buf, bucket);
- }
-
- json_object_add_value_uint(root, "Active Latency Stamp Units",
- le16_to_cpu(log_data->active_latency_stamp_units));
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- struct json_object *bucket;
-
- bucket = json_create_object();
- sprintf(buf, "Static Bucket Counter: Bucket %d", i);
- for (j = 2; j >= 0; j--) {
- json_object_add_value_uint(bucket, operation[j],
- le32_to_cpu(log_data->static_bucket_counter[i][j+1]));
- }
- json_object_add_value_object(root, buf, bucket);
- }
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- struct json_object *bucket;
-
- bucket = json_create_object();
- sprintf(buf, "Static Latency Time Stamp: Bucket %d", i);
- for (j = 2; j >= 0; j--) {
- if (le64_to_cpu(log_data->static_latency_timestamp[3-i][j]) == -1) {
- json_object_add_value_string(bucket, operation[j], "NA");
- } else {
- convert_ts(le64_to_cpu(log_data->static_latency_timestamp[3-i][j]), ts_buf);
- json_object_add_value_string(bucket, operation[j], ts_buf);
- }
- }
- json_object_add_value_object(root, buf, bucket);
- }
-
- for (i = 0; i < C3_BUCKET_NUM; i++) {
- struct json_object *bucket;
-
- bucket = json_create_object();
- sprintf(buf, "Static Measured Latency: Bucket %d", i);
- for (j = 2; j >= 0; j--) {
- json_object_add_value_uint(bucket, operation[j],
- le16_to_cpu(log_data->static_measured_latency[3-i][j]));
- }
- json_object_add_value_object(root, buf, bucket);
- }
-
- json_object_add_value_uint(root, "Static Latency Stamp Units",
- le16_to_cpu(log_data->static_latency_stamp_units));
- json_object_add_value_uint(root, "Debug Log Trigger Enable",
- le16_to_cpu(log_data->debug_log_trigger_enable));
- json_object_add_value_uint(root, "Debug Log Measured Latency",
- le16_to_cpu(log_data->debug_log_measured_latency));
- if (le64_to_cpu(log_data->debug_log_latency_stamp) == -1) {
- json_object_add_value_string(root, "Debug Log Latency Time Stamp", "NA");
- } else {
- convert_ts(le64_to_cpu(log_data->debug_log_latency_stamp), ts_buf);
- json_object_add_value_string(root, "Debug Log Latency Time Stamp", ts_buf);
- }
- json_object_add_value_uint(root, "Debug Log Pointer",
- le16_to_cpu(log_data->debug_log_ptr));
- json_object_add_value_uint(root, "Debug Counter Trigger Source",
- le16_to_cpu(log_data->debug_log_counter_trigger));
- json_object_add_value_uint(root, "Debug Log Stamp Units",
- le16_to_cpu(log_data->debug_log_stamp_units));
- json_object_add_value_uint(root, "Log Page Version",
- le16_to_cpu(log_data->log_page_version));
-
- char guid[(C3_GUID_LENGTH * 2) + 1];
- char *ptr = &guid[0];
-
- for (i = C3_GUID_LENGTH - 1; i >= 0; i--)
- ptr += sprintf(ptr, "%02X", log_data->log_page_guid[i]);
-
- json_object_add_value_string(root, "Log Page GUID", guid);
-
- json_print_object(root, NULL);
- printf("\n");
-
- json_free_object(root);
-}
-
static int get_c3_log_page(struct nvme_dev *dev, char *format)
{
struct ssd_latency_monitor_log *log_data;
@@ -513,14 +192,6 @@ static int get_c3_log_page(struct nvme_dev *dev, char *format)
if (!ret) {
log_data = (struct ssd_latency_monitor_log *)data;
- /* check log page version */
- if (log_data->log_page_version != C3_LATENCY_MON_VERSION) {
- fprintf(stderr,
- "ERROR : OCP : invalid latency monitor version\n");
- ret = -1;
- goto out;
- }
-
/*
* check log page guid
* Verify GUID matches
@@ -532,32 +203,20 @@ static int get_c3_log_page(struct nvme_dev *dev, char *format)
fprintf(stderr, "ERROR : OCP : Unknown GUID in C3 Log Page data\n");
fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", lat_mon_guid[j]);
+ fprintf(stderr, "%02x", lat_mon_guid[j]);
fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ fprintf(stderr, "%02x", log_data->log_page_guid[j]);
fprintf(stderr, "\n");
ret = -1;
goto out;
}
}
-
- switch (fmt) {
- case NORMAL:
- ocp_print_C3_log_normal(dev, log_data);
- break;
- case JSON:
- ocp_print_C3_log_json(log_data);
- break;
- default:
- fprintf(stderr, "unhandled output format\n");
-
- }
+ ocp_c3_log(dev, log_data, fmt);
} else {
- fprintf(stderr,
- "ERROR : OCP : Unable to read C3 data from buffer\n");
+ fprintf(stderr, "ERROR : OCP : Unable to read C3 data from buffer\n");
}
out:
@@ -606,7 +265,7 @@ int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd,
int err = -1;
struct nvme_dev *dev;
__u32 result;
- struct feature_latency_monitor buf = {0,};
+ struct feature_latency_monitor buf = { 0 };
__u32 nsid = NVME_NSID_ALL;
struct stat nvme_stat;
struct nvme_id_ctrl ctrl;
@@ -683,16 +342,14 @@ int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd,
if (err)
return err;
- memset(&buf, 0, sizeof(struct feature_latency_monitor));
-
- buf.active_bucket_timer_threshold = cfg.active_bucket_timer_threshold;
+ buf.active_bucket_timer_threshold = cpu_to_le16(cfg.active_bucket_timer_threshold);
buf.active_threshold_a = cfg.active_threshold_a;
buf.active_threshold_b = cfg.active_threshold_b;
buf.active_threshold_c = cfg.active_threshold_c;
buf.active_threshold_d = cfg.active_threshold_d;
- buf.active_latency_config = cfg.active_latency_config;
+ buf.active_latency_config = cpu_to_le16(cfg.active_latency_config);
buf.active_latency_minimum_window = cfg.active_latency_minimum_window;
- buf.debug_log_trigger_enable = cfg.debug_log_trigger_enable;
+ buf.debug_log_trigger_enable = cpu_to_le16(cfg.debug_log_trigger_enable);
buf.discard_debug_log = cfg.discard_debug_log;
buf.latency_monitor_feature_enable = cfg.latency_monitor_feature_enable;
@@ -714,14 +371,16 @@ int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd,
perror("set-feature");
} else if (!err) {
printf("NVME_FEAT_OCP_LATENCY_MONITOR: 0x%02x\n", NVME_FEAT_OCP_LATENCY_MONITOR);
- printf("active bucket timer threshold: 0x%x\n", buf.active_bucket_timer_threshold);
+ printf("active bucket timer threshold: 0x%x\n",
+ le16_to_cpu(buf.active_bucket_timer_threshold));
printf("active threshold a: 0x%x\n", buf.active_threshold_a);
printf("active threshold b: 0x%x\n", buf.active_threshold_b);
printf("active threshold c: 0x%x\n", buf.active_threshold_c);
printf("active threshold d: 0x%x\n", buf.active_threshold_d);
- printf("active latency config: 0x%x\n", buf.active_latency_config);
+ printf("active latency config: 0x%x\n", le16_to_cpu(buf.active_latency_config));
printf("active latency minimum window: 0x%x\n", buf.active_latency_minimum_window);
- printf("debug log trigger enable: 0x%x\n", buf.debug_log_trigger_enable);
+ printf("debug log trigger enable: 0x%x\n",
+ le16_to_cpu(buf.debug_log_trigger_enable));
printf("discard debug log: 0x%x\n", buf.discard_debug_log);
printf("latency monitor feature enable: 0x%x\n", buf.latency_monitor_feature_enable);
} else if (err > 0) {
@@ -912,6 +571,7 @@ __u8 *pC9_string_buffer;
static void get_serial_number(struct nvme_id_ctrl *ctrl, char *sn)
{
int i;
+
/* Remove trailing spaces from the name */
for (i = 0; i < sizeof(ctrl->sn); i++) {
if (ctrl->sn[i] == ' ')
@@ -920,8 +580,7 @@ static void get_serial_number(struct nvme_id_ctrl *ctrl, char *sn)
}
}
-static void print_telemetry_header(struct telemetry_initiated_log *logheader,
- int tele_type)
+static void print_telemetry_header(struct telemetry_initiated_log *logheader, int tele_type)
{
if (logheader) {
unsigned int i = 0, j = 0;
@@ -973,16 +632,14 @@ static int get_telemetry_data(struct nvme_dev *dev, __u32 ns, __u8 tele_type,
__u16 numdu = numd >> 16;
__u16 numdl = numd & 0xffff;
- cmd.cdw10 = tele_type |
- (nLSP & 0x0F) << 8 |
- (nRAE & 0x01) << 15 |
- (numdl & 0xFFFF) << 16;
+ cmd.cdw10 = tele_type | (nLSP & 0x0F) << 8 | (nRAE & 0x01) << 15 | (numdl & 0xFFFF) << 16;
cmd.cdw11 = numdu;
cmd.cdw12 = (__u32)(0x00000000FFFFFFFF & offset);
cmd.cdw13 = (__u32)((0xFFFFFFFF00000000 & offset) >> 8);
cmd.cdw14 = 0;
return nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL);
}
+
static void print_telemetry_data_area_1(struct telemetry_data_area_1 *da1,
int tele_type)
{
@@ -1004,19 +661,19 @@ static void print_telemetry_data_area_1(struct telemetry_data_area_1 *da1,
da1->no_of_tps_supp);
printf("Telemetry Profile Selected (TPS) : 0x%x\n",
da1->tps);
- printf("Telemetry String Log Size (SLS) : 0x%lx\n",
- le64_to_cpu(da1->sls));
+ printf("Telemetry String Log Size (SLS) : 0x%"PRIx64"\n",
+ le64_to_cpu(da1->sls));
printf("Firmware Revision : ");
for (i = 0; i < 8; i++)
printf("%c", (char)da1->fw_revision[i]);
printf("\n");
- printf("Data Area 1 Statistic Start : 0x%lx\n",
+ printf("Data Area 1 Statistic Start : 0x%"PRIx64"\n",
le64_to_cpu(da1->da1_stat_start));
- printf("Data Area 1 Statistic Size : 0x%lx\n",
+ printf("Data Area 1 Statistic Size : 0x%"PRIx64"\n",
le64_to_cpu(da1->da1_stat_size));
- printf("Data Area 2 Statistic Start : 0x%lx\n",
+ printf("Data Area 2 Statistic Start : 0x%"PRIx64"\n",
le64_to_cpu(da1->da2_stat_start));
- printf("Data Area 2 Statistic Size : 0x%lx\n",
+ printf("Data Area 2 Statistic Size : 0x%"PRIx64"\n",
le64_to_cpu(da1->da2_stat_size));
for (i = 0; i < 16; i++) {
printf("Event FIFO %d Data Area : 0x%x\n",
@@ -1041,10 +698,9 @@ static void print_telemetry_data_area_1(struct telemetry_data_area_1 *da1,
printf("===============================================\n\n");
}
}
-static void print_telemetry_da_stat(struct telemetry_stats_desc *da_stat,
- int tele_type,
- __u16 buf_size,
- __u8 data_area)
+
+static void print_telemetry_da_stat(struct telemetry_stats_desc *da_stat, int tele_type,
+ __u16 buf_size, __u8 data_area)
{
if (da_stat) {
unsigned int i = 0;
@@ -1052,14 +708,14 @@ static void print_telemetry_da_stat(struct telemetry_stats_desc *da_stat,
if (tele_type == TELEMETRY_TYPE_HOST)
printf("============ Telemetry Host Data Area %d Statistics ============\n",
- data_area);
+ data_area);
else
printf("========= Telemetry Controller Data Area %d Statistics =========\n",
- data_area);
+ data_area);
while ((i + 8) < buf_size) {
print_stats_desc(next_da_stat);
i += 8 + ((next_da_stat->size) * 4);
- next_da_stat = (struct telemetry_stats_desc *)((__u64)da_stat + i);
+ next_da_stat = (struct telemetry_stats_desc *)((void *)da_stat + i);
if ((next_da_stat->id == 0) && (next_da_stat->size == 0))
break;
@@ -1068,13 +724,13 @@ static void print_telemetry_da_stat(struct telemetry_stats_desc *da_stat,
}
}
static void print_telemetry_da_fifo(struct telemetry_event_desc *da_fifo,
- __le64 buf_size,
+ __u64 buf_size,
int tele_type,
int da,
int index)
{
if (da_fifo) {
- unsigned int i = 0;
+ __u64 i = 0;
struct telemetry_event_desc *next_da_fifo = da_fifo;
if (tele_type == TELEMETRY_TYPE_HOST)
@@ -1084,8 +740,11 @@ static void print_telemetry_da_fifo(struct telemetry_event_desc *da_fifo,
printf("====== Telemetry Controller Data area %d Event FIFO %d ======\n",
da, index);
-
while ((i + 4) < buf_size) {
+ /* break if last entry */
+ if (next_da_fifo->class == 0)
+ break;
+
/* Print Event Data */
print_telemetry_fifo_event(next_da_fifo->class, /* Event class type */
next_da_fifo->id, /* Event ID */
@@ -1093,7 +752,7 @@ static void print_telemetry_da_fifo(struct telemetry_event_desc *da_fifo,
(__u8 *)&next_da_fifo->data); /* Event data */
i += (4 + (next_da_fifo->size * 4));
- next_da_fifo = (struct telemetry_event_desc *)((__u64)da_fifo + i);
+ next_da_fifo = (struct telemetry_event_desc *)((void *)da_fifo + i);
}
printf("===============================================\n\n");
}
@@ -1183,8 +842,8 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
enum TELEMETRY_TYPE tele_type, int data_area, bool header_print)
{
__u32 err = 0, nsid = 0;
- __le64 da1_sz = 512, m_512_sz = 0, da1_off = 0, m_512_off = 0, diff = 0,
- temp_sz = 0, temp_ofst = 0;
+ __u64 da1_sz = 512, m_512_sz = 0, da1_off = 0, m_512_off = 0, diff = 0, temp_sz = 0,
+ temp_ofst = 0;
__u8 lsp = 0, rae = 0, flag = 0;
__u8 data[TELEMETRY_HEADER_SIZE] = { 0 };
unsigned int i = 0;
@@ -1212,8 +871,8 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
}
/* Get the telemetry header */
- err = get_telemetry_data(dev, nsid, tele_type, TELEMETRY_HEADER_SIZE,
- (void *)data, lsp, rae, 0);
+ err = get_telemetry_data(dev, nsid, tele_type, TELEMETRY_HEADER_SIZE, (void *)data, lsp,
+ rae, 0);
if (err) {
printf("get_telemetry_header failed, err: %d.\n", err);
return err;
@@ -1223,8 +882,8 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
print_telemetry_header(logheader, tele_type);
/* Get the telemetry data */
- err = get_telemetry_data(dev, nsid, tele_type, TELEMETRY_DATA_SIZE,
- (void *)data1, lsp, rae, 512);
+ err = get_telemetry_data(dev, nsid, tele_type, TELEMETRY_DATA_SIZE, (void *)data1, lsp,
+ rae, 512);
if (err) {
printf("get_telemetry_data failed for type: 0x%x, err: %d.\n", tele_type, err);
return err;
@@ -1235,26 +894,26 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
/* Print the Data Area 1 Stats */
if (da1->da1_stat_size != 0) {
diff = 0;
- da1_sz = (da1->da1_stat_size) * 4;
- m_512_sz = (da1->da1_stat_size) * 4;
- da1_off = (da1->da1_stat_start) * 4;
- m_512_off = (da1->da1_stat_start) * 4;
- temp_sz = (da1->da1_stat_size) * 4;
- temp_ofst = (da1->da1_stat_start) * 4;
+ da1_sz = le64_to_cpu(da1->da1_stat_size) * 4;
+ m_512_sz = le64_to_cpu(da1->da1_stat_size) * 4;
+ da1_off = le64_to_cpu(da1->da1_stat_start) * 4;
+ m_512_off = le64_to_cpu(da1->da1_stat_start) * 4;
+ temp_sz = le64_to_cpu(da1->da1_stat_size) * 4;
+ temp_ofst = le64_to_cpu(da1->da1_stat_start) * 4;
flag = 0;
if ((da1_off % 512) > 0) {
- m_512_off = (__le64) ((da1_off / 512));
+ m_512_off = (da1_off / 512);
da1_off = m_512_off * 512;
diff = temp_ofst - da1_off;
flag = 1;
}
- if (da1_sz < 512)
+ if (da1_sz < 512) {
da1_sz = 512;
- else if ((da1_sz % 512) > 0) {
+ } else if ((da1_sz % 512) > 0) {
if (flag == 0) {
- m_512_sz = (__le64) ((da1_sz / 512) + 1);
+ m_512_sz = (da1_sz / 512) + 1;
da1_sz = m_512_sz * 512;
} else {
if (diff < 512)
@@ -1262,48 +921,48 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
else
diff = (diff / 512) * 512;
- m_512_sz = (__le64) ((da1_sz / 512) + 1 + diff + 1);
+ m_512_sz = (da1_sz / 512) + 1 + diff + 1;
da1_sz = m_512_sz * 512;
}
}
char *da1_stat = calloc(da1_sz, sizeof(char));
- err = get_telemetry_data(dev, nsid, tele_type, da1_sz,
- (void *)da1_stat, lsp, rae, da1_off);
+ err = get_telemetry_data(dev, nsid, tele_type, da1_sz, (void *)da1_stat, lsp, rae,
+ da1_off);
if (err) {
printf("get_telemetry_data da1 stats failed, err: %d.\n", err);
return err;
}
- print_telemetry_da_stat((void *)(da1_stat + (temp_ofst - da1_off)),
- tele_type, (da1->da1_stat_size) * 4, 1);
+ print_telemetry_da_stat((void *)(da1_stat + (temp_ofst - da1_off)), tele_type,
+ le64_to_cpu(da1->da1_stat_size) * 4, 1);
}
/* Print the Data Area 1 Event FIFO's */
for (i = 0; i < 16 ; i++) {
if ((da1->event_fifo_da[i] == 1) && (da1->event_fifos[i].size != 0)) {
diff = 0;
- da1_sz = da1->event_fifos[i].size * 4;
- m_512_sz = da1->event_fifos[i].size * 4;
- da1_off = da1->event_fifos[i].start * 4;
- m_512_off = da1->event_fifos[i].start * 4;
- temp_sz = da1->event_fifos[i].size * 4;
- temp_ofst = da1->event_fifos[i].start * 4;
+ da1_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
+ m_512_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
+ da1_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
+ m_512_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
+ temp_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
+ temp_ofst = le64_to_cpu(da1->event_fifos[i].start) * 4;
flag = 0;
if ((da1_off % 512) > 0) {
- m_512_off = (__le64) ((da1_off / 512));
+ m_512_off = ((da1_off / 512));
da1_off = m_512_off * 512;
diff = temp_ofst - da1_off;
flag = 1;
}
- if (da1_sz < 512)
+ if (da1_sz < 512) {
da1_sz = 512;
- else if ((da1_sz % 512) > 0) {
+ } else if ((da1_sz % 512) > 0) {
if (flag == 0) {
- m_512_sz = (__le64) ((da1_sz / 512) + 1);
+ m_512_sz = (da1_sz / 512) + 1;
da1_sz = m_512_sz * 512;
} else {
if (diff < 512)
@@ -1311,121 +970,115 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
else
diff = (diff / 512) * 512;
- m_512_sz = (__le64) ((da1_sz / 512) + 1 + diff + 1);
+ m_512_sz = (da1_sz / 512) + 1 + diff + 1;
da1_sz = m_512_sz * 512;
}
}
char *da1_fifo = calloc(da1_sz, sizeof(char));
+ printf("Get DA 1 FIFO addr: %p, offset 0x%"PRIx64"\n", da1_fifo,
+ (uint64_t)da1_off);
err = get_telemetry_data(dev, nsid, tele_type,
- (da1->event_fifos[i].size) * 4,
- (void *)da1_fifo, lsp, rae, da1_off);
+ le64_to_cpu(da1->event_fifos[i].size) * 4,
+ (void *)da1_fifo, lsp, rae, da1_off);
if (err) {
printf("get_telemetry_data da1 event fifos failed, err: %d.\n",
- err);
+ err);
return err;
}
- print_telemetry_da_fifo((void *)(da1_fifo + (temp_ofst - da1_off)),
- temp_sz,
- tele_type,
- da1->event_fifo_da[i],
- i);
+ print_telemetry_da_fifo((void *)(da1_fifo + (temp_ofst - da1_off)), temp_sz,
+ tele_type, le64_to_cpu(da1->event_fifo_da[i]), i);
}
}
/* Print the Data Area 2 Stats */
if (da1->da2_stat_size != 0) {
- da1_off = (da1->da2_stat_start) * 4;
- temp_ofst = (da1->da2_stat_start) * 4;
- da1_sz = (da1->da2_stat_size) * 4;
+ da1_off = le64_to_cpu(da1->da2_stat_start) * 4;
+ temp_ofst = le64_to_cpu(da1->da2_stat_start) * 4;
+ da1_sz = le64_to_cpu(da1->da2_stat_size) * 4;
diff = 0;
flag = 0;
if (da1->da2_stat_start == 0) {
- da1_off = 512 + (logheader->DataArea1LastBlock * 512);
+ da1_off = 512 + (le16_to_cpu(logheader->DataArea1LastBlock) * 512);
temp_ofst = 512 + (le16_to_cpu(logheader->DataArea1LastBlock) * 512);
if ((da1_off % 512) == 0) {
- m_512_off = (__le64) (((da1_off) / 512));
+ m_512_off = ((da1_off) / 512);
da1_off = m_512_off * 512;
diff = temp_ofst - da1_off;
flag = 1;
}
} else {
-
if (((da1_off * 4) % 512) > 0) {
- m_512_off = (__le64) ((((da1->da2_stat_start) * 4) / 512));
+ m_512_off = ((le64_to_cpu(da1->da2_stat_start) * 4) / 512);
da1_off = m_512_off * 512;
- diff = ((da1->da2_stat_start) * 4) - da1_off;
+ diff = (le64_to_cpu(da1->da2_stat_start) * 4) - da1_off;
flag = 1;
}
}
- if (da1_sz < 512)
+ if (da1_sz < 512) {
da1_sz = 512;
- else if ((da1_sz % 512) > 0) {
+ } else if ((da1_sz % 512) > 0) {
if (flag == 0) {
- m_512_sz = (__le64) ((da1->da2_stat_size / 512) + 1);
+ m_512_sz = (le64_to_cpu(da1->da2_stat_size) / 512) + 1;
da1_sz = m_512_sz * 512;
} else {
if (diff < 512)
diff = 1;
else
diff = (diff / 512) * 512;
- m_512_sz = (__le64) ((da1->da2_stat_size / 512) + 1 + diff + 1);
+ m_512_sz = (le64_to_cpu(da1->da2_stat_size) / 512) + 1 + diff + 1;
da1_sz = m_512_sz * 512;
}
}
char *da2_stat = calloc(da1_sz, sizeof(char));
- err = get_telemetry_data(dev, nsid, tele_type, da1_sz,
- (void *)da2_stat, lsp, rae, da1_off);
+ err = get_telemetry_data(dev, nsid, tele_type, da1_sz, (void *)da2_stat, lsp, rae,
+ da1_off);
if (err) {
printf("get_telemetry_data da2 stats failed, err: %d.\n", err);
return err;
}
- print_telemetry_da_stat((void *)(da2_stat + (temp_ofst - da1_off)),
- tele_type,
- (da1->da2_stat_size) * 4,
- 2);
+ print_telemetry_da_stat((void *)(da2_stat + (temp_ofst - da1_off)), tele_type,
+ le64_to_cpu(da1->da2_stat_size) * 4, 2);
}
/* Print the Data Area 2 Event FIFO's */
for (i = 0; i < 16 ; i++) {
if ((da1->event_fifo_da[i] == 2) && (da1->event_fifos[i].size != 0)) {
diff = 0;
- da1_sz = da1->event_fifos[i].size * 4;
- m_512_sz = da1->event_fifos[i].size * 4;
- da1_off = da1->event_fifos[i].start * 4;
- m_512_off = da1->event_fifos[i].start * 4;
- temp_sz = da1->event_fifos[i].size * 4;
- temp_ofst = da1->event_fifos[i].start * 4;
+ da1_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
+ m_512_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
+ da1_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
+ m_512_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
+ temp_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
+ temp_ofst = le64_to_cpu(da1->event_fifos[i].start) * 4;
flag = 0;
if ((da1_off % 512) > 0) {
- m_512_off = (__le64) ((da1_off / 512));
+ m_512_off = ((da1_off / 512));
da1_off = m_512_off * 512;
diff = temp_ofst - da1_off;
flag = 1;
}
- if (da1_sz < 512)
+ if (da1_sz < 512) {
da1_sz = 512;
- else if ((da1_sz % 512) > 0) {
+ } else if ((da1_sz % 512) > 0) {
if (flag == 0) {
- m_512_sz = (__le64) ((da1_sz / 512) + 1);
+ m_512_sz = (da1_sz / 512) + 1;
da1_sz = m_512_sz * 512;
- }
-
- else {
+ } else {
if (diff < 512)
diff = 1;
else
diff = (diff / 512) * 512;
- m_512_sz = (__le64) ((da1_sz / 512) + 1 + diff + 1);
+ m_512_sz = (da1_sz / 512) + 1 + diff + 1;
da1_sz = m_512_sz * 512;
}
}
@@ -1433,18 +1086,15 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
char *da1_fifo = calloc(da1_sz, sizeof(char));
err = get_telemetry_data(dev, nsid, tele_type,
- (da1->event_fifos[i].size) * 4,
- (void *)da1_fifo, lsp, rae, da1_off);
+ le64_to_cpu(da1->event_fifos[i].size) * 4,
+ (void *)da1_fifo, lsp, rae, da1_off);
if (err) {
printf("get_telemetry_data da2 event fifos failed, err: %d.\n",
- err);
+ err);
return err;
}
- print_telemetry_da_fifo((void *)(da1_fifo + (temp_ofst - da1_off)),
- temp_sz,
- tele_type,
- da1->event_fifo_da[i],
- i);
+ print_telemetry_da_fifo((void *)(da1_fifo + (temp_ofst - da1_off)), temp_sz,
+ tele_type, le64_to_cpu(da1->event_fifo_da[i]), i);
}
}
@@ -1452,20 +1102,20 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
switch (data_area) {
case 1:
- offset = TELEMETRY_HEADER_SIZE;
- size = le16_to_cpu(logheader->DataArea1LastBlock);
+ offset = TELEMETRY_HEADER_SIZE;
+ size = le16_to_cpu(logheader->DataArea1LastBlock);
break;
case 2:
- offset = TELEMETRY_HEADER_SIZE
- + (le16_to_cpu(logheader->DataArea1LastBlock) * TELEMETRY_BYTE_PER_BLOCK);
- size = le16_to_cpu(logheader->DataArea2LastBlock)
- - le16_to_cpu(logheader->DataArea1LastBlock);
+ offset = TELEMETRY_HEADER_SIZE +
+ (le16_to_cpu(logheader->DataArea1LastBlock) * TELEMETRY_BYTE_PER_BLOCK);
+ size = le16_to_cpu(logheader->DataArea2LastBlock) -
+ le16_to_cpu(logheader->DataArea1LastBlock);
break;
case 3:
- offset = TELEMETRY_HEADER_SIZE
- + (le16_to_cpu(logheader->DataArea2LastBlock) * TELEMETRY_BYTE_PER_BLOCK);
- size = le16_to_cpu(logheader->DataArea3LastBlock)
- - le16_to_cpu(logheader->DataArea2LastBlock);
+ offset = TELEMETRY_HEADER_SIZE +
+ (le16_to_cpu(logheader->DataArea2LastBlock) * TELEMETRY_BYTE_PER_BLOCK);
+ size = le16_to_cpu(logheader->DataArea3LastBlock) -
+ le16_to_cpu(logheader->DataArea2LastBlock);
break;
default:
break;
@@ -1476,11 +1126,9 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
return err;
}
- snprintf(dumpname, FILE_NAME_SIZE,
- "Telemetry_%s_Area_%d", featurename, data_area);
+ snprintf(dumpname, FILE_NAME_SIZE, "Telemetry_%s_Area_%d", featurename, data_area);
err = extract_dump_get_log(dev, dumpname, filename, sn, size * TELEMETRY_BYTE_PER_BLOCK,
- TELEMETRY_TRANSFER_SIZE, nsid, tele_type,
- 0, offset, rae);
+ TELEMETRY_TRANSFER_SIZE, nsid, tele_type, 0, offset, rae);
return err;
}
@@ -1588,13 +1236,15 @@ exit_status:
static int get_c9_log_page_data(struct nvme_dev *dev, int print_data, int save_bin)
{
- int ret = 0, fd;
+ int ret = 0;
__le64 stat_id_str_table_ofst = 0;
__le64 event_str_table_ofst = 0;
__le64 vu_event_str_table_ofst = 0;
__le64 ascii_table_ofst = 0;
char file_path[PATH_MAX];
+ _cleanup_fd_ int fd = STDIN_FILENO;
+
header_data = (__u8 *)malloc(sizeof(__u8) * C9_TELEMETRY_STR_LOG_LEN);
if (!header_data) {
fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
@@ -1608,29 +1258,34 @@ static int get_c9_log_page_data(struct nvme_dev *dev, int print_data, int save_b
if (!ret) {
log_data = (struct telemetry_str_log_format *)header_data;
if (print_data) {
- printf("Statistics Identifier String Table Size = %lld\n",
- log_data->sitsz);
- printf("Event String Table Size = %lld\n", log_data->estsz);
- printf("VU Event String Table Size = %lld\n", log_data->vu_eve_st_sz);
- printf("ASCII Table Size = %lld\n", log_data->asctsz);
+ printf("Statistics Identifier String Table Size = %"PRIu64"\n",
+ le64_to_cpu(log_data->sitsz));
+ printf("Event String Table Size = %"PRIu64"\n",
+ le64_to_cpu(log_data->estsz));
+ printf("VU Event String Table Size = %"PRIu64"\n",
+ le64_to_cpu(log_data->vu_eve_st_sz));
+ printf("ASCII Table Size = %"PRIu64"\n", le64_to_cpu(log_data->asctsz));
}
- //Calculating the offset for dynamic fields.
+ /* Calculating the offset for dynamic fields. */
stat_id_str_table_ofst = log_data->sits * 4;
event_str_table_ofst = log_data->ests * 4;
vu_event_str_table_ofst = log_data->vu_eve_sts * 4;
ascii_table_ofst = log_data->ascts * 4;
total_log_page_sz = C9_TELEMETRY_STR_LOG_LEN +
- (log_data->sitsz * 4) + (log_data->estsz * 4) +
- (log_data->vu_eve_st_sz * 4) + (log_data->asctsz * 4);
+ (log_data->sitsz * 4) + (log_data->estsz * 4) +
+ (log_data->vu_eve_st_sz * 4) + (log_data->asctsz * 4);
if (print_data) {
- printf("stat_id_str_table_ofst = %lld\n", stat_id_str_table_ofst);
- printf("event_str_table_ofst = %lld\n", event_str_table_ofst);
- printf("vu_event_str_table_ofst = %lld\n", vu_event_str_table_ofst);
- printf("ascii_table_ofst = %lld\n", ascii_table_ofst);
- printf("total_log_page_sz = %lld\n", total_log_page_sz);
+ printf("stat_id_str_table_ofst = %"PRIu64"\n",
+ le64_to_cpu(stat_id_str_table_ofst));
+ printf("event_str_table_ofst = %"PRIu64"\n",
+ le64_to_cpu(event_str_table_ofst));
+ printf("vu_event_str_table_ofst = %"PRIu64"\n",
+ le64_to_cpu(vu_event_str_table_ofst));
+ printf("ascii_table_ofst = %"PRIu64"\n", le64_to_cpu(ascii_table_ofst));
+ printf("total_log_page_sz = %"PRIu64"\n", le64_to_cpu(total_log_page_sz));
}
pC9_string_buffer = (__u8 *)malloc(sizeof(__u8) * total_log_page_sz);
@@ -1642,26 +1297,24 @@ static int get_c9_log_page_data(struct nvme_dev *dev, int print_data, int save_b
ret = nvme_get_log_simple(dev_fd(dev), C9_TELEMETRY_STRING_LOG_ENABLE_OPCODE,
total_log_page_sz, pC9_string_buffer);
- } else
+ } else {
fprintf(stderr, "ERROR : OCP : Unable to read C9 data.\n");
+ }
if (save_bin) {
sprintf(file_path, DEFAULT_STRING_BIN);
fd = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0) {
- fprintf(stderr, "Failed to open output file %s: %s!\n",
- file_path, strerror(errno));
- goto exit_status;
+ fprintf(stderr, "Failed to open output file %s: %s!\n", file_path,
+ strerror(errno));
+ return fd;
}
ret = write(fd, (void *)pC9_string_buffer, total_log_page_sz);
if (ret != total_log_page_sz)
fprintf(stderr, "Failed to flush all data to file!\n");
-
- close(fd);
}
-exit_status:
return 0;
}
@@ -1716,22 +1369,12 @@ int parse_ocp_telemetry_log(struct ocp_telemetry_parse_options *options)
return status;
}
- switch (fmt) {
- case NORMAL:
- print_ocp_telemetry_normal(options);
- break;
- case JSON:
- print_ocp_telemetry_json(options);
- break;
- default:
- break;
- }
+ ocp_show_telemetry_log(options, fmt);
return 0;
}
-static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Retrieve and parse OCP Telemetry log.";
const char *telemetry_log = "Telemetry log binary;\n 'host.bin' or 'controller.bin'";
@@ -1769,6 +1412,9 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
if (err)
return err;
+ if (opt.telemetry_type == 0)
+ opt.telemetry_type = "host";
+
err = fstat(dev_fd(dev), &nvme_stat);
if (err < 0)
return err;
@@ -1812,6 +1458,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
}
} else {
tele_type = TELEMETRY_TYPE_HOST; //Default Type - Host
+ opt.telemetry_type = "host";
nvme_show_result("Missing telemetry-type. Using default - host.\n");
}
@@ -1843,23 +1490,21 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
}
switch (tele_type) {
- case TELEMETRY_TYPE_HOST: {
+ case TELEMETRY_TYPE_HOST:
printf("Extracting Telemetry Host Dump (Data Area %d)...\n", tele_area);
err = parse_ocp_telemetry_log(&opt);
if (err)
nvme_show_result("Status:(%x)\n", err);
- }
- break;
- case TELEMETRY_TYPE_CONTROLLER: {
+ break;
+ case TELEMETRY_TYPE_CONTROLLER:
printf("Extracting Telemetry Controller Dump (Data Area %d)...\n", tele_area);
if (is_support_telemetry_controller == true) {
err = parse_ocp_telemetry_log(&opt);
if (err)
nvme_show_result("Status:(%x)\n", err);
}
- }
- break;
- case TELEMETRY_TYPE_NONE: {
+ break;
+ case TELEMETRY_TYPE_NONE:
printf("\n-------------------------------------------------------------\n");
/* Host 0 (lsp == 0) must be executed before Host 1 (lsp == 1). */
printf("\nExtracting Telemetry Host 0 Dump (Data Area 1)...\n");
@@ -1867,7 +1512,8 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
err = get_telemetry_dump(dev, opt.output_file, sn,
TELEMETRY_TYPE_HOST_0, 1, true);
if (err)
- fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false),
+ err);
printf("\n-------------------------------------------------------------\n");
@@ -1876,7 +1522,8 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
err = get_telemetry_dump(dev, opt.output_file, sn,
TELEMETRY_TYPE_HOST_0, 3, false);
if (err)
- fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false),
+ err);
printf("\n-------------------------------------------------------------\n");
@@ -1885,7 +1532,8 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
err = get_telemetry_dump(dev, opt.output_file, sn,
TELEMETRY_TYPE_HOST_1, 1, true);
if (err)
- fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false),
+ err);
printf("\n-------------------------------------------------------------\n");
@@ -1894,7 +1542,8 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
err = get_telemetry_dump(dev, opt.output_file, sn,
TELEMETRY_TYPE_HOST_1, 3, false);
if (err)
- fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false),
+ err);
printf("\n-------------------------------------------------------------\n");
@@ -1908,19 +1557,18 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
}
printf("\n-------------------------------------------------------------\n");
- }
- break;
+ break;
case TELEMETRY_TYPE_HOST_0:
case TELEMETRY_TYPE_HOST_1:
- default: {
+ default:
printf("Extracting Telemetry Host(%d) Dump (Data Area %d)...\n",
(tele_type == TELEMETRY_TYPE_HOST_0) ? 0 : 1, tele_area);
err = get_telemetry_dump(dev, opt.output_file, sn, tele_type, tele_area, true);
if (err)
- fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
- }
- break;
+ fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false),
+ err);
+ break;
}
printf("ocp internal-log command completed.\n");
@@ -1929,7 +1577,6 @@ out:
return err;
}
-
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -1937,99 +1584,20 @@ out:
/// Unsupported Requirement Log Page (LID : C5h)
/* C5 Unsupported Requirement Log Page */
-#define C5_GUID_LENGTH 16
#define C5_UNSUPPORTED_REQS_LEN 4096
#define C5_UNSUPPORTED_REQS_OPCODE 0xC5
-#define C5_UNSUPPORTED_REQS_LOG_VERSION 0x1
-#define C5_NUM_UNSUPPORTED_REQ_ENTRIES 253
-static __u8 unsupported_req_guid[C5_GUID_LENGTH] = {
+static __u8 unsupported_req_guid[GUID_LEN] = {
0x2F, 0x72, 0x9C, 0x0E,
0x99, 0x23, 0x2C, 0xBB,
0x63, 0x48, 0x32, 0xD0,
0xB7, 0x98, 0xBB, 0xC7
};
-/*
- * struct unsupported_requirement_log - unsupported requirement list
- * @unsupported_count: Number of Unsupported Requirement IDs
- * @rsvd1: Reserved
- * @unsupported_req_list: Unsupported Requirements lists upto 253.
- * @rsvd2: Reserved
- * @log_page_version: indicates the version of the mapping this log page uses.
- * Shall be set to 0001h
- * @log_page_guid: Shall be set to C7BB98B7D0324863BB2C23990E9C722Fh.
- */
-struct __packed unsupported_requirement_log {
- __le16 unsupported_count;
- __u8 rsvd1[14];
- __u8 unsupported_req_list[C5_NUM_UNSUPPORTED_REQ_ENTRIES][16];
- __u8 rsvd2[14];
- __le16 log_page_version;
- __u8 log_page_guid[C5_GUID_LENGTH];
-};
-
/* Function declaration for unsupported requirement log page (LID:C5h) */
static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin);
-static int ocp_print_C5_log_normal(struct nvme_dev *dev,
- struct unsupported_requirement_log *log_data)
-{
- int j;
-
- printf("Unsupported Requirement-C5 Log Page Data-\n");
-
- printf(" Number Unsupported Req IDs : 0x%x\n", le16_to_cpu(log_data->unsupported_count));
-
- for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++)
- printf(" Unsupported Requirement List %d : %s\n", j, log_data->unsupported_req_list[j]);
-
- printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
- printf(" Log page GUID : 0x");
- for (j = C5_GUID_LENGTH - 1; j >= 0; j--)
- printf("%x", log_data->log_page_guid[j]);
- printf("\n");
-
- return 0;
-}
-
-static void ocp_print_C5_log_json(struct unsupported_requirement_log *log_data)
-{
- int j;
- struct json_object *root;
- char unsup_req_list_str[40];
- char guid_buf[C5_GUID_LENGTH];
- char *guid = guid_buf;
-
- root = json_create_object();
-
- json_object_add_value_int(root, "Number Unsupported Req IDs", le16_to_cpu(log_data->unsupported_count));
-
- memset((void *)unsup_req_list_str, 0, 40);
- for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++) {
- sprintf((char *)unsup_req_list_str, "Unsupported Requirement List %d", j);
- json_object_add_value_string(root, unsup_req_list_str, (char *)log_data->unsupported_req_list[j]);
- }
-
- json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
-
- memset((void *)guid, 0, C5_GUID_LENGTH);
- for (j = C5_GUID_LENGTH - 1; j >= 0; j--)
- guid += sprintf(guid, "%02x", log_data->log_page_guid[j]);
- json_object_add_value_string(root, "Log page GUID", guid_buf);
-
- json_print_object(root, NULL);
- printf("\n");
-
- json_free_object(root);
-}
-
-static void ocp_print_c5_log_binary(struct unsupported_requirement_log *log_data)
-{
- return d_raw((unsigned char *)log_data, sizeof(*log_data));
-}
-
static int get_c5_log_page(struct nvme_dev *dev, char *format)
{
nvme_print_flags_t fmt;
@@ -2057,13 +1625,6 @@ static int get_c5_log_page(struct nvme_dev *dev, char *format)
if (!ret) {
log_data = (struct unsupported_requirement_log *)data;
- /* check log page version */
- if (log_data->log_page_version != C5_UNSUPPORTED_REQS_LOG_VERSION) {
- fprintf(stderr, "ERROR : OCP : invalid unsupported requirement version\n");
- ret = -1;
- goto out;
- }
-
/*
* check log page guid
* Verify GUID matches
@@ -2073,30 +1634,17 @@ static int get_c5_log_page(struct nvme_dev *dev, char *format)
fprintf(stderr, "ERROR : OCP : Unknown GUID in C5 Log Page data\n");
fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", unsupported_req_guid[j]);
+ fprintf(stderr, "%02x", unsupported_req_guid[j]);
fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ fprintf(stderr, "%02x", log_data->log_page_guid[j]);
fprintf(stderr, "\n");
ret = -1;
goto out;
}
}
-
- switch (fmt) {
- case NORMAL:
- ocp_print_C5_log_normal(dev, log_data);
- break;
- case JSON:
- ocp_print_C5_log_json(log_data);
- break;
- case BINARY:
- ocp_print_c5_log_binary(log_data);
- break;
- default:
- break;
- }
+ ocp_c5_log(dev, log_data, fmt);
} else {
fprintf(stderr, "ERROR : OCP : Unable to read C3 data from buffer\n");
}
@@ -2146,115 +1694,17 @@ static int ocp_unsupported_requirements_log(int argc, char **argv, struct comman
#define C1_ERROR_RECOVERY_LOG_BUF_LEN 0x200
#define C1_ERROR_RECOVERY_OPCODE 0xC1
-#define C1_ERROR_RECOVERY_VERSION 0x0002
-#define C1_GUID_LENGTH 16
-static __u8 error_recovery_guid[C1_GUID_LENGTH] = {
+
+static __u8 error_recovery_guid[GUID_LEN] = {
0x44, 0xd9, 0x31, 0x21,
0xfe, 0x30, 0x34, 0xae,
0xab, 0x4d, 0xfd, 0x3d,
0xba, 0x83, 0x19, 0x5a
};
-/**
- * struct ocp_error_recovery_log_page - Error Recovery Log Page
- * @panic_reset_wait_time: Panic Reset Wait Time
- * @panic_reset_action: Panic Reset Action
- * @device_recover_action_1: Device Recovery Action 1
- * @panic_id: Panic ID
- * @device_capabilities: Device Capabilities
- * @vendor_specific_recovery_opcode: Vendor Specific Recovery Opcode
- * @reserved: Reserved
- * @vendor_specific_command_cdw12: Vendor Specific Command CDW12
- * @vendor_specific_command_cdw13: Vendor Specific Command CDW13
- * @vendor_specific_command_timeout: Vendor Specific Command Timeout
- * @device_recover_action_2: Device Recovery Action 2
- * @device_recover_action_2_timeout: Device Recovery Action 2 Timeout
- * @reserved2: Reserved
- * @log_page_version: Log Page Version
- * @log_page_guid: Log Page GUID
- */
-struct __packed ocp_error_recovery_log_page {
- __le16 panic_reset_wait_time; /* 2 bytes - 0x00 - 0x01 */
- __u8 panic_reset_action; /* 1 byte - 0x02 */
- __u8 device_recover_action_1; /* 1 byte - 0x03 */
- __le64 panic_id; /* 8 bytes - 0x04 - 0x0B */
- __le32 device_capabilities; /* 4 bytes - 0x0C - 0x0F */
- __u8 vendor_specific_recovery_opcode; /* 1 byte - 0x10 */
- __u8 reserved[0x3]; /* 3 bytes - 0x11 - 0x13 */
- __le32 vendor_specific_command_cdw12; /* 4 bytes - 0x14 - 0x17 */
- __le32 vendor_specific_command_cdw13; /* 4 bytes - 0x18 - 0x1B */
- __u8 vendor_specific_command_timeout; /* 1 byte - 0x1C */
- __u8 device_recover_action_2; /* 1 byte - 0x1D */
- __u8 device_recover_action_2_timeout; /* 1 byte - 0x1E */
- __u8 reserved2[0x1cf]; /* 463 bytes - 0x1F - 0x1ED */
- __le16 log_page_version; /* 2 bytes - 0x1EE - 0x1EF */
- __u8 log_page_guid[0x10]; /* 16 bytes - 0x1F0 - 0x1FF */
-};
-
-static void ocp_print_c1_log_normal(struct ocp_error_recovery_log_page *log_data);
-static void ocp_print_c1_log_json(struct ocp_error_recovery_log_page *log_data);
-static void ocp_print_c1_log_binary(struct ocp_error_recovery_log_page *log_data);
static int get_c1_log_page(struct nvme_dev *dev, char *format);
static int ocp_error_recovery_log(int argc, char **argv, struct command *cmd, struct plugin *plugin);
-static void ocp_print_c1_log_normal(struct ocp_error_recovery_log_page *log_data)
-{
- int i;
-
- printf(" Error Recovery/C1 Log Page Data\n");
- printf(" Panic Reset Wait Time : 0x%x\n", le16_to_cpu(log_data->panic_reset_wait_time));
- printf(" Panic Reset Action : 0x%x\n", log_data->panic_reset_action);
- printf(" Device Recovery Action 1 : 0x%x\n", log_data->device_recover_action_1);
- printf(" Panic ID : 0x%x\n", le32_to_cpu(log_data->panic_id));
- printf(" Device Capabilities : 0x%x\n", le32_to_cpu(log_data->device_capabilities));
- printf(" Vendor Specific Recovery Opcode : 0x%x\n", log_data->vendor_specific_recovery_opcode);
- printf(" Vendor Specific Command CDW12 : 0x%x\n", le32_to_cpu(log_data->vendor_specific_command_cdw12));
- printf(" Vendor Specific Command CDW13 : 0x%x\n", le32_to_cpu(log_data->vendor_specific_command_cdw13));
- printf(" Vendor Specific Command Timeout : 0x%x\n", log_data->vendor_specific_command_timeout);
- printf(" Device Recovery Action 2 : 0x%x\n", log_data->device_recover_action_2);
- printf(" Device Recovery Action 2 Timeout : 0x%x\n", log_data->device_recover_action_2_timeout);
- printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
- printf(" Log page GUID : 0x");
- for (i = C1_GUID_LENGTH - 1; i >= 0; i--)
- printf("%x", log_data->log_page_guid[i]);
- printf("\n");
-}
-
-static void ocp_print_c1_log_json(struct ocp_error_recovery_log_page *log_data)
-{
- struct json_object *root;
-
- root = json_create_object();
- char guid[64];
-
- json_object_add_value_int(root, "Panic Reset Wait Time", le16_to_cpu(log_data->panic_reset_wait_time));
- json_object_add_value_int(root, "Panic Reset Action", log_data->panic_reset_action);
- json_object_add_value_int(root, "Device Recovery Action 1", log_data->device_recover_action_1);
- json_object_add_value_int(root, "Panic ID", le32_to_cpu(log_data->panic_id));
- json_object_add_value_int(root, "Device Capabilities", le32_to_cpu(log_data->device_capabilities));
- json_object_add_value_int(root, "Vendor Specific Recovery Opcode", log_data->vendor_specific_recovery_opcode);
- json_object_add_value_int(root, "Vendor Specific Command CDW12", le32_to_cpu(log_data->vendor_specific_command_cdw12));
- json_object_add_value_int(root, "Vendor Specific Command CDW13", le32_to_cpu(log_data->vendor_specific_command_cdw13));
- json_object_add_value_int(root, "Vendor Specific Command Timeout", log_data->vendor_specific_command_timeout);
- json_object_add_value_int(root, "Device Recovery Action 2", log_data->device_recover_action_2);
- json_object_add_value_int(root, "Device Recovery Action 2 Timeout", log_data->device_recover_action_2_timeout);
- json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
-
- memset((void *)guid, 0, 64);
- sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"", (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
- json_object_add_value_string(root, "Log page GUID", guid);
-
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
-}
-
-static void ocp_print_c1_log_binary(struct ocp_error_recovery_log_page *log_data)
-{
- return d_raw((unsigned char *)log_data, sizeof(*log_data));
-}
-
static int get_c1_log_page(struct nvme_dev *dev, char *format)
{
struct ocp_error_recovery_log_page *log_data;
@@ -2281,13 +1731,6 @@ static int get_c1_log_page(struct nvme_dev *dev, char *format)
if (!ret) {
log_data = (struct ocp_error_recovery_log_page *)data;
- /* check log page version */
- if (log_data->log_page_version != C1_ERROR_RECOVERY_VERSION) {
- fprintf(stderr, "ERROR : OCP : invalid error recovery log page version\n");
- ret = -1;
- goto out;
- }
-
/*
* check log page guid
* Verify GUID matches
@@ -2297,30 +1740,17 @@ static int get_c1_log_page(struct nvme_dev *dev, char *format)
fprintf(stderr, "ERROR : OCP : Unknown GUID in C1 Log Page data\n");
fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", error_recovery_guid[j]);
+ fprintf(stderr, "%02x", error_recovery_guid[j]);
fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ fprintf(stderr, "%02x", log_data->log_page_guid[j]);
fprintf(stderr, "\n");
ret = -1;
goto out;
}
}
-
- switch (fmt) {
- case NORMAL:
- ocp_print_c1_log_normal(log_data);
- break;
- case JSON:
- ocp_print_c1_log_json(log_data);
- break;
- case BINARY:
- ocp_print_c1_log_binary(log_data);
- break;
- default:
- break;
- }
+ ocp_c1_log(log_data, fmt);
} else {
fprintf(stderr, "ERROR : OCP : Unable to read C1 data from buffer\n");
}
@@ -2368,109 +1798,16 @@ static int ocp_error_recovery_log(int argc, char **argv, struct command *cmd, st
#define C4_DEV_CAP_REQ_LEN 0x1000
#define C4_DEV_CAP_REQ_OPCODE 0xC4
-#define C4_DEV_CAP_REQ_VERSION 0x0001
-#define C4_GUID_LENGTH 16
-static __u8 dev_cap_req_guid[C4_GUID_LENGTH] = {
+static __u8 dev_cap_req_guid[GUID_LEN] = {
0x97, 0x42, 0x05, 0x0d,
0xd1, 0xe1, 0xc9, 0x98,
0x5d, 0x49, 0x58, 0x4b,
0x91, 0x3c, 0x05, 0xb7
};
-/**
- * struct ocp_device_capabilities_log_page - Device Capability Log page
- * @pcie_exp_port: PCI Express Ports
- * @oob_management_support: OOB Management Support
- * @wz_cmd_support: Write Zeroes Command Support
- * @sanitize_cmd_support: Sanitize Command Support
- * @dsm_cmd_support: Dataset Management Command Support
- * @wu_cmd_support: Write Uncorrectable Command Support
- * @fused_operation_support: Fused Operation Support
- * @min_valid_dssd_pwr_state: Minimum Valid DSSD Power State
- * @dssd_pwr_state_desc: DSSD Power State Descriptors
- * @vendor_specific_command_timeout: Vendor Specific Command Timeout
- * @reserved: Reserved
- * @log_page_version: Log Page Version
- * @log_page_guid: Log Page GUID
- */
-struct __packed ocp_device_capabilities_log_page {
- __le16 pcie_exp_port;
- __le16 oob_management_support;
- __le16 wz_cmd_support;
- __le16 sanitize_cmd_support;
- __le16 dsm_cmd_support;
- __le16 wu_cmd_support;
- __le16 fused_operation_support;
- __le16 min_valid_dssd_pwr_state;
- __u8 dssd_pwr_state_desc[128];
- __u8 reserved[3934];
- __le16 log_page_version;
- __u8 log_page_guid[16];
-};
-
-static void ocp_print_c4_log_normal(struct ocp_device_capabilities_log_page *log_data);
-static void ocp_print_c4_log_json(struct ocp_device_capabilities_log_page *log_data);
-static void ocp_print_c4_log_binary(struct ocp_device_capabilities_log_page *log_data);
static int get_c4_log_page(struct nvme_dev *dev, char *format);
static int ocp_device_capabilities_log(int argc, char **argv, struct command *cmd, struct plugin *plugin);
-static void ocp_print_c4_log_normal(struct ocp_device_capabilities_log_page *log_data)
-{
- int i;
-
- printf(" Device Capability/C4 Log Page Data\n");
- printf(" PCI Express Ports : 0x%x\n", le16_to_cpu(log_data->pcie_exp_port));
- printf(" OOB Management Support : 0x%x\n", le16_to_cpu(log_data->oob_management_support));
- printf(" Write Zeroes Command Support : 0x%x\n", le16_to_cpu(log_data->wz_cmd_support));
- printf(" Sanitize Command Support : 0x%x\n", le16_to_cpu(log_data->sanitize_cmd_support));
- printf(" Dataset Management Command Support : 0x%x\n", le16_to_cpu(log_data->dsm_cmd_support));
- printf(" Write Uncorrectable Command Support : 0x%x\n", le16_to_cpu(log_data->wu_cmd_support));
- printf(" Fused Operation Support : 0x%x\n", le16_to_cpu(log_data->fused_operation_support));
- printf(" Minimum Valid DSSD Power State : 0x%x\n", le16_to_cpu(log_data->min_valid_dssd_pwr_state));
- printf(" DSSD Power State Descriptors : 0x");
- for (i = 0; i <= 127; i++)
- printf("%x", log_data->dssd_pwr_state_desc[i]);
- printf("\n");
- printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
- printf(" Log page GUID : 0x");
- for (i = C4_GUID_LENGTH - 1; i >= 0; i--)
- printf("%x", log_data->log_page_guid[i]);
- printf("\n");
-}
-
-static void ocp_print_c4_log_json(struct ocp_device_capabilities_log_page *log_data)
-{
- struct json_object *root = json_create_object();
- char guid[64];
- int i;
-
- json_object_add_value_int(root, "PCI Express Ports", le16_to_cpu(log_data->pcie_exp_port));
- json_object_add_value_int(root, "OOB Management Support", le16_to_cpu(log_data->oob_management_support));
- json_object_add_value_int(root, "Write Zeroes Command Support", le16_to_cpu(log_data->wz_cmd_support));
- json_object_add_value_int(root, "Sanitize Command Support", le16_to_cpu(log_data->sanitize_cmd_support));
- json_object_add_value_int(root, "Dataset Management Command Support", le16_to_cpu(log_data->dsm_cmd_support));
- json_object_add_value_int(root, "Write Uncorrectable Command Support", le16_to_cpu(log_data->wu_cmd_support));
- json_object_add_value_int(root, "Fused Operation Support", le16_to_cpu(log_data->fused_operation_support));
- json_object_add_value_int(root, "Minimum Valid DSSD Power State", le16_to_cpu(log_data->min_valid_dssd_pwr_state));
- for (i = 0; i <= 127; i++)
- json_object_add_value_int(root, "DSSD Power State Descriptors", log_data->dssd_pwr_state_desc[i]);
- json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
-
- memset((void *)guid, 0, 64);
- sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"", (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
- json_object_add_value_string(root, "Log page GUID", guid);
-
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
-}
-
-static void ocp_print_c4_log_binary(struct ocp_device_capabilities_log_page *log_data)
-{
- return d_raw((unsigned char *)log_data, sizeof(*log_data));
-}
-
static int get_c4_log_page(struct nvme_dev *dev, char *format)
{
struct ocp_device_capabilities_log_page *log_data;
@@ -2497,13 +1834,6 @@ static int get_c4_log_page(struct nvme_dev *dev, char *format)
if (!ret) {
log_data = (struct ocp_device_capabilities_log_page *)data;
- /* check log page version */
- if (log_data->log_page_version != C4_DEV_CAP_REQ_VERSION) {
- fprintf(stderr, "ERROR : OCP : invalid device capabilities log page version\n");
- ret = -1;
- goto out;
- }
-
/*
* check log page guid
* Verify GUID matches
@@ -2513,30 +1843,17 @@ static int get_c4_log_page(struct nvme_dev *dev, char *format)
fprintf(stderr, "ERROR : OCP : Unknown GUID in C4 Log Page data\n");
fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", dev_cap_req_guid[j]);
+ fprintf(stderr, "%02x", dev_cap_req_guid[j]);
fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ fprintf(stderr, "%02x", log_data->log_page_guid[j]);
fprintf(stderr, "\n");
ret = -1;
goto out;
}
}
-
- switch (fmt) {
- case NORMAL:
- ocp_print_c4_log_normal(log_data);
- break;
- case JSON:
- ocp_print_c4_log_json(log_data);
- break;
- case BINARY:
- ocp_print_c4_log_binary(log_data);
- break;
- default:
- break;
- }
+ ocp_c4_log(log_data, fmt);
} else {
fprintf(stderr, "ERROR : OCP : Unable to read C4 data from buffer\n");
}
@@ -3141,457 +2458,9 @@ static int get_dssd_async_event_config(int argc, char **argv, struct command *cm
static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *cmd,
struct plugin *plugin);
-
-static int ocp_print_C9_log_normal(struct telemetry_str_log_format *log_data, __u8 *log_data_buf)
-{
- //calculating the index value for array
- __le64 stat_id_index = (log_data->sitsz * 4) / 16;
- __le64 eve_id_index = (log_data->estsz * 4) / 16;
- __le64 vu_eve_index = (log_data->vu_eve_st_sz * 4) / 16;
- __le64 ascii_table_index = (log_data->asctsz * 4);
- //Calculating the offset for dynamic fields.
- __le64 stat_id_str_table_ofst = log_data->sits * 4;
- __le64 event_str_table_ofst = log_data->ests * 4;
- __le64 vu_event_str_table_ofst = log_data->vu_eve_sts * 4;
- __le64 ascii_table_ofst = log_data->ascts * 4;
- struct statistics_id_str_table_entry stat_id_str_table_arr[stat_id_index];
- struct event_id_str_table_entry event_id_str_table_arr[eve_id_index];
- struct vu_event_id_str_table_entry vu_event_id_str_table_arr[vu_eve_index];
- int j;
-
- printf(" Log Page Version : 0x%x\n", log_data->log_page_version);
-
- printf(" Reserved : ");
- for (j = 0; j < 15; j++)
- printf("%d", log_data->reserved1[j]);
- printf("\n");
-
- printf(" Log page GUID : 0x");
- for (j = C9_GUID_LENGTH - 1; j >= 0; j--)
- printf("%x", log_data->log_page_guid[j]);
- printf("\n");
-
- printf(" Telemetry String Log Size : 0x%lx\n", le64_to_cpu(log_data->sls));
-
- printf(" Reserved : ");
- for (j = 0; j < 24; j++)
- printf("%d", log_data->reserved2[j]);
- printf("\n");
-
- printf(" Statistics Identifier String Table Start : 0x%lx\n", le64_to_cpu(log_data->sits));
- printf(" Statistics Identifier String Table Size : 0x%lx\n", le64_to_cpu(log_data->sitsz));
- printf(" Event String Table Start : 0x%lx\n", le64_to_cpu(log_data->ests));
- printf(" Event String Table Size : 0x%lx\n", le64_to_cpu(log_data->estsz));
- printf(" VU Event String Table Start : 0x%lx\n", le64_to_cpu(log_data->vu_eve_sts));
- printf(" VU Event String Table Size : 0x%lx\n", le64_to_cpu(log_data->vu_eve_st_sz));
- printf(" ASCII Table Start : 0x%lx\n", le64_to_cpu(log_data->ascts));
- printf(" ASCII Table Size : 0x%lx\n", le64_to_cpu(log_data->asctsz));
-
- printf(" FIFO 1 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo1[j], log_data->fifo1[j]);
-
- printf(" FIFO 2 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo2[j], log_data->fifo2[j]);
-
- printf(" FIFO 3 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo3[j], log_data->fifo3[j]);
-
- printf(" FIFO 4 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo4[j], log_data->fifo4[j]);
-
- printf(" FIFO 5 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo5[j], log_data->fifo5[j]);
-
- printf(" FIFO 6 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo6[j], log_data->fifo6[j]);
-
- printf(" FIFO 7 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo7[j], log_data->fifo7[j]);
-
- printf(" FIFO 8 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo8[j], log_data->fifo8[j]);
-
- printf(" FIFO 9 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo9[j], log_data->fifo9[j]);
-
- printf(" FIFO 10 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo10[j], log_data->fifo10[j]);
-
- printf(" FIFO 11 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo11[j], log_data->fifo11[j]);
-
- printf(" FIFO 12 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo12[j], log_data->fifo12[j]);
-
- printf(" FIFO 13 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo13[j], log_data->fifo13[j]);
-
- printf(" FIFO 14 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo14[j], log_data->fifo14[j]);
-
- printf(" FIFO 15 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo15[j], log_data->fifo16[j]);
-
- printf(" FIFO 16 ASCII String\n");
- printf(" index value ascii_val\n");
- for (j = 0; j < 16; j++)
- printf(" %d %d %c \n", j, log_data->fifo16[j], log_data->fifo16[j]);
-
- printf(" Reserved : ");
- for (j = 0; j < 48; j++)
- printf("%d", log_data->reserved3[j]);
- printf("\n");
-
-
- if (log_data->sitsz != 0) {
- memcpy(stat_id_str_table_arr,
- (__u8 *)log_data_buf + stat_id_str_table_ofst,
- (log_data->sitsz * 4));
- printf(" Statistics Identifier String Table\n");
- for (j = 0; j < stat_id_index; j++) {
- printf(" Vendor Specific Statistic Identifier : 0x%x\n",
- le16_to_cpu(stat_id_str_table_arr[j].vs_si));
- printf(" Reserved : 0x%x\n",
- stat_id_str_table_arr[j].reserved1);
- printf(" ASCII ID Length : 0x%x\n",
- stat_id_str_table_arr[j].ascii_id_len);
- printf(" ASCII ID offset : 0x%lx\n",
- le64_to_cpu(stat_id_str_table_arr[j].ascii_id_ofst));
- printf(" Reserved : 0x%x\n",
- stat_id_str_table_arr[j].reserved2);
- }
- }
-
-
- if (log_data->estsz != 0) {
- memcpy(event_id_str_table_arr, (__u8 *)log_data_buf +
- event_str_table_ofst, (log_data->estsz * 4));
- printf(" Event Identifier String Table Entry\n");
- for (j = 0; j < eve_id_index; j++) {
- printf(" Debug Event Class : 0x%x\n",
- event_id_str_table_arr[j].deb_eve_class);
- printf(" Event Identifier : 0x%x\n",
- le16_to_cpu(event_id_str_table_arr[j].ei));
- printf(" ASCII ID Length : 0x%x\n",
- event_id_str_table_arr[j].ascii_id_len);
- printf(" ASCII ID offset : 0x%lx\n",
- le64_to_cpu(event_id_str_table_arr[j].ascii_id_ofst));
- printf(" Reserved : 0x%x\n",
- event_id_str_table_arr[j].reserved2);
-
- }
- }
-
- if (log_data->vu_eve_st_sz != 0) {
- memcpy(vu_event_id_str_table_arr, (__u8 *)log_data_buf +
- vu_event_str_table_ofst, (log_data->vu_eve_st_sz * 4));
- printf(" VU Event Identifier String Table Entry\n");
- for (j = 0; j < vu_eve_index; j++) {
- printf(" Debug Event Class : 0x%x\n",
- vu_event_id_str_table_arr[j].deb_eve_class);
- printf(" VU Event Identifier : 0x%x\n",
- le16_to_cpu(vu_event_id_str_table_arr[j].vu_ei));
- printf(" ASCII ID Length : 0x%x\n",
- vu_event_id_str_table_arr[j].ascii_id_len);
- printf(" ASCII ID offset : 0x%lx\n",
- le64_to_cpu(vu_event_id_str_table_arr[j].ascii_id_ofst));
- printf(" Reserved : 0x%x\n",
- vu_event_id_str_table_arr[j].reserved);
-
- }
- }
-
- if (log_data->asctsz != 0) {
- printf(" ASCII Table\n");
- printf(" Byte Data_Byte ASCII_Character\n");
- for (j = 0; j < ascii_table_index; j++)
- printf(" %lld %d %c\n",
- ascii_table_ofst+j, log_data_buf[ascii_table_ofst + j],
- (char)log_data_buf[ascii_table_ofst + j]);
- }
-
- return 0;
-}
-
-static int ocp_print_C9_log_json(struct telemetry_str_log_format *log_data, __u8 *log_data_buf)
-{
- struct json_object *root = json_create_object();
- char res_arr[48];
- char *res = res_arr;
- char guid_buf[C9_GUID_LENGTH];
- char *guid = guid_buf;
- char fifo_arr[16];
- char *fifo = fifo_arr;
- char buf[128];
- //calculating the index value for array
- __le64 stat_id_index = (log_data->sitsz * 4) / 16;
- __le64 eve_id_index = (log_data->estsz * 4) / 16;
- __le64 vu_eve_index = (log_data->vu_eve_st_sz * 4) / 16;
- __le64 ascii_table_index = (log_data->asctsz * 4);
- //Calculating the offset for dynamic fields.
- __le64 stat_id_str_table_ofst = log_data->sits * 4;
- __le64 event_str_table_ofst = log_data->ests * 4;
- __le64 vu_event_str_table_ofst = log_data->vu_eve_sts * 4;
- __le64 ascii_table_ofst = log_data->ascts * 4;
- struct statistics_id_str_table_entry stat_id_str_table_arr[stat_id_index];
- struct event_id_str_table_entry event_id_str_table_arr[eve_id_index];
- struct vu_event_id_str_table_entry vu_event_id_str_table_arr[vu_eve_index];
- __u8 ascii_table_info_arr[ascii_table_index];
- char ascii_buf[ascii_table_index];
- char *ascii = ascii_buf;
- int j;
-
- json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
-
- memset((__u8 *)res, 0, 15);
- for (j = 0; j < 15; j++)
- res += sprintf(res, "%d", log_data->reserved1[j]);
- json_object_add_value_string(root, "Reserved", res_arr);
-
- memset((void *)guid, 0, C9_GUID_LENGTH);
- for (j = C9_GUID_LENGTH - 1; j >= 0; j--)
- guid += sprintf(guid, "%02x", log_data->log_page_guid[j]);
- json_object_add_value_string(root, "Log page GUID", guid_buf);
-
- json_object_add_value_int(root, "Telemetry String Log Size", le64_to_cpu(log_data->sls));
-
- memset((__u8 *)res, 0, 24);
- for (j = 0; j < 24; j++)
- res += sprintf(res, "%d", log_data->reserved2[j]);
- json_object_add_value_string(root, "Reserved", res_arr);
-
- json_object_add_value_int(root, "Statistics Identifier String Table Start", le64_to_cpu(log_data->sits));
- json_object_add_value_int(root, "Event String Table Start", le64_to_cpu(log_data->ests));
- json_object_add_value_int(root, "Event String Table Size", le64_to_cpu(log_data->estsz));
- json_object_add_value_int(root, "VU Event String Table Start", le64_to_cpu(log_data->vu_eve_sts));
- json_object_add_value_int(root, "VU Event String Table Size", le64_to_cpu(log_data->vu_eve_st_sz));
- json_object_add_value_int(root, "ASCII Table Start", le64_to_cpu(log_data->ascts));
- json_object_add_value_int(root, "ASCII Table Size", le64_to_cpu(log_data->asctsz));
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo1[j]);
- json_object_add_value_string(root, "FIFO 1 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo2[j]);
- json_object_add_value_string(root, "FIFO 2 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo3[j]);
- json_object_add_value_string(root, "FIFO 3 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo4[j]);
- json_object_add_value_string(root, "FIFO 4 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo5[j]);
- json_object_add_value_string(root, "FIFO 5 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo6[j]);
- json_object_add_value_string(root, "FIFO 6 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo7[j]);
- json_object_add_value_string(root, "FIFO 7 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo8[j]);
- json_object_add_value_string(root, "FIFO 8 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo9[j]);
- json_object_add_value_string(root, "FIFO 9 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo10[j]);
- json_object_add_value_string(root, "FIFO 10 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo11[j]);
- json_object_add_value_string(root, "FIFO 11 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo12[j]);
- json_object_add_value_string(root, "FIFO 12 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo13[j]);
- json_object_add_value_string(root, "FIFO 13 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo14[j]);
- json_object_add_value_string(root, "FIFO 14 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo15[j]);
- json_object_add_value_string(root, "FIFO 15 ASCII String", fifo_arr);
-
- memset((void *)fifo, 0, 16);
- for (j = 0; j < 16; j++)
- fifo += sprintf(fifo, "%c", log_data->fifo16[j]);
- json_object_add_value_string(root, "FIFO 16 ASCII String", fifo_arr);
-
- memset((__u8 *)res, 0, 48);
- for (j = 0; j < 48; j++)
- res += sprintf(res, "%d", log_data->reserved3[j]);
- json_object_add_value_string(root, "Reserved", res_arr);
-
- if (log_data->sitsz != 0) {
-
- memcpy(stat_id_str_table_arr,
- (__u8 *)log_data_buf + stat_id_str_table_ofst,
- (log_data->sitsz * 4));
- struct json_object *stat_table = json_create_object();
-
- for (j = 0; j < stat_id_index; j++) {
- struct json_object *entry = json_create_object();
-
- json_object_add_value_uint(entry, "Vendor Specific Statistic Identifier",
- le16_to_cpu(stat_id_str_table_arr[j].vs_si));
- json_object_add_value_uint(entry, "Reserved",
- le64_to_cpu(stat_id_str_table_arr[j].reserved1));
- json_object_add_value_uint(entry, "ASCII ID Length",
- le64_to_cpu(stat_id_str_table_arr[j].ascii_id_len));
- json_object_add_value_uint(entry, "ASCII ID offset",
- le64_to_cpu(stat_id_str_table_arr[j].ascii_id_ofst));
- json_object_add_value_uint(entry, "Reserved2",
- le64_to_cpu(stat_id_str_table_arr[j].reserved2));
- sprintf(buf, "Statistics Identifier String Table %d", j);
- json_object_add_value_object(stat_table, buf, entry);
- }
-
- json_object_add_value_object(root,
- "Statistics Identifier String Table", stat_table);
- }
-
- if (log_data->estsz != 0) {
- struct json_object *eve_table = json_create_object();
-
- memcpy(event_id_str_table_arr,
- (__u8 *)log_data_buf + event_str_table_ofst,
- (log_data->estsz * 4));
- for (j = 0; j < eve_id_index; j++) {
- struct json_object *entry = json_create_object();
-
- json_object_add_value_int(entry, "Debug Event Class",
- le16_to_cpu(event_id_str_table_arr[j].deb_eve_class));
- json_object_add_value_int(entry, "Event Identifier",
- le16_to_cpu(event_id_str_table_arr[j].ei));
- json_object_add_value_int(entry, "ASCII ID Length",
- le64_to_cpu(event_id_str_table_arr[j].ascii_id_len));
- json_object_add_value_int(entry, "ASCII ID offset",
- le64_to_cpu(event_id_str_table_arr[j].ascii_id_ofst));
- json_object_add_value_int(entry, "Reserved",
- le64_to_cpu(event_id_str_table_arr[j].reserved2));
- sprintf(buf, "Event Identifier String Table Entry %d", j);
- json_object_add_value_object(eve_table, buf, entry);
- }
- json_object_add_value_object(root,
- "Event Identifier String Table Entry",
- eve_table);
- }
-
- if (log_data->vu_eve_st_sz != 0) {
- struct json_object *vu_eve_table = json_create_object();
-
- memcpy(vu_event_id_str_table_arr,
- (__u8 *)log_data_buf + vu_event_str_table_ofst,
- (log_data->vu_eve_st_sz * 4));
- for (j = 0; j < vu_eve_index; j++) {
- struct json_object *entry = json_create_object();
-
- json_object_add_value_int(entry, "Debug Event Class",
- le16_to_cpu(vu_event_id_str_table_arr[j].deb_eve_class));
- json_object_add_value_int(entry, "VU Event Identifier",
- le16_to_cpu(vu_event_id_str_table_arr[j].vu_ei));
- json_object_add_value_int(entry, "ASCII ID Length",
- le64_to_cpu(vu_event_id_str_table_arr[j].ascii_id_len));
- json_object_add_value_int(entry, "ASCII ID offset",
- le64_to_cpu(vu_event_id_str_table_arr[j].ascii_id_ofst));
- json_object_add_value_int(entry, "Reserved",
- le64_to_cpu(vu_event_id_str_table_arr[j].reserved));
- sprintf(buf, "VU Event Identifier String Table Entry %d", j);
- json_object_add_value_object(vu_eve_table, buf, entry);
- }
- json_object_add_value_object(root,
- "VU Event Identifier String Table Entry",
- vu_eve_table);
- }
-
- if (log_data->asctsz != 0) {
- memcpy(ascii_table_info_arr,
- (__u8 *)log_data_buf + ascii_table_ofst,
- (log_data->asctsz * 4));
- memset((void *)ascii, 0, ascii_table_index);
- for (j = 0; j < ascii_table_index; j++)
- ascii += sprintf(ascii, "%c", ascii_table_info_arr[j]);
- json_object_add_value_string(root, "ASCII Table", ascii_buf);
- }
-
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
-
- return 0;
-}
-
-static void ocp_print_c9_log_binary(__u8 *log_data_buf, int total_log_page_size)
-{
- return d_raw((unsigned char *)log_data_buf, total_log_page_size);
-}
-
static int get_c9_log_page(struct nvme_dev *dev, char *format)
{
-
int ret = 0;
-
nvme_print_flags_t fmt;
ret = validate_output_format(format, &fmt);
@@ -3600,25 +2469,13 @@ static int get_c9_log_page(struct nvme_dev *dev, char *format)
return ret;
}
- get_c9_log_page_data(dev, 1, 0);
-
+ ret = get_c9_log_page_data(dev, 1, 0);
if (!ret) {
- switch (fmt) {
- case NORMAL:
- ocp_print_C9_log_normal(log_data, pC9_string_buffer);
- break;
- case JSON:
- ocp_print_C9_log_json(log_data, pC9_string_buffer);
- break;
- case BINARY:
- ocp_print_c9_log_binary(pC9_string_buffer, total_log_page_sz);
- break;
- default:
- fprintf(stderr, "unhandled output format\n");
- break;
- }
- } else
+ ocp_c9_log(log_data, pC9_string_buffer, total_log_page_sz, fmt);
+ } else {
fprintf(stderr, "ERROR : OCP : Unable to read C9 data from buffer\n");
+ }
+
free(header_data);
return ret;
}
@@ -3663,174 +2520,20 @@ static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *c
/// TCG Configuration Log Page (LID : C7h)
/* C7 TCG Configuration Log Page */
-#define C7_GUID_LENGTH 16
#define C7_TCG_CONFIGURATION_LEN 512
#define C7_TCG_CONFIGURATION_OPCODE 0xC7
-#define C7_TCG_CONFIGURATION_LOG_VERSION 0x1
-static __u8 tcg_configuration_guid[C7_GUID_LENGTH] = {
+static __u8 tcg_configuration_guid[GUID_LEN] = {
0x06, 0x40, 0x24, 0xBD,
0x7E, 0xE0, 0xE6, 0x83,
0xC0, 0x47, 0x54, 0xFA,
0x9D, 0x2A, 0xE0, 0x54
};
-/*
- * struct tcg_configuration_log - TCG Configuration Log Page Structure
- * @state: state
- * @rsvd1: Reserved1
- * @locking_sp_act_count: Locking SP Activation Count
- * @type_rev_count: Tper Revert Count
- * @locking_sp_rev_count: Locking SP Revert Count.
- * @no_of_locking_obj: Number of Locking Objects
- * @no_of_single_um_locking_obj: Number of Single User Mode Locking Objects
- * @no_of_range_prov_locking_obj: Number of Range Provisioned Locking Objects
- * @no_of_ns_prov_locking_obj: Number of Namespace Provisioned Locking Objects
- * @no_of_read_lock_locking_obj: Number of Read Locked Locking Objects
- * @no_of_write_lock_locking_obj: Number of Write Locked Locking Objects
- * @no_of_read_unlock_locking_obj: Number of Read Unlocked Locking Objects
- * @no_of_read_unlock_locking_obj: Number of Write Unlocked Locking Objects
- * @rsvd2: Reserved2
- * @sid_auth_try_count: SID Authentication Try Count
- * @sid_auth_try_limit: SID Authentication Try Limit
- * @pro_tcg_rc: Programmatic TCG Reset Count
- * @pro_rlc: Programmatic Reset Lock Count
- * @tcg_ec: TCG Error Count
- * @rsvd3: Reserved3
- * @log_page_version: Log Page Version
- */
-struct __packed tcg_configuration_log {
- __u8 state;
- __u8 rsvd1[3];
- __u8 locking_sp_act_count;
- __u8 type_rev_count;
- __u8 locking_sp_rev_count;
- __u8 no_of_locking_obj;
- __u8 no_of_single_um_locking_obj;
- __u8 no_of_range_prov_locking_obj;
- __u8 no_of_ns_prov_locking_obj;
- __u8 no_of_read_lock_locking_obj;
- __u8 no_of_write_lock_locking_obj;
- __u8 no_of_read_unlock_locking_obj;
- __u8 no_of_write_unlock_locking_obj;
- __u8 rsvd2;
- __u32 sid_auth_try_count;
- __u32 sid_auth_try_limit;
- __u32 pro_tcg_rc;
- __u32 pro_rlc;
- __u32 tcg_ec;
- __u8 rsvd3[458];
- __le16 log_page_version;
- __u8 log_page_guid[C7_GUID_LENGTH];
-
-};
-
/* Function declaration for TCG Configuration log page (LID:C7h) */
static int ocp_tcg_configuration_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin);
-static int ocp_print_C7_log_normal(struct nvme_dev *dev,
- struct tcg_configuration_log *log_data)
-{
- int j;
-
- printf("TCG Configuration C7 Log Page Data-\n");
-
- printf(" State : 0x%x\n", log_data->state);
- printf(" Reserved1 : 0x");
- for (j = 0; j < 3; j++)
- printf("%d", log_data->rsvd1[j]);
- printf("\n");
- printf(" Locking SP Activation Count : 0x%x\n", log_data->locking_sp_act_count);
- printf(" Tper Revert Count : 0x%x\n", log_data->type_rev_count);
- printf(" Locking SP Revert Count : 0x%x\n", log_data->locking_sp_rev_count);
- printf(" Number of Locking Objects : 0x%x\n", log_data->no_of_locking_obj);
- printf(" Number of Single User Mode Locking Objects : 0x%x\n", log_data->no_of_single_um_locking_obj);
- printf(" Number of Range Provisioned Locking Objects : 0x%x\n", log_data->no_of_range_prov_locking_obj);
- printf(" Number of Namespace Provisioned Locking Objects : 0x%x\n", log_data->no_of_ns_prov_locking_obj);
- printf(" Number of Read Locked Locking Objects : 0x%x\n", log_data->no_of_read_lock_locking_obj);
- printf(" Number of Write Locked Locking Objects : 0x%x\n", log_data->no_of_write_lock_locking_obj);
- printf(" Number of Read Unlocked Locking Objects : 0x%x\n", log_data->no_of_read_unlock_locking_obj);
- printf(" Number of Write Unlocked Locking Objects : 0x%x\n", log_data->no_of_write_unlock_locking_obj);
- printf(" Reserved2 : 0x%x\n", log_data->rsvd2);
-
- printf(" SID Authentication Try Count : 0x%x\n", le32_to_cpu(log_data->sid_auth_try_count));
- printf(" SID Authentication Try Limit : 0x%x\n", le32_to_cpu(log_data->sid_auth_try_limit));
- printf(" Programmatic TCG Reset Count : 0x%x\n", le32_to_cpu(log_data->pro_tcg_rc));
- printf(" Programmatic Reset Lock Count : 0x%x\n", le32_to_cpu(log_data->pro_rlc));
- printf(" TCG Error Count : 0x%x\n", le32_to_cpu(log_data->tcg_ec));
-
- printf(" Reserved3 : 0x");
- for (j = 0; j < 458; j++)
- printf("%d", log_data->rsvd3[j]);
- printf("\n");
-
- printf(" Log Page Version : 0x%x\n", le16_to_cpu(log_data->log_page_version));
- printf(" Log page GUID : 0x");
- for (j = C7_GUID_LENGTH - 1; j >= 0; j--)
- printf("%x", log_data->log_page_guid[j]);
- printf("\n");
-
- return 0;
-}
-
-static void ocp_print_C7_log_json(struct tcg_configuration_log *log_data)
-{
- int j;
- struct json_object *root;
- char guid_buf[C7_GUID_LENGTH];
- char *guid = guid_buf;
- char res_arr[458];
- char *res = res_arr;
-
- root = json_create_object();
-
- json_object_add_value_int(root, "State", le16_to_cpu(log_data->state));
- memset((__u8 *)res, 0, 3);
- for (j = 0; j < 3; j++)
- res += sprintf(res, "%d", log_data->rsvd1[j]);
- json_object_add_value_string(root, "Reserved1", res_arr);
- json_object_add_value_int(root, "Locking SP Activation Count", le16_to_cpu(log_data->locking_sp_act_count));
- json_object_add_value_int(root, "Tper Revert Count", le16_to_cpu(log_data->locking_sp_rev_count));
- json_object_add_value_int(root, "Number of Locking Objects", le16_to_cpu(log_data->no_of_locking_obj));
- json_object_add_value_int(root, "Number of Single User Mode Locking Objects", le16_to_cpu(log_data->no_of_single_um_locking_obj));
- json_object_add_value_int(root, "Number of Range Provisioned Locking Objects", le16_to_cpu(log_data->no_of_range_prov_locking_obj));
- json_object_add_value_int(root, "Number of Namespace Provisioned Locking Objects", le16_to_cpu(log_data->no_of_ns_prov_locking_obj));
- json_object_add_value_int(root, "Number of Read Locked Locking Objects", le16_to_cpu(log_data->no_of_read_lock_locking_obj));
- json_object_add_value_int(root, "Number of Write Locked Locking Objects", le16_to_cpu(log_data->no_of_write_lock_locking_obj));
- json_object_add_value_int(root, "Number of Read Unlocked Locking Objects", le16_to_cpu(log_data->no_of_read_unlock_locking_obj));
- json_object_add_value_int(root, "Number of Write Unlocked Locking Objects", le16_to_cpu(log_data->no_of_write_unlock_locking_obj));
- json_object_add_value_int(root, "Reserved2", le16_to_cpu(log_data->rsvd2));
-
- json_object_add_value_int(root, "SID Authentication Try Count", le16_to_cpu(log_data->sid_auth_try_count));
- json_object_add_value_int(root, "SID Authentication Try Limit", le16_to_cpu(log_data->sid_auth_try_limit));
- json_object_add_value_int(root, "Programmatic TCG Reset Count", le16_to_cpu(log_data->pro_tcg_rc));
- json_object_add_value_int(root, "Programmatic Reset Lock Count", le16_to_cpu(log_data->pro_rlc));
- json_object_add_value_int(root, "TCG Error Count", le16_to_cpu(log_data->tcg_ec));
-
- memset((__u8 *)res, 0, 458);
- for (j = 0; j < 458; j++)
- res += sprintf(res, "%d", log_data->rsvd3[j]);
- json_object_add_value_string(root, "Reserved3", res_arr);
-
- json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
-
- memset((void *)guid, 0, C7_GUID_LENGTH);
- for (j = C7_GUID_LENGTH - 1; j >= 0; j--)
- guid += sprintf(guid, "%02x", log_data->log_page_guid[j]);
- json_object_add_value_string(root, "Log page GUID", guid_buf);
-
- json_print_object(root, NULL);
- printf("\n");
-
- json_free_object(root);
-}
-
-static void ocp_print_c7_log_binary(struct tcg_configuration_log *log_data)
-{
- return d_raw((unsigned char *)log_data, sizeof(*log_data));
-}
-
static int get_c7_log_page(struct nvme_dev *dev, char *format)
{
nvme_print_flags_t fmt;
@@ -3858,13 +2561,6 @@ static int get_c7_log_page(struct nvme_dev *dev, char *format)
if (!ret) {
log_data = (struct tcg_configuration_log *)data;
- /* check log page version */
- if (log_data->log_page_version != C7_TCG_CONFIGURATION_LOG_VERSION) {
- fprintf(stderr, "ERROR : OCP : invalid TCG Configuration Log Page version\n");
- ret = -1;
- goto out;
- }
-
/*
* check log page guid
* Verify GUID matches
@@ -3874,30 +2570,17 @@ static int get_c7_log_page(struct nvme_dev *dev, char *format)
fprintf(stderr, "ERROR : OCP : Unknown GUID in C7 Log Page data\n");
fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", tcg_configuration_guid[j]);
+ fprintf(stderr, "%02x", tcg_configuration_guid[j]);
fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ fprintf(stderr, "%02x", log_data->log_page_guid[j]);
fprintf(stderr, "\n");
ret = -1;
goto out;
}
}
-
- switch (fmt) {
- case NORMAL:
- ocp_print_C7_log_normal(dev, log_data);
- break;
- case JSON:
- ocp_print_C7_log_json(log_data);
- break;
- case BINARY:
- ocp_print_c7_log_binary(log_data);
- break;
- default:
- break;
- }
+ ocp_c7_log(dev, log_data, fmt);
} else {
fprintf(stderr, "ERROR : OCP : Unable to read C7 data from buffer\n");
}
@@ -3907,7 +2590,6 @@ out:
return ret;
}
-
static int ocp_tcg_configuration_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
@@ -4143,3 +2825,72 @@ static int set_error_injection(int argc, char **argv, struct command *cmd, struc
return error_injection_set(dev, &cfg, !argconfig_parse_seen(opts, "no-uuid"));
}
+
+static int enable_ieee1667_silo_get(struct nvme_dev *dev, const __u8 sel, bool uuid)
+{
+ struct ieee1667_get_cq_entry cq_entry;
+ int err;
+ const __u8 fid = 0xc4;
+
+ struct nvme_get_features_args args = {
+ .result = (__u32 *)&cq_entry,
+ .args_size = sizeof(args),
+ .fd = dev_fd(dev),
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .sel = sel,
+ .fid = fid,
+ };
+
+ if (uuid) {
+ /* OCP 2.0 requires UUID index support */
+ err = ocp_get_uuid_index(dev, &args.uuidx);
+ if (err || !args.uuidx) {
+ nvme_show_error("ERROR: No OCP UUID index found");
+ return err;
+ }
+ }
+
+ err = nvme_cli_get_features(dev, &args);
+ if (!err) {
+ if (sel == NVME_GET_FEATURES_SEL_SUPPORTED)
+ nvme_show_select_result(fid, *args.result);
+ else
+ nvme_show_result("IEEE1667 Sifo Enabled (feature: 0x%02x): 0x%0x (%s: %s)",
+ fid, cq_entry.enabled, nvme_select_to_string(sel),
+ cq_entry.enabled ? "enabled" : "disabled");
+ } else {
+ nvme_show_error("Could not get feature: 0x%02x.", fid);
+ }
+
+ return err;
+}
+
+static int get_enable_ieee1667_silo(int argc, char **argv, struct command *cmd,
+ struct plugin *plugin)
+{
+ const char *desc = "return set of enable IEEE1667 silo";
+ int err;
+ struct config {
+ __u8 sel;
+ };
+ struct config cfg = { 0 };
+
+ _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+
+ OPT_ARGS(opts) = {
+ OPT_BYTE("sel", 's', &cfg.sel, sel),
+ OPT_FLAG("no-uuid", 'n', NULL, no_uuid),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ return enable_ieee1667_silo_get(dev, cfg.sel, !argconfig_parse_seen(opts, "no-uuid"));
+}
+
+static int hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ return ocp_hwcomp_log(argc, argv, cmd, plugin);
+}
diff --git a/plugins/ocp/ocp-nvme.h b/plugins/ocp/ocp-nvme.h
index 16d929d..04acbfc 100644
--- a/plugins/ocp/ocp-nvme.h
+++ b/plugins/ocp/ocp-nvme.h
@@ -11,7 +11,7 @@
#if !defined(OCP_NVME) || defined(CMD_HEADER_MULTI_READ)
#define OCP_NVME
-#define OCP_PLUGIN_VERSION "2.9.0"
+#define OCP_PLUGIN_VERSION "2.9.2"
#include "cmd.h"
PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),
@@ -38,9 +38,207 @@ PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),
ENTRY("tcg-configuration-log", "Retrieve TCG Configuration Log Page", ocp_tcg_configuration_log)
ENTRY("get-error-injection", "Return set of error injection", get_error_injection)
ENTRY("set-error-injection", "Inject error conditions", set_error_injection)
+ ENTRY("get-enable-ieee1667-silo", "return set of enable IEEE1667 silo",
+ get_enable_ieee1667_silo)
+ ENTRY("hardware-component-log", "retrieve hardware component log", hwcomp_log)
)
);
#endif
#include "define_cmd.h"
+
+#ifndef OCP_NVME_H
+#define OCP_NVME_H
+struct __packed ssd_latency_monitor_log {
+ __u8 feature_status; /* 0x00 */
+ __u8 rsvd1; /* 0x01 */
+ __le16 active_bucket_timer; /* 0x02 */
+ __le16 active_bucket_timer_threshold; /* 0x04 */
+ __u8 active_threshold_a; /* 0x06 */
+ __u8 active_threshold_b; /* 0x07 */
+ __u8 active_threshold_c; /* 0x08 */
+ __u8 active_threshold_d; /* 0x09 */
+ __le16 active_latency_config; /* 0x0A */
+ __u8 active_latency_min_window; /* 0x0C */
+ __u8 rsvd2[0x13]; /* 0x0D */
+
+ __le32 active_bucket_counter[4][4]; /* 0x20 - 0x5F */
+ __le64 active_latency_timestamp[4][3]; /* 0x60 - 0xBF */
+ __le16 active_measured_latency[4][3]; /* 0xC0 - 0xD7 */
+ __le16 active_latency_stamp_units; /* 0xD8 */
+ __u8 rsvd3[0x16]; /* 0xDA */
+
+ __le32 static_bucket_counter[4][4]; /* 0x0F0 - 0x12F */
+ __le64 static_latency_timestamp[4][3]; /* 0x130 - 0x18F */
+ __le16 static_measured_latency[4][3]; /* 0x190 - 0x1A7 */
+ __le16 static_latency_stamp_units; /* 0x1A8 */
+ __u8 rsvd4[0x16]; /* 0x1AA */
+
+ __le16 debug_log_trigger_enable; /* 0x1C0 */
+ __le16 debug_log_measured_latency; /* 0x1C2 */
+ __le64 debug_log_latency_stamp; /* 0x1C4 */
+ __le16 debug_log_ptr; /* 0x1CC */
+ __le16 debug_log_counter_trigger; /* 0x1CE */
+ __u8 debug_log_stamp_units; /* 0x1D0 */
+ __u8 rsvd5[0x1D]; /* 0x1D1 */
+
+ __le16 log_page_version; /* 0x1EE */
+ __u8 log_page_guid[0x10]; /* 0x1F0 */
+};
+
+#define GUID_LEN 16
+
+#define C3_ACTIVE_BUCKET_TIMER_INCREMENT 5
+#define C3_ACTIVE_THRESHOLD_INCREMENT 5
+#define C3_MINIMUM_WINDOW_INCREMENT 100
+#define C3_BUCKET_NUM 4
+
+#define READ 3
+#define WRITE 2
+#define TRIM 1
+
+#define C5_NUM_UNSUPPORTED_REQ_ENTRIES 253
+
+/*
+ * struct unsupported_requirement_log - unsupported requirement list
+ * @unsupported_count: Number of Unsupported Requirement IDs
+ * @rsvd1: Reserved
+ * @unsupported_req_list: Unsupported Requirements lists up to 253.
+ * @rsvd2: Reserved
+ * @log_page_version: indicates the version of the mapping this log page uses.
+ * Shall be set to 0001h
+ * @log_page_guid: Shall be set to C7BB98B7D0324863BB2C23990E9C722Fh.
+ */
+struct __packed unsupported_requirement_log {
+ __le16 unsupported_count;
+ __u8 rsvd1[14];
+ __u8 unsupported_req_list[C5_NUM_UNSUPPORTED_REQ_ENTRIES][16];
+ __u8 rsvd2[14];
+ __le16 log_page_version;
+ __u8 log_page_guid[GUID_LEN];
+};
+
+#define C1_PREV_PANIC_IDS_LENGTH 4
+
+/**
+ * struct ocp_error_recovery_log_page - Error Recovery Log Page
+ * @panic_reset_wait_time: Panic Reset Wait Time
+ * @panic_reset_action: Panic Reset Action
+ * @device_recover_action_1: Device Recovery Action 1
+ * @panic_id: Panic ID
+ * @device_capabilities: Device Capabilities
+ * @vendor_specific_recovery_opcode: Vendor Specific Recovery Opcode
+ * @reserved: Reserved
+ * @vendor_specific_command_cdw12: Vendor Specific Command CDW12
+ * @vendor_specific_command_cdw13: Vendor Specific Command CDW13
+ * @vendor_specific_command_timeout: Vendor Specific Command Timeout
+ * @device_recover_action_2: Device Recovery Action 2
+ * @device_recover_action_2_timeout: Device Recovery Action 2 Timeout
+ * @panic_count: Panic Count
+ * @prev_panic_id: Previous Panic IDs
+ * @reserved2: Reserved
+ * @log_page_version: Log Page Version
+ * @log_page_guid: Log Page GUID
+ */
+struct __packed ocp_error_recovery_log_page {
+ __le16 panic_reset_wait_time; /* 2 bytes - 0x00 - 0x01 */
+ __u8 panic_reset_action; /* 1 byte - 0x02 */
+ __u8 device_recover_action_1; /* 1 byte - 0x03 */
+ __le64 panic_id; /* 8 bytes - 0x04 - 0x0B */
+ __le32 device_capabilities; /* 4 bytes - 0x0C - 0x0F */
+ __u8 vendor_specific_recovery_opcode; /* 1 byte - 0x10 */
+ __u8 reserved[0x3]; /* 3 bytes - 0x11 - 0x13 */
+ __le32 vendor_specific_command_cdw12; /* 4 bytes - 0x14 - 0x17 */
+ __le32 vendor_specific_command_cdw13; /* 4 bytes - 0x18 - 0x1B */
+ __u8 vendor_specific_command_timeout; /* 1 byte - 0x1C */
+ __u8 device_recover_action_2; /* 1 byte - 0x1D */
+ __u8 device_recover_action_2_timeout; /* 1 byte - 0x1E */
+ __u8 panic_count; /* 1 byte - 0x1F */
+ __le64 prev_panic_id[C1_PREV_PANIC_IDS_LENGTH]; /* 32 bytes - 0x20 - 0x3F */
+ __u8 reserved2[0x1ae]; /* 430 bytes - 0x40 - 0x1ED */
+ __le16 log_page_version; /* 2 bytes - 0x1EE - 0x1EF */
+ __u8 log_page_guid[GUID_LEN]; /* 16 bytes - 0x1F0 - 0x1FF */
+};
+
+/**
+ * struct ocp_device_capabilities_log_page - Device Capability Log page
+ * @pcie_exp_port: PCI Express Ports
+ * @oob_management_support: OOB Management Support
+ * @wz_cmd_support: Write Zeroes Command Support
+ * @sanitize_cmd_support: Sanitize Command Support
+ * @dsm_cmd_support: Dataset Management Command Support
+ * @wu_cmd_support: Write Uncorrectable Command Support
+ * @fused_operation_support: Fused Operation Support
+ * @min_valid_dssd_pwr_state: Minimum Valid DSSD Power State
+ * @dssd_pwr_state_desc: DSSD Power State Descriptors
+ * @vendor_specific_command_timeout: Vendor Specific Command Timeout
+ * @reserved: Reserved
+ * @log_page_version: Log Page Version
+ * @log_page_guid: Log Page GUID
+ */
+struct __packed ocp_device_capabilities_log_page {
+ __le16 pcie_exp_port;
+ __le16 oob_management_support;
+ __le16 wz_cmd_support;
+ __le16 sanitize_cmd_support;
+ __le16 dsm_cmd_support;
+ __le16 wu_cmd_support;
+ __le16 fused_operation_support;
+ __le16 min_valid_dssd_pwr_state;
+ __u8 dssd_pwr_state_desc[128];
+ __u8 reserved[3934];
+ __le16 log_page_version;
+ __u8 log_page_guid[GUID_LEN];
+};
+
+/*
+ * struct tcg_configuration_log - TCG Configuration Log Page Structure
+ * @state: state
+ * @rsvd1: Reserved1
+ * @locking_sp_act_count: Locking SP Activation Count
+ * @type_rev_count: Tper Revert Count
+ * @locking_sp_rev_count: Locking SP Revert Count.
+ * @no_of_locking_obj: Number of Locking Objects
+ * @no_of_single_um_locking_obj: Number of Single User Mode Locking Objects
+ * @no_of_range_prov_locking_obj: Number of Range Provisioned Locking Objects
+ * @no_of_ns_prov_locking_obj: Number of Namespace Provisioned Locking Objects
+ * @no_of_read_lock_locking_obj: Number of Read Locked Locking Objects
+ * @no_of_write_lock_locking_obj: Number of Write Locked Locking Objects
+ * @no_of_read_unlock_locking_obj: Number of Read Unlocked Locking Objects
+ * @no_of_read_unlock_locking_obj: Number of Write Unlocked Locking Objects
+ * @rsvd2: Reserved2
+ * @sid_auth_try_count: SID Authentication Try Count
+ * @sid_auth_try_limit: SID Authentication Try Limit
+ * @pro_tcg_rc: Programmatic TCG Reset Count
+ * @pro_rlc: Programmatic Reset Lock Count
+ * @tcg_ec: TCG Error Count
+ * @rsvd3: Reserved3
+ * @log_page_version: Log Page Version
+ */
+struct __packed tcg_configuration_log {
+ __u8 state;
+ __u8 rsvd1[3];
+ __u8 locking_sp_act_count;
+ __u8 type_rev_count;
+ __u8 locking_sp_rev_count;
+ __u8 no_of_locking_obj;
+ __u8 no_of_single_um_locking_obj;
+ __u8 no_of_range_prov_locking_obj;
+ __u8 no_of_ns_prov_locking_obj;
+ __u8 no_of_read_lock_locking_obj;
+ __u8 no_of_write_lock_locking_obj;
+ __u8 no_of_read_unlock_locking_obj;
+ __u8 no_of_write_unlock_locking_obj;
+ __u8 rsvd2;
+ __le32 sid_auth_try_count;
+ __le32 sid_auth_try_limit;
+ __le32 pro_tcg_rc;
+ __le32 pro_rlc;
+ __le32 tcg_ec;
+ __u8 rsvd3[458];
+ __le16 log_page_version;
+ __u8 log_page_guid[GUID_LEN];
+
+};
+#endif /* OCP_NVME_H */
diff --git a/plugins/ocp/ocp-print-binary.c b/plugins/ocp/ocp-print-binary.c
new file mode 100644
index 0000000..64e1246
--- /dev/null
+++ b/plugins/ocp/ocp-print-binary.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "util/types.h"
+#include "nvme-print.h"
+#include "ocp-print.h"
+#include "ocp-hardware-component-log.h"
+
+static void binary_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list)
+{
+ long double desc_len = uint128_t_to_double(le128_to_cpu(log->size)) * sizeof(__le32);
+
+ d_raw((unsigned char *)log, offsetof(struct hwcomp_log, desc) + desc_len);
+}
+
+static void binary_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data)
+{
+ d_raw((unsigned char *)log_data, sizeof(*log_data));
+}
+
+static void binary_c1_log(struct ocp_error_recovery_log_page *log_data)
+{
+ d_raw((unsigned char *)log_data, sizeof(*log_data));
+}
+
+static void binary_c4_log(struct ocp_device_capabilities_log_page *log_data)
+{
+ d_raw((unsigned char *)log_data, sizeof(*log_data));
+}
+
+static void binary_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_data_buf,
+ int total_log_page_size)
+{
+ d_raw((unsigned char *)log_data_buf, total_log_page_size);
+}
+
+static void binary_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data)
+{
+ d_raw((unsigned char *)log_data, sizeof(*log_data));
+}
+
+static struct ocp_print_ops binary_print_ops = {
+ .hwcomp_log = binary_hwcomp_log,
+ .c5_log = binary_c5_log,
+ .c1_log = binary_c1_log,
+ .c4_log = binary_c4_log,
+ .c9_log = binary_c9_log,
+ .c7_log = binary_c7_log,
+};
+
+struct ocp_print_ops *ocp_get_binary_print_ops(nvme_print_flags_t flags)
+{
+ binary_print_ops.flags = flags;
+ return &binary_print_ops;
+}
diff --git a/plugins/ocp/ocp-print-json.c b/plugins/ocp/ocp-print-json.c
new file mode 100644
index 0000000..a600628
--- /dev/null
+++ b/plugins/ocp/ocp-print-json.c
@@ -0,0 +1,851 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "util/types.h"
+#include "common.h"
+#include "nvme-print.h"
+#include "ocp-print.h"
+#include "ocp-hardware-component-log.h"
+#include "ocp-fw-activation-history.h"
+#include "ocp-smart-extended-log.h"
+#include "ocp-telemetry-decode.h"
+#include "ocp-nvme.h"
+
+static void print_hwcomp_desc_json(struct hwcomp_desc_entry *e, struct json_object *r)
+{
+ obj_add_str(r, "Description", hwcomp_id_to_string(le32_to_cpu(e->desc->id)));
+ obj_add_nprix64(r, "Date/Lot Size", e->date_lot_size);
+ obj_add_nprix64(r, "Additional Information Size", e->add_info_size);
+ obj_add_uint_0nx(r, "Identifier", le32_to_cpu(e->desc->id), 8);
+ obj_add_0nprix64(r, "Manufacture", le64_to_cpu(e->desc->mfg), 16);
+ obj_add_0nprix64(r, "Revision", le64_to_cpu(e->desc->rev), 16);
+ obj_add_0nprix64(r, "Manufacture Code", le64_to_cpu(e->desc->mfg_code), 16);
+ obj_add_byte_array(r, "Date/Lot Code", e->date_lot_code, e->date_lot_size);
+ obj_add_byte_array(r, "Additional Information", e->add_info, e->add_info_size);
+}
+
+static void print_hwcomp_desc_list_json(struct json_object *r, struct hwcomp_desc_entry *e,
+ bool list, int num)
+{
+ _cleanup_free_ char *k = NULL;
+
+ if (asprintf(&k, "Component %d", num) < 0)
+ return;
+
+ if (list) {
+ obj_add_str(r, k, hwcomp_id_to_string(le32_to_cpu(e->desc->id)));
+ return;
+ }
+
+ print_hwcomp_desc_json(e, obj_create_array_obj(r, k));
+}
+
+static void print_hwcomp_descs_json(struct hwcomp_desc *desc, long double log_size, __u32 id,
+ bool list, struct json_object *r)
+{
+ size_t date_lot_code_offset = sizeof(struct hwcomp_desc);
+ struct hwcomp_desc_entry e = { desc };
+ int num = 1;
+
+ while (log_size > 0) {
+ e.date_lot_size = le64_to_cpu(e.desc->date_lot_size) * sizeof(__le32);
+ e.date_lot_code = e.date_lot_size ?
+ (__u8 *)e.desc + date_lot_code_offset : NULL;
+ e.add_info_size = le64_to_cpu(e.desc->add_info_size) * sizeof(__le32);
+ e.add_info = e.add_info_size ? e.date_lot_code ?
+ e.date_lot_code + e.date_lot_size :
+ (__u8 *)e.desc + date_lot_code_offset : NULL;
+ if (!id || id == le32_to_cpu(e.desc->id))
+ print_hwcomp_desc_list_json(r, &e, list, num++);
+ e.desc_size = date_lot_code_offset + e.date_lot_size + e.add_info_size;
+ e.desc = (struct hwcomp_desc *)((__u8 *)e.desc + e.desc_size);
+ log_size -= e.desc_size;
+ }
+}
+
+static void json_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list)
+{
+ struct json_object *r = json_create_object();
+
+ long double log_size = uint128_t_to_double(le128_to_cpu(log->size)) * sizeof(__le32);
+
+ obj_add_uint_02x(r, "Log Identifier", LID_HWCOMP);
+ obj_add_uint_0x(r, "Log Page Version", le16_to_cpu(log->ver));
+ obj_add_byte_array(r, "Reserved2", log->rsvd2, ARRAY_SIZE(log->rsvd2));
+ obj_add_byte_array(r, "Log page GUID", log->guid, ARRAY_SIZE(log->guid));
+ obj_add_nprix64(r, "Hardware Component Log Size", (unsigned long long)log_size);
+ obj_add_byte_array(r, "Reserved48", log->rsvd48, ARRAY_SIZE(log->rsvd48));
+ print_hwcomp_descs_json(log->desc, log_size, id, list,
+ obj_create_array_obj(r, "Component Descriptions"));
+
+ json_print(r);
+}
+
+static void json_fw_activation_history(const struct fw_activation_history *fw_history)
+{
+ struct json_object *root = json_create_object();
+
+ json_object_add_value_uint(root, "log identifier", fw_history->log_id);
+ json_object_add_value_uint(root, "valid entries", le32_to_cpu(fw_history->valid_entries));
+
+ struct json_object *entries = json_create_array();
+
+ for (int index = 0; index < le32_to_cpu(fw_history->valid_entries); index++) {
+ const struct fw_activation_history_entry *entry = &fw_history->entries[index];
+ struct json_object *entry_obj = json_create_object();
+
+ json_object_add_value_uint(entry_obj, "version number", entry->ver_num);
+ json_object_add_value_uint(entry_obj, "entry length", entry->entry_length);
+ json_object_add_value_uint(entry_obj, "activation count",
+ le16_to_cpu(entry->activation_count));
+ json_object_add_value_uint64(entry_obj, "timestamp",
+ (0x0000FFFFFFFFFFFF & le64_to_cpu(entry->timestamp)));
+ json_object_add_value_uint(entry_obj, "power cycle count",
+ le64_to_cpu(entry->power_cycle_count));
+
+ struct json_object *fw = json_object_new_string_len(entry->previous_fw,
+ sizeof(entry->previous_fw));
+
+ json_object_add_value_object(entry_obj, "previous firmware", fw);
+
+ fw = json_object_new_string_len(entry->new_fw, sizeof(entry->new_fw));
+
+ json_object_add_value_object(entry_obj, "new firmware", fw);
+ json_object_add_value_uint(entry_obj, "slot number", entry->slot_number);
+ json_object_add_value_uint(entry_obj, "commit action type", entry->commit_action);
+ json_object_add_value_uint(entry_obj, "result", le16_to_cpu(entry->result));
+
+ json_array_add_value_object(entries, entry_obj);
+ }
+
+ json_object_add_value_array(root, "entries", entries);
+
+ json_object_add_value_uint(root, "log page version",
+ le16_to_cpu(fw_history->log_page_version));
+
+ char guid[2 * sizeof(fw_history->log_page_guid) + 3] = { 0 };
+
+ sprintf(guid, "0x%"PRIx64"%"PRIx64"",
+ le64_to_cpu(fw_history->log_page_guid[1]),
+ le64_to_cpu(fw_history->log_page_guid[0]));
+ json_object_add_value_string(root, "log page guid", guid);
+
+ json_print_object(root, NULL);
+ json_free_object(root);
+
+ printf("\n");
+}
+
+static void json_smart_extended_log(void *data)
+{
+ struct json_object *root;
+ struct json_object *pmuw;
+ struct json_object *pmur;
+ uint16_t smart_log_ver = 0;
+ __u8 *log_data = data;
+ char guid[40];
+
+ root = json_create_object();
+ pmuw = json_create_object();
+ pmur = json_create_object();
+
+ json_object_add_value_uint64(pmuw, "hi",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8] & 0xFFFFFFFFFFFFFFFF));
+ json_object_add_value_uint64(pmuw, "lo",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
+ json_object_add_value_object(root, "Physical media units written", pmuw);
+ json_object_add_value_uint64(pmur, "hi",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8] & 0xFFFFFFFFFFFFFFFF));
+ json_object_add_value_uint64(pmur, "lo",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
+ json_object_add_value_object(root, "Physical media units read", pmur);
+ json_object_add_value_uint64(root, "Bad user nand blocks - Raw",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
+ json_object_add_value_uint(root, "Bad user nand blocks - Normalized",
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
+ json_object_add_value_uint64(root, "Bad system nand blocks - Raw",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
+ json_object_add_value_uint(root, "Bad system nand blocks - Normalized",
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
+ json_object_add_value_uint64(root, "XOR recovery count",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
+ json_object_add_value_uint64(root, "Uncorrectable read error count",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
+ json_object_add_value_uint64(root, "Soft ecc error count",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
+ json_object_add_value_uint(root, "End to end detected errors",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
+ json_object_add_value_uint(root, "End to end corrected errors",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
+ json_object_add_value_uint(root, "System data percent used",
+ (__u8)log_data[SCAO_SDPU]);
+ json_object_add_value_uint64(root, "Refresh counts",
+ (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
+ json_object_add_value_uint(root, "Max User data erase counts",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
+ json_object_add_value_uint(root, "Min User data erase counts",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
+ json_object_add_value_uint(root, "Number of Thermal throttling events",
+ (__u8)log_data[SCAO_NTTE]);
+ json_object_add_value_uint(root, "Current throttling status",
+ (__u8)log_data[SCAO_CTS]);
+ json_object_add_value_uint64(root, "PCIe correctable error count",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
+ json_object_add_value_uint(root, "Incomplete shutdowns",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
+ json_object_add_value_uint(root, "Percent free blocks",
+ (__u8)log_data[SCAO_PFB]);
+ json_object_add_value_uint(root, "Capacitor health",
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
+ json_object_add_value_uint64(root, "Unaligned I/O",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
+ json_object_add_value_uint64(root, "Security Version Number",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
+ json_object_add_value_uint64(root, "NUSE - Namespace utilization",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
+ json_object_add_value_uint128(root, "PLP start count",
+ le128_to_cpu(&log_data[SCAO_PSC]));
+ json_object_add_value_uint128(root, "Endurance estimate",
+ le128_to_cpu(&log_data[SCAO_EEST]));
+ smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
+
+ json_object_add_value_uint(root, "Log page version", smart_log_ver);
+
+ memset((void *)guid, 0, 40);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
+ json_object_add_value_string(root, "Log page GUID", guid);
+
+ switch (smart_log_ver) {
+ case 0 ... 1:
+ break;
+ default:
+ case 4:
+ json_object_add_value_uint(root, "NVMe Command Set Errata Version",
+ (__u8)log_data[SCAO_NCSEV]);
+ json_object_add_value_uint(root, "Lowest Permitted Firmware Revision",
+ le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
+ fallthrough;
+ case 2 ... 3:
+ json_object_add_value_uint(root, "Errata Version Field",
+ (__u8)log_data[SCAO_EVF]);
+ json_object_add_value_uint(root, "Point Version Field",
+ le16_to_cpu(*(uint16_t *)&log_data[SCAO_PVF]));
+ json_object_add_value_uint(root, "Minor Version Field",
+ le16_to_cpu(*(uint16_t *)&log_data[SCAO_MIVF]));
+ json_object_add_value_uint(root, "Major Version Field",
+ (__u8)log_data[SCAO_MAVF]);
+ json_object_add_value_uint(root, "NVMe Base Errata Version",
+ (__u8)log_data[SCAO_NBEV]);
+ json_object_add_value_uint(root, "PCIe Link Retraining Count",
+ le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
+ json_object_add_value_uint(root, "Power State Change Count",
+ le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
+ }
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+static void json_telemetry_log(struct ocp_telemetry_parse_options *options)
+{
+ print_ocp_telemetry_json(options);
+}
+
+static void json_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data)
+{
+ struct json_object *root;
+ char ts_buf[128];
+ char buf[128];
+ int i, j;
+ char *operation[3] = {"Trim", "Write", "Read"};
+
+ root = json_create_object();
+
+ json_object_add_value_uint(root, "Feature Status",
+ log_data->feature_status);
+ json_object_add_value_uint(root, "Active Bucket Timer",
+ C3_ACTIVE_BUCKET_TIMER_INCREMENT *
+ le16_to_cpu(log_data->active_bucket_timer));
+ json_object_add_value_uint(root, "Active Bucket Timer Threshold",
+ C3_ACTIVE_BUCKET_TIMER_INCREMENT *
+ le16_to_cpu(log_data->active_bucket_timer_threshold));
+ json_object_add_value_uint(root, "Active Threshold A",
+ C3_ACTIVE_THRESHOLD_INCREMENT *
+ le16_to_cpu(log_data->active_threshold_a + 1));
+ json_object_add_value_uint(root, "Active Threshold B",
+ C3_ACTIVE_THRESHOLD_INCREMENT *
+ le16_to_cpu(log_data->active_threshold_b + 1));
+ json_object_add_value_uint(root, "Active Threshold C",
+ C3_ACTIVE_THRESHOLD_INCREMENT *
+ le16_to_cpu(log_data->active_threshold_c + 1));
+ json_object_add_value_uint(root, "Active Threshold D",
+ C3_ACTIVE_THRESHOLD_INCREMENT *
+ le16_to_cpu(log_data->active_threshold_d + 1));
+ json_object_add_value_uint(root, "Active Latency Configuration",
+ le16_to_cpu(log_data->active_latency_config));
+ json_object_add_value_uint(root, "Active Latency Minimum Window",
+ C3_MINIMUM_WINDOW_INCREMENT *
+ le16_to_cpu(log_data->active_latency_min_window));
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ struct json_object *bucket;
+
+ bucket = json_create_object();
+ sprintf(buf, "Active Bucket Counter: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
+ json_object_add_value_uint(bucket, operation[j],
+ le32_to_cpu(log_data->active_bucket_counter[i][j+1]));
+ }
+ json_object_add_value_object(root, buf, bucket);
+ }
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ struct json_object *bucket;
+
+ bucket = json_create_object();
+ sprintf(buf, "Active Latency Time Stamp: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
+ if (le64_to_cpu(log_data->active_latency_timestamp[3-i][j]) == -1) {
+ json_object_add_value_string(bucket, operation[j], "NA");
+ } else {
+ convert_ts(le64_to_cpu(log_data->active_latency_timestamp[3-i][j]),
+ ts_buf);
+ json_object_add_value_string(bucket, operation[j], ts_buf);
+ }
+ }
+ json_object_add_value_object(root, buf, bucket);
+ }
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ struct json_object *bucket;
+
+ bucket = json_create_object();
+ sprintf(buf, "Active Measured Latency: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
+ json_object_add_value_uint(bucket, operation[j],
+ le16_to_cpu(log_data->active_measured_latency[3-i][j]));
+ }
+ json_object_add_value_object(root, buf, bucket);
+ }
+
+ json_object_add_value_uint(root, "Active Latency Stamp Units",
+ le16_to_cpu(log_data->active_latency_stamp_units));
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ struct json_object *bucket;
+
+ bucket = json_create_object();
+ sprintf(buf, "Static Bucket Counter: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
+ json_object_add_value_uint(bucket, operation[j],
+ le32_to_cpu(log_data->static_bucket_counter[i][j+1]));
+ }
+ json_object_add_value_object(root, buf, bucket);
+ }
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ struct json_object *bucket;
+
+ bucket = json_create_object();
+ sprintf(buf, "Static Latency Time Stamp: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
+ if (le64_to_cpu(log_data->static_latency_timestamp[3-i][j]) == -1) {
+ json_object_add_value_string(bucket, operation[j], "NA");
+ } else {
+ convert_ts(le64_to_cpu(log_data->static_latency_timestamp[3-i][j]),
+ ts_buf);
+ json_object_add_value_string(bucket, operation[j], ts_buf);
+ }
+ }
+ json_object_add_value_object(root, buf, bucket);
+ }
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ struct json_object *bucket;
+
+ bucket = json_create_object();
+ sprintf(buf, "Static Measured Latency: Bucket %d", i);
+ for (j = 2; j >= 0; j--) {
+ json_object_add_value_uint(bucket, operation[j],
+ le16_to_cpu(log_data->static_measured_latency[3-i][j]));
+ }
+ json_object_add_value_object(root, buf, bucket);
+ }
+
+ json_object_add_value_uint(root, "Static Latency Stamp Units",
+ le16_to_cpu(log_data->static_latency_stamp_units));
+ json_object_add_value_uint(root, "Debug Log Trigger Enable",
+ le16_to_cpu(log_data->debug_log_trigger_enable));
+ json_object_add_value_uint(root, "Debug Log Measured Latency",
+ le16_to_cpu(log_data->debug_log_measured_latency));
+ if (le64_to_cpu(log_data->debug_log_latency_stamp) == -1) {
+ json_object_add_value_string(root, "Debug Log Latency Time Stamp", "NA");
+ } else {
+ convert_ts(le64_to_cpu(log_data->debug_log_latency_stamp), ts_buf);
+ json_object_add_value_string(root, "Debug Log Latency Time Stamp", ts_buf);
+ }
+ json_object_add_value_uint(root, "Debug Log Pointer",
+ le16_to_cpu(log_data->debug_log_ptr));
+ json_object_add_value_uint(root, "Debug Counter Trigger Source",
+ le16_to_cpu(log_data->debug_log_counter_trigger));
+ json_object_add_value_uint(root, "Debug Log Stamp Units",
+ le16_to_cpu(log_data->debug_log_stamp_units));
+ json_object_add_value_uint(root, "Log Page Version",
+ le16_to_cpu(log_data->log_page_version));
+
+ char guid[(GUID_LEN * 2) + 1];
+ char *ptr = &guid[0];
+
+ for (i = GUID_LEN - 1; i >= 0; i--)
+ ptr += sprintf(ptr, "%02X", log_data->log_page_guid[i]);
+
+ json_object_add_value_string(root, "Log Page GUID", guid);
+
+ json_print_object(root, NULL);
+ printf("\n");
+
+ json_free_object(root);
+}
+
+static void json_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data)
+{
+ int j;
+ struct json_object *root;
+ char unsup_req_list_str[40];
+ char guid_buf[GUID_LEN];
+ char *guid = guid_buf;
+
+ root = json_create_object();
+
+ json_object_add_value_int(root, "Number Unsupported Req IDs",
+ le16_to_cpu(log_data->unsupported_count));
+
+ memset((void *)unsup_req_list_str, 0, 40);
+ for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++) {
+ sprintf((char *)unsup_req_list_str, "Unsupported Requirement List %d", j);
+ json_object_add_value_string(root, unsup_req_list_str,
+ (char *)log_data->unsupported_req_list[j]);
+ }
+
+ json_object_add_value_int(root, "Log Page Version",
+ le16_to_cpu(log_data->log_page_version));
+
+ memset((void *)guid, 0, GUID_LEN);
+ for (j = GUID_LEN - 1; j >= 0; j--)
+ guid += sprintf(guid, "%02x", log_data->log_page_guid[j]);
+ json_object_add_value_string(root, "Log page GUID", guid_buf);
+
+ json_print_object(root, NULL);
+ printf("\n");
+
+ json_free_object(root);
+}
+
+static void json_c1_log(struct ocp_error_recovery_log_page *log_data)
+{
+ struct json_object *root;
+
+ root = json_create_object();
+ char guid[64];
+
+ json_object_add_value_int(root, "Panic Reset Wait Time",
+ le16_to_cpu(log_data->panic_reset_wait_time));
+ json_object_add_value_int(root, "Panic Reset Action", log_data->panic_reset_action);
+ json_object_add_value_int(root, "Device Recovery Action 1",
+ log_data->device_recover_action_1);
+ json_object_add_value_int(root, "Panic ID", le32_to_cpu(log_data->panic_id));
+ json_object_add_value_int(root, "Device Capabilities",
+ le32_to_cpu(log_data->device_capabilities));
+ json_object_add_value_int(root, "Vendor Specific Recovery Opcode",
+ log_data->vendor_specific_recovery_opcode);
+ json_object_add_value_int(root, "Vendor Specific Command CDW12",
+ le32_to_cpu(log_data->vendor_specific_command_cdw12));
+ json_object_add_value_int(root, "Vendor Specific Command CDW13",
+ le32_to_cpu(log_data->vendor_specific_command_cdw13));
+ json_object_add_value_int(root, "Vendor Specific Command Timeout",
+ log_data->vendor_specific_command_timeout);
+ json_object_add_value_int(root, "Device Recovery Action 2",
+ log_data->device_recover_action_2);
+ json_object_add_value_int(root, "Device Recovery Action 2 Timeout",
+ log_data->device_recover_action_2_timeout);
+ json_object_add_value_int(root, "Log Page Version",
+ le16_to_cpu(log_data->log_page_version));
+
+ memset((void *)guid, 0, 64);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
+ json_object_add_value_string(root, "Log page GUID", guid);
+
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+static void json_c4_log(struct ocp_device_capabilities_log_page *log_data)
+{
+ struct json_object *root = json_create_object();
+ char guid[64];
+ int i;
+
+ json_object_add_value_int(root, "PCI Express Ports", le16_to_cpu(log_data->pcie_exp_port));
+ json_object_add_value_int(root, "OOB Management Support",
+ le16_to_cpu(log_data->oob_management_support));
+ json_object_add_value_int(root, "Write Zeroes Command Support",
+ le16_to_cpu(log_data->wz_cmd_support));
+ json_object_add_value_int(root, "Sanitize Command Support",
+ le16_to_cpu(log_data->sanitize_cmd_support));
+ json_object_add_value_int(root, "Dataset Management Command Support",
+ le16_to_cpu(log_data->dsm_cmd_support));
+ json_object_add_value_int(root, "Write Uncorrectable Command Support",
+ le16_to_cpu(log_data->wu_cmd_support));
+ json_object_add_value_int(root, "Fused Operation Support",
+ le16_to_cpu(log_data->fused_operation_support));
+ json_object_add_value_int(root, "Minimum Valid DSSD Power State",
+ le16_to_cpu(log_data->min_valid_dssd_pwr_state));
+ for (i = 0; i <= 127; i++)
+ json_object_add_value_int(root, "DSSD Power State Descriptors",
+ log_data->dssd_pwr_state_desc[i]);
+ json_object_add_value_int(root, "Log Page Version",
+ le16_to_cpu(log_data->log_page_version));
+
+ memset((void *)guid, 0, 64);
+ sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
+ json_object_add_value_string(root, "Log page GUID", guid);
+
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+static void json_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_data_buf,
+ int total_log_page_size)
+{
+ struct json_object *root = json_create_object();
+ char res_arr[48];
+ char *res = res_arr;
+ char guid_buf[GUID_LEN];
+ char *guid = guid_buf;
+ char fifo_arr[16];
+ char *fifo = fifo_arr;
+ char buf[128];
+ //calculating the index value for array
+ __le64 stat_id_index = (log_data->sitsz * 4) / 16;
+ __le64 eve_id_index = (log_data->estsz * 4) / 16;
+ __le64 vu_eve_index = (log_data->vu_eve_st_sz * 4) / 16;
+ __le64 ascii_table_index = (log_data->asctsz * 4);
+ //Calculating the offset for dynamic fields.
+ __le64 stat_id_str_table_ofst = log_data->sits * 4;
+ __le64 event_str_table_ofst = log_data->ests * 4;
+ __le64 vu_event_str_table_ofst = log_data->vu_eve_sts * 4;
+ __le64 ascii_table_ofst = log_data->ascts * 4;
+ struct statistics_id_str_table_entry stat_id_str_table_arr[stat_id_index];
+ struct event_id_str_table_entry event_id_str_table_arr[eve_id_index];
+ struct vu_event_id_str_table_entry vu_event_id_str_table_arr[vu_eve_index];
+ __u8 ascii_table_info_arr[ascii_table_index];
+ char ascii_buf[ascii_table_index];
+ char *ascii = ascii_buf;
+ int j;
+
+ json_object_add_value_int(root, "Log Page Version",
+ le16_to_cpu(log_data->log_page_version));
+
+ memset((__u8 *)res, 0, 15);
+ for (j = 0; j < 15; j++)
+ res += sprintf(res, "%d", log_data->reserved1[j]);
+ json_object_add_value_string(root, "Reserved", res_arr);
+
+ memset((void *)guid, 0, GUID_LEN);
+ for (j = GUID_LEN - 1; j >= 0; j--)
+ guid += sprintf(guid, "%02x", log_data->log_page_guid[j]);
+ json_object_add_value_string(root, "Log page GUID", guid_buf);
+
+ json_object_add_value_int(root, "Telemetry String Log Size", le64_to_cpu(log_data->sls));
+
+ memset((__u8 *)res, 0, 24);
+ for (j = 0; j < 24; j++)
+ res += sprintf(res, "%d", log_data->reserved2[j]);
+ json_object_add_value_string(root, "Reserved", res_arr);
+
+ json_object_add_value_int(root, "Statistics Identifier String Table Start",
+ le64_to_cpu(log_data->sits));
+ json_object_add_value_int(root, "Event String Table Start", le64_to_cpu(log_data->ests));
+ json_object_add_value_int(root, "Event String Table Size", le64_to_cpu(log_data->estsz));
+ json_object_add_value_int(root, "VU Event String Table Start",
+ le64_to_cpu(log_data->vu_eve_sts));
+ json_object_add_value_int(root, "VU Event String Table Size",
+ le64_to_cpu(log_data->vu_eve_st_sz));
+ json_object_add_value_int(root, "ASCII Table Start",
+ le64_to_cpu(log_data->ascts));
+ json_object_add_value_int(root, "ASCII Table Size",
+ le64_to_cpu(log_data->asctsz));
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo1[j]);
+ json_object_add_value_string(root, "FIFO 1 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo2[j]);
+ json_object_add_value_string(root, "FIFO 2 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo3[j]);
+ json_object_add_value_string(root, "FIFO 3 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo4[j]);
+ json_object_add_value_string(root, "FIFO 4 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo5[j]);
+ json_object_add_value_string(root, "FIFO 5 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo6[j]);
+ json_object_add_value_string(root, "FIFO 6 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo7[j]);
+ json_object_add_value_string(root, "FIFO 7 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo8[j]);
+ json_object_add_value_string(root, "FIFO 8 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo9[j]);
+ json_object_add_value_string(root, "FIFO 9 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo10[j]);
+ json_object_add_value_string(root, "FIFO 10 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo11[j]);
+ json_object_add_value_string(root, "FIFO 11 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo12[j]);
+ json_object_add_value_string(root, "FIFO 12 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo13[j]);
+ json_object_add_value_string(root, "FIFO 13 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo14[j]);
+ json_object_add_value_string(root, "FIFO 14 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo15[j]);
+ json_object_add_value_string(root, "FIFO 15 ASCII String", fifo_arr);
+
+ memset((void *)fifo, 0, 16);
+ for (j = 0; j < 16; j++)
+ fifo += sprintf(fifo, "%c", log_data->fifo16[j]);
+ json_object_add_value_string(root, "FIFO 16 ASCII String", fifo_arr);
+
+ memset((__u8 *)res, 0, 48);
+ for (j = 0; j < 48; j++)
+ res += sprintf(res, "%d", log_data->reserved3[j]);
+ json_object_add_value_string(root, "Reserved", res_arr);
+
+ if (log_data->sitsz != 0) {
+
+ memcpy(stat_id_str_table_arr,
+ (__u8 *)log_data_buf + stat_id_str_table_ofst,
+ (log_data->sitsz * 4));
+ struct json_object *stat_table = json_create_object();
+
+ for (j = 0; j < stat_id_index; j++) {
+ struct json_object *entry = json_create_object();
+
+ json_object_add_value_uint(entry, "Vendor Specific Statistic Identifier",
+ le16_to_cpu(stat_id_str_table_arr[j].vs_si));
+ json_object_add_value_uint(entry, "Reserved",
+ le64_to_cpu(stat_id_str_table_arr[j].reserved1));
+ json_object_add_value_uint(entry, "ASCII ID Length",
+ le64_to_cpu(stat_id_str_table_arr[j].ascii_id_len));
+ json_object_add_value_uint(entry, "ASCII ID offset",
+ le64_to_cpu(stat_id_str_table_arr[j].ascii_id_ofst));
+ json_object_add_value_uint(entry, "Reserved2",
+ le64_to_cpu(stat_id_str_table_arr[j].reserved2));
+ sprintf(buf, "Statistics Identifier String Table %d", j);
+ json_object_add_value_object(stat_table, buf, entry);
+ }
+
+ json_object_add_value_object(root,
+ "Statistics Identifier String Table", stat_table);
+ }
+
+ if (log_data->estsz != 0) {
+ struct json_object *eve_table = json_create_object();
+
+ memcpy(event_id_str_table_arr,
+ (__u8 *)log_data_buf + event_str_table_ofst,
+ (log_data->estsz * 4));
+ for (j = 0; j < eve_id_index; j++) {
+ struct json_object *entry = json_create_object();
+
+ json_object_add_value_int(entry, "Debug Event Class",
+ le16_to_cpu(event_id_str_table_arr[j].deb_eve_class));
+ json_object_add_value_int(entry, "Event Identifier",
+ le16_to_cpu(event_id_str_table_arr[j].ei));
+ json_object_add_value_int(entry, "ASCII ID Length",
+ le64_to_cpu(event_id_str_table_arr[j].ascii_id_len));
+ json_object_add_value_int(entry, "ASCII ID offset",
+ le64_to_cpu(event_id_str_table_arr[j].ascii_id_ofst));
+ json_object_add_value_int(entry, "Reserved",
+ le64_to_cpu(event_id_str_table_arr[j].reserved2));
+ sprintf(buf, "Event Identifier String Table Entry %d", j);
+ json_object_add_value_object(eve_table, buf, entry);
+ }
+ json_object_add_value_object(root,
+ "Event Identifier String Table Entry",
+ eve_table);
+ }
+
+ if (log_data->vu_eve_st_sz != 0) {
+ struct json_object *vu_eve_table = json_create_object();
+
+ memcpy(vu_event_id_str_table_arr,
+ (__u8 *)log_data_buf + vu_event_str_table_ofst,
+ (log_data->vu_eve_st_sz * 4));
+ for (j = 0; j < vu_eve_index; j++) {
+ struct json_object *entry = json_create_object();
+
+ json_object_add_value_int(entry, "Debug Event Class",
+ le16_to_cpu(vu_event_id_str_table_arr[j].deb_eve_class));
+ json_object_add_value_int(entry, "VU Event Identifier",
+ le16_to_cpu(vu_event_id_str_table_arr[j].vu_ei));
+ json_object_add_value_int(entry, "ASCII ID Length",
+ le64_to_cpu(vu_event_id_str_table_arr[j].ascii_id_len));
+ json_object_add_value_int(entry, "ASCII ID offset",
+ le64_to_cpu(vu_event_id_str_table_arr[j].ascii_id_ofst));
+ json_object_add_value_int(entry, "Reserved",
+ le64_to_cpu(vu_event_id_str_table_arr[j].reserved));
+ sprintf(buf, "VU Event Identifier String Table Entry %d", j);
+ json_object_add_value_object(vu_eve_table, buf, entry);
+ }
+ json_object_add_value_object(root,
+ "VU Event Identifier String Table Entry",
+ vu_eve_table);
+ }
+
+ if (log_data->asctsz != 0) {
+ memcpy(ascii_table_info_arr,
+ (__u8 *)log_data_buf + ascii_table_ofst,
+ (log_data->asctsz * 4));
+ memset((void *)ascii, 0, ascii_table_index);
+ for (j = 0; j < ascii_table_index; j++)
+ ascii += sprintf(ascii, "%c", ascii_table_info_arr[j]);
+ json_object_add_value_string(root, "ASCII Table", ascii_buf);
+ }
+
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+static void json_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data)
+{
+ int j;
+ struct json_object *root;
+ char guid_buf[GUID_LEN];
+ char *guid = guid_buf;
+ char res_arr[458];
+ char *res = res_arr;
+
+ root = json_create_object();
+
+ json_object_add_value_int(root, "State", log_data->state);
+ memset((__u8 *)res, 0, 3);
+ for (j = 0; j < 3; j++)
+ res += sprintf(res, "%d", log_data->rsvd1[j]);
+ json_object_add_value_string(root, "Reserved1", res_arr);
+ json_object_add_value_int(root, "Locking SP Activation Count",
+ log_data->locking_sp_act_count);
+ json_object_add_value_int(root, "Tper Revert Count",
+ log_data->locking_sp_rev_count);
+ json_object_add_value_int(root, "Number of Locking Objects",
+ log_data->no_of_locking_obj);
+ json_object_add_value_int(root, "Number of Single User Mode Locking Objects",
+ log_data->no_of_single_um_locking_obj);
+ json_object_add_value_int(root, "Number of Range Provisioned Locking Objects",
+ log_data->no_of_range_prov_locking_obj);
+ json_object_add_value_int(root, "Number of Namespace Provisioned Locking Objects",
+ log_data->no_of_ns_prov_locking_obj);
+ json_object_add_value_int(root, "Number of Read Locked Locking Objects",
+ log_data->no_of_read_lock_locking_obj);
+ json_object_add_value_int(root, "Number of Write Locked Locking Objects",
+ log_data->no_of_write_lock_locking_obj);
+ json_object_add_value_int(root, "Number of Read Unlocked Locking Objects",
+ log_data->no_of_read_unlock_locking_obj);
+ json_object_add_value_int(root, "Number of Write Unlocked Locking Objects",
+ log_data->no_of_write_unlock_locking_obj);
+ json_object_add_value_int(root, "Reserved2", log_data->rsvd2);
+
+ json_object_add_value_int(root, "SID Authentication Try Count",
+ le32_to_cpu(log_data->sid_auth_try_count));
+ json_object_add_value_int(root, "SID Authentication Try Limit",
+ le32_to_cpu(log_data->sid_auth_try_limit));
+ json_object_add_value_int(root, "Programmatic TCG Reset Count",
+ le32_to_cpu(log_data->pro_tcg_rc));
+ json_object_add_value_int(root, "Programmatic Reset Lock Count",
+ le32_to_cpu(log_data->pro_rlc));
+ json_object_add_value_int(root, "TCG Error Count", le32_to_cpu(log_data->tcg_ec));
+
+ memset((__u8 *)res, 0, 458);
+ for (j = 0; j < 458; j++)
+ res += sprintf(res, "%d", log_data->rsvd3[j]);
+ json_object_add_value_string(root, "Reserved3", res_arr);
+
+ json_object_add_value_int(root, "Log Page Version",
+ le16_to_cpu(log_data->log_page_version));
+
+ memset((void *)guid, 0, GUID_LEN);
+ for (j = GUID_LEN - 1; j >= 0; j--)
+ guid += sprintf(guid, "%02x", log_data->log_page_guid[j]);
+ json_object_add_value_string(root, "Log page GUID", guid_buf);
+
+ json_print_object(root, NULL);
+ printf("\n");
+
+ json_free_object(root);
+}
+
+static struct ocp_print_ops json_print_ops = {
+ .hwcomp_log = json_hwcomp_log,
+ .fw_act_history = json_fw_activation_history,
+ .smart_extended_log = json_smart_extended_log,
+ .telemetry_log = json_telemetry_log,
+ .c3_log = json_c3_log,
+ .c5_log = json_c5_log,
+ .c1_log = json_c1_log,
+ .c4_log = json_c4_log,
+ .c9_log = json_c9_log,
+ .c7_log = json_c7_log,
+};
+
+struct ocp_print_ops *ocp_get_json_print_ops(nvme_print_flags_t flags)
+{
+ json_print_ops.flags = flags;
+ return &json_print_ops;
+}
diff --git a/plugins/ocp/ocp-print-stdout.c b/plugins/ocp/ocp-print-stdout.c
new file mode 100644
index 0000000..e48c171
--- /dev/null
+++ b/plugins/ocp/ocp-print-stdout.c
@@ -0,0 +1,710 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "util/types.h"
+#include "common.h"
+#include "nvme-print.h"
+#include "ocp-print.h"
+#include "ocp-hardware-component-log.h"
+#include "ocp-fw-activation-history.h"
+#include "ocp-smart-extended-log.h"
+#include "ocp-telemetry-decode.h"
+#include "ocp-nvme.h"
+
+static void print_hwcomp_desc(struct hwcomp_desc_entry *e, bool list, int num)
+{
+ printf(" Component %d: %s\n", num, hwcomp_id_to_string(le32_to_cpu(e->desc->id)));
+
+ if (list)
+ return;
+
+ printf(" Date/Lot Size: 0x%"PRIx64"\n", (uint64_t)e->date_lot_size);
+ printf(" Additional Information Size: 0x%"PRIx64"\n", (uint64_t)e->add_info_size);
+ printf(" Identifier: 0x%08x\n", le32_to_cpu(e->desc->id));
+ printf(" Manufacture: 0x%016"PRIx64"\n", le64_to_cpu(e->desc->mfg));
+ printf(" Revision: 0x%016"PRIx64"\n", le64_to_cpu(e->desc->rev));
+ printf(" Manufacture Code: 0x%016"PRIx64"\n", le64_to_cpu(e->desc->mfg_code));
+ print_array(" Date/Lot Code", e->date_lot_code, e->date_lot_size);
+ print_array(" Additional Information", e->add_info, e->add_info_size);
+}
+
+static void stdout_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list)
+{
+ size_t date_lot_code_offset = sizeof(struct hwcomp_desc);
+ int num = 1;
+ struct hwcomp_desc_entry e = { log->desc };
+
+ long double log_size = uint128_t_to_double(le128_to_cpu(log->size)) * sizeof(__le32);
+
+ printf("Log Identifier: 0x%02xh\n", LID_HWCOMP);
+ printf("Log Page Version: 0x%x\n", le16_to_cpu(log->ver));
+ print_array("Reserved2", log->rsvd2, ARRAY_SIZE(log->rsvd2));
+ print_array("Log page GUID", log->guid, ARRAY_SIZE(log->guid));
+ printf("Hardware Component Log Size: 0x%"PRIx64"\n", (uint64_t)log_size);
+ print_array("Reserved48", log->rsvd48, ARRAY_SIZE(log->rsvd48));
+ printf("Component Descriptions\n");
+ while (log_size > 0) {
+ e.date_lot_size = le64_to_cpu(e.desc->date_lot_size) * sizeof(__le32);
+ e.date_lot_code = e.date_lot_size ? (__u8 *)e.desc + date_lot_code_offset : NULL;
+ e.add_info_size = le64_to_cpu(e.desc->add_info_size) * sizeof(__le32);
+ e.add_info = e.add_info_size ? e.date_lot_code ? e.date_lot_code + e.date_lot_size :
+ (__u8 *)e.desc + date_lot_code_offset : NULL;
+ if (!id || id == le32_to_cpu(e.desc->id))
+ print_hwcomp_desc(&e, list, num++);
+ e.desc_size = date_lot_code_offset + e.date_lot_size + e.add_info_size;
+ e.desc = (struct hwcomp_desc *)((__u8 *)e.desc + e.desc_size);
+ log_size -= e.desc_size;
+ }
+}
+
+static void stdout_fw_activation_history(const struct fw_activation_history *fw_history)
+{
+ printf("Firmware History Log:\n");
+
+ printf(" %-26s%d\n", "log identifier:", fw_history->log_id);
+ printf(" %-26s%d\n", "valid entries:", le32_to_cpu(fw_history->valid_entries));
+
+ printf(" entries:\n");
+
+ for (int index = 0; index < le32_to_cpu(fw_history->valid_entries); index++) {
+ const struct fw_activation_history_entry *entry = &fw_history->entries[index];
+
+ printf(" entry[%d]:\n", index);
+ printf(" %-22s%d\n", "version number:", entry->ver_num);
+ printf(" %-22s%d\n", "entry length:", entry->entry_length);
+ printf(" %-22s%d\n", "activation count:",
+ le16_to_cpu(entry->activation_count));
+ printf(" %-22s%"PRIu64"\n", "timestamp:",
+ (0x0000FFFFFFFFFFFF & le64_to_cpu(entry->timestamp)));
+ printf(" %-22s%"PRIu64"\n", "power cycle count:",
+ le64_to_cpu(entry->power_cycle_count));
+ printf(" %-22s%.*s\n", "previous firmware:", (int)sizeof(entry->previous_fw),
+ entry->previous_fw);
+ printf(" %-22s%.*s\n", "new firmware:", (int)sizeof(entry->new_fw),
+ entry->new_fw);
+ printf(" %-22s%d\n", "slot number:", entry->slot_number);
+ printf(" %-22s%d\n", "commit action type:", entry->commit_action);
+ printf(" %-22s%d\n", "result:", le16_to_cpu(entry->result));
+ }
+
+ printf(" %-26s%d\n", "log page version:",
+ le16_to_cpu(fw_history->log_page_version));
+
+ printf(" %-26s0x%"PRIx64"%"PRIx64"\n", "log page guid:",
+ le64_to_cpu(fw_history->log_page_guid[1]),
+ le64_to_cpu(fw_history->log_page_guid[0]));
+
+ printf("\n");
+}
+
+static void stdout_smart_extended_log(void *data)
+{
+ uint16_t smart_log_ver = 0;
+ __u8 *log_data = data;
+
+ printf("SMART Cloud Attributes :-\n");
+
+ printf(" Physical media units written - %"PRIu64" %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8] & 0xFFFFFFFFFFFFFFFF),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
+ printf(" Physical media units read - %"PRIu64" %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8] & 0xFFFFFFFFFFFFFFFF),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
+ printf(" Bad user nand blocks - Raw %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
+ printf(" Bad user nand blocks - Normalized %d\n",
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
+ printf(" Bad system nand blocks - Raw %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
+ printf(" Bad system nand blocks - Normalized %d\n",
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
+ printf(" XOR recovery count %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
+ printf(" Uncorrectable read error count %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
+ printf(" Soft ecc error count %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
+ printf(" End to end detected errors %"PRIu32"\n",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
+ printf(" End to end corrected errors %"PRIu32"\n",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
+ printf(" System data percent used %d\n",
+ (__u8)log_data[SCAO_SDPU]);
+ printf(" Refresh counts %"PRIu64"\n",
+ (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
+ printf(" Max User data erase counts %"PRIu32"\n",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
+ printf(" Min User data erase counts %"PRIu32"\n",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
+ printf(" Number of Thermal throttling events %d\n",
+ (__u8)log_data[SCAO_NTTE]);
+ printf(" Current throttling status 0x%x\n",
+ (__u8)log_data[SCAO_CTS]);
+ printf(" PCIe correctable error count %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
+ printf(" Incomplete shutdowns %"PRIu32"\n",
+ (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
+ printf(" Percent free blocks %d\n",
+ (__u8)log_data[SCAO_PFB]);
+ printf(" Capacitor health %"PRIu16"\n",
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
+ printf(" NVMe base errata version %c\n",
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
+ printf(" NVMe command set errata version %c\n",
+ (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
+ printf(" Unaligned I/O %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
+ printf(" Security Version Number %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
+ printf(" NUSE - Namespace utilization %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
+ printf(" PLP start count %s\n",
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC])));
+ printf(" Endurance estimate %s\n",
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_EEST])));
+ smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
+ printf(" Log page version %"PRIu16"\n", smart_log_ver);
+ printf(" Log page GUID 0x");
+ printf("%"PRIx64"%"PRIx64"\n", (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
+ switch (smart_log_ver) {
+ case 0 ... 1:
+ break;
+ default:
+ case 4:
+ printf(" NVMe Command Set Errata Version %d\n",
+ (__u8)log_data[SCAO_NCSEV]);
+ printf(" Lowest Permitted Firmware Revision %"PRIu64"\n",
+ le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
+ fallthrough;
+ case 2 ... 3:
+ printf(" Errata Version Field %d\n",
+ (__u8)log_data[SCAO_EVF]);
+ printf(" Point Version Field %"PRIu16"\n",
+ le16_to_cpu(*(uint16_t *)&log_data[SCAO_PVF]));
+ printf(" Minor Version Field %"PRIu16"\n",
+ le16_to_cpu(*(uint16_t *)&log_data[SCAO_MIVF]));
+ printf(" Major Version Field %d\n",
+ (__u8)log_data[SCAO_MAVF]);
+ printf(" NVMe Base Errata Version %d\n",
+ (__u8)log_data[SCAO_NBEV]);
+ printf(" PCIe Link Retraining Count %"PRIu64"\n",
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
+ printf(" Power State Change Count %"PRIu64"\n",
+ le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
+ }
+ printf("\n");
+}
+
+static void stdout_telemetry_log(struct ocp_telemetry_parse_options *options)
+{
+#ifdef CONFIG_JSONC
+ print_ocp_telemetry_normal(options);
+#endif /* CONFIG_JSONC */
+}
+
+static void stdout_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data)
+{
+ char ts_buf[128];
+ int i, j;
+
+ printf("-Latency Monitor/C3 Log Page Data-\n");
+ printf(" Controller : %s\n", dev->name);
+ printf(" Feature Status 0x%x\n",
+ log_data->feature_status);
+ printf(" Active Bucket Timer %d min\n",
+ C3_ACTIVE_BUCKET_TIMER_INCREMENT *
+ le16_to_cpu(log_data->active_bucket_timer));
+ printf(" Active Bucket Timer Threshold %d min\n",
+ C3_ACTIVE_BUCKET_TIMER_INCREMENT *
+ le16_to_cpu(log_data->active_bucket_timer_threshold));
+ printf(" Active Threshold A %d ms\n",
+ C3_ACTIVE_THRESHOLD_INCREMENT *
+ le16_to_cpu(log_data->active_threshold_a+1));
+ printf(" Active Threshold B %d ms\n",
+ C3_ACTIVE_THRESHOLD_INCREMENT *
+ le16_to_cpu(log_data->active_threshold_b+1));
+ printf(" Active Threshold C %d ms\n",
+ C3_ACTIVE_THRESHOLD_INCREMENT *
+ le16_to_cpu(log_data->active_threshold_c+1));
+ printf(" Active Threshold D %d ms\n",
+ C3_ACTIVE_THRESHOLD_INCREMENT *
+ le16_to_cpu(log_data->active_threshold_d+1));
+ printf(" Active Latency Configuration 0x%x\n",
+ le16_to_cpu(log_data->active_latency_config));
+ printf(" Active Latency Minimum Window %d ms\n",
+ C3_MINIMUM_WINDOW_INCREMENT *
+ le16_to_cpu(log_data->active_latency_min_window));
+ printf(" Active Latency Stamp Units %d\n",
+ le16_to_cpu(log_data->active_latency_stamp_units));
+ printf(" Static Latency Stamp Units %d\n",
+ le16_to_cpu(log_data->static_latency_stamp_units));
+ printf(" Debug Log Trigger Enable %d\n",
+ le16_to_cpu(log_data->debug_log_trigger_enable));
+ printf(" Debug Log Measured Latency %d\n",
+ le16_to_cpu(log_data->debug_log_measured_latency));
+ if (le64_to_cpu(log_data->debug_log_latency_stamp) == -1) {
+ printf(" Debug Log Latency Time Stamp N/A\n");
+ } else {
+ convert_ts(le64_to_cpu(log_data->debug_log_latency_stamp), ts_buf);
+ printf(" Debug Log Latency Time Stamp %s\n", ts_buf);
+ }
+ printf(" Debug Log Pointer %d\n",
+ le16_to_cpu(log_data->debug_log_ptr));
+ printf(" Debug Counter Trigger Source %d\n",
+ le16_to_cpu(log_data->debug_log_counter_trigger));
+ printf(" Debug Log Stamp Units %d\n",
+ le16_to_cpu(log_data->debug_log_stamp_units));
+ printf(" Log Page Version %d\n",
+ le16_to_cpu(log_data->log_page_version));
+
+ char guid[(GUID_LEN * 2) + 1];
+ char *ptr = &guid[0];
+
+ for (i = GUID_LEN - 1; i >= 0; i--)
+ ptr += sprintf(ptr, "%02X", log_data->log_page_guid[i]);
+
+ printf(" Log Page GUID %s\n", guid);
+ printf("\n");
+
+ printf("%64s%92s%119s\n", "Read", "Write", "Deallocate/Trim");
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ printf(" Active Bucket Counter: Bucket %d %27d %27d %27d\n",
+ i,
+ le32_to_cpu(log_data->active_bucket_counter[i][READ]),
+ le32_to_cpu(log_data->active_bucket_counter[i][WRITE]),
+ le32_to_cpu(log_data->active_bucket_counter[i][TRIM]));
+ }
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ printf(" Active Latency Time Stamp: Bucket %d ", i);
+ for (j = 2; j >= 0; j--) {
+ if (le64_to_cpu(log_data->active_latency_timestamp[3-i][j]) == -1) {
+ printf(" N/A ");
+ } else {
+ convert_ts(le64_to_cpu(log_data->active_latency_timestamp[3-i][j]),
+ ts_buf);
+ printf("%s ", ts_buf);
+ }
+ }
+ printf("\n");
+ }
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
+ i,
+ le16_to_cpu(log_data->active_measured_latency[3-i][READ-1]),
+ le16_to_cpu(log_data->active_measured_latency[3-i][WRITE-1]),
+ le16_to_cpu(log_data->active_measured_latency[3-i][TRIM-1]));
+ }
+
+ printf("\n");
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ printf(" Static Bucket Counter: Bucket %d %27d %27d %27d\n",
+ i,
+ le32_to_cpu(log_data->static_bucket_counter[i][READ]),
+ le32_to_cpu(log_data->static_bucket_counter[i][WRITE]),
+ le32_to_cpu(log_data->static_bucket_counter[i][TRIM]));
+ }
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ printf(" Static Latency Time Stamp: Bucket %d ", i);
+ for (j = 2; j >= 0; j--) {
+ if (le64_to_cpu(log_data->static_latency_timestamp[3-i][j]) == -1) {
+ printf(" N/A ");
+ } else {
+ convert_ts(le64_to_cpu(log_data->static_latency_timestamp[3-i][j]),
+ ts_buf);
+ printf("%s ", ts_buf);
+ }
+ }
+ printf("\n");
+ }
+
+ for (i = 0; i < C3_BUCKET_NUM; i++) {
+ printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
+ i,
+ le16_to_cpu(log_data->static_measured_latency[3-i][READ-1]),
+ le16_to_cpu(log_data->static_measured_latency[3-i][WRITE-1]),
+ le16_to_cpu(log_data->static_measured_latency[3-i][TRIM-1]));
+ }
+}
+
+static void stdout_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data)
+{
+ int j;
+
+ printf("Unsupported Requirement-C5 Log Page Data-\n");
+
+ printf(" Number Unsupported Req IDs : 0x%x\n",
+ le16_to_cpu(log_data->unsupported_count));
+
+ for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++)
+ printf(" Unsupported Requirement List %d : %s\n", j,
+ log_data->unsupported_req_list[j]);
+
+ printf(" Log Page Version : 0x%x\n",
+ le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (j = GUID_LEN - 1; j >= 0; j--)
+ printf("%02x", log_data->log_page_guid[j]);
+ printf("\n");
+}
+
+static void stdout_c1_log(struct ocp_error_recovery_log_page *log_data)
+{
+ int i;
+
+ printf(" Error Recovery/C1 Log Page Data\n");
+ printf(" Panic Reset Wait Time : 0x%x\n",
+ le16_to_cpu(log_data->panic_reset_wait_time));
+ printf(" Panic Reset Action : 0x%x\n", log_data->panic_reset_action);
+ printf(" Device Recovery Action 1 : 0x%x\n", log_data->device_recover_action_1);
+ printf(" Panic ID : 0x%x\n", le32_to_cpu(log_data->panic_id));
+ printf(" Device Capabilities : 0x%x\n",
+ le32_to_cpu(log_data->device_capabilities));
+ printf(" Vendor Specific Recovery Opcode : 0x%x\n",
+ log_data->vendor_specific_recovery_opcode);
+ printf(" Vendor Specific Command CDW12 : 0x%x\n",
+ le32_to_cpu(log_data->vendor_specific_command_cdw12));
+ printf(" Vendor Specific Command CDW13 : 0x%x\n",
+ le32_to_cpu(log_data->vendor_specific_command_cdw13));
+ printf(" Vendor Specific Command Timeout : 0x%x\n",
+ log_data->vendor_specific_command_timeout);
+ printf(" Device Recovery Action 2 : 0x%x\n",
+ log_data->device_recover_action_2);
+ printf(" Device Recovery Action 2 Timeout : 0x%x\n",
+ log_data->device_recover_action_2_timeout);
+ printf(" Panic Count : 0x%x\n", log_data->panic_count);
+ printf(" Previous Panic IDs:");
+ for (i = 0; i < C1_PREV_PANIC_IDS_LENGTH; i++)
+ printf("%s Panic ID N-%d : 0x%"PRIx64"\n", i ? " " : "", i + 1,
+ le64_to_cpu(log_data->prev_panic_id[i]));
+ printf(" Log Page Version : 0x%x\n",
+ le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (i = GUID_LEN - 1; i >= 0; i--)
+ printf("%02x", log_data->log_page_guid[i]);
+ printf("\n");
+}
+
+static void stdout_c4_log(struct ocp_device_capabilities_log_page *log_data)
+{
+ int i;
+
+ printf(" Device Capability/C4 Log Page Data\n");
+ printf(" PCI Express Ports : 0x%x\n",
+ le16_to_cpu(log_data->pcie_exp_port));
+ printf(" OOB Management Support : 0x%x\n",
+ le16_to_cpu(log_data->oob_management_support));
+ printf(" Write Zeroes Command Support : 0x%x\n",
+ le16_to_cpu(log_data->wz_cmd_support));
+ printf(" Sanitize Command Support : 0x%x\n",
+ le16_to_cpu(log_data->sanitize_cmd_support));
+ printf(" Dataset Management Command Support : 0x%x\n",
+ le16_to_cpu(log_data->dsm_cmd_support));
+ printf(" Write Uncorrectable Command Support : 0x%x\n",
+ le16_to_cpu(log_data->wu_cmd_support));
+ printf(" Fused Operation Support : 0x%x\n",
+ le16_to_cpu(log_data->fused_operation_support));
+ printf(" Minimum Valid DSSD Power State : 0x%x\n",
+ le16_to_cpu(log_data->min_valid_dssd_pwr_state));
+ printf(" DSSD Power State Descriptors : 0x");
+ for (i = 0; i <= 127; i++)
+ printf("%x", log_data->dssd_pwr_state_desc[i]);
+ printf("\n");
+ printf(" Log Page Version : 0x%x\n",
+ le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (i = GUID_LEN - 1; i >= 0; i--)
+ printf("%02x", log_data->log_page_guid[i]);
+ printf("\n");
+}
+
+static void stdout_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_data_buf,
+ int total_log_page_size)
+{
+ //calculating the index value for array
+ __le64 stat_id_index = (log_data->sitsz * 4) / 16;
+ __le64 eve_id_index = (log_data->estsz * 4) / 16;
+ __le64 vu_eve_index = (log_data->vu_eve_st_sz * 4) / 16;
+ __le64 ascii_table_index = (log_data->asctsz * 4);
+ //Calculating the offset for dynamic fields.
+ __le64 stat_id_str_table_ofst = log_data->sits * 4;
+ __le64 event_str_table_ofst = log_data->ests * 4;
+ __le64 vu_event_str_table_ofst = log_data->vu_eve_sts * 4;
+ __le64 ascii_table_ofst = log_data->ascts * 4;
+ struct statistics_id_str_table_entry stat_id_str_table_arr[stat_id_index];
+ struct event_id_str_table_entry event_id_str_table_arr[eve_id_index];
+ struct vu_event_id_str_table_entry vu_event_id_str_table_arr[vu_eve_index];
+ int j;
+
+ printf(" Log Page Version : 0x%x\n",
+ log_data->log_page_version);
+
+ printf(" Reserved : ");
+ for (j = 0; j < 15; j++)
+ printf("%d", log_data->reserved1[j]);
+ printf("\n");
+
+ printf(" Log page GUID : 0x");
+ for (j = GUID_LEN - 1; j >= 0; j--)
+ printf("%02x", log_data->log_page_guid[j]);
+ printf("\n");
+
+ printf(" Telemetry String Log Size : 0x%"PRIx64"\n",
+ le64_to_cpu(log_data->sls));
+
+ printf(" Reserved : ");
+ for (j = 0; j < 24; j++)
+ printf("%d", log_data->reserved2[j]);
+ printf("\n");
+
+ printf(" Statistics Identifier String Table Start : 0x%"PRIx64"\n",
+ le64_to_cpu(log_data->sits));
+ printf(" Statistics Identifier String Table Size : 0x%"PRIx64"\n",
+ le64_to_cpu(log_data->sitsz));
+ printf(" Event String Table Start : 0x%"PRIx64"\n",
+ le64_to_cpu(log_data->ests));
+ printf(" Event String Table Size : 0x%"PRIx64"\n",
+ le64_to_cpu(log_data->estsz));
+ printf(" VU Event String Table Start : 0x%"PRIx64"\n",
+ le64_to_cpu(log_data->vu_eve_sts));
+ printf(" VU Event String Table Size : 0x%"PRIx64"\n",
+ le64_to_cpu(log_data->vu_eve_st_sz));
+ printf(" ASCII Table Start : 0x%"PRIx64"\n",
+ le64_to_cpu(log_data->ascts));
+ printf(" ASCII Table Size : 0x%"PRIx64"\n",
+ le64_to_cpu(log_data->asctsz));
+
+ printf(" FIFO 1 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo1[j],
+ log_data->fifo1[j]);
+
+ printf(" FIFO 2 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo2[j],
+ log_data->fifo2[j]);
+
+ printf(" FIFO 3 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo3[j],
+ log_data->fifo3[j]);
+
+ printf(" FIFO 4 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo4[j], log_data->fifo4[j]);
+
+ printf(" FIFO 5 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo5[j], log_data->fifo5[j]);
+
+ printf(" FIFO 6 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo6[j], log_data->fifo6[j]);
+
+ printf(" FIFO 7 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo7[j], log_data->fifo7[j]);
+
+ printf(" FIFO 8 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo8[j], log_data->fifo8[j]);
+
+ printf(" FIFO 9 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo9[j], log_data->fifo9[j]);
+
+ printf(" FIFO 10 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo10[j], log_data->fifo10[j]);
+
+ printf(" FIFO 11 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo11[j], log_data->fifo11[j]);
+
+ printf(" FIFO 12 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo12[j], log_data->fifo12[j]);
+
+ printf(" FIFO 13 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo13[j], log_data->fifo13[j]);
+
+ printf(" FIFO 14 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo14[j], log_data->fifo14[j]);
+
+ printf(" FIFO 15 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo15[j], log_data->fifo16[j]);
+
+ printf(" FIFO 16 ASCII String\n");
+ printf(" index value ascii_val\n");
+ for (j = 0; j < 16; j++)
+ printf(" %d %d %c\n", j, log_data->fifo16[j], log_data->fifo16[j]);
+
+ printf(" Reserved : ");
+ for (j = 0; j < 48; j++)
+ printf("%d", log_data->reserved3[j]);
+ printf("\n");
+
+ if (log_data->sitsz != 0) {
+ memcpy(stat_id_str_table_arr, (__u8 *)log_data_buf + stat_id_str_table_ofst,
+ (log_data->sitsz * 4));
+ printf(" Statistics Identifier String Table\n");
+ for (j = 0; j < stat_id_index; j++) {
+ printf(" Vendor Specific Statistic Identifier : 0x%x\n",
+ le16_to_cpu(stat_id_str_table_arr[j].vs_si));
+ printf(" Reserved : 0x%x\n",
+ stat_id_str_table_arr[j].reserved1);
+ printf(" ASCII ID Length : 0x%x\n",
+ stat_id_str_table_arr[j].ascii_id_len);
+ printf(" ASCII ID offset : 0x%"PRIx64"\n",
+ le64_to_cpu(stat_id_str_table_arr[j].ascii_id_ofst));
+ printf(" Reserved : 0x%x\n",
+ stat_id_str_table_arr[j].reserved2);
+ }
+ }
+
+ if (log_data->estsz != 0) {
+ memcpy(event_id_str_table_arr, (__u8 *)log_data_buf + event_str_table_ofst,
+ (log_data->estsz * 4));
+ printf(" Event Identifier String Table Entry\n");
+ for (j = 0; j < eve_id_index; j++) {
+ printf(" Debug Event Class : 0x%x\n",
+ event_id_str_table_arr[j].deb_eve_class);
+ printf(" Event Identifier : 0x%x\n",
+ le16_to_cpu(event_id_str_table_arr[j].ei));
+ printf(" ASCII ID Length : 0x%x\n",
+ event_id_str_table_arr[j].ascii_id_len);
+ printf(" ASCII ID offset : 0x%"PRIx64"\n",
+ le64_to_cpu(event_id_str_table_arr[j].ascii_id_ofst));
+ printf(" Reserved : 0x%x\n",
+ event_id_str_table_arr[j].reserved2);
+
+ }
+ }
+
+ if (log_data->vu_eve_st_sz != 0) {
+ memcpy(vu_event_id_str_table_arr, (__u8 *)log_data_buf + vu_event_str_table_ofst,
+ (log_data->vu_eve_st_sz * 4));
+ printf(" VU Event Identifier String Table Entry\n");
+ for (j = 0; j < vu_eve_index; j++) {
+ printf(" Debug Event Class : 0x%x\n",
+ vu_event_id_str_table_arr[j].deb_eve_class);
+ printf(" VU Event Identifier : 0x%x\n",
+ le16_to_cpu(vu_event_id_str_table_arr[j].vu_ei));
+ printf(" ASCII ID Length : 0x%x\n",
+ vu_event_id_str_table_arr[j].ascii_id_len);
+ printf(" ASCII ID offset : 0x%"PRIx64"\n",
+ le64_to_cpu(vu_event_id_str_table_arr[j].ascii_id_ofst));
+ printf(" Reserved : 0x%x\n",
+ vu_event_id_str_table_arr[j].reserved);
+ }
+ }
+
+ if (log_data->asctsz != 0) {
+ printf(" ASCII Table\n");
+ printf(" Byte Data_Byte ASCII_Character\n");
+ for (j = 0; j < ascii_table_index; j++)
+ printf(" %"PRIu64" %d %c\n",
+ le64_to_cpu(ascii_table_ofst + j),
+ log_data_buf[ascii_table_ofst + j],
+ (char)log_data_buf[ascii_table_ofst + j]);
+ }
+}
+
+static void stdout_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data)
+{
+ int j;
+
+ printf("TCG Configuration C7 Log Page Data-\n");
+
+ printf(" State : 0x%x\n",
+ log_data->state);
+ printf(" Reserved1 : 0x");
+ for (j = 0; j < 3; j++)
+ printf("%d", log_data->rsvd1[j]);
+ printf("\n");
+ printf(" Locking SP Activation Count : 0x%x\n",
+ log_data->locking_sp_act_count);
+ printf(" Tper Revert Count : 0x%x\n",
+ log_data->type_rev_count);
+ printf(" Locking SP Revert Count : 0x%x\n",
+ log_data->locking_sp_rev_count);
+ printf(" Number of Locking Objects : 0x%x\n",
+ log_data->no_of_locking_obj);
+ printf(" Number of Single User Mode Locking Objects : 0x%x\n",
+ log_data->no_of_single_um_locking_obj);
+ printf(" Number of Range Provisioned Locking Objects : 0x%x\n",
+ log_data->no_of_range_prov_locking_obj);
+ printf(" Number of Namespace Provisioned Locking Objects : 0x%x\n",
+ log_data->no_of_ns_prov_locking_obj);
+ printf(" Number of Read Locked Locking Objects : 0x%x\n",
+ log_data->no_of_read_lock_locking_obj);
+ printf(" Number of Write Locked Locking Objects : 0x%x\n",
+ log_data->no_of_write_lock_locking_obj);
+ printf(" Number of Read Unlocked Locking Objects : 0x%x\n",
+ log_data->no_of_read_unlock_locking_obj);
+ printf(" Number of Write Unlocked Locking Objects : 0x%x\n",
+ log_data->no_of_write_unlock_locking_obj);
+ printf(" Reserved2 : 0x%x\n",
+ log_data->rsvd2);
+
+ printf(" SID Authentication Try Count : 0x%x\n",
+ le32_to_cpu(log_data->sid_auth_try_count));
+ printf(" SID Authentication Try Limit : 0x%x\n",
+ le32_to_cpu(log_data->sid_auth_try_limit));
+ printf(" Programmatic TCG Reset Count : 0x%x\n",
+ le32_to_cpu(log_data->pro_tcg_rc));
+ printf(" Programmatic Reset Lock Count : 0x%x\n",
+ le32_to_cpu(log_data->pro_rlc));
+ printf(" TCG Error Count : 0x%x\n",
+ le32_to_cpu(log_data->tcg_ec));
+
+ printf(" Reserved3 : 0x");
+ for (j = 0; j < 458; j++)
+ printf("%d", log_data->rsvd3[j]);
+ printf("\n");
+
+ printf(" Log Page Version : 0x%x\n",
+ le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (j = GUID_LEN - 1; j >= 0; j--)
+ printf("%02x", log_data->log_page_guid[j]);
+ printf("\n");
+}
+
+static struct ocp_print_ops stdout_print_ops = {
+ .hwcomp_log = stdout_hwcomp_log,
+ .fw_act_history = stdout_fw_activation_history,
+ .smart_extended_log = stdout_smart_extended_log,
+ .telemetry_log = stdout_telemetry_log,
+ .c3_log = stdout_c3_log,
+ .c5_log = stdout_c5_log,
+ .c1_log = stdout_c1_log,
+ .c4_log = stdout_c4_log,
+ .c9_log = stdout_c9_log,
+ .c7_log = stdout_c7_log,
+};
+
+struct ocp_print_ops *ocp_get_stdout_print_ops(nvme_print_flags_t flags)
+{
+ stdout_print_ops.flags = flags;
+ return &stdout_print_ops;
+}
diff --git a/plugins/ocp/ocp-print.c b/plugins/ocp/ocp-print.c
new file mode 100644
index 0000000..916c653
--- /dev/null
+++ b/plugins/ocp/ocp-print.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "nvme-print.h"
+#include "ocp-print.h"
+#include "ocp-hardware-component-log.h"
+
+#define ocp_print(name, flags, ...) \
+ do { \
+ struct ocp_print_ops *ops = ocp_print_ops(flags); \
+ if (ops && ops->name) \
+ ops->name(__VA_ARGS__); \
+ else \
+ fprintf(stderr, "unhandled output format\n"); \
+ } while (false)
+
+static struct ocp_print_ops *ocp_print_ops(nvme_print_flags_t flags)
+{
+ struct ocp_print_ops *ops = NULL;
+
+ if (flags & JSON || nvme_is_output_format_json())
+ ops = ocp_get_json_print_ops(flags);
+ else if (flags & BINARY)
+ ops = ocp_get_binary_print_ops(flags);
+ else
+ ops = ocp_get_stdout_print_ops(flags);
+
+ return ops;
+}
+
+void ocp_show_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list, nvme_print_flags_t flags)
+{
+ ocp_print(hwcomp_log, flags, log, id, list);
+}
+
+void ocp_fw_act_history(const struct fw_activation_history *fw_history, nvme_print_flags_t flags)
+{
+ ocp_print(fw_act_history, flags, fw_history);
+}
+
+void ocp_smart_extended_log(void *data, nvme_print_flags_t flags)
+{
+ ocp_print(smart_extended_log, flags, data);
+}
+
+void ocp_show_telemetry_log(struct ocp_telemetry_parse_options *options, nvme_print_flags_t flags)
+{
+ ocp_print(telemetry_log, flags, options);
+}
+
+void ocp_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data,
+ nvme_print_flags_t flags)
+{
+ ocp_print(c3_log, flags, dev, log_data);
+}
+
+void ocp_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data,
+ nvme_print_flags_t flags)
+{
+ ocp_print(c5_log, flags, dev, log_data);
+}
+
+void ocp_c1_log(struct ocp_error_recovery_log_page *log_data, nvme_print_flags_t flags)
+{
+ ocp_print(c1_log, flags, log_data);
+}
+
+void ocp_c4_log(struct ocp_device_capabilities_log_page *log_data, nvme_print_flags_t flags)
+{
+ ocp_print(c4_log, flags, log_data);
+}
+
+void ocp_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_data_buf,
+ int total_log_page_size, nvme_print_flags_t flags)
+{
+ ocp_print(c9_log, flags, log_data, log_data_buf, total_log_page_size);
+}
+
+void ocp_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data,
+ nvme_print_flags_t flags)
+{
+ ocp_print(c7_log, flags, dev, log_data);
+}
diff --git a/plugins/ocp/ocp-print.h b/plugins/ocp/ocp-print.h
new file mode 100644
index 0000000..85655b9
--- /dev/null
+++ b/plugins/ocp/ocp-print.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef OCP_PRINT_H
+#define OCP_PRINT_H
+
+#include "ocp-hardware-component-log.h"
+#include "ocp-fw-activation-history.h"
+#include "ocp-telemetry-decode.h"
+#include "ocp-nvme.h"
+
+struct ocp_print_ops {
+ void (*hwcomp_log)(struct hwcomp_log *log, __u32 id, bool list);
+ void (*fw_act_history)(const struct fw_activation_history *fw_history);
+ void (*smart_extended_log)(void *data);
+ void (*telemetry_log)(struct ocp_telemetry_parse_options *options);
+ void (*c3_log)(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data);
+ void (*c5_log)(struct nvme_dev *dev, struct unsupported_requirement_log *log_data);
+ void (*c1_log)(struct ocp_error_recovery_log_page *log_data);
+ void (*c4_log)(struct ocp_device_capabilities_log_page *log_data);
+ void (*c9_log)(struct telemetry_str_log_format *log_data, __u8 *log_data_buf,
+ int total_log_page_size);
+ void (*c7_log)(struct nvme_dev *dev, struct tcg_configuration_log *log_data);
+ nvme_print_flags_t flags;
+};
+
+struct ocp_print_ops *ocp_get_stdout_print_ops(nvme_print_flags_t flags);
+struct ocp_print_ops *ocp_get_binary_print_ops(nvme_print_flags_t flags);
+
+#ifdef CONFIG_JSONC
+struct ocp_print_ops *ocp_get_json_print_ops(nvme_print_flags_t flags);
+#else /* !CONFIG_JSONC */
+static inline struct ocp_print_ops *ocp_get_json_print_ops(nvme_print_flags_t flags)
+{
+ return NULL;
+}
+#endif /* !CONFIG_JSONC */
+
+void ocp_show_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list, nvme_print_flags_t flags);
+void ocp_fw_act_history(const struct fw_activation_history *fw_history, nvme_print_flags_t flags);
+void ocp_smart_extended_log(void *data, nvme_print_flags_t flags);
+void ocp_show_telemetry_log(struct ocp_telemetry_parse_options *options, nvme_print_flags_t flags);
+void ocp_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data,
+ nvme_print_flags_t flags);
+void ocp_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data,
+ nvme_print_flags_t flags);
+void ocp_c1_log(struct ocp_error_recovery_log_page *log_data, nvme_print_flags_t flags);
+void ocp_c4_log(struct ocp_device_capabilities_log_page *log_data, nvme_print_flags_t flags);
+void ocp_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_data_buf,
+ int total_log_page_size, nvme_print_flags_t flags);
+void ocp_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data,
+ nvme_print_flags_t flags);
+#endif /* OCP_PRINT_H */
diff --git a/plugins/ocp/ocp-smart-extended-log.c b/plugins/ocp/ocp-smart-extended-log.c
index 6a524d3..5f84191 100644
--- a/plugins/ocp/ocp-smart-extended-log.c
+++ b/plugins/ocp/ocp-smart-extended-log.c
@@ -13,243 +13,19 @@
#include "common.h"
#include "nvme-print.h"
+#include "ocp-print.h"
/* C0 SCAO Log Page */
#define C0_SMART_CLOUD_ATTR_LEN 0x200
#define C0_SMART_CLOUD_ATTR_OPCODE 0xC0
-#define C0_GUID_LENGTH 16
-static __u8 scao_guid[C0_GUID_LENGTH] = {
+static __u8 scao_guid[GUID_LEN] = {
0xC5, 0xAF, 0x10, 0x28,
0xEA, 0xBF, 0xF2, 0xA4,
0x9C, 0x4F, 0x6F, 0x7C,
0xC9, 0x14, 0xD5, 0xAF
};
-enum {
- SCAO_PMUW = 0, /* Physical media units written */
- SCAO_PMUR = 16, /* Physical media units read */
- SCAO_BUNBR = 32, /* Bad user nand blocks raw */
- SCAO_BUNBN = 38, /* Bad user nand blocks normalized */
- SCAO_BSNBR = 40, /* Bad system nand blocks raw */
- SCAO_BSNBN = 46, /* Bad system nand blocks normalized */
- SCAO_XRC = 48, /* XOR recovery count */
- SCAO_UREC = 56, /* Uncorrectable read error count */
- SCAO_SEEC = 64, /* Soft ecc error count */
- SCAO_EEDC = 72, /* End to end detected errors */
- SCAO_EECE = 76, /* End to end corrected errors */
- SCAO_SDPU = 80, /* System data percent used */
- SCAO_RFSC = 81, /* Refresh counts */
- SCAO_MXUDEC = 88, /* Max User data erase counts */
- SCAO_MNUDEC = 92, /* Min User data erase counts */
- SCAO_NTTE = 96, /* Number of Thermal throttling events */
- SCAO_CTS = 97, /* Current throttling status */
- SCAO_EVF = 98, /* Errata Version Field */
- SCAO_PVF = 99, /* Point Version Field */
- SCAO_MIVF = 101, /* Minor Version Field */
- SCAO_MAVF = 103, /* Major Version Field */
- SCAO_PCEC = 104, /* PCIe correctable error count */
- SCAO_ICS = 112, /* Incomplete shutdowns */
- SCAO_PFB = 120, /* Percent free blocks */
- SCAO_CPH = 128, /* Capacitor health */
- SCAO_NEV = 130, /* NVMe Errata Version */
- SCAO_UIO = 136, /* Unaligned I/O */
- SCAO_SVN = 144, /* Security Version Number */
- SCAO_NUSE = 152, /* NUSE - Namespace utilization */
- SCAO_PSC = 160, /* PLP start count */
- SCAO_EEST = 176, /* Endurance estimate */
- SCAO_PLRC = 192, /* PCIe Link Retraining Count */
- SCAO_PSCC = 200, /* Power State Change Count */
- SCAO_LPV = 494, /* Log page version */
- SCAO_LPG = 496, /* Log page GUID */
-};
-
-static void ocp_print_C0_log_normal(void *data)
-{
- uint16_t smart_log_ver = 0;
- __u8 *log_data = data;
-
- printf("SMART Cloud Attributes :-\n");
-
- printf(" Physical media units written - %"PRIu64" %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8] & 0xFFFFFFFFFFFFFFFF),
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
- printf(" Physical media units read - %"PRIu64" %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8] & 0xFFFFFFFFFFFFFFFF),
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
- printf(" Bad user nand blocks - Raw %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
- printf(" Bad user nand blocks - Normalized %d\n",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
- printf(" Bad system nand blocks - Raw %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
- printf(" Bad system nand blocks - Normalized %d\n",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
- printf(" XOR recovery count %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
- printf(" Uncorrectable read error count %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
- printf(" Soft ecc error count %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
- printf(" End to end detected errors %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
- printf(" End to end corrected errors %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
- printf(" System data percent used %d\n",
- (__u8)log_data[SCAO_SDPU]);
- printf(" Refresh counts %"PRIu64"\n",
- (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
- printf(" Max User data erase counts %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
- printf(" Min User data erase counts %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
- printf(" Number of Thermal throttling events %d\n",
- (__u8)log_data[SCAO_NTTE]);
- printf(" Current throttling status 0x%x\n",
- (__u8)log_data[SCAO_CTS]);
- printf(" PCIe correctable error count %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
- printf(" Incomplete shutdowns %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
- printf(" Percent free blocks %d\n",
- (__u8)log_data[SCAO_PFB]);
- printf(" Capacitor health %"PRIu16"\n",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
- printf(" Unaligned I/O %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
- printf(" Security Version Number %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
- printf(" NUSE - Namespace utilization %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
- printf(" PLP start count %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC])));
- printf(" Endurance estimate %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_EEST])));
- smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
- printf(" Log page version %"PRIu16"\n", smart_log_ver);
- printf(" Log page GUID 0x");
- printf("%"PRIx64"%"PRIx64"\n", (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
- if (smart_log_ver > 2) {
- printf(" Errata Version Field %d\n",
- (__u8)log_data[SCAO_EVF]);
- printf(" Point Version Field %"PRIu16"\n",
- le16_to_cpu(*(uint16_t *)&log_data[SCAO_PVF]));
- printf(" Minor Version Field %"PRIu16"\n",
- le16_to_cpu(*(uint16_t *)&log_data[SCAO_MIVF]));
- printf(" Major Version Field %d\n",
- (__u8)log_data[SCAO_MAVF]);
- printf(" NVMe Errata Version %d\n",
- (__u8)log_data[SCAO_NEV]);
- printf(" PCIe Link Retraining Count %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
- printf(" Power State Change Count %"PRIu64"\n",
- le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
- }
- printf("\n");
-}
-
-static void ocp_print_C0_log_json(void *data)
-{
- struct json_object *root;
- struct json_object *pmuw;
- struct json_object *pmur;
- uint16_t smart_log_ver = 0;
- __u8 *log_data = data;
- char guid[40];
-
- root = json_create_object();
- pmuw = json_create_object();
- pmur = json_create_object();
-
- json_object_add_value_uint64(pmuw, "hi",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW + 8] & 0xFFFFFFFFFFFFFFFF));
- json_object_add_value_uint64(pmuw, "lo",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
- json_object_add_value_object(root, "Physical media units written", pmuw);
- json_object_add_value_uint64(pmur, "hi",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR + 8] & 0xFFFFFFFFFFFFFFFF));
- json_object_add_value_uint64(pmur, "lo",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
- json_object_add_value_object(root, "Physical media units read", pmur);
- json_object_add_value_uint64(root, "Bad user nand blocks - Raw",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
- json_object_add_value_uint(root, "Bad user nand blocks - Normalized",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
- json_object_add_value_uint64(root, "Bad system nand blocks - Raw",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
- json_object_add_value_uint(root, "Bad system nand blocks - Normalized",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
- json_object_add_value_uint64(root, "XOR recovery count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
- json_object_add_value_uint64(root, "Uncorrectable read error count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
- json_object_add_value_uint64(root, "Soft ecc error count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
- json_object_add_value_uint(root, "End to end detected errors",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
- json_object_add_value_uint(root, "End to end corrected errors",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
- json_object_add_value_uint(root, "System data percent used",
- (__u8)log_data[SCAO_SDPU]);
- json_object_add_value_uint64(root, "Refresh counts",
- (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
- json_object_add_value_uint(root, "Max User data erase counts",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
- json_object_add_value_uint(root, "Min User data erase counts",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
- json_object_add_value_uint(root, "Number of Thermal throttling events",
- (__u8)log_data[SCAO_NTTE]);
- json_object_add_value_uint(root, "Current throttling status",
- (__u8)log_data[SCAO_CTS]);
- json_object_add_value_uint64(root, "PCIe correctable error count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
- json_object_add_value_uint(root, "Incomplete shutdowns",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
- json_object_add_value_uint(root, "Percent free blocks",
- (__u8)log_data[SCAO_PFB]);
- json_object_add_value_uint(root, "Capacitor health",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
- json_object_add_value_uint64(root, "Unaligned I/O",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
- json_object_add_value_uint64(root, "Security Version Number",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
- json_object_add_value_uint64(root, "NUSE - Namespace utilization",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
- json_object_add_value_uint128(root, "PLP start count",
- le128_to_cpu(&log_data[SCAO_PSC]));
- json_object_add_value_uint128(root, "Endurance estimate",
- le128_to_cpu(&log_data[SCAO_EEST]));
- smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
-
- json_object_add_value_uint(root, "Log page version", smart_log_ver);
-
- memset((void *)guid, 0, 40);
- sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"", (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
- json_object_add_value_string(root, "Log page GUID", guid);
-
- if (smart_log_ver > 2) {
- json_object_add_value_uint(root, "Errata Version Field",
- (__u8)log_data[SCAO_EVF]);
- json_object_add_value_uint(root, "Point Version Field",
- le16_to_cpu(*(uint16_t *)&log_data[SCAO_PVF]));
- json_object_add_value_uint(root, "Minor Version Field",
- le16_to_cpu(*(uint16_t *)&log_data[SCAO_MIVF]));
- json_object_add_value_uint(root, "Major Version Field",
- (__u8)log_data[SCAO_MAVF]);
- json_object_add_value_uint(root, "NVMe Errata Version",
- (__u8)log_data[SCAO_NEV]);
- json_object_add_value_uint(root, "PCIe Link Retraining Count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
- json_object_add_value_uint(root, "Power State Change Count",
- le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
- }
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
-}
-
static int get_c0_log_page(int fd, char *format)
{
nvme_print_flags_t fmt;
@@ -300,16 +76,7 @@ static int get_c0_log_page(int fd, char *format)
}
/* print the data */
- switch (fmt) {
- case NORMAL:
- ocp_print_C0_log_normal(data);
- break;
- case JSON:
- ocp_print_C0_log_json(data);
- break;
- default:
- break;
- }
+ ocp_smart_extended_log(data, fmt);
} else {
fprintf(stderr, "ERROR : OCP : Unable to read C0 data from buffer\n");
}
diff --git a/plugins/ocp/ocp-smart-extended-log.h b/plugins/ocp/ocp-smart-extended-log.h
index 42c1f98..3e64b1b 100644
--- a/plugins/ocp/ocp-smart-extended-log.h
+++ b/plugins/ocp/ocp-smart-extended-log.h
@@ -12,6 +12,46 @@
struct command;
struct plugin;
+enum {
+ SCAO_PMUW = 0, /* Physical media units written */
+ SCAO_PMUR = 16, /* Physical media units read */
+ SCAO_BUNBR = 32, /* Bad user nand blocks raw */
+ SCAO_BUNBN = 38, /* Bad user nand blocks normalized */
+ SCAO_BSNBR = 40, /* Bad system nand blocks raw */
+ SCAO_BSNBN = 46, /* Bad system nand blocks normalized */
+ SCAO_XRC = 48, /* XOR recovery count */
+ SCAO_UREC = 56, /* Uncorrectable read error count */
+ SCAO_SEEC = 64, /* Soft ecc error count */
+ SCAO_EEDC = 72, /* End to end detected errors */
+ SCAO_EECE = 76, /* End to end corrected errors */
+ SCAO_SDPU = 80, /* System data percent used */
+ SCAO_RFSC = 81, /* Refresh counts */
+ SCAO_MXUDEC = 88, /* Max User data erase counts */
+ SCAO_MNUDEC = 92, /* Min User data erase counts */
+ SCAO_NTTE = 96, /* Number of Thermal throttling events */
+ SCAO_CTS = 97, /* Current throttling status */
+ SCAO_EVF = 98, /* Errata Version Field */
+ SCAO_PVF = 99, /* Point Version Field */
+ SCAO_MIVF = 101, /* Minor Version Field */
+ SCAO_MAVF = 103, /* Major Version Field */
+ SCAO_PCEC = 104, /* PCIe correctable error count */
+ SCAO_ICS = 112, /* Incomplete shutdowns */
+ SCAO_PFB = 120, /* Percent free blocks */
+ SCAO_CPH = 128, /* Capacitor health */
+ SCAO_NBEV = 130, /* NVMe Base Errata Version */
+ SCAO_NCSEV = 131, /* NVMe Command Set Errata Version */
+ SCAO_UIO = 136, /* Unaligned I/O */
+ SCAO_SVN = 144, /* Security Version Number */
+ SCAO_NUSE = 152, /* NUSE - Namespace utilization */
+ SCAO_PSC = 160, /* PLP start count */
+ SCAO_EEST = 176, /* Endurance estimate */
+ SCAO_PLRC = 192, /* PCIe Link Retraining Count */
+ SCAO_PSCC = 200, /* Power State Change Count */
+ SCAO_LPFR = 208, /* Lowest Permitted Firmware Revision */
+ SCAO_LPV = 494, /* Log page version */
+ SCAO_LPG = 496, /* Log page GUID */
+};
+
int ocp_smart_add_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin);
diff --git a/plugins/ocp/ocp-telemetry-decode.c b/plugins/ocp/ocp-telemetry-decode.c
index 11963be..1a6ebe3 100644
--- a/plugins/ocp/ocp-telemetry-decode.c
+++ b/plugins/ocp/ocp-telemetry-decode.c
@@ -64,6 +64,7 @@ void print_telemetry_fifo_event(__u8 class_type,
if (class_type) {
class_str = telemetry_event_class_to_string(class_type);
printf("Event Class : %s\n", class_str);
+ printf(" Size : 0x%02x\n", size);
}
switch (class_type) {
@@ -75,9 +76,8 @@ void print_telemetry_fifo_event(__u8 class_type,
(int)((le64_to_cpu(timestamp%3600)/60)),
(int)(le64_to_cpu(timestamp%60)));
- printf(" Event ID : 0x%02x %s\n", id, telemetry_ts_event_to_string(id));
+ printf(" Event ID : 0x%04x %s\n", id, telemetry_ts_event_to_string(id));
printf(" Timestamp : %s\n", time_str);
- printf(" Size : %d\n", size);
if (size > 8) {
printf(" VU Data : 0x");
for (j = 8; j < size; j++)
@@ -87,7 +87,7 @@ void print_telemetry_fifo_event(__u8 class_type,
break;
case TELEMETRY_PCIE_CLASS:
- printf(" Event ID : 0x%02x %s\n",
+ printf(" Event ID : 0x%04x %s\n",
id, telemetry_pcie_event_id_to_string(id));
printf(" State : 0x%02x %s\n",
data[0], telemetry_pcie_state_data_to_string(data[0]));
@@ -104,7 +104,7 @@ void print_telemetry_fifo_event(__u8 class_type,
break;
case TELEMETRY_NVME_CLASS:
- printf(" Event ID : 0x%02x %s\n",
+ printf(" Event ID : 0x%04x %s\n",
id, telemetry_nvme_event_id_to_string(id));
if ((id == ADMIN_QUEUE_NONZERO_STATUS) ||
(id == IO_QUEUE_NONZERO_STATUS)) {
@@ -128,46 +128,46 @@ void print_telemetry_fifo_event(__u8 class_type,
le32_to_cpu(csts_reg_data));
}
if (size > 8)
- print_vu_event_data(size, (__u8 *)&data[8]);
+ print_vu_event_data((size-8), (__u8 *)&data[8]);
break;
case TELEMETRY_RESET_CLASS:
- printf(" Event ID : 0x%02x %s\n",
+ printf(" Event ID : 0x%04x %s\n",
id, telemetry_reset_event_id_to_string(id));
if (size)
print_vu_event_data(size, data);
break;
case TELEMETRY_BOOT_SEQ_CLASS:
- printf(" Event ID : 0x%02x %s\n",
+ printf(" Event ID : 0x%04x %s\n",
id, telemetry_boot_seq_event_id_to_string(id));
if (size)
print_vu_event_data(size, data);
break;
case TELEMETRY_FW_ASSERT_CLASS:
- printf(" Event ID : 0x%02x %s\n",
+ printf(" Event ID : 0x%04x %s\n",
id, telemetry_fw_assert_event_id_to_string(id));
if (size)
print_vu_event_data(size, data);
break;
case TELEMETRY_TEMPERATURE_CLASS:
- printf(" Event ID : 0x%02x %s\n",
+ printf(" Event ID : 0x%04x %s\n",
id, telemetry_temperature_event_id_to_string(id));
if (size)
print_vu_event_data(size, data);
break;
case TELEMETRY_MEDIA_DBG_CLASS:
- printf(" Event ID : 0x%02x %s\n",
+ printf(" Event ID : 0x%04x %s\n",
id, telemetry_media_debug_event_id_to_string(id));
if (size)
print_vu_event_data(size, data);
break;
case TELEMETRY_MEDIA_WEAR_CLASS:
- printf(" Event ID : 0x%02x %s\n",
+ printf(" Event ID : 0x%04x %s\n",
id, telemetry_media_debug_event_id_to_string(id));
__u32 host_tb_written = *(__u32 *)&data[0];
__u32 media_tb_written = *(__u32 *)&data[4];
@@ -181,7 +181,7 @@ void print_telemetry_fifo_event(__u8 class_type,
le16_to_cpu(media_tb_erased));
if (size > 12)
- print_vu_event_data(size, (__u8 *)&data[12]);
+ print_vu_event_data((size-12), (__u8 *)&data[12]);
break;
case TELEMETRY_STAT_SNAPSHOT_CLASS:
@@ -280,7 +280,7 @@ struct request_data ocp_header_in_da1[] = {
{ "Minor Version", 2 },
{ "Reserved1", 4 },
{ "Timestamp", 8 },
- { "Log page GUID", 16 },
+ { "Log page GUID", GUID_LEN },
{ "Number Telemetry Profiles Supported", 1 },
{ "Telemetry Profile Selected", 1 },
{ "Reserved2", 6 },
@@ -419,9 +419,10 @@ struct request_data smart_extended[] = {
{ "Lowest Permitted Firmware Revision", 8 },
{ "Reserved4", 278 },
{ "Log Page Version", 2 },
- { "Log page GUID", 16 }
+ { "Log page GUID", GUID_LEN }
};
+#ifdef CONFIG_JSONC
void json_add_formatted_u32_str(struct json_object *pobject, const char *msg, unsigned int pdata)
{
char data_str[70] = { 0 };
@@ -443,6 +444,7 @@ void json_add_formatted_var_size_str(struct json_object *pobject, const char *ms
json_object_add_value_string(pobject, msg, description_str);
}
+#endif /* CONFIG_JSONC */
int get_telemetry_das_offset_and_size(
struct nvme_ocp_telemetry_common_header *ptelemetry_common_header,
@@ -636,49 +638,67 @@ int parse_ocp_telemetry_string_log(int event_fifo_num, int identifier, int debug
return 0;
}
+#ifdef CONFIG_JSONC
void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
struct json_object *pevent_fifos_object, FILE *fp)
{
struct nvme_ocp_time_stamp_dbg_evt_class_format *ptime_stamp_event =
(struct nvme_ocp_time_stamp_dbg_evt_class_format *) pevent_specific_data;
-
- int vu_event_id = (int)ptime_stamp_event->vu_event_identifier;
-
- unsigned int data_size = ((pevent_descriptor->event_data_size * SIZE_OF_DWORD)-
- sizeof(struct nvme_ocp_time_stamp_dbg_evt_class_format));
-
- __u8 *pdata = (__u8 *)ptime_stamp_event +
- sizeof(struct nvme_ocp_time_stamp_dbg_evt_class_format);
-
+ struct nvme_ocp_common_dbg_evt_class_vu_data *ptime_stamp_event_vu_data = NULL;
+ __u16 vu_event_id = 0;
+ __u8 *pdata = NULL;
char description_str[256] = "";
-
- parse_ocp_telemetry_string_log(0, ptime_stamp_event->vu_event_identifier,
- pevent_descriptor->debug_event_class_type,
- VU_EVENT_STRING, description_str);
+ unsigned int vu_data_size = 0;
+ bool vu_data_present = false;
+
+ if ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) >
+ sizeof(struct nvme_ocp_time_stamp_dbg_evt_class_format)) {
+ vu_data_present = true;
+ vu_data_size =
+ ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) -
+ (sizeof(struct nvme_ocp_time_stamp_dbg_evt_class_format) +
+ SIZE_OF_VU_EVENT_ID));
+
+ ptime_stamp_event_vu_data =
+ (struct nvme_ocp_common_dbg_evt_class_vu_data *)((__u64)ptime_stamp_event +
+ sizeof(struct nvme_ocp_time_stamp_dbg_evt_class_format));
+ vu_event_id = le16_to_cpu(ptime_stamp_event_vu_data->vu_event_identifier);
+ pdata = (__u8 *)&(ptime_stamp_event_vu_data->data);
+
+ parse_ocp_telemetry_string_log(0, vu_event_id,
+ pevent_descriptor->debug_event_class_type,
+ VU_EVENT_STRING, description_str);
+ }
if (pevent_fifos_object != NULL) {
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
ptime_stamp_event->time_stamp, DATA_SIZE_8);
- json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
- vu_event_id);
- json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
- description_str);
- json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
- data_size);
+ if (vu_data_present) {
+ json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
+ vu_event_id);
+ json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
+ description_str);
+ json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
+ vu_data_size);
+ }
} else {
if (fp) {
print_formatted_var_size_str(STR_CLASS_SPECIFIC_DATA,
ptime_stamp_event->time_stamp, DATA_SIZE_8, fp);
- fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (vu_data_present) {
+ fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ }
} else {
print_formatted_var_size_str(STR_CLASS_SPECIFIC_DATA,
ptime_stamp_event->time_stamp, DATA_SIZE_8, fp);
- printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (vu_data_present) {
+ printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ }
}
}
}
@@ -689,37 +709,60 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
{
struct nvme_ocp_pcie_dbg_evt_class_format *ppcie_event =
(struct nvme_ocp_pcie_dbg_evt_class_format *) pevent_specific_data;
- int vu_event_id = (int) ppcie_event->vu_event_identifier;
- unsigned int data_size = ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) -
- sizeof(struct nvme_ocp_pcie_dbg_evt_class_format));
- __u8 *pdata = (__u8 *) ppcie_event + sizeof(struct nvme_ocp_pcie_dbg_evt_class_format);
+ struct nvme_ocp_common_dbg_evt_class_vu_data *ppcie_event_vu_data = NULL;
+ __u16 vu_event_id = 0;
+ __u8 *pdata = NULL;
char description_str[256] = "";
-
- parse_ocp_telemetry_string_log(0, ppcie_event->vu_event_identifier,
- pevent_descriptor->debug_event_class_type, VU_EVENT_STRING, description_str);
+ unsigned int vu_data_size = 0;
+ bool vu_data_present = false;
+
+ if ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) >
+ sizeof(struct nvme_ocp_pcie_dbg_evt_class_format)) {
+ vu_data_present = true;
+ vu_data_size =
+ ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) -
+ (sizeof(struct nvme_ocp_pcie_dbg_evt_class_format) +
+ SIZE_OF_VU_EVENT_ID));
+
+ ppcie_event_vu_data =
+ (struct nvme_ocp_common_dbg_evt_class_vu_data *)((__u64)ppcie_event +
+ sizeof(struct nvme_ocp_pcie_dbg_evt_class_format));
+ vu_event_id = le16_to_cpu(ppcie_event_vu_data->vu_event_identifier);
+ pdata = (__u8 *)&(ppcie_event_vu_data->data);
+
+ parse_ocp_telemetry_string_log(0, vu_event_id,
+ pevent_descriptor->debug_event_class_type,
+ VU_EVENT_STRING, description_str);
+ }
if (pevent_fifos_object != NULL) {
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
ppcie_event->pCIeDebugEventData, DATA_SIZE_4);
- json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
- vu_event_id);
- json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
- description_str);
- json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
- data_size);
+ if (vu_data_present) {
+ json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
+ vu_event_id);
+ json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
+ description_str);
+ json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
+ vu_data_size);
+ }
} else {
if (fp) {
print_formatted_var_size_str(STR_CLASS_SPECIFIC_DATA,
ppcie_event->pCIeDebugEventData, DATA_SIZE_4, fp);
- fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (vu_data_present) {
+ fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ }
} else {
print_formatted_var_size_str(STR_CLASS_SPECIFIC_DATA,
ppcie_event->pCIeDebugEventData, DATA_SIZE_4, fp);
- printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (vu_data_present) {
+ printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ }
}
}
}
@@ -730,38 +773,61 @@ void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
{
struct nvme_ocp_nvme_dbg_evt_class_format *pnvme_event =
(struct nvme_ocp_nvme_dbg_evt_class_format *) pevent_specific_data;
- int vu_event_id = (int) pnvme_event->vu_event_identifier;
- unsigned int data_size = ((pevent_descriptor->event_data_size *
- SIZE_OF_DWORD) - sizeof(struct nvme_ocp_nvme_dbg_evt_class_format));
- __u8 *pdata = (__u8 *) pnvme_event + sizeof(struct nvme_ocp_nvme_dbg_evt_class_format);
+ struct nvme_ocp_common_dbg_evt_class_vu_data *pnvme_event_vu_data = NULL;
+ __u16 vu_event_id = 0;
+ __u8 *pdata = NULL;
char description_str[256] = "";
-
- parse_ocp_telemetry_string_log(0, pnvme_event->vu_event_identifier,
- pevent_descriptor->debug_event_class_type, VU_EVENT_STRING,
- description_str);
+ unsigned int vu_data_size = 0;
+ bool vu_data_present = false;
+
+ if ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) >
+ sizeof(struct nvme_ocp_nvme_dbg_evt_class_format)) {
+ vu_data_present = true;
+ vu_data_size =
+ ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) -
+ (sizeof(struct nvme_ocp_nvme_dbg_evt_class_format) +
+ SIZE_OF_VU_EVENT_ID));
+ pnvme_event_vu_data =
+ (struct nvme_ocp_common_dbg_evt_class_vu_data *)((__u64)pnvme_event +
+ sizeof(struct nvme_ocp_nvme_dbg_evt_class_format));
+
+ vu_event_id = le16_to_cpu(pnvme_event_vu_data->vu_event_identifier);
+ pdata = (__u8 *)&(pnvme_event_vu_data->data);
+
+ parse_ocp_telemetry_string_log(0, vu_event_id,
+ pevent_descriptor->debug_event_class_type,
+ VU_EVENT_STRING,
+ description_str);
+ }
if (pevent_fifos_object != NULL) {
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
- pnvme_event->nvmeDebugEventData, DATA_SIZE_8);
- json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
- vu_event_id);
- json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
- description_str);
- json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
- data_size);
+ pnvme_event->nvmeDebugEventData, DATA_SIZE_8);
+ if (vu_data_present) {
+ json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
+ vu_event_id);
+ json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
+ description_str);
+ json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
+ vu_data_size);
+ }
} else {
if (fp) {
print_formatted_var_size_str(STR_CLASS_SPECIFIC_DATA,
pnvme_event->nvmeDebugEventData, DATA_SIZE_8, fp);
- fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (vu_data_present) {
+ fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ }
} else {
print_formatted_var_size_str(STR_CLASS_SPECIFIC_DATA,
pnvme_event->nvmeDebugEventData, DATA_SIZE_8, fp);
- printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (vu_data_present) {
+ printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ }
}
}
}
@@ -770,34 +836,38 @@ void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descr
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
struct json_object *pevent_fifos_object, FILE *fp)
{
- struct nvme_ocp_common_dbg_evt_class_format *pcommon_debug_event =
- (struct nvme_ocp_common_dbg_evt_class_format *) pevent_specific_data;
- int vu_event_id = (int) pcommon_debug_event->vu_event_identifier;
- unsigned int data_size = ((pevent_descriptor->event_data_size *
- SIZE_OF_DWORD) - sizeof(struct nvme_ocp_common_dbg_evt_class_format));
- __u8 *pdata = (__u8 *) pcommon_debug_event +
- sizeof(struct nvme_ocp_common_dbg_evt_class_format);
- char description_str[256] = "";
-
- parse_ocp_telemetry_string_log(0, pcommon_debug_event->vu_event_identifier,
- pevent_descriptor->debug_event_class_type, VU_EVENT_STRING, description_str);
-
- if (pevent_fifos_object != NULL) {
- json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
- vu_event_id);
- json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
- description_str);
- json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
- data_size);
- } else {
- if (fp) {
- fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (pevent_specific_data) {
+ struct nvme_ocp_common_dbg_evt_class_vu_data *pcommon_debug_event_vu_data =
+ (struct nvme_ocp_common_dbg_evt_class_vu_data *) pevent_specific_data;
+
+ __u16 vu_event_id = le16_to_cpu(pcommon_debug_event_vu_data->vu_event_identifier);
+ char description_str[256] = "";
+ __u8 *pdata = (__u8 *)&(pcommon_debug_event_vu_data->data);
+
+ unsigned int vu_data_size = ((pevent_descriptor->event_data_size *
+ SIZE_OF_DWORD) - SIZE_OF_VU_EVENT_ID);
+
+ parse_ocp_telemetry_string_log(0, vu_event_id,
+ pevent_descriptor->debug_event_class_type,
+ VU_EVENT_STRING, description_str);
+
+ if (pevent_fifos_object != NULL) {
+ json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
+ vu_event_id);
+ json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
+ description_str);
+ json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
+ vu_data_size);
} else {
- printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (fp) {
+ fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ } else {
+ printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ }
}
}
}
@@ -808,39 +878,62 @@ void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
{
struct nvme_ocp_media_wear_dbg_evt_class_format *pmedia_wear_event =
(struct nvme_ocp_media_wear_dbg_evt_class_format *) pevent_specific_data;
- int vu_event_id = (int) pmedia_wear_event->vu_event_identifier;
- unsigned int data_size = ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) -
- sizeof(struct nvme_ocp_media_wear_dbg_evt_class_format));
- __u8 *pdata = (__u8 *) pmedia_wear_event +
- sizeof(struct nvme_ocp_media_wear_dbg_evt_class_format);
- char description_str[256] = "";
+ struct nvme_ocp_common_dbg_evt_class_vu_data *pmedia_wear_event_vu_data = NULL;
- parse_ocp_telemetry_string_log(0, pmedia_wear_event->vu_event_identifier,
- pevent_descriptor->debug_event_class_type, VU_EVENT_STRING,
- description_str);
+ __u16 vu_event_id = 0;
+ __u8 *pdata = NULL;
+ char description_str[256] = "";
+ unsigned int vu_data_size = 0;
+ bool vu_data_present = false;
+
+ if ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) >
+ sizeof(struct nvme_ocp_media_wear_dbg_evt_class_format)) {
+ vu_data_present = true;
+ vu_data_size =
+ ((pevent_descriptor->event_data_size * SIZE_OF_DWORD) -
+ (sizeof(struct nvme_ocp_media_wear_dbg_evt_class_format) +
+ SIZE_OF_VU_EVENT_ID));
+
+ pmedia_wear_event_vu_data =
+ (struct nvme_ocp_common_dbg_evt_class_vu_data *)((__u64)pmedia_wear_event +
+ sizeof(struct nvme_ocp_media_wear_dbg_evt_class_format));
+ vu_event_id = le16_to_cpu(pmedia_wear_event_vu_data->vu_event_identifier);
+ pdata = (__u8 *)&(pmedia_wear_event_vu_data->data);
+
+ parse_ocp_telemetry_string_log(0, vu_event_id,
+ pevent_descriptor->debug_event_class_type,
+ VU_EVENT_STRING,
+ description_str);
+ }
if (pevent_fifos_object != NULL) {
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
pmedia_wear_event->currentMediaWear, DATA_SIZE_12);
- json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
- vu_event_id);
- json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
- description_str);
- json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
- data_size);
+ if (vu_data_present) {
+ json_add_formatted_u32_str(pevent_descriptor_obj, STR_VU_EVENT_ID_STRING,
+ vu_event_id);
+ json_object_add_value_string(pevent_descriptor_obj, STR_VU_EVENT_STRING,
+ description_str);
+ json_add_formatted_var_size_str(pevent_descriptor_obj, STR_VU_DATA, pdata,
+ vu_data_size);
+ }
} else {
if (fp) {
print_formatted_var_size_str(STR_CLASS_SPECIFIC_DATA,
pmedia_wear_event->currentMediaWear, DATA_SIZE_12, fp);
- fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (vu_data_present) {
+ fprintf(fp, "%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ fprintf(fp, "%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ }
} else {
print_formatted_var_size_str(STR_CLASS_SPECIFIC_DATA,
pmedia_wear_event->currentMediaWear, DATA_SIZE_12, NULL);
- printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
- printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
- print_formatted_var_size_str(STR_VU_DATA, pdata, data_size, fp);
+ if (vu_data_present) {
+ printf("%s: 0x%x\n", STR_VU_EVENT_ID_STRING, vu_event_id);
+ printf("%s: %s\n", STR_VU_EVENT_STRING, description_str);
+ print_formatted_var_size_str(STR_VU_DATA, pdata, vu_data_size, fp);
+ }
}
}
}
@@ -895,16 +988,27 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
(struct nvme_ocp_telemetry_event_descriptor *)
(pfifo_start + offset_to_move);
+ /* check if at the end of the list */
+ if (pevent_descriptor->debug_event_class_type == RESERVED_CLASS_TYPE)
+ break;
+
if (pevent_descriptor != NULL && pevent_descriptor->event_data_size >= 0) {
- //Data is present in the form of DWORDS, So multiplying with sizeof(DWORD)
+ /* Data is present in the form of DWORDS,
+ * So multiplying with sizeof(DWORD)
+ */
unsigned int data_size = pevent_descriptor->event_data_size *
SIZE_OF_DWORD;
- __u8 *pevent_specific_data = (__u8 *)pevent_descriptor + event_des_size;
-
+ __u8 *pevent_specific_data = NULL;
+ __u16 event_id = 0;
char description_str[256] = "";
- parse_ocp_telemetry_string_log(0, pevent_descriptor->event_id,
+ if (pevent_descriptor != NULL && pevent_descriptor->event_data_size > 0)
+ pevent_specific_data = (__u8 *)pevent_descriptor + event_des_size;
+
+ event_id = le16_to_cpu(pevent_descriptor->event_id);
+
+ parse_ocp_telemetry_string_log(0, event_id,
pevent_descriptor->debug_event_class_type, EVENT_STRING,
description_str);
@@ -916,7 +1020,7 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
STR_DBG_EVENT_CLASS_TYPE,
pevent_descriptor->debug_event_class_type);
json_add_formatted_u32_str(pevent_descriptor_obj,
- STR_EVENT_IDENTIFIER, pevent_descriptor->event_id);
+ STR_EVENT_IDENTIFIER, event_id);
json_object_add_value_string(pevent_descriptor_obj,
STR_EVENT_STRING, description_str);
json_add_formatted_u32_str(pevent_descriptor_obj,
@@ -930,18 +1034,18 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
fprintf(fp, "%s: 0x%x\n", STR_DBG_EVENT_CLASS_TYPE,
pevent_descriptor->debug_event_class_type);
fprintf(fp, "%s: 0x%x\n", STR_EVENT_IDENTIFIER,
- pevent_descriptor->event_id);
+ event_id);
fprintf(fp, "%s: %s\n", STR_EVENT_STRING, description_str);
fprintf(fp, "%s: 0x%x\n", STR_EVENT_DATA_SIZE,
pevent_descriptor->event_data_size);
} else {
printf("%s: 0x%x\n", STR_DBG_EVENT_CLASS_TYPE,
- pevent_descriptor->debug_event_class_type);
+ pevent_descriptor->debug_event_class_type);
printf("%s: 0x%x\n", STR_EVENT_IDENTIFIER,
- pevent_descriptor->event_id);
+ event_id);
printf("%s: %s\n", STR_EVENT_STRING, description_str);
printf("%s: 0x%x\n", STR_EVENT_DATA_SIZE,
- pevent_descriptor->event_data_size);
+ pevent_descriptor->event_data_size);
}
if (pevent_descriptor->debug_event_class_type >= 0x80)
@@ -951,28 +1055,43 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
switch (pevent_descriptor->debug_event_class_type) {
case TIME_STAMP_CLASS_TYPE:
- parse_time_stamp_event(pevent_descriptor, pevent_descriptor_obj,
- pevent_specific_data, pevent_fifos_object, fp);
+ parse_time_stamp_event(pevent_descriptor,
+ pevent_descriptor_obj,
+ pevent_specific_data,
+ pevent_fifos_object,
+ fp);
break;
case PCIE_CLASS_TYPE:
- parse_pcie_event(pevent_descriptor, pevent_descriptor_obj,
- pevent_specific_data, pevent_fifos_object, fp);
+ parse_pcie_event(pevent_descriptor,
+ pevent_descriptor_obj,
+ pevent_specific_data,
+ pevent_fifos_object,
+ fp);
break;
case NVME_CLASS_TYPE:
- parse_nvme_event(pevent_descriptor, pevent_descriptor_obj,
- pevent_specific_data, pevent_fifos_object, fp);
+ parse_nvme_event(pevent_descriptor,
+ pevent_descriptor_obj,
+ pevent_specific_data,
+ pevent_fifos_object,
+ fp);
break;
case RESET_CLASS_TYPE:
case BOOT_SEQUENCE_CLASS_TYPE:
case FIRMWARE_ASSERT_CLASS_TYPE:
case TEMPERATURE_CLASS_TYPE:
case MEDIA_CLASS_TYPE:
- parse_common_event(pevent_descriptor, pevent_descriptor_obj,
- pevent_specific_data, pevent_fifos_object, fp);
+ parse_common_event(pevent_descriptor,
+ pevent_descriptor_obj,
+ pevent_specific_data,
+ pevent_fifos_object,
+ fp);
break;
case MEDIA_WEAR_CLASS_TYPE:
- parse_media_wear_event(pevent_descriptor, pevent_descriptor_obj,
- pevent_specific_data, pevent_fifos_object, fp);
+ parse_media_wear_event(pevent_descriptor,
+ pevent_descriptor_obj,
+ pevent_specific_data,
+ pevent_fifos_object,
+ fp);
break;
case STATISTIC_SNAPSHOT_CLASS_TYPE: {
struct nvme_ocp_statistic_snapshot_evt_class_format
@@ -989,20 +1108,22 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
case RESERVED_CLASS_TYPE:
default:
break;
- }
+ }
- if (pevent_descriptor_obj != NULL && pevent_fifo_array != NULL)
- json_array_add_value_object(pevent_fifo_array, pevent_descriptor_obj);
- else {
- if (fp)
- fprintf(fp, STR_LINE2);
- else
- printf(STR_LINE2);
- }
- } else
- break;
+ if (pevent_descriptor_obj != NULL && pevent_fifo_array != NULL)
+ json_array_add_value_object(pevent_fifo_array,
+ pevent_descriptor_obj);
+ else {
+ if (fp)
+ fprintf(fp, STR_LINE2);
+ else
+ printf(STR_LINE2);
+ }
+ } else
+ break;
- offset_to_move += (pevent_descriptor->event_data_size * SIZE_OF_DWORD + event_des_size);
+ offset_to_move += (pevent_descriptor->event_data_size * SIZE_OF_DWORD +
+ event_des_size);
}
if (pevent_fifos_object != NULL && pevent_fifo_array != NULL)
@@ -1241,9 +1362,16 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
fprintf(fp, STR_LINE);
fprintf(fp, "%s\n", STR_LOG_PAGE_HEADER);
fprintf(fp, STR_LINE);
- if (!strcmp(options->telemetry_type, "host"))
- generic_structure_parser(ptelemetry_buffer, host_log_page_header,
- ARRAY_SIZE(host_log_page_header), NULL, 0, fp);
+ if (!strcmp(options->telemetry_type, "host")) {
+ if ((ptelemetry_buffer == NULL) ||
+ (ARRAY_SIZE(host_log_page_header) == 0))
+ printf("skip generic_structure_parser\n");
+ else
+ generic_structure_parser(ptelemetry_buffer,
+ host_log_page_header,
+ ARRAY_SIZE(host_log_page_header),
+ NULL, 0, fp);
+ }
else if (!strcmp(options->telemetry_type, "controller"))
generic_structure_parser(ptelemetry_buffer,
controller_log_page_header,
@@ -1350,9 +1478,15 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
printf(STR_LINE);
printf("%s\n", STR_LOG_PAGE_HEADER);
printf(STR_LINE);
- if (!strcmp(options->telemetry_type, "host"))
- generic_structure_parser(ptelemetry_buffer, host_log_page_header,
- ARRAY_SIZE(host_log_page_header), NULL, 0, NULL);
+ if (!strcmp(options->telemetry_type, "host")) {
+ if ((ptelemetry_buffer == NULL) ||
+ (ARRAY_SIZE(host_log_page_header) == 0))
+ printf("skip generic_structure_parser\n");
+ else {
+ generic_structure_parser(ptelemetry_buffer, host_log_page_header,
+ ARRAY_SIZE(host_log_page_header), NULL, 0, NULL);
+ }
+ }
else if (!strcmp(options->telemetry_type, "controller"))
generic_structure_parser(ptelemetry_buffer, controller_log_page_header,
ARRAY_SIZE(controller_log_page_header), NULL, 0, NULL);
@@ -1363,7 +1497,7 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
__u8 *preason_identifier_offset = ptelemetry_buffer +
offsetof(struct nvme_ocp_telemetry_host_initiated_header, reason_id);
generic_structure_parser(preason_identifier_offset, reason_identifier,
- ARRAY_SIZE(reason_identifier), NULL, 0, NULL);
+ ARRAY_SIZE(reason_identifier), NULL, 0, NULL);
printf(STR_LINE);
printf("%s\n", STR_TELEMETRY_HOST_DATA_BLOCK_1);
@@ -1382,7 +1516,7 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
__u8 *pda1_header_offset = ptelemetry_buffer + offsets.da1_start_offset;//512
generic_structure_parser(pda1_header_offset, ocp_header_in_da1,
- ARRAY_SIZE(ocp_header_in_da1), NULL, 0, NULL);
+ ARRAY_SIZE(ocp_header_in_da1), NULL, 0, NULL);
printf(STR_LINE);
printf("%s\n", STR_SMART_HEALTH_INFO);
@@ -1391,7 +1525,7 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
offsetof(struct nvme_ocp_header_in_da1, smart_health_info);
generic_structure_parser(pda1_smart_offset, smart, ARRAY_SIZE(smart), NULL, 0,
- NULL);
+ NULL);
printf(STR_LINE);
printf("%s\n", STR_SMART_HEALTH_INTO_EXTENDED);
@@ -1400,7 +1534,7 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
offsetof(struct nvme_ocp_header_in_da1, smart_health_info_extended);
generic_structure_parser(pda1_smart_ext_offset, smart_extended,
- ARRAY_SIZE(smart_extended), NULL, 0, NULL);
+ ARRAY_SIZE(smart_extended), NULL, 0, NULL);
printf(STR_LINE);
printf("%s\n", STR_DA_1_STATS);
@@ -1564,3 +1698,4 @@ int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
return status;
}
+#endif /* CONFIG_JSONC */
diff --git a/plugins/ocp/ocp-telemetry-decode.h b/plugins/ocp/ocp-telemetry-decode.h
index ed31a6c..ce7de75 100644
--- a/plugins/ocp/ocp-telemetry-decode.h
+++ b/plugins/ocp/ocp-telemetry-decode.h
@@ -3,11 +3,14 @@
*
* Authors: Jeff Lien <jeff.lien@wdc.com>,
*/
+#ifndef OCP_TELEMETRY_DECODE_H
+#define OCP_TELEMETRY_DECODE_H
#include "nvme.h"
#include "nvme-print.h"
#include "util/utils.h"
#include "common.h"
+#include "ocp-nvme.h"
extern __u8 *ptelemetry_buffer;
extern __u8 *pstring_buffer;
@@ -382,7 +385,7 @@ struct telemetry_stats_desc {
__u8 data[];
};
-struct telemetry_event_desc {
+struct __packed telemetry_event_desc {
__u8 class;
__le16 id;
__u8 size;
@@ -399,7 +402,7 @@ struct telemetry_data_area_1 {
__le16 minor_version;
__u8 reserved1[4];
__le64 timestamp;
- __u8 log_page_guid[16];
+ __u8 log_page_guid[GUID_LEN];
__u8 no_of_tps_supp;
__u8 tps;
__u8 reserved2[6];
@@ -428,13 +431,13 @@ struct telemetry_data_area_1 {
#define MAX_NUM_FIFOS 16
#define DA1_OFFSET 512
#define DEFAULT_ASCII_STRING_SIZE 16
+#define SIZE_OF_VU_EVENT_ID 2
#define DEFAULT_TELEMETRY_BIN "telemetry.bin"
#define DEFAULT_STRING_BIN "string.bin"
#define DEFAULT_OUTPUT_FORMAT_JSON "json"
/* C9 Telemetry String Log Format Log Page */
-#define C9_GUID_LENGTH 16
#define C9_TELEMETRY_STRING_LOG_ENABLE_OPCODE 0xC9
#define C9_TELEMETRY_STR_LOG_LEN 432
#define C9_TELEMETRY_STR_LOG_SIST_OFST 431
@@ -566,7 +569,7 @@ enum ocp_telemetry_debug_event_class_types {
struct __packed telemetry_str_log_format {
__u8 log_page_version;
__u8 reserved1[15];
- __u8 log_page_guid[C9_GUID_LENGTH];
+ __u8 log_page_guid[GUID_LEN];
__le64 sls;
__u8 reserved2[24];
__le64 sits;
@@ -778,7 +781,7 @@ struct __packed nvme_ocp_telemetry_smart_extended
__le64 lowest_permitted_firmware_revision; // Bytes 215:208
__u8 reserved4[278]; // Bytes 493:216
__le16 log_page_version; // Bytes 495:494
- __u8 log_page_guid[16]; // Bytes 511:496
+ __u8 log_page_guid[GUID_LEN]; // Bytes 511:496
};
struct __packed nvme_ocp_event_fifo_data
@@ -815,7 +818,7 @@ struct __packed nvme_ocp_header_in_da1
__le16 minor_version; // Bytes 3:2
__le32 reserved1; // Bytes 7:4
__le64 time_stamp; // Bytes 15:8
- __u8 log_page_guid[16]; // Bytes 31:16
+ __u8 log_page_guid[GUID_LEN]; // Bytes 31:16
__u8 num_telemetry_profiles_supported; // Byte 32
__u8 telemetry_profile_selected; // Byte 33
__u8 reserved2[6]; // Bytes 39:34
@@ -856,30 +859,28 @@ struct __packed nvme_ocp_telemetry_event_descriptor
struct __packed nvme_ocp_time_stamp_dbg_evt_class_format
{
__u8 time_stamp[DATA_SIZE_8]; // Bytes 11:4
- __le16 vu_event_identifier; // Bytes 13:12
};
struct __packed nvme_ocp_pcie_dbg_evt_class_format
{
__u8 pCIeDebugEventData[DATA_SIZE_4]; // Bytes 7:4
- __le16 vu_event_identifier; // Bytes 9:8
};
struct __packed nvme_ocp_nvme_dbg_evt_class_format
{
__u8 nvmeDebugEventData[DATA_SIZE_8]; // Bytes 11:4
- __le16 vu_event_identifier; // Bytes 13:12
};
-struct __packed nvme_ocp_common_dbg_evt_class_format
+struct __packed nvme_ocp_media_wear_dbg_evt_class_format
{
- __le16 vu_event_identifier; // Bytes 5:4
+ __u8 currentMediaWear[DATA_SIZE_12]; // Bytes 15:4
+
};
-struct __packed nvme_ocp_media_wear_dbg_evt_class_format
+struct __packed nvme_ocp_common_dbg_evt_class_vu_data
{
- __u8 currentMediaWear[DATA_SIZE_12]; // Bytes 15:4
- __le16 vu_event_identifier; // Bytes 17:16
+ __le16 vu_event_identifier; // Bytes 5:4
+ __u8 data[]; // Bytes N:6
};
struct __packed nvme_ocp_statistic_snapshot_evt_class_format
@@ -918,7 +919,7 @@ struct __packed nvme_ocp_telemetry_string_header
{
__u8 version; //0:0
__u8 reserved1[15]; //15:1
- __u8 guid[16]; //32:16
+ __u8 guid[GUID_LEN]; //32:16
__le64 string_log_size; //39:32
__u8 reserved2[24]; //63:40
__le64 sits; //71:64 Statistics Identifier String Table Start(SITS)
@@ -1226,3 +1227,4 @@ void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descr
void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
struct json_object *pevent_fifos_object, FILE *fp);
+#endif /* OCP_TELEMETRY_DECODE_H */