]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
plugins/micron: Move OCP internal log parsing from Micron to OCP Plugin.
authorChaithanya shoba <ashoba@micron.com>
Sun, 14 Jul 2024 17:29:11 +0000 (22:59 +0530)
committerDaniel Wagner <wagi@monom.org>
Wed, 17 Jul 2024 15:05:26 +0000 (17:05 +0200)
Move OCP internal log parsing from Micron to OCP Plugin. Previous
PR https://github.com/linux-nvme/nvme-cli/pull/2354. Datacenter
NVMe SSD Specification v2.5r9, section 4.9.

Signed-off-by: Chaithanya shoba <ashoba@micron.com>
17 files changed:
Documentation/cmd-plugins.txt
Documentation/meson.build
Documentation/nvme-micron-ocp-telemetry-log-parse.txt [deleted file]
Documentation/nvme-ocp-internal-log.txt [new file with mode: 0644]
completions/_nvme
completions/bash-nvme-completion.sh
plugins/meson.build
plugins/micron/micron-nvme.c
plugins/micron/micron-nvme.h
plugins/micron/micron-ocp-telemetry.c [deleted file]
plugins/micron/micron-ocp-telemetry.h [deleted file]
plugins/ocp/ocp-nvme.c
plugins/ocp/ocp-telemetry-decode.c
plugins/ocp/ocp-telemetry-decode.h
util/meson.build
util/utils.c [moved from plugins/micron/micron-utils.c with 95% similarity]
util/utils.h [moved from plugins/micron/micron-utils.h with 89% similarity]

index 382746563074da07589df9c3766d020f101eff39..338425efaaa80c8369e63733f57f18c08af37093 100644 (file)
@@ -46,8 +46,8 @@ linknvme:nvme-micron-smart-add-log[1]::
 linknvme:nvme-micron-temperature-stats[1]::
        Retrieves temperature information of given micron device
 
-linknvme:nvme-micron-ocp-telemetry-log-parse[1]::
-       Parse OCP Telemetry DA1 and DA2 logs.
+linknvme:nvme-ocp-internal-log[1]::
+       Retrieves and parses OCP Telemetry DA1 and DA2 logs.
 
 linknvme:nvme-netapp-ontapdevices[1]::
        Display information about ONTAP devices
index 22a995fe030332ed03bab3d3af097faeddb58066..30c0efc418a4319e9fe17a982fdf8db613bda583 100644 (file)
@@ -81,7 +81,6 @@ adoc_sources = [
   'nvme-micron-selective-download',
   'nvme-micron-smart-add-log',
   'nvme-micron-temperature-stats',
-  'nvme-micron-ocp-telemetry-log-parse',
   'nvme-netapp-ontapdevices',
   'nvme-netapp-smdevices',
   'nvme-ns-descs',
@@ -105,6 +104,7 @@ adoc_sources = [
   'nvme-ocp-smart-add-log',
   'nvme-ocp-telemetry-string-log-page',
   'nvme-ocp-unsupported-reqs-log-pages',
+  'nvme-ocp-internal-log',
   'nvme-persistent-event-log',
   'nvme-pred-lat-event-agg-log',
   'nvme-predictable-lat-log',
diff --git a/Documentation/nvme-micron-ocp-telemetry-log-parse.txt b/Documentation/nvme-micron-ocp-telemetry-log-parse.txt
deleted file mode 100644 (file)
index 417284f..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-nvme-micron-ocp-telemetry-log-parse(1)
-======================================
-
-NAME
-----
-nvme-micron-ocp-telemetry-log-parse - Parses OCP Telemetry DA1 and DA2 logs.
-
-SYNOPSIS
---------
-[verse]
-'nvme micron ocp-telemetry-log-parse' <device>
-                       [--telemetry-log=<file> | -l <file>]
-                       [--string-log=<file> | -s <file>]
-                       [--output-file=<file> | -o <file>]
-                       [--format=<fmt> | -f <fmt>]
-
-DESCRIPTION
------------
-For the given NVMe device, parses the telemetry log and string log
-(in binary format) and provides the parsed data in json and normal text formats.
-
-The <device> parameter is mandatory and may be either the NVMe
-character device (ex: /dev/nvme0), or a namespace block device (ex:
-/dev/nvme0n1).
-
-This will only work on Micron devices of model numbers 51Bx. Support for new
-devices may be added subsequently. Results for any other device are undefined.
-
-OPTIONS
--------
--l <file>::
---telemetry-log=<file>::
-       This option will allow the users to specify input telemetry-log file name.
-
--o <file>::
---string-log=<file>::
-       This option will allow the users to specify input string-log file name.
-
--o <file>::
---output-file=<file>::
-       This option will allow the users to specify the output file name.
-
--f <fmt>::
---format=<fmt>::
-       Set the reporting format to 'normal', 'json'. Only one output format can be
-       used at a time.
-
-EXAMPLES
---------
-* Parse nvme_host_telemetry_log.bin with nvmelog_ocp_c9.bin and output parsed
-json data into nvme_cli_telemetry_host.json
-+
-------------
-# sudo ./nvme micron ocp-telemetry-log-parse --format=json
- --string-log="nvmelog_ocp_c9.bin" --telemetry-log="nvme_host_telemetry_log.bin"
- --output-file=nvme_cli_telemetry_host.json /dev/nvme0
-------------
-
-* Parse nvme_host_telemetry_log.bin with nvmelog_ocp_c9.bin and output parsed
-text data into nvme_cli_telemetry_host_normal.txt
-+
-------------
-# sudo ./nvme micron ocp-telemetry-log-parse --format=normal
- --string-log="nvmelog_ocp_c9.bin" --telemetry-log="nvme_host_telemetry_log.bin"
- --output-file=nvme_cli_telemetry_host_normal.txt /dev/nvme0
-------------
-
-* Parse nvme_host_telemetry_log.bin with nvmelog_ocp_c9.bin and redirect parsed
-json data into nvme_cli_telemetry_host_console.json
-+
-------------
-#  sudo ./nvme micron ocp-telemetry-log-parse --format=json
- --string-log="nvmelog_ocp_c9.bin" --telemetry-log="nvme_host_telemetry_log.bin"
- > nvme_cli_telemetry_host_console.txt /dev/nvme0
-------------
-
-* Parse nvme_host_telemetry_log.bin with nvmelog_ocp_c9.bin and redirect parsed
-text data into nvme_cli_telemetry_host_console.json
-+
-------------
-# sudo ./nvme micron ocp-telemetry-log-parse --format=normal
- --string-log="nvmelog_ocp_c9.bin" --telemetry-log="nvme_host_telemetry_log.bin"
- > nvme_cli_telemetry_host_console.txt /dev/nvme0
-------------
-
-NVME
-----
-Part of the nvme-user suite
diff --git a/Documentation/nvme-ocp-internal-log.txt b/Documentation/nvme-ocp-internal-log.txt
new file mode 100644 (file)
index 0000000..7393349
--- /dev/null
@@ -0,0 +1,109 @@
+nvme-ocp-internal-log(1)
+========================
+
+NAME
+----
+nvme-ocp-internal-log - Conditionally retrieves 07h Telemetry Host-Initiated
+log, C9h OCP Strings Log from an NVMe device or from user-specified file path.
+Takes retrieved logs and decodes into human-readable output format specified by
+user.
+
+SYNOPSIS
+--------
+[verse]
+'nvme ocp internal-log' <device>
+                       [--telemetry-log=<file> | -l <file>]
+                       [--string-log=<file> | -s <file>]
+                       [--output-file=<file> | -o <file>]
+                       [--output-format=<fmt> | -f <fmt>]
+                       [--data-area=<da> | -a <da>]
+                       [--telemetry-type=<type> | -t <type>]
+
+DESCRIPTION
+-----------
+Conditionally retrieves 07h Telemetry Host-Initiated log, C9h OCP Strings Log
+from an NVMe device or from user-specified file path. Takes retrieved logs and
+decodes (or) parses into human-readable output format specified by user.
+
+The <device> parameter is mandatory and may be either the NVMe
+character device (ex: /dev/nvme0), or a namespace block device (ex:
+/dev/nvme0n1).
+
+This will only work on OCP compliant devices supporting this feature.
+Results for any other device are undefined.
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+-l <file>::
+--telemetry-log=<file>::
+       File name to existing Telemetry Host-Initiated raw binary data to be used.
+       If no path is specified, a live retrieval of payload on <device> will be
+       performed.
+
+-s <file>::
+--string-log=<file>::
+       File name to existing OCP String Log raw binary data to be used. If no path
+       is specified, a live retrieval of payload on <device> will be
+       performed.
+
+-o <file>::
+--output-file=<file>::
+       Filepath name to where human-readable output data will be saved to.
+
+-f <fmt>::
+--output-format=<fmt>::
+       Set the reporting format to 'normal', 'json'. Only one output format can be
+       used at a time, the default value is 'json'.
+
+-a <da>::
+--data-area=<da>::
+       Retrieves the specific data area requested. Valid inputs are 1,2. If this
+       option is not specified, the default value is 1.
+
+-t <type>::
+--telemetry-type=<type>::
+       If set to 1, controller shall capture the Telemetry Host-Initiated data
+       representing the internal state of the controller at the time the associated
+       Get Log Page command is processed. If cleared to 0, controller shall not
+       update this data.
+
+EXAMPLES
+--------
+
+* Retrieve in both OCP String Log and Telemetry Host-Initiated Log from
+device. Decode default data-area(s) in default format and output to console.
++
+----------------------------------
+# nvme ocp internal-log /dev/nvme0
+----------------------------------
+
+* Retrieve Telemetry Host-Initiated data, reads in the OCP String Log locally.
+Decode default data-area(s) in default format.
++
+--------------------------------------------------------------------
+# nvme ocp internal-log /dev/nvme0 --string-log=ocp_string_log.bin
+ --output-file=output_file.json
+--------------------------------------------------------------------
+
+* Retrieve OCP String Log, reads in the Telemetry Host-Initiated Log locally.
+Decode data-areas 1 and 2, and output in json format.
++
+---------------------------------------------------------------------
+# nvme ocp internal-log /dev/nvme0 --telemetry-log=host_telemetry.bin
+ --output-format=json --output-file=output_file.json --data-area=2
+---------------------------------------------------------------------
+
+* Reads in both OCP String Log and Telemetry Host-Initiated Log locally.
+Decode data-areas 1 and 2, and output in normal text format.
++
+------------------------------------------------------------------
+# nvme ocp internal-log /dev/nvme0 --string-log=ocp_string_log.bin
+ --telemetry-log=host_telemetry.bin --output-format=normal
+ --output-file=output_file.txt --data-area=2
+------------------------------------------------------------------
+
+NVME
+----
+Part of the nvme-user suite
index 28786bbdfb850ba8d0ebda7d05e1871f75dde104..fd8e5d5893525a230a6dd3ae4a47c94c9927861a 100644 (file)
@@ -180,12 +180,18 @@ _nvme () {
                                local _internal_log
                                _internal_log=(
                                /dev/nvme':supply a device to use (required)'
-                               --telemetry_type=':Telemetry Type; host (Create bit) or controller'
-                               -t':alias for --telemetry_type'
-                               --telemetry_data_area=':Telemetry Data Area; 1 or 3'
-                               -a':alias for --telemetry_data_area'
+                               --telemetry-type=':Telemetry Type; host or controller generated'
+                               -t':alias for --telemetry-type'
+                               --data-area=':Telemetry Data Area; 1 or 2'
+                               -a':alias for --data-area'
                                --output-file=':Output file name with path'
                                -o':alias for --output-file'
+                               --telemetry-log=':Telemetry log binary'
+                               -l':alias for --telemetry-log'
+                               --string-log=':String log binary'
+                               -s':alias for --string-log'
+                               --output-format':Output format: normal|json'
+                               -f':alias for --output-format'
                                )
                                _arguments '*:: :->subcmds'
                                _describe -t commands "nvme ocp internal-log options" _internal_log
@@ -532,29 +538,6 @@ _nvme () {
                (*)
                        _files
                        ;;
-               esac
-                       ;;
-               (micron)
-                       case ${words[2]} in
-                       (ocp-telemetry-log-parse)
-                               local _ocp-telemetry-log-parse
-                               _ocp-telemetry-log-parse=(
-                               /dev/nvme':supply a device to use (required)'
-                               --output-file=':Output file name with path'
-                               -o':alias for --output-file'
-                               --telemetry-log=':Telemetry log binary'
-                               -l':alias for --telemetry-log'
-                               --string-log=':String log binary'
-                               -s':alias for --string-log'
-                               --format':Output format: normal|json'
-                               -f':alias for --format'
-                               )
-                               _arguments '*:: :->subcmds'
-                               _describe -t commands "nvme micron ocp-telemetry-log-parse" _ocp-telemetry-log-parse
-                               ;;
-               (*)
-                       _files
-                       ;;
                esac
                return
        else
index 00ea5e9b27a1e801a0e97a8a2f42a480546ad9e0..35149c196b38fe89683d436db42f87e8be038632 100644 (file)
@@ -889,10 +889,6 @@ plugin_micron_opts () {
                "vs-smbus-option")
                opts+=" --option= -o --value= -v --save= -s"
                        ;;
-               "ocp-telemetry-log-parse")
-               opts+=" --format= -f --telemetry-log= -l --string-log= -s \
-                       --output-file= -o"
-                       ;;
                "help")
                opts+=$NO_OPTS
                        ;;
@@ -1448,8 +1444,9 @@ plugin_ocp_opts () {
                        --latency_monitor_feature_enable= -e"
                        ;;
                "internal-log")
-               opts+=" --telemetry_type= -t --telemetry_data_area= -a \
-                       --output-file= -o"
+               opts+=" --telemetry-log= -l --string-log= -s \
+                       --output-file= -o --output-format= -f \
+                       --data-area= -a --telemetry-type= -t"
                        ;;
                "clear-fw-activate-history")
                opts+=" --no-uuid -n"
index 45defa06b2321e6c718622e4da9f122f993af552..146fa2a0ad35a40e40af389a0af09baa8658e90e 100644 (file)
@@ -11,8 +11,6 @@ if json_c_dep.found()
     'plugins/inspur/inspur-nvme.c',
     'plugins/intel/intel-nvme.c',
     'plugins/memblaze/memblaze-nvme.c',
-    'plugins/micron/micron-utils.c',
-    'plugins/micron/micron-ocp-telemetry.c',
     'plugins/micron/micron-nvme.c',
     'plugins/nbft/nbft-plugin.c',
     'plugins/netapp/netapp-nvme.c',
index dcb3748fa8cf8b0d78e1a50d9375f00d585a8f1a..27825953c929f17eb4148642e52b0d7e44dff80f 100644 (file)
@@ -7,7 +7,27 @@
  * @authors:Chaithanya Shoba <ashoba@micron.com>,
  */
 
-#include "micron-ocp-telemetry.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <libgen.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "common.h"
+#include "nvme.h"
+#include "libnvme.h"
+#include <limits.h>
+#include "linux/types.h"
+#include "nvme-print.h"
+#include "util/cleanup.h"
+#include "util/utils.h"
 
 #define CREATE_CMD
 #include "micron-nvme.h"
@@ -1183,7 +1203,7 @@ static void init_d0_log_page(__u8 *buf, __u8 nsze)
 }
 
 /* Smart Health Log information as per OCP spec M51CX models */
-struct micron_vs_logpage ocp_c0_log_page[] = {
+struct request_data ocp_c0_log_page[] = {
        { "Physical Media Units Written", 16},
        { "Physical Media Units Read", 16 },
        { "Raw Bad User NAND Block Count", 6},
@@ -1317,7 +1337,7 @@ static void print_smart_cloud_health_log(__u8 *buf, bool is_json)
                                            logPages);
        }
 
-       print_micron_vs_logs(buf, ocp_c0_log_page, field_count, stats, 0, NULL);
+       generic_structure_parser(buf, ocp_c0_log_page, field_count, stats, 0, NULL);
 
        if (is_json) {
                json_array_add_value_object(logPages, stats);
@@ -1342,7 +1362,7 @@ static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json,
                                            logPages);
        }
 
-       print_micron_vs_logs(buf, fb_log_page, field_count, stats, spec, NULL);
+       generic_structure_parser(buf, fb_log_page, field_count, stats, spec, NULL);
 
        /* print last three entries from D0 log page */
        if (buf2) {
@@ -1496,7 +1516,7 @@ static void print_ext_smart_logs_e1(__u8 *buf, bool is_json)
                printf("SMART Extended Log:0xE1\n");
        }
 
-       print_micron_vs_logs(buf, e1_log_page, field_count, stats, 0, NULL);
+       generic_structure_parser(buf, e1_log_page, field_count, stats, 0, NULL);
 
        if (is_json) {
                json_array_add_value_object(logPages, stats);
@@ -3274,47 +3294,3 @@ static int micron_logpage_dir(int argc, char **argv, struct command *cmd,
 
        return err;
 }
-
-static int micron_ocp_telemetry_log_parse(int argc, char **argv,
-                                         struct command *cmd, struct plugin *plugin)
-{
-       const char *desc = "Parse OCP Telemetry DA1 and DA2 logs.";
-       const char *output_fmt = "output format normal|json";
-       const char *telemetry_log = "Telemetry log binary;\n 'host.bin' or 'controller.bin'";
-       const char *string_log = "String log binary; 'C9.bin'";
-       const char *output_file = "Output file name with path;\n"
-                       "e.g. '-o ./path/name'\n'-o ./path1/path2/';\n"
-                       "If requested path doesn't exist, the file will be newly created.";
-       enum eDriveModel eModel = UNKNOWN_MODEL;
-       int err = 0;
-       struct nvme_dev *dev;
-       struct ocp_telemetry_parse_options opt;
-
-       OPT_ARGS(opts) = {
-               OPT_STR("telemetry-log", 'l', &opt.telemetry_log, telemetry_log),
-               OPT_STR("string-log", 's', &opt.string_log, string_log),
-               OPT_FILE("output-file", 'o', &opt.output_file, output_file),
-               OPT_FMT("format", 'f', &opt.output_fmt, output_fmt),
-               OPT_END()
-       };
-
-       err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel);
-       if (err < 0)
-               return -1;
-
-       if (!opt.telemetry_log) {
-               nvme_show_result("\nMissing telemetry-log.\n");
-               return -1;
-       } else if (!opt.string_log) {
-               nvme_show_result("\nMissing string-log. Skipping adding string data.\n");
-       } else if (!opt.output_fmt) {
-               nvme_show_result("\nMissing format. Using default format - JSON.\n");
-       }
-
-       err = parse_ocp_telemetry_log(&opt);
-
-       dev_close(dev);
-       if (err != 0)
-               nvme_show_status(err);
-       return err;
-}
index 91fc2c8da24af05e3559a361cf1215f0892c5279..c9e3ca7a6a806eb7662a5354e7d840622d7c8b55 100644 (file)
@@ -35,8 +35,6 @@ PLUGIN(NAME("micron", "Micron vendor specific extensions", NVME_VERSION),
                ENTRY("vs-smart-add-log", "Retrieve extended SMART data", micron_ocp_smart_health_logs)
                ENTRY("clear-fw-activate-history", "Clear FW activation history", micron_clr_fw_activation_history)
                ENTRY("vs-smbus-option", "Enable/Disable SMBUS on the drive", micron_smbus_option)
-               ENTRY("ocp-telemetry-log-parse", "Parse OCP Telemetry DA1 and DA2 logs",
-                       micron_ocp_telemetry_log_parse)
        )
 );
 
diff --git a/plugins/micron/micron-ocp-telemetry.c b/plugins/micron/micron-ocp-telemetry.c
deleted file mode 100644 (file)
index b177722..0000000
+++ /dev/null
@@ -1,1416 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) Micron, Inc 2024.
- *
- * @file: micron-ocp-telemetry.c
- * @brief: This module contains all the constructs needed for parsing (or)
- *  decoding ocp telemetry log files.
- * @author: Chaithanya Shoba <ashoba@micron.com>
- */
-
-#include "micron-ocp-telemetry.h"
-
-//global buffers
-static unsigned char *ptelemetry_buffer;
-static unsigned char *pstring_buffer;
-
-struct statistic_entry statistic_identifiers_map[] = {
-       { 0x00, "Error, this entry does not exist." },
-       { 0x01, "Outstanding Admin Commands" },
-       { 0x02, "Host Write Bandwidth"},
-       { 0x03, "GC Write Bandwidth"},
-       { 0x04, "Active Namespaces"},
-       { 0x05, "Internal Write Workload"},
-       { 0x06, "Internal Read Workload"},
-       { 0x07, "Internal Write Queue Depth"},
-       { 0x08, "Internal Read Queue Depth"},
-       { 0x09, "Pending Trim LBA Count"},
-       { 0x0A, "Host Trim LBA Request Count"},
-       { 0x0B, "Current NVMe Power State"},
-       { 0x0C, "Current DSSD Power State"},
-       { 0x0D, "Program Fail Count"},
-       { 0x0E, "Erase Fail Count"},
-       { 0x0F, "Read Disturb Writes"},
-       { 0x10, "Retention Writes"},
-       { 0x11, "Wear Leveling Writes"},
-       { 0x12, "Read Recovery Writes"},
-       { 0x13, "GC Writes"},
-       { 0x14, "SRAM Correctable Count"},
-       { 0x15, "DRAM Correctable Count"},
-       { 0x16, "SRAM Uncorrectable Count"},
-       { 0x17, "DRAM Uncorrectable Count"},
-       { 0x18, "Data Integrity Error Count"},
-       { 0x19, "Read Retry Error Count"},
-       { 0x1A, "PERST Events Count"},
-       { 0x1B, "Max Die Bad Block"},
-       { 0x1C, "Max NAND Channel Bad Block"},
-       { 0x1D, "Minimum NAND Channel Bad Block"}
-};
-
-struct micron_vs_logpage host_log_page_header[] = {
-       { "LogIdentifier", 1 },
-       { "Reserved1", 4 },
-       { "IEEE OUI Identifier", 3 },
-       { "Telemetry Host-Initiated Data Area 1 Last Block", 2 },
-       { "Telemetry Host-Initiated Data Area 2 Last Block", 2 },
-       { "Telemetry Host-Initiated Data Area 3 Last Block", 2 },
-       { "Reserved2", 2 },
-       { "Telemetry Host-Initiated Data Area 4 Last Block", 4 },
-       { "Reserved3", 360 },
-       { "Telemetry Host-Initiated Scope", 1 },
-       { "Telemetry Host Initiated Generation Number", 1 },
-       { "Telemetry Host-Initiated Data Available", 1 },
-       { "Telemetry Controller-Initiated Data Generation Number", 1 }
-};
-
-struct micron_vs_logpage controller_log_page_header[] = {
-       { "LogIdentifier", 1 },
-       { "Reserved1", 4 },
-       { "IEEE OUI Identifier", 3 },
-       { "Telemetry Host-Initiated Data Area 1 Last Block", 2 },
-       { "Telemetry Host-Initiated Data Area 2 Last Block", 2 },
-       { "Telemetry Host-Initiated Data Area 3 Last Block", 2 },
-       { "Reserved2", 2 },
-       { "Telemetry Host-Initiated Data Area 4 Last Block", 4 },
-       { "Reserved3", 361 },
-       { "Telemetry Controller-Initiated Scope", 1 },
-       { "Telemetry Controller-Initiated Data Available", 1 },
-       { "Telemetry Controller-Initiated Data Generation Number", 1 }
-};
-
-struct micron_vs_logpage reason_identifier[] = {
-       { "Error ID", 64 },
-       { "File ID", 8 },
-       { "Line Number", 2 },
-       { "Valid Flags", 1 },
-       { "Reserved", 21 },
-       { "VU Reason Extension", 32 }
-};
-
-struct micron_vs_logpage ocp_header_in_da1[] = {
-       { "Major Version", 2 },
-       { "Minor Version", 2 },
-       { "Reserved1", 4 },
-       { "Timestamp", 8 },
-       { "Log page GUID", 16 },
-       { "Number Telemetry Profiles Supported", 1 },
-       { "Telemetry Profile Selected", 1 },
-       { "Reserved2", 6 },
-       { "Telemetry String Log Size", 8 },
-       { "Reserved3", 8 },
-       { "Firmware Revision", 8 },
-       { "Reserved4", 32 },
-       { "Data Area 1 Statistic Start", 8 },
-       { "Data Area 1 Statistic Size", 8 },
-       { "Data Area 2 Statistic Start", 8 },
-       { "Data Area 2 Statistic Size", 8 },
-       { "Reserved5", 32 },
-       { "Event FIFO 1 Data Area", 1 },
-       { "Event FIFO 2 Data Area", 1 },
-       { "Event FIFO 3 Data Area", 1 },
-       { "Event FIFO 4 Data Area", 1 },
-       { "Event FIFO 5 Data Area", 1 },
-       { "Event FIFO 6 Data Area", 1 },
-       { "Event FIFO 7 Data Area", 1 },
-       { "Event FIFO 8 Data Area", 1 },
-       { "Event FIFO 9 Data Area", 1 },
-       { "Event FIFO 10 Data Area", 1 },
-       { "Event FIFO 11 Data Area", 1 },
-       { "Event FIFO 12 Data Area", 1 },
-       { "Event FIFO 13 Data Area", 1 },
-       { "Event FIFO 14 Data Area", 1 },
-       { "Event FIFO 15 Data Area", 1 },
-       { "Event FIFO 16 Data Area", 1 },
-       { "Event FIFO 1 Start", 8 },
-       { "Event FIFO 1 Size", 8 },
-       { "Event FIFO 2 Start", 8 },
-       { "Event FIFO 2 Size", 8 },
-       { "Event FIFO 3 Start", 8 },
-       { "Event FIFO 3 Size", 8 },
-       { "Event FIFO 4 Start", 8 },
-       { "Event FIFO 4 Size", 8 },
-       { "Event FIFO 5 Start", 8 },
-       { "Event FIFO 5 Size", 8 },
-       { "Event FIFO 6 Start", 8 },
-       { "Event FIFO 6 Size", 8 },
-       { "Event FIFO 7 Start", 8 },
-       { "Event FIFO 7 Size", 8 },
-       { "Event FIFO 8 Start", 8 },
-       { "Event FIFO 8 Size", 8 },
-       { "Event FIFO 9 Start", 8 },
-       { "Event FIFO 9 Size", 8 },
-       { "Event FIFO 10 Start", 8 },
-       { "Event FIFO 10 Size", 8 },
-       { "Event FIFO 11 Start", 8 },
-       { "Event FIFO 11 Size", 8 },
-       { "Event FIFO 12 Start", 8 },
-       { "Event FIFO 12 Size", 8 },
-       { "Event FIFO 13 Start", 8 },
-       { "Event FIFO 13 Size", 8 },
-       { "Event FIFO 14 Start", 8 },
-       { "Event FIFO 14 Size", 8 },
-       { "Event FIFO 15 Start", 8 },
-       { "Event FIFO 15 Size", 8 },
-       { "Event FIFO 16 Start", 8 },
-       { "Event FIFO 16 Size", 8 },
-       { "Reserved6", 80 }
-};
-
-struct micron_vs_logpage smart[] = {
-       { "Critical Warning", 1 },
-       { "Composite Temperature", 2 },
-       { "Available Spare", 1 },
-       { "Available Spare Threshold", 1 },
-       { "Percentage Used", 1 },
-       { "Reserved1", 26 },
-       { "Data Units Read", 16 },
-       { "Data Units Written", 16 },
-       { "Host Read Commands", 16 },
-       { "Host Write Commands", 16 },
-       { "Controller Busy Time", 16 },
-       { "Power Cycles", 16 },
-       { "Power On Hours", 16 },
-       { "Unsafe Shutdowns", 16 },
-       { "Media and Data Integrity Errors", 16 },
-       { "Number of Error Information Log Entries", 16 },
-       { "Warning Composite Temperature Time", 4 },
-       { "Critical Composite Temperature Time", 4 },
-       { "Temperature Sensor 1", 2 },
-       { "Temperature Sensor 2", 2 },
-       { "Temperature Sensor 3", 2 },
-       { "Temperature Sensor 4", 2 },
-       { "Temperature Sensor 5", 2 },
-       { "Temperature Sensor 6", 2 },
-       { "Temperature Sensor 7", 2 },
-       { "Temperature Sensor 8", 2 },
-       { "Thermal Management Temperature 1 Transition Count", 4 },
-       { "Thermal Management Temperature 2 Transition Count", 4 },
-       { "Total Time for Thermal Management Temperature 1", 4 },
-       { "Total Time for Thermal Management Temperature 2", 4 },
-       { "Reserved2", 280 }
-};
-
-struct micron_vs_logpage smart_extended[] = {
-       { "Physical Media Units Written", 16 },
-       { "Physical Media Units Read", 16 },
-       { "Bad User NAND Blocks Raw Count", 6 },
-       { "Bad User NAND Blocks Normalized Value", 2 },
-       { "Bad System NAND Blocks Raw Count", 6 },
-       { "Bad System NAND Blocks Normalized Value", 2 },
-       { "XOR Recovery Count", 8 },
-       { "Uncorrectable Read Error Count", 8 },
-       { "Soft ECC Error Count", 8 },
-       { "End to End Correction Counts Detected Errors", 4 },
-       { "End to End Correction Counts Corrected Errors", 4 },
-       { "System Data Percent Used", 1 },
-       { "Refresh Counts", 7 },
-       { "Maximum User Data Erase Count", 4 },
-       { "Minimum User Data Erase Count", 4 },
-       { "Number of thermal throttling events", 1 },
-       { "Current Throttling Status", 1 },
-       { "Errata Version Field", 1 },
-       { "Point Version Field", 2 },
-       { "Minor Version Field", 2 },
-       { "Major Version Field", 1 },
-       { "PCIe Correctable Error Count", 8 },
-       { "Incomplete Shutdowns", 4 },
-       { "Reserved1", 4 },
-       { "Percent Free Blocks", 1 },
-       { "Reserved2", 7 },
-       { "Capacitor Health", 2 },
-       { "NVMe Base Errata Version", 1 },
-       { "NVMe Command Set Errata Version", 1 },
-       { "Reserved3", 4 },
-       { "Unaligned IO", 8 },
-       { "Security Version Number", 8 },
-       { "Total NUSE", 8 },
-       { "PLP Start Count", 16 },
-       { "Endurance Estimate", 16 },
-       { "PCIe Link Retraining Count", 8 },
-       { "Power State Change Count", 8 },
-       { "Lowest Permitted Firmware Revision", 8 },
-       { "Reserved4", 278 },
-       { "Log Page Version", 2 },
-       { "Log page GUID", 16 }
-};
-
-void json_add_formatted_u32_str(struct json_object *pobject, const char *msg, unsigned int pdata)
-{
-       char data_str[70] = { 0 };
-
-       sprintf(data_str, "0x%x", pdata);
-       json_object_add_value_string(pobject, msg, data_str);
-}
-
-void json_add_formatted_var_size_str(struct json_object *pobject, const char *msg, __u8 *pdata,
-       unsigned int data_size)
-{
-       char description_str[256] = "";
-       char temp_buffer[3] = { 0 };
-
-       for (size_t i = 0; i < data_size; ++i) {
-               sprintf(temp_buffer, "%02X", pdata[i]);
-               strcat(description_str, temp_buffer);
-       }
-
-       json_object_add_value_string(pobject, msg, description_str);
-}
-
-int get_telemetry_das_offset_and_size(
-       struct nvme_ocp_telemetry_common_header *ptelemetry_common_header,
-       struct nvme_ocp_telemetry_offsets *ptelemetry_das_offset)
-{
-       if (NULL == ptelemetry_common_header || NULL == ptelemetry_das_offset) {
-               nvme_show_error("Invalid input arguments.");
-               return -1;
-       }
-
-       if (ptelemetry_common_header->log_id == NVME_HOST_TELEMETRY_LOG)
-               ptelemetry_das_offset->header_size =
-               sizeof(struct nvme_ocp_telemetry_host_initiated_header);
-       else if (ptelemetry_common_header->log_id == NVME_CNTRL_TELEMETRY_LOG)
-               ptelemetry_das_offset->header_size =
-               sizeof(struct nvme_ocp_telemetry_controller_initiated_header);
-       else
-               return -1;
-
-       ptelemetry_das_offset->da1_start_offset = ptelemetry_das_offset->header_size;
-       ptelemetry_das_offset->da1_size = ptelemetry_common_header->da1_last_block *
-               OCP_TELEMETRY_DATA_BLOCK_SIZE;
-
-       ptelemetry_das_offset->da2_start_offset = ptelemetry_das_offset->da1_start_offset +
-               ptelemetry_das_offset->da1_size;
-       ptelemetry_das_offset->da2_size =
-               (ptelemetry_common_header->da2_last_block -
-               ptelemetry_common_header->da1_last_block) * OCP_TELEMETRY_DATA_BLOCK_SIZE;
-
-       ptelemetry_das_offset->da3_start_offset = ptelemetry_das_offset->da2_start_offset +
-               ptelemetry_das_offset->da2_size;
-       ptelemetry_das_offset->da3_size =
-               (ptelemetry_common_header->da3_last_block -
-               ptelemetry_common_header->da2_last_block) * OCP_TELEMETRY_DATA_BLOCK_SIZE;
-
-       ptelemetry_das_offset->da4_start_offset = ptelemetry_das_offset->da3_start_offset +
-               ptelemetry_das_offset->da3_size;
-       ptelemetry_das_offset->da4_size =
-               (ptelemetry_common_header->da4_last_block -
-               ptelemetry_common_header->da3_last_block) * OCP_TELEMETRY_DATA_BLOCK_SIZE;
-
-       return 0;
-}
-
-int get_static_id_ascii_string(int identifier, char *description)
-{
-       if (pstring_buffer == NULL)
-               return -1;
-
-       struct nvme_ocp_telemetry_string_header *pocp_ts_header =
-               (struct nvme_ocp_telemetry_string_header *)pstring_buffer;
-
-       //Calculating the sizes of the tables. Note: Data is present in the form of DWORDS,
-       //So multiplying with sizeof(DWORD)
-       unsigned long long sits_table_size = (pocp_ts_header->sitsz) * SIZE_OF_DWORD;
-
-       //Calculating number of entries present in all 3 tables
-       int sits_entries = (int)sits_table_size /
-               sizeof(struct nvme_ocp_statistics_identifier_string_table);
-
-       for (int sits_entry = 0; sits_entry < sits_entries; sits_entry++) {
-               struct nvme_ocp_statistics_identifier_string_table
-                       *peach_statistic_entry =
-                       (struct nvme_ocp_statistics_identifier_string_table *)
-                       (pstring_buffer + (pocp_ts_header->sits * SIZE_OF_DWORD) +
-                       (sits_entry *
-                       sizeof(struct nvme_ocp_statistics_identifier_string_table)));
-
-               if (identifier == (int)peach_statistic_entry->vs_statistic_identifier) {
-                       char *pdescription = (char *)(pstring_buffer +
-                               (pocp_ts_header->ascts * SIZE_OF_DWORD) +
-                               (peach_statistic_entry->ascii_id_offset *
-                               SIZE_OF_DWORD));
-
-                       memcpy(description, pdescription,
-                              peach_statistic_entry->ascii_id_length + 1);
-
-                       // If ASCII string isn't found, see in our internal Map
-                       // for 2.5 Spec defined strings (id < 0x1D).
-                       if ((description == NULL) && (identifier < 0x1D))
-                               memcpy(description,
-                                      statistic_identifiers_map[identifier].description,
-                                      peach_statistic_entry->ascii_id_length + 1);
-                       return 0;
-               }
-       }
-
-       return -1;
-}
-
-int get_event_id_ascii_string(int identifier, int debug_event_class, char *description)
-{
-       if (pstring_buffer == NULL)
-               return -1;
-
-       struct nvme_ocp_telemetry_string_header *pocp_ts_header =
-               (struct nvme_ocp_telemetry_string_header *)pstring_buffer;
-
-       //Calculating the sizes of the tables. Note: Data is present in the form of DWORDS,
-       //So multiplying with sizeof(DWORD)
-       unsigned long long ests_table_size = (pocp_ts_header->estsz) * SIZE_OF_DWORD;
-
-       //Calculating number of entries present in all 3 tables
-       int ests_entries = (int)ests_table_size / sizeof(struct nvme_ocp_event_string_table);
-
-       for (int ests_entry = 0; ests_entry < ests_entries; ests_entry++) {
-               struct nvme_ocp_event_string_table *peach_event_entry =
-                       (struct nvme_ocp_event_string_table *)
-                       (pstring_buffer + (pocp_ts_header->ests * SIZE_OF_DWORD) +
-                       (ests_entry * sizeof(struct nvme_ocp_event_string_table)));
-
-               if (identifier == (int)peach_event_entry->event_identifier &&
-                       debug_event_class == (int)peach_event_entry->debug_event_class) {
-                       char *pdescription = (char *)(pstring_buffer +
-                               (pocp_ts_header->ascts * SIZE_OF_DWORD) +
-                               (peach_event_entry->ascii_id_offset * SIZE_OF_DWORD));
-
-                       memcpy(description, pdescription,
-                              peach_event_entry->ascii_id_length + 1);
-                       return 0;
-               }
-       }
-
-       return -1;
-}
-
-int get_vu_event_id_ascii_string(int identifier, int debug_event_class, char *description)
-{
-       if (pstring_buffer == NULL)
-               return -1;
-
-       struct nvme_ocp_telemetry_string_header *pocp_ts_header =
-               (struct nvme_ocp_telemetry_string_header *)pstring_buffer;
-
-       //Calculating the sizes of the tables. Note: Data is present in the form of DWORDS,
-       //So multiplying with sizeof(DWORD)
-       unsigned long long vuests_table_size = (pocp_ts_header->vu_estsz) * SIZE_OF_DWORD;
-
-       //Calculating number of entries present in all 3 tables
-       int vu_ests_entries = (int)vuests_table_size /
-               sizeof(struct nvme_ocp_vu_event_string_table);
-
-       for (int vu_ests_entry = 0; vu_ests_entry < vu_ests_entries; vu_ests_entry++) {
-               struct nvme_ocp_vu_event_string_table *peach_vu_event_entry =
-                       (struct nvme_ocp_vu_event_string_table *)
-                       (pstring_buffer + (pocp_ts_header->vu_ests * SIZE_OF_DWORD) +
-                       (vu_ests_entry * sizeof(struct nvme_ocp_vu_event_string_table)));
-
-               if (identifier == (int)peach_vu_event_entry->vu_event_identifier &&
-                       debug_event_class ==
-                               (int)peach_vu_event_entry->debug_event_class) {
-                       char *pdescription = (char *)(pstring_buffer +
-                               (pocp_ts_header->ascts * SIZE_OF_DWORD) +
-                               (peach_vu_event_entry->ascii_id_offset * SIZE_OF_DWORD));
-
-                       memcpy(description, pdescription,
-                              peach_vu_event_entry->ascii_id_length + 1);
-                       return 0;
-               }
-       }
-
-       return -1;
-}
-
-int parse_ocp_telemetry_string_log(int event_fifo_num, int identifier, int debug_event_class,
-       enum ocp_telemetry_string_tables string_table, char *description)
-{
-       if (pstring_buffer == NULL)
-               return -1;
-
-       if (event_fifo_num != 0) {
-               struct nvme_ocp_telemetry_string_header *pocp_ts_header =
-                       (struct nvme_ocp_telemetry_string_header *)pstring_buffer;
-
-               if (*pocp_ts_header->fifo_ascii_string[event_fifo_num-1] != '\0')
-                       memcpy(description, pocp_ts_header->fifo_ascii_string[event_fifo_num-1],
-                              16);
-               else
-                       description = "";
-
-               return 0;
-       }
-
-       if (string_table == STATISTICS_IDENTIFIER_STRING)
-               get_static_id_ascii_string(identifier, description);
-       else if (string_table == EVENT_STRING)
-               get_event_id_ascii_string(identifier, debug_event_class, description);
-       else if (string_table == VU_EVENT_STRING)
-               get_vu_event_id_ascii_string(identifier, debug_event_class, description);
-
-       return 0;
-}
-
-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);
-
-       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);
-
-       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);
-       } 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);
-               } 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);
-               }
-       }
-}
-
-void parse_pcie_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_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);
-       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);
-
-       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);
-       } 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);
-               } 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);
-               }
-       }
-}
-
-void parse_nvme_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_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);
-       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);
-
-       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);
-       } 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);
-               } 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);
-               }
-       }
-}
-
-void parse_common_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_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);
-               } 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);
-               }
-       }
-}
-
-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)
-{
-       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] = "";
-
-       parse_ocp_telemetry_string_log(0, pmedia_wear_event->vu_event_identifier,
-                                       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);
-       } 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);
-               } 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);
-               }
-       }
-}
-
-int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
-       struct json_object *pevent_fifos_object, unsigned char *pstring_buffer,
-       struct nvme_ocp_telemetry_offsets *poffsets, __u64 fifo_size, FILE *fp)
-{
-       if (NULL == pfifo_start || NULL == poffsets) {
-               nvme_show_error("Input buffer was NULL");
-               return -1;
-       }
-
-       int status = 0;
-       unsigned int event_fifo_number = fifo_num + 1;
-       char *description = (char *)malloc((40 + 1) * sizeof(char));
-
-       memset(description, 0, sizeof(40));
-
-       status =
-               parse_ocp_telemetry_string_log(event_fifo_number, 0, 0, EVENT_STRING, description);
-
-       if (status != 0) {
-               nvme_show_error("Failed to get C9 String. status: %d\n", status);
-               return -1;
-       }
-
-       char event_fifo_name[100] = {0};
-
-       snprintf(event_fifo_name, sizeof(event_fifo_name), "%s%d%s%s", "EVENT FIFO ",
-                event_fifo_number, " - ", description);
-
-       struct json_object *pevent_fifo_array = NULL;
-
-       if (pevent_fifos_object != NULL)
-               pevent_fifo_array = json_create_array();
-       else {
-               char buffer[1024] = {0};
-
-               sprintf(buffer, "%s%s\n%s", STR_LINE, event_fifo_name, STR_LINE);
-               if (fp)
-                       fprintf(fp, "%s", buffer);
-               else
-                       printf("%s", buffer);
-       }
-
-       int offset_to_move = 0;
-       unsigned int event_des_size = sizeof(struct nvme_ocp_telemetry_event_descriptor);
-
-       while ((fifo_size > 0) && (offset_to_move < fifo_size)) {
-               struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor =
-                       (struct nvme_ocp_telemetry_event_descriptor *)
-                       (pfifo_start + offset_to_move);
-
-               if (pevent_descriptor != NULL && pevent_descriptor->event_data_size >= 0) {
-                       //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;
-
-                       char description_str[256] = "";
-
-                       parse_ocp_telemetry_string_log(0, pevent_descriptor->event_id,
-                               pevent_descriptor->debug_event_class_type, EVENT_STRING,
-                               description_str);
-
-                       struct json_object *pevent_descriptor_obj =
-                               ((pevent_fifos_object != NULL)?json_create_object():NULL);
-
-                       if (pevent_descriptor_obj != NULL) {
-                               json_add_formatted_u32_str(pevent_descriptor_obj,
-                                       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);
-                               json_object_add_value_string(pevent_descriptor_obj,
-                                       STR_EVENT_STRING, description_str);
-                               json_add_formatted_u32_str(pevent_descriptor_obj,
-                                       STR_EVENT_DATA_SIZE, pevent_descriptor->event_data_size);
-
-                               if (pevent_descriptor->debug_event_class_type >= 0x80)
-                                       json_add_formatted_var_size_str(pevent_descriptor_obj,
-                                               STR_VU_DATA, pevent_specific_data, data_size);
-                       } else {
-                               if (fp) {
-                                       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);
-                                       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);
-                                       printf("%s: 0x%x\n", STR_EVENT_IDENTIFIER,
-                                              pevent_descriptor->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);
-                               }
-
-                               if (pevent_descriptor->debug_event_class_type >= 0x80)
-                                       print_formatted_var_size_str(STR_VU_DATA,
-                                               pevent_specific_data, data_size, fp);
-                       }
-
-                       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);
-                               break;
-                       case PCIE_CLASS_TYPE:
-                               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);
-                               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);
-                               break;
-                       case MEDIA_WEAR_CLASS_TYPE:
-                               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
-                               *pStaticSnapshotEvent =
-                                       (struct nvme_ocp_statistic_snapshot_evt_class_format *)
-                                       pevent_specific_data;
-                               struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_entry =
-                                       (struct nvme_ocp_telemetry_statistic_descriptor *)
-                                       (&pStaticSnapshotEvent->statisticDescriptorData);
-
-                               parse_statistic(pstatistic_entry, pevent_descriptor_obj, fp);
-                               break;
-                       }
-                       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;
-
-       offset_to_move += (pevent_descriptor->event_data_size * SIZE_OF_DWORD + event_des_size);
-       }
-
-       if (pevent_fifos_object != NULL && pevent_fifo_array != NULL)
-               json_object_add_value_array(pevent_fifos_object, event_fifo_name,
-                       pevent_fifo_array);
-
-       free(description);
-       return 0;
-}
-
-int parse_event_fifos(struct json_object *root, struct nvme_ocp_telemetry_offsets *poffsets,
-       FILE *fp)
-{
-       if (poffsets == NULL) {
-               nvme_show_error("Input buffer was NULL");
-               return -1;
-       }
-
-       struct json_object *pevent_fifos_object = NULL;
-
-       if (root != NULL)
-               pevent_fifos_object = json_create_object();
-
-       __u8 *pda1_header_offset = ptelemetry_buffer + poffsets->da1_start_offset;//512
-       __u8 *pda2_offset = ptelemetry_buffer + poffsets->da2_start_offset;
-       struct nvme_ocp_header_in_da1 *pda1_header = (struct nvme_ocp_header_in_da1 *)
-               pda1_header_offset;
-       struct nvme_ocp_event_fifo_data event_fifo[MAX_NUM_FIFOS];
-
-       for (int fifo_num = 0; fifo_num < MAX_NUM_FIFOS; fifo_num++) {
-               event_fifo[fifo_num].event_fifo_num = fifo_num;
-               event_fifo[fifo_num].event_fifo_da = pda1_header->event_fifo_da[fifo_num];
-               event_fifo[fifo_num].event_fifo_start =
-                       pda1_header->fifo_offsets[fifo_num].event_fifo_start;
-               event_fifo[fifo_num].event_fifo_size =
-                       pda1_header->fifo_offsets[fifo_num].event_fifo_size;
-       }
-
-       //Parse all the FIFOs DA wise
-       for (int fifo_no = 0; fifo_no < MAX_NUM_FIFOS; fifo_no++) {
-               if (event_fifo[fifo_no].event_fifo_da == poffsets->data_area) {
-                       __u64 fifo_offset =
-                               (event_fifo[fifo_no].event_fifo_start  * SIZE_OF_DWORD);
-                       __u64 fifo_size =
-                               (event_fifo[fifo_no].event_fifo_size  * SIZE_OF_DWORD);
-                       __u8 *pfifo_start = NULL;
-
-                       if (event_fifo[fifo_no].event_fifo_da == 1)
-                               pfifo_start = pda1_header_offset + fifo_offset;
-                       else if (event_fifo[fifo_no].event_fifo_da == 2)
-                               pfifo_start = pda2_offset + fifo_offset;
-                       else {
-                               nvme_show_error("Unsupported Data Area:[%d]", poffsets->data_area);
-                               return -1;
-                       }
-
-                       int status = parse_event_fifo(fifo_no, pfifo_start, pevent_fifos_object,
-                                                     pstring_buffer, poffsets, fifo_size, fp);
-
-                       if (status != 0) {
-                               nvme_show_error("Failed to parse Event FIFO. status:%d\n", status);
-                               return -1;
-                       }
-               }
-       }
-
-       if (pevent_fifos_object != NULL && root != NULL) {
-               const char *data_area = (poffsets->data_area == 1 ? STR_DA_1_EVENT_FIFO_INFO :
-                                       STR_DA_2_EVENT_FIFO_INFO);
-
-               json_object_add_value_array(root, data_area, pevent_fifos_object);
-       }
-
-       return 0;
-}
-
-int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_entry,
-                   struct json_object *pstats_array, FILE *fp)
-{
-       if (pstatistic_entry == NULL) {
-               nvme_show_error("Input buffer was NULL");
-               return -1;
-       }
-
-       unsigned int data_size = pstatistic_entry->statistic_data_size * SIZE_OF_DWORD;
-       __u8 *pdata = (__u8 *)pstatistic_entry +
-               sizeof(struct nvme_ocp_telemetry_statistic_descriptor);
-       char description_str[256] = "";
-
-       parse_ocp_telemetry_string_log(0, pstatistic_entry->statistic_id, 0,
-               STATISTICS_IDENTIFIER_STRING, description_str);
-
-       if (pstats_array != NULL) {
-               struct json_object *pstatistics_object = json_create_object();
-
-               json_add_formatted_u32_str(pstatistics_object, STR_STATISTICS_IDENTIFIER,
-                       pstatistic_entry->statistic_id);
-               json_object_add_value_string(pstatistics_object, STR_STATISTICS_IDENTIFIER_STR,
-                       description_str);
-               json_add_formatted_u32_str(pstatistics_object,
-                       STR_STATISTICS_INFO_BEHAVIOUR_TYPE,
-                       pstatistic_entry->statistic_info_behaviour_type);
-               json_add_formatted_u32_str(pstatistics_object, STR_STATISTICS_INFO_RESERVED,
-                       pstatistic_entry->statistic_info_reserved);
-               json_add_formatted_u32_str(pstatistics_object, STR_NAMESPACE_IDENTIFIER,
-                       pstatistic_entry->ns_info_nsid);
-               json_add_formatted_u32_str(pstatistics_object, STR_NAMESPACE_INFO_VALID,
-                       pstatistic_entry->ns_info_ns_info_valid);
-               json_add_formatted_u32_str(pstatistics_object, STR_STATISTICS_DATA_SIZE,
-                       pstatistic_entry->statistic_data_size);
-               json_add_formatted_u32_str(pstatistics_object, STR_RESERVED,
-                       pstatistic_entry->reserved);
-               json_add_formatted_var_size_str(pstatistics_object, STR_STATISTICS_SPECIFIC_DATA,
-                       pdata, data_size);
-
-               if (pstatistics_object != NULL)
-                       json_array_add_value_object(pstats_array, pstatistics_object);
-       } else {
-               if (fp) {
-                       fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_IDENTIFIER,
-                               pstatistic_entry->statistic_id);
-                       fprintf(fp, "%s: %s\n", STR_STATISTICS_IDENTIFIER_STR, description_str);
-                       fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_INFO_BEHAVIOUR_TYPE,
-                               pstatistic_entry->statistic_info_behaviour_type);
-                       fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_INFO_RESERVED,
-                               pstatistic_entry->statistic_info_reserved);
-                       fprintf(fp, "%s: 0x%x\n", STR_NAMESPACE_IDENTIFIER,
-                               pstatistic_entry->ns_info_nsid);
-                       fprintf(fp, "%s: 0x%x\n", STR_NAMESPACE_INFO_VALID,
-                               pstatistic_entry->ns_info_ns_info_valid);
-                       fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
-                               pstatistic_entry->statistic_data_size);
-                       fprintf(fp, "%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
-                       print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
-                               data_size, fp);
-                       fprintf(fp, STR_LINE2);
-               } else {
-                       printf("%s: 0x%x\n", STR_STATISTICS_IDENTIFIER,
-                              pstatistic_entry->statistic_id);
-                       printf("%s: %s\n", STR_STATISTICS_IDENTIFIER_STR, description_str);
-                       printf("%s: 0x%x\n", STR_STATISTICS_INFO_BEHAVIOUR_TYPE,
-                              pstatistic_entry->statistic_info_behaviour_type);
-                       printf("%s: 0x%x\n", STR_STATISTICS_INFO_RESERVED,
-                              pstatistic_entry->statistic_info_reserved);
-                       printf("%s: 0x%x\n", STR_NAMESPACE_IDENTIFIER,
-                              pstatistic_entry->ns_info_nsid);
-                       printf("%s: 0x%x\n", STR_NAMESPACE_INFO_VALID,
-                              pstatistic_entry->ns_info_ns_info_valid);
-                       printf("%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
-                              pstatistic_entry->statistic_data_size);
-                       printf("%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
-                       print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
-                                               data_size, fp);
-                       printf(STR_LINE2);
-               }
-       }
-
-       return 0;
-}
-
-int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets *poffsets,
-                    FILE *fp)
-{
-       if (poffsets == NULL) {
-               nvme_show_error("Input buffer was NULL");
-               return -1;
-       }
-
-       __u8 *pda1_ocp_header_offset = ptelemetry_buffer + poffsets->header_size;//512
-       __u32 statistics_size = 0;
-       __u32 stats_da_1_start_dw = 0, stats_da_1_size_dw = 0;
-       __u32 stats_da_2_start_dw = 0, stats_da_2_size_dw = 0;
-       __u8 *pstats_offset = NULL;
-
-       if (poffsets->data_area == 1) {
-               __u32 stats_da_1_start = *(__u32 *)(pda1_ocp_header_offset +
-                       offsetof(struct nvme_ocp_header_in_da1, da1_statistic_start));
-               __u32 stats_da_1_size = *(__u32 *)(pda1_ocp_header_offset +
-                       offsetof(struct nvme_ocp_header_in_da1, da1_statistic_size));
-
-               //Data is present in the form of DWORDS, So multiplying with sizeof(DWORD)
-               stats_da_1_start_dw = (stats_da_1_start * SIZE_OF_DWORD);
-               stats_da_1_size_dw = (stats_da_1_size * SIZE_OF_DWORD);
-
-               pstats_offset = pda1_ocp_header_offset + stats_da_1_start_dw;
-               statistics_size = stats_da_1_size_dw;
-       } else if (poffsets->data_area == 2) {
-               __u32 stats_da_2_start = *(__u32 *)(pda1_ocp_header_offset +
-                       offsetof(struct nvme_ocp_header_in_da1, da2_statistic_start));
-               __u32 stats_da_2_size = *(__u32 *)(pda1_ocp_header_offset +
-                       offsetof(struct nvme_ocp_header_in_da1, da2_statistic_size));
-
-               stats_da_2_start_dw = (stats_da_2_start * SIZE_OF_DWORD);
-               stats_da_2_size_dw = (stats_da_2_size * SIZE_OF_DWORD);
-
-               pstats_offset = pda1_ocp_header_offset + poffsets->da1_size + stats_da_2_start_dw;
-               statistics_size = stats_da_2_size_dw;
-       } else {
-               nvme_show_error("Unsupported Data Area:[%d]", poffsets->data_area);
-               return -1;
-       }
-
-       struct json_object *pstats_array = ((root != NULL) ? json_create_array() : NULL);
-
-       __u32 stat_des_size = sizeof(struct nvme_ocp_telemetry_statistic_descriptor);//8
-       __u32 offset_to_move = 0;
-
-       while (((statistics_size > 0) && (offset_to_move < statistics_size))) {
-               struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_entry =
-                       (struct nvme_ocp_telemetry_statistic_descriptor *)
-                       (pstats_offset + offset_to_move);
-
-               parse_statistic(pstatistic_entry, pstats_array, fp);
-               offset_to_move += (pstatistic_entry->statistic_data_size * SIZE_OF_DWORD +
-                       stat_des_size);
-       }
-
-       if (root != NULL && pstats_array != NULL) {
-               const char *pdata_area =
-                       (poffsets->data_area == 1 ? STR_DA_1_STATS : STR_DA_2_STATS);
-
-               json_object_add_value_array(root, pdata_area, pstats_array);
-       }
-
-       return 0;
-}
-
-int print_ocp_telemetry_normal(char *output_file)
-{
-       int status = 0;
-
-       if (output_file != NULL) {
-               FILE *fp = fopen(output_file, "w");
-
-               if (fp) {
-                       fprintf(fp, STR_LINE);
-                       fprintf(fp, "%s\n", STR_LOG_PAGE_HEADER);
-                       fprintf(fp, STR_LINE);
-                       print_micron_vs_logs(ptelemetry_buffer, host_log_page_header,
-                               ARRAY_SIZE(host_log_page_header), NULL, 0, fp);
-
-                       fprintf(fp, STR_LINE);
-                       fprintf(fp, "%s\n", STR_REASON_IDENTIFIER);
-                       fprintf(fp, STR_LINE);
-                       __u8 *preason_identifier_offset = ptelemetry_buffer +
-                               offsetof(struct nvme_ocp_telemetry_host_initiated_header,
-                               reason_id);
-
-                       print_micron_vs_logs(preason_identifier_offset, reason_identifier,
-                               ARRAY_SIZE(reason_identifier), NULL, 0, fp);
-
-                       fprintf(fp, STR_LINE);
-                       fprintf(fp, "%s\n", STR_TELEMETRY_HOST_DATA_BLOCK_1);
-                       fprintf(fp, STR_LINE);
-
-                       //Set DA to 1 and get offsets
-                       struct nvme_ocp_telemetry_offsets offsets = { 0 };
-
-                       offsets.data_area = 1;
-
-                       struct nvme_ocp_telemetry_common_header *ptelemetry_common_header =
-                               (struct nvme_ocp_telemetry_common_header *) ptelemetry_buffer;
-
-                       get_telemetry_das_offset_and_size(ptelemetry_common_header, &offsets);
-
-                       __u8 *pda1_header_offset = ptelemetry_buffer +
-                               offsets.da1_start_offset;//512
-
-                       print_micron_vs_logs(pda1_header_offset, ocp_header_in_da1,
-                                ARRAY_SIZE(ocp_header_in_da1), NULL, 0, fp);
-
-                       fprintf(fp, STR_LINE);
-                       fprintf(fp, "%s\n", STR_SMART_HEALTH_INFO);
-                       fprintf(fp, STR_LINE);
-                       __u8 *pda1_smart_offset = pda1_header_offset +
-                               offsetof(struct nvme_ocp_header_in_da1, smart_health_info);
-                       //512+512 =1024
-
-                       print_micron_vs_logs(pda1_smart_offset, smart, ARRAY_SIZE(smart),
-                               NULL, 0, fp);
-
-                       fprintf(fp, STR_LINE);
-                       fprintf(fp, "%s\n", STR_SMART_HEALTH_INTO_EXTENDED);
-                       fprintf(fp, STR_LINE);
-                       __u8 *pda1_smart_ext_offset = pda1_header_offset +
-                                                       offsetof(struct nvme_ocp_header_in_da1,
-                                                                smart_health_info_extended);
-
-                       print_micron_vs_logs(pda1_smart_ext_offset, smart_extended,
-                                            ARRAY_SIZE(smart_extended), NULL, 0, fp);
-
-                       fprintf(fp, STR_LINE);
-                       fprintf(fp, "%s\n", STR_DA_1_STATS);
-                       fprintf(fp, STR_LINE);
-
-                       status = parse_statistics(NULL, &offsets, fp);
-                       if (status != 0) {
-                               nvme_show_error("status: %d\n", status);
-                               return -1;
-                       }
-
-                       fprintf(fp, STR_LINE);
-                       fprintf(fp, "%s\n", STR_DA_1_EVENT_FIFO_INFO);
-                       fprintf(fp, STR_LINE);
-                       status = parse_event_fifos(NULL, &offsets, fp);
-                       if (status != 0) {
-                               nvme_show_error("status: %d\n", status);
-                               return -1;
-                       }
-
-                       //Set the DA to 2
-                       offsets.data_area = 2;
-
-                       fprintf(fp, STR_LINE);
-                       fprintf(fp, "%s\n", STR_DA_2_STATS);
-                       fprintf(fp, STR_LINE);
-                       status = parse_statistics(NULL, &offsets, fp);
-
-                       if (status != 0) {
-                               nvme_show_error("status: %d\n", status);
-                               return -1;
-                       }
-
-                       fprintf(fp, STR_LINE);
-                       fprintf(fp, "%s\n", STR_DA_2_EVENT_FIFO_INFO);
-                       fprintf(fp, STR_LINE);
-                       status = parse_event_fifos(NULL, &offsets, fp);
-                       if (status != 0) {
-                               nvme_show_error("status: %d\n", status);
-                               return -1;
-                       }
-
-                       fprintf(fp, STR_LINE);
-
-                       fclose(fp);
-               } else {
-                       nvme_show_error("Failed to open %s file.\n", output_file);
-                       return -1;
-               }
-       } else {
-               printf(STR_LINE);
-               printf("%s\n", STR_LOG_PAGE_HEADER);
-               printf(STR_LINE);
-               print_micron_vs_logs(ptelemetry_buffer, host_log_page_header,
-                                    ARRAY_SIZE(host_log_page_header), NULL, 0, NULL);
-
-               printf(STR_LINE);
-               printf("%s\n", STR_REASON_IDENTIFIER);
-               printf(STR_LINE);
-               __u8 *preason_identifier_offset = ptelemetry_buffer +
-                       offsetof(struct nvme_ocp_telemetry_host_initiated_header, reason_id);
-               print_micron_vs_logs(preason_identifier_offset, reason_identifier,
-                                    ARRAY_SIZE(reason_identifier), NULL, 0, NULL);
-
-               printf(STR_LINE);
-               printf("%s\n", STR_TELEMETRY_HOST_DATA_BLOCK_1);
-               printf(STR_LINE);
-
-               //Set DA to 1 and get offsets
-               struct nvme_ocp_telemetry_offsets offsets = { 0 };
-
-               offsets.data_area = 1;
-
-               struct nvme_ocp_telemetry_common_header *ptelemetry_common_header =
-                       (struct nvme_ocp_telemetry_common_header *) ptelemetry_buffer;
-
-               get_telemetry_das_offset_and_size(ptelemetry_common_header, &offsets);
-
-               __u8 *pda1_header_offset = ptelemetry_buffer + offsets.da1_start_offset;//512
-
-               print_micron_vs_logs(pda1_header_offset, ocp_header_in_da1,
-                                    ARRAY_SIZE(ocp_header_in_da1), NULL, 0, NULL);
-
-               printf(STR_LINE);
-               printf("%s\n", STR_SMART_HEALTH_INFO);
-               printf(STR_LINE);
-               __u8 *pda1_smart_offset = pda1_header_offset +
-                       offsetof(struct nvme_ocp_header_in_da1, smart_health_info);
-
-               print_micron_vs_logs(pda1_smart_offset, smart, ARRAY_SIZE(smart), NULL, 0, NULL);
-
-               printf(STR_LINE);
-               printf("%s\n", STR_SMART_HEALTH_INTO_EXTENDED);
-               printf(STR_LINE);
-               __u8 *pda1_smart_ext_offset = pda1_header_offset +
-                       offsetof(struct nvme_ocp_header_in_da1, smart_health_info_extended);
-
-               print_micron_vs_logs(pda1_smart_ext_offset, smart_extended,
-                                    ARRAY_SIZE(smart_extended), NULL, 0, NULL);
-
-               printf(STR_LINE);
-               printf("%s\n", STR_DA_1_STATS);
-               printf(STR_LINE);
-               status = parse_statistics(NULL, &offsets, NULL);
-               if (status != 0) {
-                       nvme_show_error("status: %d\n", status);
-                       return -1;
-               }
-
-               printf(STR_LINE);
-               printf("%s\n", STR_DA_1_EVENT_FIFO_INFO);
-               printf(STR_LINE);
-               status = parse_event_fifos(NULL, &offsets, NULL);
-               if (status != 0) {
-                       nvme_show_error("status: %d\n", status);
-                       return -1;
-               }
-
-               //Set the DA to 2
-               offsets.data_area = 2;
-
-               printf(STR_LINE);
-               printf("%s\n", STR_DA_2_STATS);
-               printf(STR_LINE);
-               status = parse_statistics(NULL, &offsets, NULL);
-               if (status != 0) {
-                       nvme_show_error("status: %d\n", status);
-                       return -1;
-               }
-
-               printf(STR_LINE);
-               printf("%s\n", STR_DA_2_EVENT_FIFO_INFO);
-               printf(STR_LINE);
-               status = parse_event_fifos(NULL, &offsets, NULL);
-               if (status != 0) {
-                       nvme_show_error("status: %d\n", status);
-                       return -1;
-               }
-
-               printf(STR_LINE);
-       }
-
-       return status;
-}
-
-int print_ocp_telemetry_json(char *output_file)
-{
-       int status = 0;
-
-       //create json objects
-       struct json_object *root, *pheader, *preason_identifier, *da1_header, *smart_obj,
-       *ext_smart_obj;
-
-       root = json_create_object();
-
-       //Add data to root json object
-
-       //"Log Page Header"
-       pheader = json_create_object();
-
-       print_micron_vs_logs(ptelemetry_buffer, host_log_page_header,
-                            ARRAY_SIZE(host_log_page_header), pheader, 0, NULL);
-       json_object_add_value_object(root, STR_LOG_PAGE_HEADER, pheader);
-
-       //"Reason Identifier"
-       preason_identifier = json_create_object();
-
-       __u8 *preason_identifier_offset = ptelemetry_buffer +
-               offsetof(struct nvme_ocp_telemetry_host_initiated_header, reason_id);
-
-       print_micron_vs_logs(preason_identifier_offset, reason_identifier,
-                            ARRAY_SIZE(reason_identifier), preason_identifier, 0, NULL);
-       json_object_add_value_object(pheader, STR_REASON_IDENTIFIER, preason_identifier);
-
-       struct nvme_ocp_telemetry_offsets offsets = { 0 };
-
-       //Set DA to 1 and get offsets
-       offsets.data_area = 1;
-       struct nvme_ocp_telemetry_common_header *ptelemetry_common_header =
-               (struct nvme_ocp_telemetry_common_header *) ptelemetry_buffer;
-
-       get_telemetry_das_offset_and_size(ptelemetry_common_header, &offsets);
-
-       //"Telemetry Host-Initiated Data Block 1"
-       __u8 *pda1_header_offset = ptelemetry_buffer + offsets.da1_start_offset;//512
-
-       da1_header = json_create_object();
-
-       print_micron_vs_logs(pda1_header_offset, ocp_header_in_da1, ARRAY_SIZE(ocp_header_in_da1),
-                            da1_header, 0, NULL);
-       json_object_add_value_object(root, STR_TELEMETRY_HOST_DATA_BLOCK_1, da1_header);
-
-       //"SMART / Health Information Log(LID-02h)"
-       __u8 *pda1_smart_offset = pda1_header_offset + offsetof(struct nvme_ocp_header_in_da1,
-                                                               smart_health_info);
-       smart_obj = json_create_object();
-
-       print_micron_vs_logs(pda1_smart_offset, smart, ARRAY_SIZE(smart), smart_obj, 0, NULL);
-       json_object_add_value_object(da1_header, STR_SMART_HEALTH_INFO, smart_obj);
-
-       //"SMART / Health Information Extended(LID-C0h)"
-       __u8 *pda1_smart_ext_offset = pda1_header_offset + offsetof(struct nvme_ocp_header_in_da1,
-                                                                   smart_health_info_extended);
-       ext_smart_obj = json_create_object();
-
-       print_micron_vs_logs(pda1_smart_ext_offset, smart_extended, ARRAY_SIZE(smart_extended),
-                            ext_smart_obj, 0, NULL);
-       json_object_add_value_object(da1_header, STR_SMART_HEALTH_INTO_EXTENDED, ext_smart_obj);
-
-       //Data Area 1 Statistics
-       status = parse_statistics(root, &offsets, NULL);
-       if (status != 0) {
-               nvme_show_error("status: %d\n", status);
-               return -1;
-       }
-
-       //Data Area 1 Event FIFOs
-       status = parse_event_fifos(root, &offsets, NULL);
-       if (status != 0) {
-               nvme_show_error("status: %d\n", status, NULL);
-               return -1;
-       }
-
-       //Set the DA to 2
-       offsets.data_area = 2;
-
-       //Data Area 2 Statistics
-       status = parse_statistics(root, &offsets, NULL);
-       if (status != 0) {
-               nvme_show_error("status: %d\n", status);
-               return -1;
-       }
-
-       //Data Area 2 Event FIFOs
-       status = parse_event_fifos(root, &offsets, NULL);
-       if (status != 0) {
-               nvme_show_error("status: %d\n", status);
-               return -1;
-       }
-
-       if (output_file != NULL) {
-               const char *json_string = json_object_to_json_string(root);
-               FILE *fp = fopen(output_file, "w");
-
-               if (fp) {
-                       fputs(json_string, fp);
-                       fclose(fp);
-               } else {
-                       nvme_show_error("Failed to open %s file.\n", output_file);
-                       return -1;
-               }
-       } else {
-               //Print root json object
-               json_print_object(root, NULL);
-               nvme_show_result("\n");
-               json_free_object(root);
-       }
-
-       return status;
-}
-
-int parse_ocp_telemetry_log(struct ocp_telemetry_parse_options *options)
-{
-       int status = 0;
-       long telemetry_buffer_size = 0;
-       long string_buffer_size = 0;
-       enum nvme_print_flags fmt;
-       unsigned char log_id;
-
-       // Read the data from the telemetry binary file
-       ptelemetry_buffer =
-               read_binary_file(NULL, options->telemetry_log, &telemetry_buffer_size, 1);
-       if (ptelemetry_buffer == NULL) {
-               nvme_show_error("Failed to read telemetry bin file.\n");
-               return -1;
-       }
-
-       log_id = ptelemetry_buffer[0];
-       if ((log_id != NVME_HOST_TELEMETRY_LOG) && (log_id != NVME_CNTRL_TELEMETRY_LOG)) {
-               nvme_show_error("Invalid LogPageId [0x%02X]\n", log_id);
-               return -1;
-       }
-
-       // Read the data from the string binary file
-       pstring_buffer = read_binary_file(NULL, options->string_log, &string_buffer_size, 1);
-       if (pstring_buffer == NULL) {
-               nvme_show_error("Failed to read string log bin file.\n");
-               return -1;
-       }
-
-       status = validate_output_format(options->output_fmt, &fmt);
-       if (status < 0) {
-               nvme_show_error("Invalid output format\n");
-               return status;
-       }
-
-       switch (fmt) {
-       case NORMAL:
-               print_ocp_telemetry_normal(options->output_file);
-               break;
-       case JSON:
-               print_ocp_telemetry_json(options->output_file);
-               break;
-       default:
-               break;
-       }
-
-       return 0;
-}
diff --git a/plugins/micron/micron-ocp-telemetry.h b/plugins/micron/micron-ocp-telemetry.h
deleted file mode 100644 (file)
index 96eefa9..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) Micron, Inc 2024.
- *
- * @file: micron-ocp-telemetry.h
- * @brief: This module contains all the constructs needed for parsing
- *         (or) decoding ocp telemetry log files.
- * @author: Chaithanya Shoba <ashoba@micron.com>
- */
-
-#include "nvme.h"
-#include "nvme-print.h"
-#include "micron-utils.h"
-#include "common.h"
-
-#define DATA_SIZE_12   12
-#define DATA_SIZE_8    8
-#define DATA_SIZE_4    4
-#define NVME_HOST_TELEMETRY_LOG       0x07
-#define NVME_CNTRL_TELEMETRY_LOG      0x08
-#define MAX_BUFFER_32_KB              0x8000
-#define OCP_TELEMETRY_DATA_BLOCK_SIZE 512
-#define SIZE_OF_DWORD                 4
-#define MAX_NUM_FIFOS                 16
-#define DA1_OFFSET                    512
-#define DEFAULT_ASCII_STRING_SIZE     16
-
-#define STR_LOG_PAGE_HEADER "Log Page Header"
-#define STR_REASON_IDENTIFIER "Reason Identifier"
-#define STR_TELEMETRY_HOST_DATA_BLOCK_1 "Telemetry Host-Initiated Data Block 1"
-#define STR_SMART_HEALTH_INFO "SMART / Health Information Log(LID-02h)"
-#define STR_SMART_HEALTH_INTO_EXTENDED "SMART / Health Information Extended(LID-C0h)"
-#define STR_DA_1_STATS "Data Area 1 Statistics"
-#define STR_DA_2_STATS "Data Area 2 Statistics"
-#define STR_DA_1_EVENT_FIFO_INFO "Data Area 1 Event FIFO info"
-#define STR_DA_2_EVENT_FIFO_INFO "Data Area 2 Event FIFO info"
-#define STR_STATISTICS_IDENTIFIER "Statistics Identifier"
-#define STR_STATISTICS_IDENTIFIER_STR "Statistic Identifier String"
-#define STR_STATISTICS_INFO_BEHAVIOUR_TYPE "Statistics Info Behavior Type"
-#define STR_STATISTICS_INFO_RESERVED "Statistics Info Reserved"
-#define STR_NAMESPACE_IDENTIFIER "Namespace Identifier"
-#define STR_NAMESPACE_INFO_VALID "Namespace Information Valid"
-#define STR_STATISTICS_DATA_SIZE "Statistic Data Size"
-#define STR_RESERVED "Reserved"
-#define STR_STATISTICS_SPECIFIC_DATA "Statistic Specific Data"
-#define STR_CLASS_SPECIFIC_DATA "Class Specific Data"
-#define STR_DBG_EVENT_CLASS_TYPE "Debug Event Class type"
-#define STR_EVENT_IDENTIFIER "Event Identifier"
-#define STR_EVENT_STRING "Event String"
-#define STR_EVENT_DATA_SIZE "Event Data Size"
-#define STR_VU_EVENT_STRING "VU Event String"
-#define STR_VU_EVENT_ID_STRING "VU Event Identifier"
-#define STR_VU_DATA "VU Data"
-#define STR_LINE "==============================================================================\n"
-#define STR_LINE2 "-----------------------------------------------------------------------------\n"
-
-struct __packed nvme_ocp_telemetry_reason_id
-{
-       __u8 error_id[64];                // Bytes 63:00
-       __u8 file_id[8];                  // Bytes 71:64
-       __le16 line_number;               // Bytes 73:72
-       __u8 valid_flags;                 // Bytes 74
-       __u8 reserved[21];                // Bytes 95:75
-       __u8 vu_reason_ext[32];           // Bytes 127:96
-};
-
-struct __packed nvme_ocp_telemetry_common_header
-{
-       __u8 log_id;                             // Byte 00
-       __le32 reserved1;                        // Bytes 04:01
-       __u8 ieee_oui_id[3];                     // Bytes 07:05
-       __le16 da1_last_block;                   // Bytes 09:08
-       __le16 da2_last_block;                   // Bytes 11:10
-       __le16 da3_last_block;                   // Bytes 13:12
-       __le16 reserved2;                        // Bytes 15:14
-       __le32 da4_last_block;                   // Bytes 19:16
-};
-
-struct __packed nvme_ocp_telemetry_host_initiated_header
-{
-       struct nvme_ocp_telemetry_common_header commonHeader;    // Bytes 19:00
-       __u8 reserved3[360];                                     // Bytes 379:20
-       __u8 host_initiated_scope;                               // Byte 380
-       __u8 host_initiated_gen_number;                          // Byte 381
-       __u8 host_initiated_data_available;                      // Byte 382
-       __u8 ctrl_initiated_gen_number;                          // Byte 383
-       struct nvme_ocp_telemetry_reason_id reason_id;           // Bytes 511:384
-};
-
-struct __packed nvme_ocp_telemetry_controller_initiated_header
-{
-       struct nvme_ocp_telemetry_common_header commonHeader;   // Bytes 19:00
-       __u8 reserved3[361];                                    // Bytes 380:20
-       __u8 ctrl_initiated_scope;                              // Byte 381
-       __u8 ctrl_initiated_data_available;                     // Byte 382
-       __u8 ctrl_initiated_gen_number;                         // Byte 383
-       struct nvme_ocp_telemetry_reason_id reason_id;          // Bytes 511:384
-};
-
-struct __packed nvme_ocp_telemetry_smart
-{
-       __u8 critical_warning;                                         // Byte 0
-       __le16 composite_temperature;                                  // Bytes 2:1
-       __u8 available_spare;                                          // Bytes 3
-       __u8 available_spare_threshold;                                // Bytes 4
-       __u8 percentage_used;                                          // Bytes 5
-       __u8 reserved1[26];                                            // Bytes 31:6
-       __u8 data_units_read[16];                                      // Bytes 47:32
-       __u8 data_units_written[16];                                   // Bytes 63:48
-       __u8 host_read_commands[16];                                   // Byte  79:64
-       __u8 host_write_commands[16];                                  // Bytes 95:80
-       __u8 controller_busy_time[16];                                 // Bytes 111:96
-       __u8 power_cycles[16];                                         // Bytes 127:112
-       __u8 power_on_hours[16];                                       // Bytes 143:128
-       __u8 unsafe_shutdowns[16];                                     // Bytes 159:144
-       __u8 media_and_data_integrity_errors[16];                      // Bytes 175:160
-       __u8 number_of_error_information_log_entries[16];              // Bytes 191:176
-       __le32 warning_composite_temperature_time;                     // Byte  195:192
-       __le32 critical_composite_temperature_time;                    // Bytes 199:196
-       __le16 temperature_sensor1;                                    // Bytes 201:200
-       __le16 temperature_sensor2;                                    // Byte  203:202
-       __le16 temperature_sensor3;                                    // Byte  205:204
-       __le16 temperature_sensor4;                                    // Bytes 207:206
-       __le16 temperature_sensor5;                                    // Bytes 209:208
-       __le16 temperature_sensor6;                                    // Bytes 211:210
-       __le16 temperature_sensor7;                                    // Bytes 213:212
-       __le16 temperature_sensor8;                                    // Bytes 215:214
-       __le32 thermal_management_temperature1_transition_count;       // Bytes 219:216
-       __le32 thermal_management_temperature2_transition_count;       // Bytes 223:220
-       __le32 total_time_for_thermal_management_temperature1;         // Bytes 227:224
-       __le32 total_time_for_thermal_management_temperature2;         // Bytes 231:228
-       __u8 reserved2[280];                                           // Bytes 511:232
-};
-
-struct __packed nvme_ocp_telemetry_smart_extended
-{
-       __u8 physical_media_units_written[16];                   // Bytes 15:0
-       __u8 physical_media_units_read[16];                      // Bytes 31:16
-       __u8 bad_user_nand_blocks_raw_count[6];                  // Bytes 37:32
-       __le16 bad_user_nand_blocks_normalized_value;            // Bytes 39:38
-       __u8 bad_system_nand_blocks_raw_count[6];                // Bytes 45:40
-       __le16 bad_system_nand_blocks_normalized_value;          // Bytes 47:46
-       __le64 xor_recovery_count;                               // Bytes 55:48
-       __le64 uncorrectable_read_error_count;                   // Bytes 63:56
-       __le64 soft_ecc_error_count;                             // Bytes 71:64
-       __le32 end_to_end_correction_counts_detected_errors;     // Bytes 75:72
-       __le32 end_to_end_correction_counts_corrected_errors;    // Bytes 79:76
-       __u8 system_data_percent_used;                           // Byte  80
-       __u8 refresh_counts[7];                                  // Bytes 87:81
-       __le32 max_user_data_erase_count;                        // Bytes 91:88
-       __le32 min_user_data_erase_count;                        // Bytes 95:92
-       __u8 num_thermal_throttling_events;                      // Bytes 96
-       __u8 current_throttling_status;                          // Bytes 97
-       __u8  errata_version_field;                              // Byte 98
-       __le16 point_version_field;                              // Byte 100:99
-       __le16 minor_version_field;                              // Byte 102:101
-       __u8  major_version_field;                               // Byte 103
-       __le64 pcie_correctable_error_count;                     // Bytes 111:104
-       __le32 incomplete_shutdowns;                             // Bytes 115:112
-       __le32 reserved1;                                        // Bytes 119:116
-       __u8 percent_free_blocks;                                // Byte  120
-       __u8 reserved2[7];                                       // Bytes 127:121
-       __le16 capacitor_health;                                 // Bytes 129:128
-       __u8 nvme_base_errata_version;                           // Byte  130
-       __u8 nvme_command_set_errata_version;                    // Byte  131
-       __le32 reserved3;                                        // Bytes 135:132
-       __le64 unaligned_io;                                     // Bytes 143:136
-       __le64 security_version_number;                          // Bytes 151:144
-       __le64 total_nuse;                                       // Bytes 159:152
-       __u8 plp_start_count[16];                                // Bytes 175:160
-       __u8 endurance_estimate[16];                             // Bytes 191:176
-       __le64 pcie_link_retraining_count;                       // Bytes 199:192
-       __le64 power_state_change_count;                         // Bytes 207:200
-       __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
-};
-
-struct __packed nvme_ocp_event_fifo_data
-{
-       __le32 event_fifo_num;
-       __u8 event_fifo_da;
-       __le64 event_fifo_start;
-       __le64 event_fifo_size;
-};
-
-struct __packed nvme_ocp_telemetry_offsets
-{
-       __le32 data_area;
-       __le32 header_size;
-       __le32 da1_start_offset;
-       __le32 da1_size;
-       __le32 da2_start_offset;
-       __le32 da2_size;
-       __le32 da3_start_offset;
-       __le32 da3_size;
-       __le32 da4_start_offset;
-       __le32 da4_size;
-};
-
-struct __packed nvme_ocp_event_fifo_offsets
-{
-       __le64 event_fifo_start;
-       __le64 event_fifo_size;
-};
-
-struct __packed nvme_ocp_header_in_da1
-{
-       __le16 major_version;                                                // Bytes 1:0
-       __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 num_telemetry_profiles_supported;                               // Byte 32
-       __u8 telemetry_profile_selected;                                     // Byte 33
-       __u8 reserved2[6];                                                   // Bytes 39:34
-       __le64 string_log_size;                                              // Bytes 47:40
-       __le64 reserved3;                                                    // Bytes 55:48
-       __le64 firmware_revision;                                            // Bytes 63:56
-       __u8 reserved4[32];                                                  // Bytes 95:64
-       __le64 da1_statistic_start;                                          // Bytes 103:96
-       __le64 da1_statistic_size;                                           // Bytes 111:104
-       __le64 da2_statistic_start;                                          // Bytes 119:112
-       __le64 da2_statistic_size;                                           // Bytes 127:120
-       __u8 reserved5[32];                                                  // Bytes 159:128
-       __u8 event_fifo_da[16];                                              // Bytes 175:160
-       struct nvme_ocp_event_fifo_offsets fifo_offsets[16];                 // Bytes 431:176
-       __u8 reserved6[80];                                                  // Bytes 511:432
-       struct nvme_ocp_telemetry_smart smart_health_info;                   // Bytes 1023:512
-       struct nvme_ocp_telemetry_smart_extended smart_health_info_extended; // Bytes 1535:1024
-};
-
-struct __packed nvme_ocp_telemetry_statistic_descriptor
-{
-       __le16 statistic_id;                    // Bytes 1:0
-       __u8 statistic_info_behaviour_type : 4; // Byte  2(3:0)
-       __u8 statistic_info_reserved : 4;       // Byte  2(7:4)
-       __u8 ns_info_nsid : 7;                  // Bytes 3(6:0)
-       __u8 ns_info_ns_info_valid : 1;         // Bytes 3(7)
-       __le16 statistic_data_size;             // Bytes 5:4
-       __le16 reserved;                        // Bytes 7:6
-};
-
-struct __packed nvme_ocp_telemetry_event_descriptor
-{
-       __u8 debug_event_class_type;    // Byte 0
-       __le16 event_id;                // Bytes 2:1
-       __u8 event_data_size;           // Byte 3
-};
-
-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
-{
-       __le16 vu_event_identifier;    // Bytes 5:4
-};
-
-struct __packed nvme_ocp_media_wear_dbg_evt_class_format
-{
-       __u8 currentMediaWear[DATA_SIZE_12];         // Bytes 15:4
-       __le16 vu_event_identifier;                  // Bytes 17:16
-};
-
-struct __packed nvme_ocp_statistic_snapshot_evt_class_format
-{
-       struct nvme_ocp_telemetry_statistic_descriptor statisticDescriptorData; // Bytes 11:10
-};
-
-struct __packed nvme_ocp_statistics_identifier_string_table
-{
-       __le16 vs_statistic_identifier;     //1:0
-       __u8 reserved1;                     //2
-       __u8 ascii_id_length;               //3
-       __le64 ascii_id_offset;             //11:4
-       __le32 reserved2;                   //15:12
-};
-
-struct __packed nvme_ocp_event_string_table
-{
-       __u8 debug_event_class;         //0
-       __le16 event_identifier;        //2:1
-       __u8 ascii_id_length;           //3
-       __le64 ascii_id_offset;         //11:4
-       __le32 reserved;                //15:12
-};
-
-struct __packed nvme_ocp_vu_event_string_table
-{
-       __u8 debug_event_class;        //0
-       __le16 vu_event_identifier;    //2:1
-       __u8 ascii_id_length;          //3
-       __le64 ascii_id_offset;        //11:4
-       __le32 reserved;               //15:12
-};
-
-struct __packed nvme_ocp_telemetry_string_header
-{
-       __u8 version;                   //0:0
-       __u8 reserved1[15];             //15:1
-       __u8 guid[16];                  //32:16
-       __le64 string_log_size;         //39:32
-       __u8 reserved2[24];             //63:40
-       __le64 sits;                    //71:64 Statistics Identifier String Table Start(SITS)
-       __le64 sitsz;                   //79:72 Statistics Identifier String Table Size (SITSZ)
-       __le64 ests;                    //87:80 Event String Table Start(ESTS)
-       __le64 estsz;                   //95:88 Event String Table Size(ESTSZ)
-       __le64 vu_ests;                 //103:96 VU Event String Table Start
-       __le64 vu_estsz;                //111:104 VU Event String Table Size
-       __le64 ascts;                   //119:112 ASCII Table start
-       __le64 asctsz;                  //127:120 ASCII Table Size
-       __u8 fifo_ascii_string[16][16]; //383:128
-       __u8 reserved3[48];             //431:384
-};
-
-struct __packed statistic_entry {
-       int identifier;
-       char *description;
-};
-
-struct __packed ocp_telemetry_parse_options {
-       char *telemetry_log;
-       char *string_log;
-       char *output_file;
-       char *output_fmt;
-};
-
-/**
- * enum ocp_telemetry_data_area - Telemetry Data Areas
- * @DATA_AREA_1:       Data Area 1
- * @DATA_AREA_2:       Data Area 2
- * @DATA_AREA_3:       Data Area 3
- * @DATA_AREA_4:       Data Area 4
- */
-enum ocp_telemetry_data_area {
-       DATA_AREA_1 = 0x01,
-       DATA_AREA_2 = 0x02,
-       DATA_AREA_3 = 0x03,
-       DATA_AREA_4 = 0x04,
-};
-
-/**
- * enum ocp_telemetry_string_tables - OCP telemetry string tables
- * @STATISTICS_IDENTIFIER_STRING:      Statistic Identifier string
- * @EVENT_STRING:      Event String
- * @VU_EVENT_STRING:   VU Event String
- */
-enum ocp_telemetry_string_tables {
-       STATISTICS_IDENTIFIER_STRING = 0,
-       EVENT_STRING,
-       VU_EVENT_STRING
-};
-
-/**
- * enum ocp_telemetry_debug_event_class_types - OCP Debug Event Class types
- * @RESERVED_CLASS_TYPE:              Reserved class
- * @TIME_STAMP_CLASS_TYPE:            Time stamp class
- * @PCIE_CLASS_TYPE:              PCIe class
- * @NVME_CLASS_TYPE:              NVME class
- * @RESET_CLASS_TYPE:             Reset class
- * @BOOT_SEQUENCE_CLASS_TYPE:     Boot Sequence class
- * @FIRMWARE_ASSERT_CLASS_TYPE:           Firmware Assert class
- * @TEMPERATURE_CLASS_TYPE:           Temperature class
- * @MEDIA_CLASS_TYPE:             Media class
- * @MEDIA_WEAR_CLASS_TYPE:            Media wear class
- * @STATISTIC_SNAPSHOT_CLASS_TYPE: Statistic snapshot class
- * @RESERVED:                     Reserved class
- * @VENDOR_UNIQUE_CLASS_TYPE:     Vendor Unique class
- */
-enum ocp_telemetry_debug_event_class_types {
-       RESERVED_CLASS_TYPE = 0x00,
-       TIME_STAMP_CLASS_TYPE = 0x01,
-       PCIE_CLASS_TYPE = 0x02,
-       NVME_CLASS_TYPE = 0x03,
-       RESET_CLASS_TYPE = 0x04,
-       BOOT_SEQUENCE_CLASS_TYPE = 0x05,
-       FIRMWARE_ASSERT_CLASS_TYPE = 0x06,
-       TEMPERATURE_CLASS_TYPE = 0x07,
-       MEDIA_CLASS_TYPE = 0x08,
-       MEDIA_WEAR_CLASS_TYPE = 0x09,
-       STATISTIC_SNAPSHOT_CLASS_TYPE = 0x0A,
-       //RESERVED = 7Fh-0Bh,
-       //VENDOR_UNIQUE_CLASS_TYPE = FFh-80h,
-};
-
-/**
- * @brief parse the ocp telemetry host or controller log binary file
- *        into json or text
- *
- * @param options, input pointer for inputs like telemetry log bin file,
- *        string log bin file and output file etc.
- *
- * @return 0 success
- */
-int parse_ocp_telemetry_log(struct ocp_telemetry_parse_options *options);
-
-/**
- * @brief parse the ocp telemetry string log binary file to json or text
- *
- * @param event_fifo_num, input event FIFO number
- * @param debug_event_class, input debug event class id
- * @param string_table, input string table
- * @param description, input description string
- *
- * @return 0 success
- */
-int parse_ocp_telemetry_string_log(int event_fifo_num, int identifier, int debug_event_class,
-       enum ocp_telemetry_string_tables string_table, char *description);
-
-/**
- * @brief gets the telemetry datas areas, offsets and sizes information
- *
- * @param ptelemetry_common_header, input telemetry common header pointer
- * @param ptelemetry_das_offset, input telemetry offsets pointer
- *
- * @return 0 success
- */
-int get_telemetry_das_offset_and_size(
-       struct nvme_ocp_telemetry_common_header *ptelemetry_common_header,
-       struct nvme_ocp_telemetry_offsets *ptelemetry_das_offset);
-
-/**
- * @brief parses statistics data to text or json formats
- *
- * @param root, input time json root object pointer
- * @param ptelemetry_das_offset, input telemetry offsets pointer
- * @param fp, input file pointer
- *
- * @return 0 success
- */
-int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets *pOffsets,
-       FILE *fp);
-
-/**
- * @brief parses a single statistic data to text or json formats
- *
- * @param pstatistic_entry, statistic entry pointer
- * @param pstats_array, stats array pointer
- * @param fp, input file pointer
- *
- * @return 0 success
- */
-int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_entry,
-       struct json_object *pstats_array, FILE *fp);
-
-/**
- * @brief parses event fifos data to text or json formats
- *
- * @param root, input time json root object pointer
- * @param poffsets, input telemetry offsets pointer
- * @param fp, input file pointer
- *
- * @return 0 success
- */
-int parse_event_fifos(struct json_object *root, struct nvme_ocp_telemetry_offsets *poffsets,
-       FILE *fp);
-
-/**
- * @brief parses a single event fifo data to text or json formats
- *
- * @param fifo_num, input event fifo number
- * @param pfifo_start, event fifo start pointer
- * @param pevent_fifos_object, event fifos json object pointer
- * @param ptelemetry_das_offset, input telemetry offsets pointer
- * @param fifo_size, input event fifo size
- * @param fp, input file pointer
- *
- * @return 0 success
- */
-int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
-       struct json_object *pevent_fifos_object, unsigned char *pstring_buffer,
-       struct nvme_ocp_telemetry_offsets *poffsets, __u64 fifo_size, FILE *fp);
-
-/**
- * @brief parses event fifos data to text or json formats
- *
- * @return 0 success
- */
-int print_ocp_telemetry_normal(char *output_file);
-
-/**
- * @brief parses event fifos data to text or json formats
- *
- * @return 0 success
- */
-int print_ocp_telemetry_json(char *output_file);
-
-/**
- * @brief gets statistic id ascii string
- *
- * @param identifier, string id
- * @param description, string description
- *
- * @return 0 success
- */
-int get_static_id_ascii_string(int identifier, char *description);
-
-/**
- * @brief gets event id ascii string
- *
- * @param identifier, string id
- * @param debug_event_class, debug event class
- * @param description, string description
- *
- * @return 0 success
- */
-int get_event_id_ascii_string(int identifier, int debug_event_class, char *description);
-
-/**
- * @brief gets vu event id ascii string
- *
- * @param identifier, string id
- * @param debug_event_class, debug event class
- * @param description, string description
- *
- * @return 0 success
- */
-int get_vu_event_id_ascii_string(int identifier, int debug_event_class, char *description);
-
-/**
- * @brief parses a time-stamp event fifo data to text or json formats
- *
- * @param pevent_descriptor, input event descriptor data
- * @param pevent_descriptor_obj, event descriptor json object pointer
- * @param pevent_specific_data, input event specific data
- * @param pevent_fifos_object, event fifos json object pointer
- * @param fp, input file pointer
- *
- * @return
- */
-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);
-
-/**
- * @brief parses a pcie event fifo data to text or json formats
- *
- * @param pevent_descriptor, input event descriptor data
- * @param pevent_descriptor_obj, event descriptor json object pointer
- * @param pevent_specific_data, input event specific data
- * @param pevent_fifos_object, event fifos json object pointer
- * @param fp, input file pointer
- *
- * @return
- */
-void parse_pcie_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);
-
-/**
- * @brief parses a nvme event fifo data to text or json formats
- *
- * @param pevent_descriptor, input event descriptor data
- * @param pevent_descriptor_obj, event descriptor json object pointer
- * @param pevent_specific_data, input event specific data
- * @param pevent_fifos_object, event fifos json object pointer
- * @param fp, input file pointer
- *
- * @return
- */
-void parse_nvme_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);
-
-/**
- * @brief parses common event fifo data to text or json formats
- *
- * @param pevent_descriptor, input event descriptor data
- * @param pevent_descriptor_obj, event descriptor json object pointer
- * @param pevent_specific_data, input event specific data
- * @param pevent_fifos_object, event fifos json object pointer
- * @param fp, input file pointer
- *
- * @return
- */
-void parse_common_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);
-
-/**
- * @brief parses a media-wear event fifo data to text or json formats
- *
- * @param pevent_descriptor, input event descriptor data
- * @param pevent_descriptor_obj, event descriptor json object pointer
- * @param pevent_specific_data, input event specific data
- * @param pevent_fifos_object, event fifos json object pointer
- * @param fp, input file pointer
- *
- * @return
- */
-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);
index 1ffa40b990ced077a2a3919cb60e8ac8d8027469..8ea22896a26811b082d59b9367342b21a537a8d8 100644 (file)
@@ -218,7 +218,7 @@ static int ocp_print_C3_log_normal(struct nvme_dev *dev,
        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",
+       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 *
@@ -889,6 +889,13 @@ static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd,
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 /// Telemetry Log
+//global buffers
+static __le64 total_log_page_sz;
+static struct telemetry_str_log_format *log_data;
+
+__u8 *ptelemetry_buffer;
+__u8 *pstring_buffer;
+__u8 *pC9_string_buffer;
 
 static void get_serial_number(struct nvme_id_ctrl *ctrl, char *sn)
 {
@@ -953,6 +960,7 @@ static int get_telemetry_data(struct nvme_dev *dev, __u32 ns, __u8 tele_type,
        __u32 numd = (data_len >> 2) - 1;
        __u16 numdu = numd >> 16;
        __u16 numdl = numd & 0xffff;
+
        cmd.cdw10 = tele_type |
                        (nLSP & 0x0F) << 8 |
                        (nRAE & 0x01) << 15 |
@@ -968,6 +976,7 @@ static void print_telemetry_data_area_1(struct telemetry_data_area_1 *da1,
 {
        if (da1) {
                int i = 0;
+
                if (tele_type == TELEMETRY_TYPE_HOST)
                        printf("============ Telemetry Host Data area 1 ============\n");
                else
@@ -1035,7 +1044,7 @@ static void print_telemetry_da_stat(struct telemetry_stats_desc *da_stat,
                else
                        printf("========= Telemetry Controller Data Area %d Statistics =========\n",
                                data_area);
-               while((i + 8) < buf_size) {
+               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);
@@ -1064,7 +1073,7 @@ static void print_telemetry_da_fifo(struct telemetry_event_desc *da_fifo,
                                da, index);
 
 
-               while((i + 4) < buf_size) {
+               while ((i + 4) < buf_size) {
                        /* Print Event Data */
                        print_telemetry_fifo_event(next_da_fifo->class, /* Event class type */
                                next_da_fifo->id,                           /* Event ID         */
@@ -1464,43 +1473,286 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
        return err;
 }
 
+static int get_telemetry_log_page_data(struct nvme_dev *dev, int tele_type)
+{
+       char file_path[PATH_MAX];
+       void *telemetry_log;
+       const size_t bs = 512;
+       struct nvme_telemetry_log *hdr;
+       size_t full_size, offset = bs;
+       int err, fd;
+
+       if ((tele_type == TELEMETRY_TYPE_HOST_0) || (tele_type == TELEMETRY_TYPE_HOST_1))
+               tele_type = TELEMETRY_TYPE_HOST;
+
+       int log_id = (tele_type == TELEMETRY_TYPE_HOST ? NVME_LOG_LID_TELEMETRY_HOST :
+                       NVME_LOG_LID_TELEMETRY_CTRL);
+
+       hdr = malloc(bs);
+       telemetry_log = malloc(bs);
+       if (!hdr || !telemetry_log) {
+               fprintf(stderr, "Failed to allocate %zu bytes for log: %s\n",
+                       bs, strerror(errno));
+               err = -ENOMEM;
+               goto exit_status;
+       }
+       memset(hdr, 0, bs);
+
+       sprintf(file_path, DEFAULT_TELEMETRY_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));
+               err = fd;
+               goto exit_status;
+       }
+
+       struct nvme_get_log_args args = {
+               .lpo = 0,
+               .result = NULL,
+               .log = hdr,
+               .args_size = sizeof(args),
+               .fd = dev_fd(dev),
+               .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+               .lid = log_id,
+               .len = bs,
+               .nsid = NVME_NSID_ALL,
+               .csi = NVME_CSI_NVM,
+               .lsi = NVME_LOG_LSI_NONE,
+               .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE,
+               .uuidx = NVME_UUID_NONE,
+               .rae = true,
+               .ot = false,
+       };
+
+       err = nvme_get_log(&args);
+       if (err < 0)
+               nvme_show_error("Failed to fetch the log from drive.\n");
+       else if (err > 0) {
+               nvme_show_status(err);
+               nvme_show_error("Failed to fetch telemetry-header. Error:%d.\n", err);
+               goto close_fd;
+       }
+
+       err = write(fd, (void *)hdr, bs);
+       if (err != bs) {
+               nvme_show_error("Failed to write data to file.\n");
+               goto close_fd;
+       }
+
+       full_size = (le16_to_cpu(hdr->dalb3) * bs) + offset;
+
+       while (offset != full_size) {
+               args.log = telemetry_log;
+               args.lpo = offset;
+               args.lsp = NVME_LOG_LSP_NONE;
+               err = nvme_get_log(&args);
+               if (err < 0) {
+                       nvme_show_error("Failed to fetch the log from drive.\n");
+                       break;
+               } else if (err > 0) {
+                       nvme_show_error("Failed to fetch telemetry-log.\n");
+                       nvme_show_status(err);
+                       break;
+               }
+
+               err = write(fd, (void *)telemetry_log, bs);
+               if (err != bs) {
+                       nvme_show_error("Failed to write data to file.\n");
+                       break;
+               }
+               err = 0;
+               offset += bs;
+       }
+
+close_fd:
+       close(fd);
+exit_status:
+       free(hdr);
+       free(telemetry_log);
+
+       return err;
+}
+
+static int get_c9_log_page_data(struct nvme_dev *dev, int print_data, int save_bin)
+{
+       int ret = 0, fd;
+       __u8 *header_data;
+       struct telemetry_str_log_format *log_data;
+       __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];
+
+       header_data = (__u8 *)malloc(sizeof(__u8) * C9_TELEMETRY_STR_LOG_LEN);
+       if (!header_data) {
+               fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
+               return -1;
+       }
+       memset(header_data, 0, sizeof(__u8) * C9_TELEMETRY_STR_LOG_LEN);
+
+       ret = nvme_get_log_simple(dev_fd(dev), C9_TELEMETRY_STRING_LOG_ENABLE_OPCODE,
+                                 C9_TELEMETRY_STR_LOG_LEN, header_data);
+
+       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);
+               }
+
+               //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);
+
+               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);
+               }
+
+               pC9_string_buffer = (__u8 *)malloc(sizeof(__u8) * total_log_page_sz);
+               if (!pC9_string_buffer) {
+                       fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
+                       return -1;
+               }
+               memset(pC9_string_buffer, 0, sizeof(__u8) * total_log_page_sz);
+
+               ret = nvme_get_log_simple(dev_fd(dev), C9_TELEMETRY_STRING_LOG_ENABLE_OPCODE,
+                                         total_log_page_sz, pC9_string_buffer);
+       } 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;
+               }
+
+               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:
+       free(header_data);
+       return 0;
+}
+
+int parse_ocp_telemetry_log(struct ocp_telemetry_parse_options *options)
+{
+       int status = 0;
+       long telemetry_buffer_size = 0;
+       long string_buffer_size = 0;
+       enum nvme_print_flags fmt;
+       unsigned char log_id;
+
+       if (options->telemetry_log) {
+               if (strstr((const char *)options->telemetry_log, "bin")) {
+                       // Read the data from the telemetry binary file
+                       ptelemetry_buffer =
+                               read_binary_file(NULL, (const char *)options->telemetry_log,
+                                                &telemetry_buffer_size, 1);
+                       if (ptelemetry_buffer == NULL) {
+                               nvme_show_error("Failed to read telemetry-log.\n");
+                               return -1;
+                       }
+               }
+       } else {
+               nvme_show_error("telemetry-log is empty.\n");
+               return -1;
+       }
+
+       log_id = ptelemetry_buffer[0];
+       if ((log_id != NVME_LOG_LID_TELEMETRY_HOST) && (log_id != NVME_LOG_LID_TELEMETRY_CTRL)) {
+               nvme_show_error("Invalid LogPageId [0x%02X]\n", log_id);
+               return -1;
+       }
+
+       if (options->string_log) {
+               // Read the data from the string binary file
+               if (strstr((const char *)options->string_log, "bin")) {
+                       pstring_buffer = read_binary_file(NULL, (const char *)options->string_log,
+                                                         &string_buffer_size, 1);
+                       if (pstring_buffer == NULL) {
+                               nvme_show_error("Failed to read string-log.\n");
+                               return -1;
+                       }
+               }
+       } else {
+               nvme_show_error("string-log is empty.\n");
+               return -1;
+       }
+
+       status = validate_output_format(options->output_format, &fmt);
+       if (status < 0) {
+               nvme_show_error("Invalid output format\n");
+               return status;
+       }
+
+       switch (fmt) {
+       case NORMAL:
+               print_ocp_telemetry_normal(options);
+               break;
+       case JSON:
+               print_ocp_telemetry_json(options);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
                              struct plugin *plugin)
 {
-       struct nvme_dev *dev;
-       int err = 0;
-       const char *desc = "Retrieve and save telemetry log.";
-       const char *type = "Telemetry Type; 'host[Create bit]' or 'controller'";
-       const char *area = "Telemetry Data Area; 1 or 3";
-       const char *file = "Output file name with path;\n"
+       const char *desc = "Retrieve and parse OCP Telemetry log.";
+       const char *telemetry_log = "Telemetry log binary;\n 'host.bin' or 'controller.bin'";
+       const char *string_log = "String log binary; 'C9.bin'";
+       const char *output_file = "Output file name with path;\n"
                        "e.g. '-o ./path/name'\n'-o ./path1/path2/';\n"
                        "If requested path does not exist, the directory will be newly created.";
+       const char *output_format = "output format normal|json";
+       const char *data_area = "Telemetry Data Area; 1 or 2;\n"
+                       "e.g. '-a 1 for Data Area 1.'\n'-a 2 for Data Areas 1 and 2.';\n";
+       const char *telemetry_type = "Telemetry Type; 'host' or 'controller'";
 
+       struct nvme_dev *dev;
+       int err = 0;
        __u32  nsid = NVME_NSID_ALL;
        struct stat nvme_stat;
        char sn[21] = {0,};
        struct nvme_id_ctrl ctrl;
        bool is_support_telemetry_controller;
-
+       struct ocp_telemetry_parse_options opt;
        int tele_type = 0;
        int tele_area = 0;
 
-       struct config {
-               char *type;
-               int area;
-               char *file;
-       };
-
-       struct config cfg = {
-               .type = NULL,
-               .area = 0,
-               .file = NULL,
-       };
-
        OPT_ARGS(opts) = {
-               OPT_STR("telemetry_type", 't', &cfg.type, type),
-               OPT_INT("telemetry_data_area", 'a', &cfg.area, area),
-               OPT_FILE("output-file", 'o', &cfg.file, file),
+               OPT_STR("telemetry-log", 'l', &opt.telemetry_log, telemetry_log),
+               OPT_STR("string-log", 's', &opt.string_log, string_log),
+               OPT_FILE("output-file", 'o', &opt.output_file, output_file),
+               OPT_FMT("output-format", 'f', &opt.output_format, output_format),
+               OPT_INT("data-area", 'a', &opt.data_area, data_area),
+               OPT_STR("telemetry-type", 't', &opt.telemetry_type, telemetry_type),
                OPT_END()
        };
 
@@ -1526,36 +1778,84 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
 
        is_support_telemetry_controller = ((ctrl.lpa & 0x8) >> 3);
 
-       if (!cfg.type && !cfg.area) {
-               tele_type = TELEMETRY_TYPE_NONE;
-               tele_area = 0;
-       } else if (cfg.type && cfg.area) {
-               if (!strcmp(cfg.type, "host0"))
+       if (!opt.data_area) {
+               nvme_show_result("Missing data-area. Using default data area 1.\n");
+               opt.data_area = DATA_AREA_1;//Default data area 1
+       } else if (opt.data_area != 1 && opt.data_area != 2) {
+               nvme_show_result("Invalid data-area specified. Please specify 1 or 2.\n");
+               goto out;
+       }
+
+       tele_area = opt.data_area;
+
+       if (opt.telemetry_type) {
+               if (!strcmp(opt.telemetry_type, "host0"))
                        tele_type = TELEMETRY_TYPE_HOST_0;
-               else if (!strcmp(cfg.type, "host1"))
+               else if (!strcmp(opt.telemetry_type, "host1"))
                        tele_type = TELEMETRY_TYPE_HOST_1;
-               else if (!strcmp(cfg.type, "controller"))
+               else if (!strcmp(opt.telemetry_type, "host"))
+                       tele_type = TELEMETRY_TYPE_HOST;
+               else if (!strcmp(opt.telemetry_type, "controller"))
                        tele_type = TELEMETRY_TYPE_CONTROLLER;
+               else {
+                       nvme_show_error("telemetry-type should be host or controller.\n");
+                       goto out;
+               }
+       } else {
+               tele_type = TELEMETRY_TYPE_HOST; //Default Type - Host
+               nvme_show_result("Missing telemetry-type. Using default - host.\n");
+       }
 
-               tele_area = cfg.area;
+       if (!opt.telemetry_log) {
+               nvme_show_result("\nMissing telemetry-log. Fetching from drive...\n");
+               err = get_telemetry_log_page_data(dev, tele_type);//Pull Telemetry log
+               if (err) {
+                       nvme_show_error("Failed to fetch telemetry-log from the drive.\n");
+                       goto out;
+               }
+               nvme_show_result("telemetry.bin generated. Proceeding with next steps.\n");
+               opt.telemetry_log = DEFAULT_TELEMETRY_BIN;
+       }
 
-               if ((tele_area != 1 && tele_area != 3) ||
-                       (tele_type == TELEMETRY_TYPE_CONTROLLER && tele_area != 3)) {
-                       printf("\nUnsupported parameters entered.\n");
-                       printf("Possible combinations; {'host0',1}, {'host0',3}, {'host1',1}, {'host1',3}, {'controller',3}\n");
-                       return err;
+       if (!opt.string_log) {
+               nvme_show_result("Missing string-log. Fetching from drive...\n");
+               err = get_c9_log_page_data(dev, 0, 1); //Pull String log
+               if (err) {
+                       nvme_show_error("Failed to fetch string-log from the drive.\n");
+                       goto out;
                }
-       } else {
-               printf("\nShould provide these all; 'telemetry_type' and 'telemetry_data_area'\n");
-               return err;
+               nvme_show_result("string.bin generated. Proceeding with next steps.\n");
+               opt.string_log = DEFAULT_STRING_BIN;
        }
 
-       if (tele_type == TELEMETRY_TYPE_NONE) {
+       if (!opt.output_format) {
+               nvme_show_result("Missing format. Using default format - JSON.\n");
+               opt.output_format = DEFAULT_OUTPUT_FORMAT_JSON;
+       }
+
+       switch (tele_type) {
+       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: {
+               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: {
                printf("\n-------------------------------------------------------------\n");
                /* Host 0 (lsp == 0) must be executed before Host 1 (lsp == 1). */
                printf("\nExtracting Telemetry Host 0 Dump (Data Area 1)...\n");
 
-               err = get_telemetry_dump(dev, cfg.file, sn,
+               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);
@@ -1564,7 +1864,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
 
                printf("\nExtracting Telemetry Host 0 Dump (Data Area 3)...\n");
 
-               err = get_telemetry_dump(dev, cfg.file, sn,
+               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);
@@ -1573,7 +1873,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
 
                printf("\nExtracting Telemetry Host 1 Dump (Data Area 1)...\n");
 
-               err = get_telemetry_dump(dev, cfg.file, sn,
+               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);
@@ -1582,7 +1882,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
 
                printf("\nExtracting Telemetry Host 1 Dump (Data Area 3)...\n");
 
-               err = get_telemetry_dump(dev, cfg.file, sn,
+               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);
@@ -1592,32 +1892,31 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
                printf("\nExtracting Telemetry Controller Dump (Data Area 3)...\n");
 
                if (is_support_telemetry_controller == true) {
-                       err = get_telemetry_dump(dev, cfg.file, sn,
+                       err = get_telemetry_dump(dev, opt.output_file, sn,
                                        TELEMETRY_TYPE_CONTROLLER, 3, true);
                        if (err)
                                fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
                }
 
                printf("\n-------------------------------------------------------------\n");
-       } else if (tele_type == TELEMETRY_TYPE_CONTROLLER) {
-               printf("Extracting Telemetry Controller Dump (Data Area %d)...\n", tele_area);
-
-               if (is_support_telemetry_controller == true) {
-                       err = get_telemetry_dump(dev, cfg.file, sn, tele_type, tele_area, true);
-                       if (err)
-                               fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err);
-               }
-       } else {
+       }
+       break;
+       case TELEMETRY_TYPE_HOST_0:
+       case TELEMETRY_TYPE_HOST_1:
+       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, cfg.file, sn, tele_type, tele_area, true);
+               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;
+       }
 
-       printf("telemetry-log done.\n");
-
+       printf("ocp internal-log command completed.\n");
+out:
+       dev_close(dev);
        return err;
 }
 
@@ -2829,139 +3128,12 @@ static int get_dssd_async_event_config(int argc, char **argv, struct command *cm
 ///////////////////////////////////////////////////////////////////////////////
 /// Telemetry String Log Format Log Page (LID : C9h)
 
-/* 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
-
-/**
- * struct telemetry_str_log_format - Telemetry String Log Format
- * @log_page_version:          indicates the version of the mapping this log page uses 
- *                             Shall be set to 01h.
- * @reserved1:                 Reserved.
- * @log_page_guid:             Shall be set to B13A83691A8F408B9EA495940057AA44h.
- * @sls:                       Shall be set to the number of DWORDS in the String Log.
- * @reserved2:                 reserved.
- * @sits:                      shall be set to the number of DWORDS in the Statistics 
- *                             Identifier String Table
- * @ests:                      Shall be set to the number of DWORDS from byte 0 of this 
- *                             log page to the start of the Event String Table
- * @estsz:                     shall be set to the number of DWORDS in the Event String Table
- * @vu_eve_sts:                Shall be set to the number of DWORDS from byte 0 of this 
- *                             log page to the start of the VU Event String Table
- * @vu_eve_st_sz:              shall be set to the number of DWORDS in the VU Event String Table
- * @ascts:                     the number of DWORDS from byte 0 of this log page until the ASCII Table Starts.
- * @asctsz:                    the number of DWORDS in the ASCII Table
- * @fifo1:                     FIFO 0 ASCII String
- * @fifo2:                     FIFO 1 ASCII String
- * @fifo3:                     FIFO 2 ASCII String 
- * @fifo4:                     FIFO 3 ASCII String
- * @fif05:                     FIFO 4 ASCII String
- * @fifo6:                     FIFO 5 ASCII String
- * @fifo7:                     FIFO 6 ASCII String
- * @fifo8:                     FIFO 7 ASCII String
- * @fifo9:                     FIFO 8 ASCII String 
- * @fifo10:                    FIFO 9 ASCII String
- * @fif011:                    FIFO 10 ASCII String
- * @fif012:                    FIFO 11 ASCII String
- * @fifo13:                    FIFO 12 ASCII String
- * @fif014:                    FIFO 13 ASCII String
- * @fif015:                    FIFO 14 ASCII String
- * @fif016:                    FIFO 15 ASCII String
- * @reserved3:                 reserved
- */
-struct __attribute__((__packed__)) telemetry_str_log_format {
-       __u8    log_page_version;
-       __u8    reserved1[15];
-       __u8    log_page_guid[C9_GUID_LENGTH];
-       __le64  sls;
-       __u8    reserved2[24];
-       __le64  sits;
-       __le64  sitsz;
-       __le64  ests;
-       __le64  estsz;
-       __le64  vu_eve_sts;
-       __le64  vu_eve_st_sz;
-       __le64  ascts;
-       __le64  asctsz;
-       __u8    fifo1[16];
-       __u8    fifo2[16];
-       __u8    fifo3[16];
-       __u8    fifo4[16];
-       __u8    fifo5[16];
-       __u8    fifo6[16];
-       __u8    fifo7[16];
-       __u8    fifo8[16];
-       __u8    fifo9[16];
-       __u8    fifo10[16];
-       __u8    fifo11[16];
-       __u8    fifo12[16];
-       __u8    fifo13[16];
-       __u8    fifo14[16];
-       __u8    fifo15[16];
-       __u8    fifo16[16];
-       __u8    reserved3[48];
-};
-
-/*
- * struct statistics_id_str_table_entry - Statistics Identifier String Table Entry
- * @vs_si:                    Shall be set the Vendor Unique Statistic Identifier number.
- * @reserved1:                Reserved
- * @ascii_id_len:             Shall be set the number of ASCII Characters that are valid.
- * @ascii_id_ofst:            Shall be set to the offset from DWORD 0/Byte 0 of the Start 
- *                            of the ASCII Table to the first character of the string for 
- *                            this Statistic Identifier string..
- * @reserved2                 reserved
- */
-struct __attribute__((__packed__)) statistics_id_str_table_entry {
-       __le16  vs_si;
-       __u8    reserved1;
-       __u8    ascii_id_len;
-       __le64  ascii_id_ofst;
-       __le32  reserved2;
-};
-
-/*
- * struct event_id_str_table_entry - Event Identifier String Table Entry
- * @deb_eve_class:            Shall be set the Debug Class.
- * @ei:                       Shall be set to the Event Identifier
- * @ascii_id_len:             Shall be set the number of ASCII Characters that are valid.
- * @ascii_id_ofst:            This is the offset from DWORD 0/ Byte 0 of the start of the
- *                            ASCII table to the ASCII data for this identifier
- * @reserved2                 reserved
- */
-struct __attribute__((__packed__)) event_id_str_table_entry {
-       __u8      deb_eve_class;
-       __le16    ei;
-       __u8      ascii_id_len;
-       __le64    ascii_id_ofst;
-       __le32    reserved2;
-};
-
-/*
- * struct vu_event_id_str_table_entry - VU Event Identifier String Table Entry
- * @deb_eve_class:            Shall be set the Debug Class.
- * @vu_ei:                    Shall be set to the VU Event Identifier
- * @ascii_id_len:             Shall be set the number of ASCII Characters that are valid.
- * @ascii_id_ofst:            This is the offset from DWORD 0/ Byte 0 of the start of the 
- *                            ASCII table to the ASCII data for this identifier
- * @reserved                  reserved
- */
-struct __attribute__((__packed__)) vu_event_id_str_table_entry {
-       __u8      deb_eve_class;
-       __le16    vu_ei;
-       __u8      ascii_id_len;
-       __le64    ascii_id_ofst;
-       __le32    reserved;
-};
-
 /* Function declaration for Telemetry String Log Format (LID:C9h) */
 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)
+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;
@@ -3162,7 +3334,7 @@ static int ocp_print_C9_log_normal(struct telemetry_str_log_format *log_data,__u
        return 0;
 }
 
-static int ocp_print_C9_log_json(struct telemetry_str_log_format *log_data,__u8 *log_data_buf)
+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];
@@ -3401,23 +3573,17 @@ static int ocp_print_C9_log_json(struct telemetry_str_log_format *log_data,__u8
        return 0;
 }
 
-static void ocp_print_c9_log_binary(__u8 *log_data_buf,int total_log_page_size)
+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;
-       __u8 *header_data;
-       struct telemetry_str_log_format *log_data;
+
        nvme_print_flags_t fmt;
-       __u8 *full_log_buf_data = NULL;
-       __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;
-       __le64 total_log_page_sz = 0;
 
        ret = validate_output_format(format, &fmt);
        if (ret < 0) {
@@ -3425,75 +3591,25 @@ static int get_c9_log_page(struct nvme_dev *dev, char *format)
                return ret;
        }
 
-       header_data = (__u8 *)malloc(sizeof(__u8) * C9_TELEMETRY_STR_LOG_LEN);
-       if (!header_data) {
-               fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
-               return -1;
-       }
-       memset(header_data, 0, sizeof(__u8) * C9_TELEMETRY_STR_LOG_LEN);
-
-       ret = nvme_get_log_simple(dev_fd(dev), C9_TELEMETRY_STRING_LOG_ENABLE_OPCODE,
-                                 C9_TELEMETRY_STR_LOG_LEN, header_data);
+       get_c9_log_page_data(dev, 1, 0);
 
        if (!ret) {
-               log_data = (struct telemetry_str_log_format *)header_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);
-
-               //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);
-
-
-
-               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);
-
-               full_log_buf_data = (__u8 *)malloc(sizeof(__u8) * total_log_page_sz);
-               if (!full_log_buf_data) {
-                       fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
-                       return -1;
-               }
-               memset(full_log_buf_data, 0, sizeof(__u8) * total_log_page_sz);
-
-               ret = nvme_get_log_simple(dev_fd(dev), C9_TELEMETRY_STRING_LOG_ENABLE_OPCODE,
-                                         total_log_page_sz, full_log_buf_data);
-
-               if (!ret) {
-                       switch (fmt) {
-                       case NORMAL:
-                               ocp_print_C9_log_normal(log_data,full_log_buf_data);
-                               break;
-                       case JSON:
-                               ocp_print_C9_log_json(log_data,full_log_buf_data);
-                               break;
-                       case BINARY:
-                               ocp_print_c9_log_binary(full_log_buf_data,total_log_page_sz);
-                               break;
-                       default:
-                               fprintf(stderr, "unhandled output format\n");
-                               break;
-                       }
-               } else{
-                       fprintf(stderr, "ERROR : OCP : Unable to read C9 data from buffer\n");
+               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 {
+       } else
                fprintf(stderr, "ERROR : OCP : Unable to read C9 data from buffer\n");
-       }
-
-       free(header_data);
-       free(full_log_buf_data);
 
        return ret;
 }
index 2842dc16ef826c7ae091dc905244e4ef568bfb7e..11963be4372bc37fa61620e2abea9b67e92850c1 100644 (file)
@@ -58,6 +58,7 @@ void print_telemetry_fifo_event(__u8 class_type,
        __u32 size = size_dw * 4;
        char time_str[40];
        uint64_t timestamp = 0;
+
        memset((void *)time_str, '\0', 40);
 
        if (class_type) {
@@ -200,3 +201,1366 @@ void print_telemetry_fifo_event(__u8 class_type,
                break;
        }
 }
+
+struct statistic_entry statistic_identifiers_map[] = {
+       { 0x00, "Error, this entry does not exist." },
+       { 0x01, "Outstanding Admin Commands" },
+       { 0x02, "Host Write Bandwidth"},
+       { 0x03, "GC Write Bandwidth"},
+       { 0x04, "Active Namespaces"},
+       { 0x05, "Internal Write Workload"},
+       { 0x06, "Internal Read Workload"},
+       { 0x07, "Internal Write Queue Depth"},
+       { 0x08, "Internal Read Queue Depth"},
+       { 0x09, "Pending Trim LBA Count"},
+       { 0x0A, "Host Trim LBA Request Count"},
+       { 0x0B, "Current NVMe Power State"},
+       { 0x0C, "Current DSSD Power State"},
+       { 0x0D, "Program Fail Count"},
+       { 0x0E, "Erase Fail Count"},
+       { 0x0F, "Read Disturb Writes"},
+       { 0x10, "Retention Writes"},
+       { 0x11, "Wear Leveling Writes"},
+       { 0x12, "Read Recovery Writes"},
+       { 0x13, "GC Writes"},
+       { 0x14, "SRAM Correctable Count"},
+       { 0x15, "DRAM Correctable Count"},
+       { 0x16, "SRAM Uncorrectable Count"},
+       { 0x17, "DRAM Uncorrectable Count"},
+       { 0x18, "Data Integrity Error Count"},
+       { 0x19, "Read Retry Error Count"},
+       { 0x1A, "PERST Events Count"},
+       { 0x1B, "Max Die Bad Block"},
+       { 0x1C, "Max NAND Channel Bad Block"},
+       { 0x1D, "Minimum NAND Channel Bad Block"}
+};
+
+struct request_data host_log_page_header[] = {
+       { "LogIdentifier", 1 },
+       { "Reserved1", 4 },
+       { "IEEE OUI Identifier", 3 },
+       { "Telemetry Host-Initiated Data Area 1 Last Block", 2 },
+       { "Telemetry Host-Initiated Data Area 2 Last Block", 2 },
+       { "Telemetry Host-Initiated Data Area 3 Last Block", 2 },
+       { "Reserved2", 2 },
+       { "Telemetry Host-Initiated Data Area 4 Last Block", 4 },
+       { "Reserved3", 360 },
+       { "Telemetry Host-Initiated Scope", 1 },
+       { "Telemetry Host Initiated Generation Number", 1 },
+       { "Telemetry Host-Initiated Data Available", 1 },
+       { "Telemetry Controller-Initiated Data Generation Number", 1 }
+};
+
+struct request_data controller_log_page_header[] = {
+       { "LogIdentifier", 1 },
+       { "Reserved1", 4 },
+       { "IEEE OUI Identifier", 3 },
+       { "Telemetry Host-Initiated Data Area 1 Last Block", 2 },
+       { "Telemetry Host-Initiated Data Area 2 Last Block", 2 },
+       { "Telemetry Host-Initiated Data Area 3 Last Block", 2 },
+       { "Reserved2", 2 },
+       { "Telemetry Host-Initiated Data Area 4 Last Block", 4 },
+       { "Reserved3", 361 },
+       { "Telemetry Controller-Initiated Scope", 1 },
+       { "Telemetry Controller-Initiated Data Available", 1 },
+       { "Telemetry Controller-Initiated Data Generation Number", 1 }
+};
+
+struct request_data reason_identifier[] = {
+       { "Error ID", 64 },
+       { "File ID", 8 },
+       { "Line Number", 2 },
+       { "Valid Flags", 1 },
+       { "Reserved", 21 },
+       { "VU Reason Extension", 32 }
+};
+
+struct request_data ocp_header_in_da1[] = {
+       { "Major Version", 2 },
+       { "Minor Version", 2 },
+       { "Reserved1", 4 },
+       { "Timestamp", 8 },
+       { "Log page GUID", 16 },
+       { "Number Telemetry Profiles Supported", 1 },
+       { "Telemetry Profile Selected", 1 },
+       { "Reserved2", 6 },
+       { "Telemetry String Log Size", 8 },
+       { "Reserved3", 8 },
+       { "Firmware Revision", 8 },
+       { "Reserved4", 32 },
+       { "Data Area 1 Statistic Start", 8 },
+       { "Data Area 1 Statistic Size", 8 },
+       { "Data Area 2 Statistic Start", 8 },
+       { "Data Area 2 Statistic Size", 8 },
+       { "Reserved5", 32 },
+       { "Event FIFO 1 Data Area", 1 },
+       { "Event FIFO 2 Data Area", 1 },
+       { "Event FIFO 3 Data Area", 1 },
+       { "Event FIFO 4 Data Area", 1 },
+       { "Event FIFO 5 Data Area", 1 },
+       { "Event FIFO 6 Data Area", 1 },
+       { "Event FIFO 7 Data Area", 1 },
+       { "Event FIFO 8 Data Area", 1 },
+       { "Event FIFO 9 Data Area", 1 },
+       { "Event FIFO 10 Data Area", 1 },
+       { "Event FIFO 11 Data Area", 1 },
+       { "Event FIFO 12 Data Area", 1 },
+       { "Event FIFO 13 Data Area", 1 },
+       { "Event FIFO 14 Data Area", 1 },
+       { "Event FIFO 15 Data Area", 1 },
+       { "Event FIFO 16 Data Area", 1 },
+       { "Event FIFO 1 Start", 8 },
+       { "Event FIFO 1 Size", 8 },
+       { "Event FIFO 2 Start", 8 },
+       { "Event FIFO 2 Size", 8 },
+       { "Event FIFO 3 Start", 8 },
+       { "Event FIFO 3 Size", 8 },
+       { "Event FIFO 4 Start", 8 },
+       { "Event FIFO 4 Size", 8 },
+       { "Event FIFO 5 Start", 8 },
+       { "Event FIFO 5 Size", 8 },
+       { "Event FIFO 6 Start", 8 },
+       { "Event FIFO 6 Size", 8 },
+       { "Event FIFO 7 Start", 8 },
+       { "Event FIFO 7 Size", 8 },
+       { "Event FIFO 8 Start", 8 },
+       { "Event FIFO 8 Size", 8 },
+       { "Event FIFO 9 Start", 8 },
+       { "Event FIFO 9 Size", 8 },
+       { "Event FIFO 10 Start", 8 },
+       { "Event FIFO 10 Size", 8 },
+       { "Event FIFO 11 Start", 8 },
+       { "Event FIFO 11 Size", 8 },
+       { "Event FIFO 12 Start", 8 },
+       { "Event FIFO 12 Size", 8 },
+       { "Event FIFO 13 Start", 8 },
+       { "Event FIFO 13 Size", 8 },
+       { "Event FIFO 14 Start", 8 },
+       { "Event FIFO 14 Size", 8 },
+       { "Event FIFO 15 Start", 8 },
+       { "Event FIFO 15 Size", 8 },
+       { "Event FIFO 16 Start", 8 },
+       { "Event FIFO 16 Size", 8 },
+       { "Reserved6", 80 }
+};
+
+struct request_data smart[] = {
+       { "Critical Warning", 1 },
+       { "Composite Temperature", 2 },
+       { "Available Spare", 1 },
+       { "Available Spare Threshold", 1 },
+       { "Percentage Used", 1 },
+       { "Reserved1", 26 },
+       { "Data Units Read", 16 },
+       { "Data Units Written", 16 },
+       { "Host Read Commands", 16 },
+       { "Host Write Commands", 16 },
+       { "Controller Busy Time", 16 },
+       { "Power Cycles", 16 },
+       { "Power On Hours", 16 },
+       { "Unsafe Shutdowns", 16 },
+       { "Media and Data Integrity Errors", 16 },
+       { "Number of Error Information Log Entries", 16 },
+       { "Warning Composite Temperature Time", 4 },
+       { "Critical Composite Temperature Time", 4 },
+       { "Temperature Sensor 1", 2 },
+       { "Temperature Sensor 2", 2 },
+       { "Temperature Sensor 3", 2 },
+       { "Temperature Sensor 4", 2 },
+       { "Temperature Sensor 5", 2 },
+       { "Temperature Sensor 6", 2 },
+       { "Temperature Sensor 7", 2 },
+       { "Temperature Sensor 8", 2 },
+       { "Thermal Management Temperature 1 Transition Count", 4 },
+       { "Thermal Management Temperature 2 Transition Count", 4 },
+       { "Total Time for Thermal Management Temperature 1", 4 },
+       { "Total Time for Thermal Management Temperature 2", 4 },
+       { "Reserved2", 280 }
+};
+
+struct request_data smart_extended[] = {
+       { "Physical Media Units Written", 16 },
+       { "Physical Media Units Read", 16 },
+       { "Bad User NAND Blocks Raw Count", 6 },
+       { "Bad User NAND Blocks Normalized Value", 2 },
+       { "Bad System NAND Blocks Raw Count", 6 },
+       { "Bad System NAND Blocks Normalized Value", 2 },
+       { "XOR Recovery Count", 8 },
+       { "Uncorrectable Read Error Count", 8 },
+       { "Soft ECC Error Count", 8 },
+       { "End to End Correction Counts Detected Errors", 4 },
+       { "End to End Correction Counts Corrected Errors", 4 },
+       { "System Data Percent Used", 1 },
+       { "Refresh Counts", 7 },
+       { "Maximum User Data Erase Count", 4 },
+       { "Minimum User Data Erase Count", 4 },
+       { "Number of thermal throttling events", 1 },
+       { "Current Throttling Status", 1 },
+       { "Errata Version Field", 1 },
+       { "Point Version Field", 2 },
+       { "Minor Version Field", 2 },
+       { "Major Version Field", 1 },
+       { "PCIe Correctable Error Count", 8 },
+       { "Incomplete Shutdowns", 4 },
+       { "Reserved1", 4 },
+       { "Percent Free Blocks", 1 },
+       { "Reserved2", 7 },
+       { "Capacitor Health", 2 },
+       { "NVMe Base Errata Version", 1 },
+       { "NVMe Command Set Errata Version", 1 },
+       { "Reserved3", 4 },
+       { "Unaligned IO", 8 },
+       { "Security Version Number", 8 },
+       { "Total NUSE", 8 },
+       { "PLP Start Count", 16 },
+       { "Endurance Estimate", 16 },
+       { "PCIe Link Retraining Count", 8 },
+       { "Power State Change Count", 8 },
+       { "Lowest Permitted Firmware Revision", 8 },
+       { "Reserved4", 278 },
+       { "Log Page Version", 2 },
+       { "Log page GUID", 16 }
+};
+
+void json_add_formatted_u32_str(struct json_object *pobject, const char *msg, unsigned int pdata)
+{
+       char data_str[70] = { 0 };
+
+       sprintf(data_str, "0x%x", pdata);
+       json_object_add_value_string(pobject, msg, data_str);
+}
+
+void json_add_formatted_var_size_str(struct json_object *pobject, const char *msg, __u8 *pdata,
+       unsigned int data_size)
+{
+       char description_str[256] = "";
+       char temp_buffer[3] = { 0 };
+
+       for (size_t i = 0; i < data_size; ++i) {
+               sprintf(temp_buffer, "%02X", pdata[i]);
+               strcat(description_str, temp_buffer);
+       }
+
+       json_object_add_value_string(pobject, msg, description_str);
+}
+
+int get_telemetry_das_offset_and_size(
+       struct nvme_ocp_telemetry_common_header *ptelemetry_common_header,
+       struct nvme_ocp_telemetry_offsets *ptelemetry_das_offset)
+{
+       if (NULL == ptelemetry_common_header || NULL == ptelemetry_das_offset) {
+               nvme_show_error("Invalid input arguments.");
+               return -1;
+       }
+
+       if (ptelemetry_common_header->log_id == NVME_LOG_LID_TELEMETRY_HOST)
+               ptelemetry_das_offset->header_size =
+               sizeof(struct nvme_ocp_telemetry_host_initiated_header);
+       else if (ptelemetry_common_header->log_id == NVME_LOG_LID_TELEMETRY_CTRL)
+               ptelemetry_das_offset->header_size =
+               sizeof(struct nvme_ocp_telemetry_controller_initiated_header);
+       else
+               return -1;
+
+       ptelemetry_das_offset->da1_start_offset = ptelemetry_das_offset->header_size;
+       ptelemetry_das_offset->da1_size = ptelemetry_common_header->da1_last_block *
+               OCP_TELEMETRY_DATA_BLOCK_SIZE;
+
+       ptelemetry_das_offset->da2_start_offset = ptelemetry_das_offset->da1_start_offset +
+               ptelemetry_das_offset->da1_size;
+       ptelemetry_das_offset->da2_size =
+               (ptelemetry_common_header->da2_last_block -
+               ptelemetry_common_header->da1_last_block) * OCP_TELEMETRY_DATA_BLOCK_SIZE;
+
+       ptelemetry_das_offset->da3_start_offset = ptelemetry_das_offset->da2_start_offset +
+               ptelemetry_das_offset->da2_size;
+       ptelemetry_das_offset->da3_size =
+               (ptelemetry_common_header->da3_last_block -
+               ptelemetry_common_header->da2_last_block) * OCP_TELEMETRY_DATA_BLOCK_SIZE;
+
+       ptelemetry_das_offset->da4_start_offset = ptelemetry_das_offset->da3_start_offset +
+               ptelemetry_das_offset->da3_size;
+       ptelemetry_das_offset->da4_size =
+               (ptelemetry_common_header->da4_last_block -
+               ptelemetry_common_header->da3_last_block) * OCP_TELEMETRY_DATA_BLOCK_SIZE;
+
+       return 0;
+}
+
+int get_static_id_ascii_string(int identifier, char *description)
+{
+       if (pstring_buffer == NULL)
+               return -1;
+
+       struct nvme_ocp_telemetry_string_header *pocp_ts_header =
+               (struct nvme_ocp_telemetry_string_header *)pstring_buffer;
+
+       //Calculating the sizes of the tables. Note: Data is present in the form of DWORDS,
+       //So multiplying with sizeof(DWORD)
+       unsigned long long sits_table_size = (pocp_ts_header->sitsz) * SIZE_OF_DWORD;
+
+       //Calculating number of entries present in all 3 tables
+       int sits_entries = (int)sits_table_size /
+               sizeof(struct nvme_ocp_statistics_identifier_string_table);
+
+       for (int sits_entry = 0; sits_entry < sits_entries; sits_entry++) {
+               struct nvme_ocp_statistics_identifier_string_table
+                       *peach_statistic_entry =
+                       (struct nvme_ocp_statistics_identifier_string_table *)
+                       (pstring_buffer + (pocp_ts_header->sits * SIZE_OF_DWORD) +
+                       (sits_entry *
+                       sizeof(struct nvme_ocp_statistics_identifier_string_table)));
+
+               if (identifier == (int)peach_statistic_entry->vs_statistic_identifier) {
+                       char *pdescription = (char *)(pstring_buffer +
+                               (pocp_ts_header->ascts * SIZE_OF_DWORD) +
+                               (peach_statistic_entry->ascii_id_offset *
+                               SIZE_OF_DWORD));
+
+                       memcpy(description, pdescription,
+                              peach_statistic_entry->ascii_id_length + 1);
+
+                       // If ASCII string isn't found, see in our internal Map
+                       // for 2.5 Spec defined strings (id < 0x1D).
+                       if ((description == NULL) && (identifier < 0x1D))
+                               memcpy(description,
+                                      statistic_identifiers_map[identifier].description,
+                                      peach_statistic_entry->ascii_id_length + 1);
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+int get_event_id_ascii_string(int identifier, int debug_event_class, char *description)
+{
+       if (pstring_buffer == NULL)
+               return -1;
+
+       struct nvme_ocp_telemetry_string_header *pocp_ts_header =
+               (struct nvme_ocp_telemetry_string_header *)pstring_buffer;
+
+       //Calculating the sizes of the tables. Note: Data is present in the form of DWORDS,
+       //So multiplying with sizeof(DWORD)
+       unsigned long long ests_table_size = (pocp_ts_header->estsz) * SIZE_OF_DWORD;
+
+       //Calculating number of entries present in all 3 tables
+       int ests_entries = (int)ests_table_size / sizeof(struct nvme_ocp_event_string_table);
+
+       for (int ests_entry = 0; ests_entry < ests_entries; ests_entry++) {
+               struct nvme_ocp_event_string_table *peach_event_entry =
+                       (struct nvme_ocp_event_string_table *)
+                       (pstring_buffer + (pocp_ts_header->ests * SIZE_OF_DWORD) +
+                       (ests_entry * sizeof(struct nvme_ocp_event_string_table)));
+
+               if (identifier == (int)peach_event_entry->event_identifier &&
+                       debug_event_class == (int)peach_event_entry->debug_event_class) {
+                       char *pdescription = (char *)(pstring_buffer +
+                               (pocp_ts_header->ascts * SIZE_OF_DWORD) +
+                               (peach_event_entry->ascii_id_offset * SIZE_OF_DWORD));
+
+                       memcpy(description, pdescription,
+                              peach_event_entry->ascii_id_length + 1);
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+int get_vu_event_id_ascii_string(int identifier, int debug_event_class, char *description)
+{
+       if (pstring_buffer == NULL)
+               return -1;
+
+       struct nvme_ocp_telemetry_string_header *pocp_ts_header =
+               (struct nvme_ocp_telemetry_string_header *)pstring_buffer;
+
+       //Calculating the sizes of the tables. Note: Data is present in the form of DWORDS,
+       //So multiplying with sizeof(DWORD)
+       unsigned long long vuests_table_size = (pocp_ts_header->vu_estsz) * SIZE_OF_DWORD;
+
+       //Calculating number of entries present in all 3 tables
+       int vu_ests_entries = (int)vuests_table_size /
+               sizeof(struct nvme_ocp_vu_event_string_table);
+
+       for (int vu_ests_entry = 0; vu_ests_entry < vu_ests_entries; vu_ests_entry++) {
+               struct nvme_ocp_vu_event_string_table *peach_vu_event_entry =
+                       (struct nvme_ocp_vu_event_string_table *)
+                       (pstring_buffer + (pocp_ts_header->vu_ests * SIZE_OF_DWORD) +
+                       (vu_ests_entry * sizeof(struct nvme_ocp_vu_event_string_table)));
+
+               if (identifier == (int)peach_vu_event_entry->vu_event_identifier &&
+                       debug_event_class ==
+                               (int)peach_vu_event_entry->debug_event_class) {
+                       char *pdescription = (char *)(pstring_buffer +
+                               (pocp_ts_header->ascts * SIZE_OF_DWORD) +
+                               (peach_vu_event_entry->ascii_id_offset * SIZE_OF_DWORD));
+
+                       memcpy(description, pdescription,
+                              peach_vu_event_entry->ascii_id_length + 1);
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+int parse_ocp_telemetry_string_log(int event_fifo_num, int identifier, int debug_event_class,
+       enum ocp_telemetry_string_tables string_table, char *description)
+{
+       if (pstring_buffer == NULL)
+               return -1;
+
+       if (event_fifo_num != 0) {
+               struct nvme_ocp_telemetry_string_header *pocp_ts_header =
+                       (struct nvme_ocp_telemetry_string_header *)pstring_buffer;
+
+               if (*pocp_ts_header->fifo_ascii_string[event_fifo_num-1] != '\0')
+                       memcpy(description, pocp_ts_header->fifo_ascii_string[event_fifo_num-1],
+                              16);
+               else
+                       description = "";
+
+               return 0;
+       }
+
+       if (string_table == STATISTICS_IDENTIFIER_STRING)
+               get_static_id_ascii_string(identifier, description);
+       else if (string_table == EVENT_STRING)
+               get_event_id_ascii_string(identifier, debug_event_class, description);
+       else if (string_table == VU_EVENT_STRING)
+               get_vu_event_id_ascii_string(identifier, debug_event_class, description);
+
+       return 0;
+}
+
+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);
+
+       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);
+
+       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);
+       } 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);
+               } 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);
+               }
+       }
+}
+
+void parse_pcie_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_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);
+       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);
+
+       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);
+       } 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);
+               } 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);
+               }
+       }
+}
+
+void parse_nvme_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_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);
+       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);
+
+       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);
+       } 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);
+               } 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);
+               }
+       }
+}
+
+void parse_common_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_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);
+               } 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);
+               }
+       }
+}
+
+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)
+{
+       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] = "";
+
+       parse_ocp_telemetry_string_log(0, pmedia_wear_event->vu_event_identifier,
+                                       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);
+       } 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);
+               } 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);
+               }
+       }
+}
+
+int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
+       struct json_object *pevent_fifos_object, unsigned char *pstring_buffer,
+       struct nvme_ocp_telemetry_offsets *poffsets, __u64 fifo_size, FILE *fp)
+{
+       if (NULL == pfifo_start || NULL == poffsets) {
+               nvme_show_error("Input buffer was NULL");
+               return -1;
+       }
+
+       int status = 0;
+       unsigned int event_fifo_number = fifo_num + 1;
+       char *description = (char *)malloc((40 + 1) * sizeof(char));
+
+       memset(description, 0, sizeof(40));
+
+       status =
+               parse_ocp_telemetry_string_log(event_fifo_number, 0, 0, EVENT_STRING, description);
+
+       if (status != 0) {
+               nvme_show_error("Failed to get C9 String. status: %d\n", status);
+               return -1;
+       }
+
+       char event_fifo_name[100] = {0};
+
+       snprintf(event_fifo_name, sizeof(event_fifo_name), "%s%d%s%s", "EVENT FIFO ",
+                event_fifo_number, " - ", description);
+
+       struct json_object *pevent_fifo_array = NULL;
+
+       if (pevent_fifos_object != NULL)
+               pevent_fifo_array = json_create_array();
+       else {
+               char buffer[1024] = {0};
+
+               sprintf(buffer, "%s%s\n%s", STR_LINE, event_fifo_name, STR_LINE);
+               if (fp)
+                       fprintf(fp, "%s", buffer);
+               else
+                       printf("%s", buffer);
+       }
+
+       int offset_to_move = 0;
+       unsigned int event_des_size = sizeof(struct nvme_ocp_telemetry_event_descriptor);
+
+       while ((fifo_size > 0) && (offset_to_move < fifo_size)) {
+               struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor =
+                       (struct nvme_ocp_telemetry_event_descriptor *)
+                       (pfifo_start + offset_to_move);
+
+               if (pevent_descriptor != NULL && pevent_descriptor->event_data_size >= 0) {
+                       //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;
+
+                       char description_str[256] = "";
+
+                       parse_ocp_telemetry_string_log(0, pevent_descriptor->event_id,
+                               pevent_descriptor->debug_event_class_type, EVENT_STRING,
+                               description_str);
+
+                       struct json_object *pevent_descriptor_obj =
+                               ((pevent_fifos_object != NULL)?json_create_object():NULL);
+
+                       if (pevent_descriptor_obj != NULL) {
+                               json_add_formatted_u32_str(pevent_descriptor_obj,
+                                       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);
+                               json_object_add_value_string(pevent_descriptor_obj,
+                                       STR_EVENT_STRING, description_str);
+                               json_add_formatted_u32_str(pevent_descriptor_obj,
+                                       STR_EVENT_DATA_SIZE, pevent_descriptor->event_data_size);
+
+                               if (pevent_descriptor->debug_event_class_type >= 0x80)
+                                       json_add_formatted_var_size_str(pevent_descriptor_obj,
+                                               STR_VU_DATA, pevent_specific_data, data_size);
+                       } else {
+                               if (fp) {
+                                       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);
+                                       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);
+                                       printf("%s: 0x%x\n", STR_EVENT_IDENTIFIER,
+                                              pevent_descriptor->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);
+                               }
+
+                               if (pevent_descriptor->debug_event_class_type >= 0x80)
+                                       print_formatted_var_size_str(STR_VU_DATA,
+                                               pevent_specific_data, data_size, fp);
+                       }
+
+                       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);
+                               break;
+                       case PCIE_CLASS_TYPE:
+                               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);
+                               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);
+                               break;
+                       case MEDIA_WEAR_CLASS_TYPE:
+                               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
+                               *pStaticSnapshotEvent =
+                                       (struct nvme_ocp_statistic_snapshot_evt_class_format *)
+                                       pevent_specific_data;
+                               struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_entry =
+                                       (struct nvme_ocp_telemetry_statistic_descriptor *)
+                                       (&pStaticSnapshotEvent->statisticDescriptorData);
+
+                               parse_statistic(pstatistic_entry, pevent_descriptor_obj, fp);
+                               break;
+                       }
+                       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;
+
+       offset_to_move += (pevent_descriptor->event_data_size * SIZE_OF_DWORD + event_des_size);
+       }
+
+       if (pevent_fifos_object != NULL && pevent_fifo_array != NULL)
+               json_object_add_value_array(pevent_fifos_object, event_fifo_name,
+                       pevent_fifo_array);
+
+       free(description);
+       return 0;
+}
+
+int parse_event_fifos(struct json_object *root, struct nvme_ocp_telemetry_offsets *poffsets,
+       FILE *fp)
+{
+       if (poffsets == NULL) {
+               nvme_show_error("Input buffer was NULL");
+               return -1;
+       }
+
+       struct json_object *pevent_fifos_object = NULL;
+
+       if (root != NULL)
+               pevent_fifos_object = json_create_object();
+
+       __u8 *pda1_header_offset = ptelemetry_buffer + poffsets->da1_start_offset;//512
+       __u8 *pda2_offset = ptelemetry_buffer + poffsets->da2_start_offset;
+       struct nvme_ocp_header_in_da1 *pda1_header = (struct nvme_ocp_header_in_da1 *)
+               pda1_header_offset;
+       struct nvme_ocp_event_fifo_data event_fifo[MAX_NUM_FIFOS];
+
+       for (int fifo_num = 0; fifo_num < MAX_NUM_FIFOS; fifo_num++) {
+               event_fifo[fifo_num].event_fifo_num = fifo_num;
+               event_fifo[fifo_num].event_fifo_da = pda1_header->event_fifo_da[fifo_num];
+               event_fifo[fifo_num].event_fifo_start =
+                       pda1_header->fifo_offsets[fifo_num].event_fifo_start;
+               event_fifo[fifo_num].event_fifo_size =
+                       pda1_header->fifo_offsets[fifo_num].event_fifo_size;
+       }
+
+       //Parse all the FIFOs DA wise
+       for (int fifo_no = 0; fifo_no < MAX_NUM_FIFOS; fifo_no++) {
+               if (event_fifo[fifo_no].event_fifo_da == poffsets->data_area) {
+                       __u64 fifo_offset =
+                               (event_fifo[fifo_no].event_fifo_start  * SIZE_OF_DWORD);
+                       __u64 fifo_size =
+                               (event_fifo[fifo_no].event_fifo_size  * SIZE_OF_DWORD);
+                       __u8 *pfifo_start = NULL;
+
+                       if (event_fifo[fifo_no].event_fifo_da == 1)
+                               pfifo_start = pda1_header_offset + fifo_offset;
+                       else if (event_fifo[fifo_no].event_fifo_da == 2)
+                               pfifo_start = pda2_offset + fifo_offset;
+                       else {
+                               nvme_show_error("Unsupported Data Area:[%d]", poffsets->data_area);
+                               return -1;
+                       }
+
+                       int status = parse_event_fifo(fifo_no, pfifo_start, pevent_fifos_object,
+                                                     pstring_buffer, poffsets, fifo_size, fp);
+
+                       if (status != 0) {
+                               nvme_show_error("Failed to parse Event FIFO. status:%d\n", status);
+                               return -1;
+                       }
+               }
+       }
+
+       if (pevent_fifos_object != NULL && root != NULL) {
+               const char *data_area = (poffsets->data_area == 1 ? STR_DA_1_EVENT_FIFO_INFO :
+                                       STR_DA_2_EVENT_FIFO_INFO);
+
+               json_object_add_value_array(root, data_area, pevent_fifos_object);
+       }
+
+       return 0;
+}
+
+int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_entry,
+                   struct json_object *pstats_array, FILE *fp)
+{
+       if (pstatistic_entry == NULL) {
+               nvme_show_error("Input buffer was NULL");
+               return -1;
+       }
+
+       unsigned int data_size = pstatistic_entry->statistic_data_size * SIZE_OF_DWORD;
+       __u8 *pdata = (__u8 *)pstatistic_entry +
+               sizeof(struct nvme_ocp_telemetry_statistic_descriptor);
+       char description_str[256] = "";
+
+       parse_ocp_telemetry_string_log(0, pstatistic_entry->statistic_id, 0,
+               STATISTICS_IDENTIFIER_STRING, description_str);
+
+       if (pstats_array != NULL) {
+               struct json_object *pstatistics_object = json_create_object();
+
+               json_add_formatted_u32_str(pstatistics_object, STR_STATISTICS_IDENTIFIER,
+                       pstatistic_entry->statistic_id);
+               json_object_add_value_string(pstatistics_object, STR_STATISTICS_IDENTIFIER_STR,
+                       description_str);
+               json_add_formatted_u32_str(pstatistics_object,
+                       STR_STATISTICS_INFO_BEHAVIOUR_TYPE,
+                       pstatistic_entry->statistic_info_behaviour_type);
+               json_add_formatted_u32_str(pstatistics_object, STR_STATISTICS_INFO_RESERVED,
+                       pstatistic_entry->statistic_info_reserved);
+               json_add_formatted_u32_str(pstatistics_object, STR_NAMESPACE_IDENTIFIER,
+                       pstatistic_entry->ns_info_nsid);
+               json_add_formatted_u32_str(pstatistics_object, STR_NAMESPACE_INFO_VALID,
+                       pstatistic_entry->ns_info_ns_info_valid);
+               json_add_formatted_u32_str(pstatistics_object, STR_STATISTICS_DATA_SIZE,
+                       pstatistic_entry->statistic_data_size);
+               json_add_formatted_u32_str(pstatistics_object, STR_RESERVED,
+                       pstatistic_entry->reserved);
+               json_add_formatted_var_size_str(pstatistics_object, STR_STATISTICS_SPECIFIC_DATA,
+                       pdata, data_size);
+
+               if (pstatistics_object != NULL)
+                       json_array_add_value_object(pstats_array, pstatistics_object);
+       } else {
+               if (fp) {
+                       fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_IDENTIFIER,
+                               pstatistic_entry->statistic_id);
+                       fprintf(fp, "%s: %s\n", STR_STATISTICS_IDENTIFIER_STR, description_str);
+                       fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_INFO_BEHAVIOUR_TYPE,
+                               pstatistic_entry->statistic_info_behaviour_type);
+                       fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_INFO_RESERVED,
+                               pstatistic_entry->statistic_info_reserved);
+                       fprintf(fp, "%s: 0x%x\n", STR_NAMESPACE_IDENTIFIER,
+                               pstatistic_entry->ns_info_nsid);
+                       fprintf(fp, "%s: 0x%x\n", STR_NAMESPACE_INFO_VALID,
+                               pstatistic_entry->ns_info_ns_info_valid);
+                       fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
+                               pstatistic_entry->statistic_data_size);
+                       fprintf(fp, "%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
+                       print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
+                               data_size, fp);
+                       fprintf(fp, STR_LINE2);
+               } else {
+                       printf("%s: 0x%x\n", STR_STATISTICS_IDENTIFIER,
+                              pstatistic_entry->statistic_id);
+                       printf("%s: %s\n", STR_STATISTICS_IDENTIFIER_STR, description_str);
+                       printf("%s: 0x%x\n", STR_STATISTICS_INFO_BEHAVIOUR_TYPE,
+                              pstatistic_entry->statistic_info_behaviour_type);
+                       printf("%s: 0x%x\n", STR_STATISTICS_INFO_RESERVED,
+                              pstatistic_entry->statistic_info_reserved);
+                       printf("%s: 0x%x\n", STR_NAMESPACE_IDENTIFIER,
+                              pstatistic_entry->ns_info_nsid);
+                       printf("%s: 0x%x\n", STR_NAMESPACE_INFO_VALID,
+                              pstatistic_entry->ns_info_ns_info_valid);
+                       printf("%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
+                              pstatistic_entry->statistic_data_size);
+                       printf("%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
+                       print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
+                                               data_size, fp);
+                       printf(STR_LINE2);
+               }
+       }
+
+       return 0;
+}
+
+int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets *poffsets,
+                    FILE *fp)
+{
+       if (poffsets == NULL) {
+               nvme_show_error("Input buffer was NULL");
+               return -1;
+       }
+
+       __u8 *pda1_ocp_header_offset = ptelemetry_buffer + poffsets->header_size;//512
+       __u32 statistics_size = 0;
+       __u32 stats_da_1_start_dw = 0, stats_da_1_size_dw = 0;
+       __u32 stats_da_2_start_dw = 0, stats_da_2_size_dw = 0;
+       __u8 *pstats_offset = NULL;
+
+       if (poffsets->data_area == 1) {
+               __u32 stats_da_1_start = *(__u32 *)(pda1_ocp_header_offset +
+                       offsetof(struct nvme_ocp_header_in_da1, da1_statistic_start));
+               __u32 stats_da_1_size = *(__u32 *)(pda1_ocp_header_offset +
+                       offsetof(struct nvme_ocp_header_in_da1, da1_statistic_size));
+
+               //Data is present in the form of DWORDS, So multiplying with sizeof(DWORD)
+               stats_da_1_start_dw = (stats_da_1_start * SIZE_OF_DWORD);
+               stats_da_1_size_dw = (stats_da_1_size * SIZE_OF_DWORD);
+
+               pstats_offset = pda1_ocp_header_offset + stats_da_1_start_dw;
+               statistics_size = stats_da_1_size_dw;
+       } else if (poffsets->data_area == 2) {
+               __u32 stats_da_2_start = *(__u32 *)(pda1_ocp_header_offset +
+                       offsetof(struct nvme_ocp_header_in_da1, da2_statistic_start));
+               __u32 stats_da_2_size = *(__u32 *)(pda1_ocp_header_offset +
+                       offsetof(struct nvme_ocp_header_in_da1, da2_statistic_size));
+
+               stats_da_2_start_dw = (stats_da_2_start * SIZE_OF_DWORD);
+               stats_da_2_size_dw = (stats_da_2_size * SIZE_OF_DWORD);
+
+               pstats_offset = pda1_ocp_header_offset + poffsets->da1_size + stats_da_2_start_dw;
+               statistics_size = stats_da_2_size_dw;
+       } else {
+               nvme_show_error("Unsupported Data Area:[%d]", poffsets->data_area);
+               return -1;
+       }
+
+       struct json_object *pstats_array = ((root != NULL) ? json_create_array() : NULL);
+
+       __u32 stat_des_size = sizeof(struct nvme_ocp_telemetry_statistic_descriptor);//8
+       __u32 offset_to_move = 0;
+
+       while (((statistics_size > 0) && (offset_to_move < statistics_size))) {
+               struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_entry =
+                       (struct nvme_ocp_telemetry_statistic_descriptor *)
+                       (pstats_offset + offset_to_move);
+
+               parse_statistic(pstatistic_entry, pstats_array, fp);
+               offset_to_move += (pstatistic_entry->statistic_data_size * SIZE_OF_DWORD +
+                       stat_des_size);
+       }
+
+       if (root != NULL && pstats_array != NULL) {
+               const char *pdata_area =
+                       (poffsets->data_area == 1 ? STR_DA_1_STATS : STR_DA_2_STATS);
+
+               json_object_add_value_array(root, pdata_area, pstats_array);
+       }
+
+       return 0;
+}
+
+int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
+{
+       int status = 0;
+
+       if (options->output_file != NULL) {
+               FILE *fp = fopen(options->output_file, "w");
+
+               if (fp) {
+                       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);
+                       else if (!strcmp(options->telemetry_type, "controller"))
+                               generic_structure_parser(ptelemetry_buffer,
+                                       controller_log_page_header,
+                                       ARRAY_SIZE(controller_log_page_header), NULL, 0, fp);
+                       fprintf(fp, STR_LINE);
+                       fprintf(fp, "%s\n", STR_REASON_IDENTIFIER);
+                       fprintf(fp, STR_LINE);
+                       __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, fp);
+
+                       fprintf(fp, STR_LINE);
+                       fprintf(fp, "%s\n", STR_TELEMETRY_HOST_DATA_BLOCK_1);
+                       fprintf(fp, STR_LINE);
+
+                       //Set DA to 1 and get offsets
+                       struct nvme_ocp_telemetry_offsets offsets = { 0 };
+
+                       offsets.data_area = 1;// Default DA - DA1
+
+                       struct nvme_ocp_telemetry_common_header *ptelemetry_common_header =
+                               (struct nvme_ocp_telemetry_common_header *) ptelemetry_buffer;
+
+                       get_telemetry_das_offset_and_size(ptelemetry_common_header, &offsets);
+
+                       __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, fp);
+
+                       fprintf(fp, STR_LINE);
+                       fprintf(fp, "%s\n", STR_SMART_HEALTH_INFO);
+                       fprintf(fp, STR_LINE);
+                       __u8 *pda1_smart_offset = pda1_header_offset +
+                               offsetof(struct nvme_ocp_header_in_da1, smart_health_info);
+                       //512+512 =1024
+
+                       generic_structure_parser(pda1_smart_offset, smart, ARRAY_SIZE(smart),
+                               NULL, 0, fp);
+
+                       fprintf(fp, STR_LINE);
+                       fprintf(fp, "%s\n", STR_SMART_HEALTH_INTO_EXTENDED);
+                       fprintf(fp, STR_LINE);
+                       __u8 *pda1_smart_ext_offset = pda1_header_offset +
+                                                       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, fp);
+
+                       fprintf(fp, STR_LINE);
+                       fprintf(fp, "%s\n", STR_DA_1_STATS);
+                       fprintf(fp, STR_LINE);
+
+                       status = parse_statistics(NULL, &offsets, fp);
+                       if (status != 0) {
+                               nvme_show_error("status: %d\n", status);
+                               return -1;
+                       }
+
+                       fprintf(fp, STR_LINE);
+                       fprintf(fp, "%s\n", STR_DA_1_EVENT_FIFO_INFO);
+                       fprintf(fp, STR_LINE);
+                       status = parse_event_fifos(NULL, &offsets, fp);
+                       if (status != 0) {
+                               nvme_show_error("status: %d\n", status);
+                               return -1;
+                       }
+
+                       //Set the DA to 2
+                       if (options->data_area == 2) {
+                               offsets.data_area = 2;
+                               fprintf(fp, STR_LINE);
+                               fprintf(fp, "%s\n", STR_DA_2_STATS);
+                               fprintf(fp, STR_LINE);
+                               status = parse_statistics(NULL, &offsets, fp);
+
+                               if (status != 0) {
+                                       nvme_show_error("status: %d\n", status);
+                                       return -1;
+                               }
+
+                               fprintf(fp, STR_LINE);
+                               fprintf(fp, "%s\n", STR_DA_2_EVENT_FIFO_INFO);
+                               fprintf(fp, STR_LINE);
+                               status = parse_event_fifos(NULL, &offsets, fp);
+                               if (status != 0) {
+                                       nvme_show_error("status: %d\n", status);
+                                       return -1;
+                               }
+                       }
+
+                       fprintf(fp, STR_LINE);
+                       fclose(fp);
+               } else {
+                       nvme_show_error("Failed to open %s file.\n", options->output_file);
+                       return -1;
+               }
+       } else {
+               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);
+               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);
+
+               printf(STR_LINE);
+               printf("%s\n", STR_REASON_IDENTIFIER);
+               printf(STR_LINE);
+               __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);
+
+               printf(STR_LINE);
+               printf("%s\n", STR_TELEMETRY_HOST_DATA_BLOCK_1);
+               printf(STR_LINE);
+
+               //Set DA to 1 and get offsets
+               struct nvme_ocp_telemetry_offsets offsets = { 0 };
+
+               offsets.data_area = 1;
+
+               struct nvme_ocp_telemetry_common_header *ptelemetry_common_header =
+                       (struct nvme_ocp_telemetry_common_header *) ptelemetry_buffer;
+
+               get_telemetry_das_offset_and_size(ptelemetry_common_header, &offsets);
+
+               __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);
+
+               printf(STR_LINE);
+               printf("%s\n", STR_SMART_HEALTH_INFO);
+               printf(STR_LINE);
+               __u8 *pda1_smart_offset = pda1_header_offset +
+                       offsetof(struct nvme_ocp_header_in_da1, smart_health_info);
+
+               generic_structure_parser(pda1_smart_offset, smart, ARRAY_SIZE(smart), NULL, 0,
+                                        NULL);
+
+               printf(STR_LINE);
+               printf("%s\n", STR_SMART_HEALTH_INTO_EXTENDED);
+               printf(STR_LINE);
+               __u8 *pda1_smart_ext_offset = pda1_header_offset +
+                       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);
+
+               printf(STR_LINE);
+               printf("%s\n", STR_DA_1_STATS);
+               printf(STR_LINE);
+               status = parse_statistics(NULL, &offsets, NULL);
+               if (status != 0) {
+                       nvme_show_error("status: %d\n", status);
+                       return -1;
+               }
+
+               printf(STR_LINE);
+               printf("%s\n", STR_DA_1_EVENT_FIFO_INFO);
+               printf(STR_LINE);
+               status = parse_event_fifos(NULL, &offsets, NULL);
+               if (status != 0) {
+                       nvme_show_error("status: %d\n", status);
+                       return -1;
+               }
+
+               //Set the DA to 2
+               if (options->data_area == 2) {
+                       offsets.data_area = 2;
+                       printf(STR_LINE);
+                       printf("%s\n", STR_DA_2_STATS);
+                       printf(STR_LINE);
+                       status = parse_statistics(NULL, &offsets, NULL);
+                       if (status != 0) {
+                               nvme_show_error("status: %d\n", status);
+                               return -1;
+                       }
+
+                       printf(STR_LINE);
+                       printf("%s\n", STR_DA_2_EVENT_FIFO_INFO);
+                       printf(STR_LINE);
+                       status = parse_event_fifos(NULL, &offsets, NULL);
+                       if (status != 0) {
+                               nvme_show_error("status: %d\n", status);
+                               return -1;
+                       }
+               }
+
+               printf(STR_LINE);
+       }
+
+       return status;
+}
+
+int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
+{
+       int status = 0;
+
+       //create json objects
+       struct json_object *root, *pheader, *preason_identifier, *da1_header, *smart_obj,
+       *ext_smart_obj;
+
+       root = json_create_object();
+
+       //Add data to root json object
+
+       //"Log Page Header"
+       pheader = json_create_object();
+
+       generic_structure_parser(ptelemetry_buffer, host_log_page_header,
+                            ARRAY_SIZE(host_log_page_header), pheader, 0, NULL);
+       json_object_add_value_object(root, STR_LOG_PAGE_HEADER, pheader);
+
+       //"Reason Identifier"
+       preason_identifier = json_create_object();
+
+       __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), preason_identifier, 0, NULL);
+       json_object_add_value_object(pheader, STR_REASON_IDENTIFIER, preason_identifier);
+
+       struct nvme_ocp_telemetry_offsets offsets = { 0 };
+
+       //Set DA to 1 and get offsets
+       offsets.data_area = 1;
+       struct nvme_ocp_telemetry_common_header *ptelemetry_common_header =
+               (struct nvme_ocp_telemetry_common_header *) ptelemetry_buffer;
+
+       get_telemetry_das_offset_and_size(ptelemetry_common_header, &offsets);
+
+       //"Telemetry Host-Initiated Data Block 1"
+       __u8 *pda1_header_offset = ptelemetry_buffer + offsets.da1_start_offset;//512
+
+       da1_header = json_create_object();
+
+       generic_structure_parser(pda1_header_offset, ocp_header_in_da1,
+                                ARRAY_SIZE(ocp_header_in_da1), da1_header, 0, NULL);
+       json_object_add_value_object(root, STR_TELEMETRY_HOST_DATA_BLOCK_1, da1_header);
+
+       //"SMART / Health Information Log(LID-02h)"
+       __u8 *pda1_smart_offset = pda1_header_offset + offsetof(struct nvme_ocp_header_in_da1,
+                                                               smart_health_info);
+       smart_obj = json_create_object();
+
+       generic_structure_parser(pda1_smart_offset, smart, ARRAY_SIZE(smart), smart_obj, 0, NULL);
+       json_object_add_value_object(da1_header, STR_SMART_HEALTH_INFO, smart_obj);
+
+       //"SMART / Health Information Extended(LID-C0h)"
+       __u8 *pda1_smart_ext_offset = pda1_header_offset + offsetof(struct nvme_ocp_header_in_da1,
+                                                                   smart_health_info_extended);
+       ext_smart_obj = json_create_object();
+
+       generic_structure_parser(pda1_smart_ext_offset, smart_extended, ARRAY_SIZE(smart_extended),
+                            ext_smart_obj, 0, NULL);
+       json_object_add_value_object(da1_header, STR_SMART_HEALTH_INTO_EXTENDED, ext_smart_obj);
+
+       //Data Area 1 Statistics
+       status = parse_statistics(root, &offsets, NULL);
+       if (status != 0) {
+               nvme_show_error("status: %d\n", status);
+               return -1;
+       }
+
+       //Data Area 1 Event FIFOs
+       status = parse_event_fifos(root, &offsets, NULL);
+       if (status != 0) {
+               nvme_show_error("status: %d\n", status, NULL);
+               return -1;
+       }
+
+       if (options->data_area == 2) {
+               //Set the DA to 2
+               offsets.data_area = 2;
+               //Data Area 2 Statistics
+               status = parse_statistics(root, &offsets, NULL);
+               if (status != 0) {
+                       nvme_show_error("status: %d\n", status);
+                       return -1;
+               }
+
+               //Data Area 2 Event FIFOs
+               status = parse_event_fifos(root, &offsets, NULL);
+               if (status != 0) {
+                       nvme_show_error("status: %d\n", status);
+                       return -1;
+               }
+       }
+
+       if (options->output_file != NULL) {
+               const char *json_string = json_object_to_json_string(root);
+               FILE *fp = fopen(options->output_file, "w");
+
+               if (fp) {
+                       fputs(json_string, fp);
+                       fclose(fp);
+               } else {
+                       nvme_show_error("Failed to open %s file.\n", options->output_file);
+                       return -1;
+               }
+       } else {
+               //Print root json object
+               json_print_object(root, NULL);
+               nvme_show_result("\n");
+               json_free_object(root);
+       }
+
+       return status;
+}
index 312c41db57733b69aa0a46934008d1d834604874..ed31a6c91fd015e59a3a9c4d71d363cd545cf7ef 100644 (file)
@@ -4,6 +4,14 @@
  * Authors: Jeff Lien <jeff.lien@wdc.com>,
  */
 
+#include "nvme.h"
+#include "nvme-print.h"
+#include "util/utils.h"
+#include "common.h"
+
+extern __u8 *ptelemetry_buffer;
+extern __u8 *pstring_buffer;
+
 /*****************************************************************************
  * Telemetry Statistics ID's and Strings
  *****************************************************************************/
@@ -411,6 +419,524 @@ struct telemetry_data_area_1 {
        __u8   smart_health_info_extended[512];
 };
 
+#define DATA_SIZE_12   12
+#define DATA_SIZE_8    8
+#define DATA_SIZE_4    4
+#define MAX_BUFFER_32_KB              0x8000
+#define OCP_TELEMETRY_DATA_BLOCK_SIZE 512
+#define SIZE_OF_DWORD                 4
+#define MAX_NUM_FIFOS                 16
+#define DA1_OFFSET                    512
+#define DEFAULT_ASCII_STRING_SIZE     16
+
+#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
+
+#define STR_LOG_PAGE_HEADER "Log Page Header"
+#define STR_REASON_IDENTIFIER "Reason Identifier"
+#define STR_TELEMETRY_HOST_DATA_BLOCK_1 "Telemetry Host-Initiated Data Block 1"
+#define STR_SMART_HEALTH_INFO "SMART / Health Information Log(LID-02h)"
+#define STR_SMART_HEALTH_INTO_EXTENDED "SMART / Health Information Extended(LID-C0h)"
+#define STR_DA_1_STATS "Data Area 1 Statistics"
+#define STR_DA_2_STATS "Data Area 2 Statistics"
+#define STR_DA_1_EVENT_FIFO_INFO "Data Area 1 Event FIFO info"
+#define STR_DA_2_EVENT_FIFO_INFO "Data Area 2 Event FIFO info"
+#define STR_STATISTICS_IDENTIFIER "Statistics Identifier"
+#define STR_STATISTICS_IDENTIFIER_STR "Statistic Identifier String"
+#define STR_STATISTICS_INFO_BEHAVIOUR_TYPE "Statistics Info Behavior Type"
+#define STR_STATISTICS_INFO_RESERVED "Statistics Info Reserved"
+#define STR_NAMESPACE_IDENTIFIER "Namespace Identifier"
+#define STR_NAMESPACE_INFO_VALID "Namespace Information Valid"
+#define STR_STATISTICS_DATA_SIZE "Statistic Data Size"
+#define STR_RESERVED "Reserved"
+#define STR_STATISTICS_SPECIFIC_DATA "Statistic Specific Data"
+#define STR_CLASS_SPECIFIC_DATA "Class Specific Data"
+#define STR_DBG_EVENT_CLASS_TYPE "Debug Event Class type"
+#define STR_EVENT_IDENTIFIER "Event Identifier"
+#define STR_EVENT_STRING "Event String"
+#define STR_EVENT_DATA_SIZE "Event Data Size"
+#define STR_VU_EVENT_STRING "VU Event String"
+#define STR_VU_EVENT_ID_STRING "VU Event Identifier"
+#define STR_VU_DATA "VU Data"
+#define STR_LINE "==============================================================================\n"
+#define STR_LINE2 "-----------------------------------------------------------------------------\n"
+
+/**
+ * enum ocp_telemetry_data_area - Telemetry Data Areas
+ * @DATA_AREA_1:       Data Area 1
+ * @DATA_AREA_2:       Data Area 2
+ * @DATA_AREA_3:       Data Area 3
+ * @DATA_AREA_4:       Data Area 4
+ */
+enum ocp_telemetry_data_area {
+       DATA_AREA_1 = 0x01,
+       DATA_AREA_2 = 0x02,
+       DATA_AREA_3 = 0x03,
+       DATA_AREA_4 = 0x04,
+};
+
+/**
+ * enum ocp_telemetry_string_tables - OCP telemetry string tables
+ * @STATISTICS_IDENTIFIER_STRING:      Statistic Identifier string
+ * @EVENT_STRING:      Event String
+ * @VU_EVENT_STRING:   VU Event String
+ */
+enum ocp_telemetry_string_tables {
+       STATISTICS_IDENTIFIER_STRING = 0,
+       EVENT_STRING,
+       VU_EVENT_STRING
+};
+
+/**
+ * enum ocp_telemetry_debug_event_class_types - OCP Debug Event Class types
+ * @RESERVED_CLASS_TYPE:              Reserved class
+ * @TIME_STAMP_CLASS_TYPE:            Time stamp class
+ * @PCIE_CLASS_TYPE:              PCIe class
+ * @NVME_CLASS_TYPE:              NVME class
+ * @RESET_CLASS_TYPE:             Reset class
+ * @BOOT_SEQUENCE_CLASS_TYPE:     Boot Sequence class
+ * @FIRMWARE_ASSERT_CLASS_TYPE:           Firmware Assert class
+ * @TEMPERATURE_CLASS_TYPE:           Temperature class
+ * @MEDIA_CLASS_TYPE:             Media class
+ * @MEDIA_WEAR_CLASS_TYPE:            Media wear class
+ * @STATISTIC_SNAPSHOT_CLASS_TYPE: Statistic snapshot class
+ * @RESERVED:                     Reserved class
+ * @VENDOR_UNIQUE_CLASS_TYPE:     Vendor Unique class
+ */
+enum ocp_telemetry_debug_event_class_types {
+       RESERVED_CLASS_TYPE = 0x00,
+       TIME_STAMP_CLASS_TYPE = 0x01,
+       PCIE_CLASS_TYPE = 0x02,
+       NVME_CLASS_TYPE = 0x03,
+       RESET_CLASS_TYPE = 0x04,
+       BOOT_SEQUENCE_CLASS_TYPE = 0x05,
+       FIRMWARE_ASSERT_CLASS_TYPE = 0x06,
+       TEMPERATURE_CLASS_TYPE = 0x07,
+       MEDIA_CLASS_TYPE = 0x08,
+       MEDIA_WEAR_CLASS_TYPE = 0x09,
+       STATISTIC_SNAPSHOT_CLASS_TYPE = 0x0A,
+       //RESERVED = 7Fh-0Bh,
+       //VENDOR_UNIQUE_CLASS_TYPE = FFh-80h,
+};
+
+/**
+ * struct telemetry_str_log_format - Telemetry String Log Format
+ * @log_page_version:          indicates the version of the mapping this log page uses
+ *                             Shall be set to 01h.
+ * @reserved1:                 Reserved.
+ * @log_page_guid:             Shall be set to B13A83691A8F408B9EA495940057AA44h.
+ * @sls:                       Shall be set to the number of DWORDS in the String Log.
+ * @reserved2:                 reserved.
+ * @sits:                      shall be set to the number of DWORDS in the Statistics
+ *                             Identifier String Table
+ * @ests:                      Shall be set to the number of DWORDS from byte 0 of this
+ *                             log page to the start of the Event String Table
+ * @estsz:                     shall be set to the number of DWORDS in the Event String Table
+ * @vu_eve_sts:                Shall be set to the number of DWORDS from byte 0 of this
+ *                             log page to the start of the VU Event String Table
+ * @vu_eve_st_sz:              shall be set to the number of DWORDS in the VU Event String Table
+ * @ascts:                     the number of DWORDS from byte 0 of this log page until the
+ *                             ASCII Table Starts.
+ * @asctsz:                    the number of DWORDS in the ASCII Table
+ * @fifo1:                     FIFO 0 ASCII String
+ * @fifo2:                     FIFO 1 ASCII String
+ * @fifo3:                     FIFO 2 ASCII String
+ * @fifo4:                     FIFO 3 ASCII String
+ * @fif05:                     FIFO 4 ASCII String
+ * @fifo6:                     FIFO 5 ASCII String
+ * @fifo7:                     FIFO 6 ASCII String
+ * @fifo8:                     FIFO 7 ASCII String
+ * @fifo9:                     FIFO 8 ASCII String
+ * @fifo10:                    FIFO 9 ASCII String
+ * @fif011:                    FIFO 10 ASCII String
+ * @fif012:                    FIFO 11 ASCII String
+ * @fifo13:                    FIFO 12 ASCII String
+ * @fif014:                    FIFO 13 ASCII String
+ * @fif015:                    FIFO 14 ASCII String
+ * @fif016:                    FIFO 15 ASCII String
+ * @reserved3:                 reserved
+ */
+struct __packed telemetry_str_log_format {
+       __u8    log_page_version;
+       __u8    reserved1[15];
+       __u8    log_page_guid[C9_GUID_LENGTH];
+       __le64  sls;
+       __u8    reserved2[24];
+       __le64  sits;
+       __le64  sitsz;
+       __le64  ests;
+       __le64  estsz;
+       __le64  vu_eve_sts;
+       __le64  vu_eve_st_sz;
+       __le64  ascts;
+       __le64  asctsz;
+       __u8    fifo1[16];
+       __u8    fifo2[16];
+       __u8    fifo3[16];
+       __u8    fifo4[16];
+       __u8    fifo5[16];
+       __u8    fifo6[16];
+       __u8    fifo7[16];
+       __u8    fifo8[16];
+       __u8    fifo9[16];
+       __u8    fifo10[16];
+       __u8    fifo11[16];
+       __u8    fifo12[16];
+       __u8    fifo13[16];
+       __u8    fifo14[16];
+       __u8    fifo15[16];
+       __u8    fifo16[16];
+       __u8    reserved3[48];
+};
+
+/*
+ * struct statistics_id_str_table_entry - Statistics Identifier String Table Entry
+ * @vs_si:                    Shall be set the Vendor Unique Statistic Identifier number.
+ * @reserved1:                Reserved
+ * @ascii_id_len:             Shall be set the number of ASCII Characters that are valid.
+ * @ascii_id_ofst:            Shall be set to the offset from DWORD 0/Byte 0 of the Start
+ *                            of the ASCII Table to the first character of the string for
+ *                            this Statistic Identifier string..
+ * @reserved2                 reserved
+ */
+struct __packed statistics_id_str_table_entry {
+       __le16  vs_si;
+       __u8    reserved1;
+       __u8    ascii_id_len;
+       __le64  ascii_id_ofst;
+       __le32  reserved2;
+};
+
+/*
+ * struct event_id_str_table_entry - Event Identifier String Table Entry
+ * @deb_eve_class:            Shall be set the Debug Class.
+ * @ei:                       Shall be set to the Event Identifier
+ * @ascii_id_len:             Shall be set the number of ASCII Characters that are valid.
+ * @ascii_id_ofst:            This is the offset from DWORD 0/ Byte 0 of the start of the
+ *                            ASCII table to the ASCII data for this identifier
+ * @reserved2                 reserved
+ */
+struct __packed event_id_str_table_entry {
+       __u8      deb_eve_class;
+       __le16    ei;
+       __u8      ascii_id_len;
+       __le64    ascii_id_ofst;
+       __le32    reserved2;
+};
+
+/*
+ * struct vu_event_id_str_table_entry - VU Event Identifier String Table Entry
+ * @deb_eve_class:            Shall be set the Debug Class.
+ * @vu_ei:                    Shall be set to the VU Event Identifier
+ * @ascii_id_len:             Shall be set the number of ASCII Characters that are valid.
+ * @ascii_id_ofst:            This is the offset from DWORD 0/ Byte 0 of the start of the
+ *                            ASCII table to the ASCII data for this identifier
+ * @reserved                  reserved
+ */
+struct __packed vu_event_id_str_table_entry {
+       __u8      deb_eve_class;
+       __le16    vu_ei;
+       __u8      ascii_id_len;
+       __le64    ascii_id_ofst;
+       __le32    reserved;
+};
+
+
+struct __packed ocp_telemetry_parse_options {
+       char *telemetry_log;
+       char *string_log;
+       char *output_file;
+       char *output_format;
+       int data_area;
+       char *telemetry_type;
+};
+
+struct __packed nvme_ocp_telemetry_reason_id
+{
+       __u8 error_id[64];                // Bytes 63:00
+       __u8 file_id[8];                  // Bytes 71:64
+       __le16 line_number;               // Bytes 73:72
+       __u8 valid_flags;                 // Bytes 74
+       __u8 reserved[21];                // Bytes 95:75
+       __u8 vu_reason_ext[32];           // Bytes 127:96
+};
+
+struct __packed nvme_ocp_telemetry_common_header
+{
+       __u8 log_id;                             // Byte 00
+       __le32 reserved1;                        // Bytes 04:01
+       __u8 ieee_oui_id[3];                     // Bytes 07:05
+       __le16 da1_last_block;                   // Bytes 09:08
+       __le16 da2_last_block;                   // Bytes 11:10
+       __le16 da3_last_block;                   // Bytes 13:12
+       __le16 reserved2;                        // Bytes 15:14
+       __le32 da4_last_block;                   // Bytes 19:16
+};
+
+struct __packed nvme_ocp_telemetry_host_initiated_header
+{
+       struct nvme_ocp_telemetry_common_header commonHeader;    // Bytes 19:00
+       __u8 reserved3[360];                                     // Bytes 379:20
+       __u8 host_initiated_scope;                               // Byte 380
+       __u8 host_initiated_gen_number;                          // Byte 381
+       __u8 host_initiated_data_available;                      // Byte 382
+       __u8 ctrl_initiated_gen_number;                          // Byte 383
+       struct nvme_ocp_telemetry_reason_id reason_id;           // Bytes 511:384
+};
+
+struct __packed nvme_ocp_telemetry_controller_initiated_header
+{
+       struct nvme_ocp_telemetry_common_header commonHeader;   // Bytes 19:00
+       __u8 reserved3[361];                                    // Bytes 380:20
+       __u8 ctrl_initiated_scope;                              // Byte 381
+       __u8 ctrl_initiated_data_available;                     // Byte 382
+       __u8 ctrl_initiated_gen_number;                         // Byte 383
+       struct nvme_ocp_telemetry_reason_id reason_id;          // Bytes 511:384
+};
+
+struct __packed nvme_ocp_telemetry_smart
+{
+       __u8 critical_warning;                                         // Byte 0
+       __le16 composite_temperature;                                  // Bytes 2:1
+       __u8 available_spare;                                          // Bytes 3
+       __u8 available_spare_threshold;                                // Bytes 4
+       __u8 percentage_used;                                          // Bytes 5
+       __u8 reserved1[26];                                            // Bytes 31:6
+       __u8 data_units_read[16];                                      // Bytes 47:32
+       __u8 data_units_written[16];                                   // Bytes 63:48
+       __u8 host_read_commands[16];                                   // Byte  79:64
+       __u8 host_write_commands[16];                                  // Bytes 95:80
+       __u8 controller_busy_time[16];                                 // Bytes 111:96
+       __u8 power_cycles[16];                                         // Bytes 127:112
+       __u8 power_on_hours[16];                                       // Bytes 143:128
+       __u8 unsafe_shutdowns[16];                                     // Bytes 159:144
+       __u8 media_and_data_integrity_errors[16];                      // Bytes 175:160
+       __u8 number_of_error_information_log_entries[16];              // Bytes 191:176
+       __le32 warning_composite_temperature_time;                     // Byte  195:192
+       __le32 critical_composite_temperature_time;                    // Bytes 199:196
+       __le16 temperature_sensor1;                                    // Bytes 201:200
+       __le16 temperature_sensor2;                                    // Byte  203:202
+       __le16 temperature_sensor3;                                    // Byte  205:204
+       __le16 temperature_sensor4;                                    // Bytes 207:206
+       __le16 temperature_sensor5;                                    // Bytes 209:208
+       __le16 temperature_sensor6;                                    // Bytes 211:210
+       __le16 temperature_sensor7;                                    // Bytes 213:212
+       __le16 temperature_sensor8;                                    // Bytes 215:214
+       __le32 thermal_management_temperature1_transition_count;       // Bytes 219:216
+       __le32 thermal_management_temperature2_transition_count;       // Bytes 223:220
+       __le32 total_time_for_thermal_management_temperature1;         // Bytes 227:224
+       __le32 total_time_for_thermal_management_temperature2;         // Bytes 231:228
+       __u8 reserved2[280];                                           // Bytes 511:232
+};
+
+struct __packed nvme_ocp_telemetry_smart_extended
+{
+       __u8 physical_media_units_written[16];                   // Bytes 15:0
+       __u8 physical_media_units_read[16];                      // Bytes 31:16
+       __u8 bad_user_nand_blocks_raw_count[6];                  // Bytes 37:32
+       __le16 bad_user_nand_blocks_normalized_value;            // Bytes 39:38
+       __u8 bad_system_nand_blocks_raw_count[6];                // Bytes 45:40
+       __le16 bad_system_nand_blocks_normalized_value;          // Bytes 47:46
+       __le64 xor_recovery_count;                               // Bytes 55:48
+       __le64 uncorrectable_read_error_count;                   // Bytes 63:56
+       __le64 soft_ecc_error_count;                             // Bytes 71:64
+       __le32 end_to_end_correction_counts_detected_errors;     // Bytes 75:72
+       __le32 end_to_end_correction_counts_corrected_errors;    // Bytes 79:76
+       __u8 system_data_percent_used;                           // Byte  80
+       __u8 refresh_counts[7];                                  // Bytes 87:81
+       __le32 max_user_data_erase_count;                        // Bytes 91:88
+       __le32 min_user_data_erase_count;                        // Bytes 95:92
+       __u8 num_thermal_throttling_events;                      // Bytes 96
+       __u8 current_throttling_status;                          // Bytes 97
+       __u8  errata_version_field;                              // Byte 98
+       __le16 point_version_field;                              // Byte 100:99
+       __le16 minor_version_field;                              // Byte 102:101
+       __u8  major_version_field;                               // Byte 103
+       __le64 pcie_correctable_error_count;                     // Bytes 111:104
+       __le32 incomplete_shutdowns;                             // Bytes 115:112
+       __le32 reserved1;                                        // Bytes 119:116
+       __u8 percent_free_blocks;                                // Byte  120
+       __u8 reserved2[7];                                       // Bytes 127:121
+       __le16 capacitor_health;                                 // Bytes 129:128
+       __u8 nvme_base_errata_version;                           // Byte  130
+       __u8 nvme_command_set_errata_version;                    // Byte  131
+       __le32 reserved3;                                        // Bytes 135:132
+       __le64 unaligned_io;                                     // Bytes 143:136
+       __le64 security_version_number;                          // Bytes 151:144
+       __le64 total_nuse;                                       // Bytes 159:152
+       __u8 plp_start_count[16];                                // Bytes 175:160
+       __u8 endurance_estimate[16];                             // Bytes 191:176
+       __le64 pcie_link_retraining_count;                       // Bytes 199:192
+       __le64 power_state_change_count;                         // Bytes 207:200
+       __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
+};
+
+struct __packed nvme_ocp_event_fifo_data
+{
+       __le32 event_fifo_num;
+       __u8 event_fifo_da;
+       __le64 event_fifo_start;
+       __le64 event_fifo_size;
+};
+
+struct __packed nvme_ocp_telemetry_offsets
+{
+       __le32 data_area;
+       __le32 header_size;
+       __le32 da1_start_offset;
+       __le32 da1_size;
+       __le32 da2_start_offset;
+       __le32 da2_size;
+       __le32 da3_start_offset;
+       __le32 da3_size;
+       __le32 da4_start_offset;
+       __le32 da4_size;
+};
+
+struct __packed nvme_ocp_event_fifo_offsets
+{
+       __le64 event_fifo_start;
+       __le64 event_fifo_size;
+};
+
+struct __packed nvme_ocp_header_in_da1
+{
+       __le16 major_version;                                                // Bytes 1:0
+       __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 num_telemetry_profiles_supported;                               // Byte 32
+       __u8 telemetry_profile_selected;                                     // Byte 33
+       __u8 reserved2[6];                                                   // Bytes 39:34
+       __le64 string_log_size;                                              // Bytes 47:40
+       __le64 reserved3;                                                    // Bytes 55:48
+       __le64 firmware_revision;                                            // Bytes 63:56
+       __u8 reserved4[32];                                                  // Bytes 95:64
+       __le64 da1_statistic_start;                                          // Bytes 103:96
+       __le64 da1_statistic_size;                                           // Bytes 111:104
+       __le64 da2_statistic_start;                                          // Bytes 119:112
+       __le64 da2_statistic_size;                                           // Bytes 127:120
+       __u8 reserved5[32];                                                  // Bytes 159:128
+       __u8 event_fifo_da[16];                                              // Bytes 175:160
+       struct nvme_ocp_event_fifo_offsets fifo_offsets[16];                 // Bytes 431:176
+       __u8 reserved6[80];                                                  // Bytes 511:432
+       struct nvme_ocp_telemetry_smart smart_health_info;                   // Bytes 1023:512
+       struct nvme_ocp_telemetry_smart_extended smart_health_info_extended; // Bytes 1535:1024
+};
+
+struct __packed nvme_ocp_telemetry_statistic_descriptor
+{
+       __le16 statistic_id;                    // Bytes 1:0
+       __u8 statistic_info_behaviour_type : 4; // Byte  2(3:0)
+       __u8 statistic_info_reserved : 4;       // Byte  2(7:4)
+       __u8 ns_info_nsid : 7;                  // Bytes 3(6:0)
+       __u8 ns_info_ns_info_valid : 1;         // Bytes 3(7)
+       __le16 statistic_data_size;             // Bytes 5:4
+       __le16 reserved;                        // Bytes 7:6
+};
+
+struct __packed nvme_ocp_telemetry_event_descriptor
+{
+       __u8 debug_event_class_type;    // Byte 0
+       __le16 event_id;                // Bytes 2:1
+       __u8 event_data_size;           // Byte 3
+};
+
+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
+{
+       __le16 vu_event_identifier;    // Bytes 5:4
+};
+
+struct __packed nvme_ocp_media_wear_dbg_evt_class_format
+{
+       __u8 currentMediaWear[DATA_SIZE_12];         // Bytes 15:4
+       __le16 vu_event_identifier;                  // Bytes 17:16
+};
+
+struct __packed nvme_ocp_statistic_snapshot_evt_class_format
+{
+       struct nvme_ocp_telemetry_statistic_descriptor statisticDescriptorData; // Bytes 11:10
+};
+
+struct __packed nvme_ocp_statistics_identifier_string_table
+{
+       __le16 vs_statistic_identifier;     //1:0
+       __u8 reserved1;                     //2
+       __u8 ascii_id_length;               //3
+       __le64 ascii_id_offset;             //11:4
+       __le32 reserved2;                   //15:12
+};
+
+struct __packed nvme_ocp_event_string_table
+{
+       __u8 debug_event_class;         //0
+       __le16 event_identifier;        //2:1
+       __u8 ascii_id_length;           //3
+       __le64 ascii_id_offset;         //11:4
+       __le32 reserved;                //15:12
+};
+
+struct __packed nvme_ocp_vu_event_string_table
+{
+       __u8 debug_event_class;        //0
+       __le16 vu_event_identifier;    //2:1
+       __u8 ascii_id_length;          //3
+       __le64 ascii_id_offset;        //11:4
+       __le32 reserved;               //15:12
+};
+
+struct __packed nvme_ocp_telemetry_string_header
+{
+       __u8 version;                   //0:0
+       __u8 reserved1[15];             //15:1
+       __u8 guid[16];                  //32:16
+       __le64 string_log_size;         //39:32
+       __u8 reserved2[24];             //63:40
+       __le64 sits;                    //71:64 Statistics Identifier String Table Start(SITS)
+       __le64 sitsz;                   //79:72 Statistics Identifier String Table Size (SITSZ)
+       __le64 ests;                    //87:80 Event String Table Start(ESTS)
+       __le64 estsz;                   //95:88 Event String Table Size(ESTSZ)
+       __le64 vu_ests;                 //103:96 VU Event String Table Start
+       __le64 vu_estsz;                //111:104 VU Event String Table Size
+       __le64 ascts;                   //119:112 ASCII Table start
+       __le64 asctsz;                  //127:120 ASCII Table Size
+       __u8 fifo_ascii_string[16][16]; //383:128
+       __u8 reserved3[48];             //431:384
+};
+
+struct __packed statistic_entry {
+       int identifier;
+       char *description;
+};
 
 /************************************************************
  * Telemetry Parsing Function Prototypes
@@ -491,3 +1017,212 @@ static inline const char *telemetry_media_wear_event_id_to_string(int event_id)
 {
        return ARGSTR(telemetry_media_wear_event_id_str, event_id);
 }
+
+/**
+ * @brief parse the ocp telemetry host or controller log binary file
+ *        into json or text
+ *
+ * @param options, input pointer for inputs like telemetry log bin file,
+ *        string log bin file and output file etc.
+ *
+ * @return 0 success
+ */
+int parse_ocp_telemetry_log(struct ocp_telemetry_parse_options *options);
+
+/**
+ * @brief parse the ocp telemetry string log binary file to json or text
+ *
+ * @param event_fifo_num, input event FIFO number
+ * @param debug_event_class, input debug event class id
+ * @param string_table, input string table
+ * @param description, input description string
+ *
+ * @return 0 success
+ */
+int parse_ocp_telemetry_string_log(int event_fifo_num, int identifier, int debug_event_class,
+       enum ocp_telemetry_string_tables string_table, char *description);
+
+/**
+ * @brief gets the telemetry datas areas, offsets and sizes information
+ *
+ * @param ptelemetry_common_header, input telemetry common header pointer
+ * @param ptelemetry_das_offset, input telemetry offsets pointer
+ *
+ * @return 0 success
+ */
+int get_telemetry_das_offset_and_size(
+       struct nvme_ocp_telemetry_common_header *ptelemetry_common_header,
+       struct nvme_ocp_telemetry_offsets *ptelemetry_das_offset);
+
+/**
+ * @brief parses statistics data to text or json formats
+ *
+ * @param root, input time json root object pointer
+ * @param ptelemetry_das_offset, input telemetry offsets pointer
+ * @param fp, input file pointer
+ *
+ * @return 0 success
+ */
+int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets *pOffsets,
+       FILE *fp);
+
+/**
+ * @brief parses a single statistic data to text or json formats
+ *
+ * @param pstatistic_entry, statistic entry pointer
+ * @param pstats_array, stats array pointer
+ * @param fp, input file pointer
+ *
+ * @return 0 success
+ */
+int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_entry,
+       struct json_object *pstats_array, FILE *fp);
+
+/**
+ * @brief parses event fifos data to text or json formats
+ *
+ * @param root, input time json root object pointer
+ * @param poffsets, input telemetry offsets pointer
+ * @param fp, input file pointer
+ *
+ * @return 0 success
+ */
+int parse_event_fifos(struct json_object *root, struct nvme_ocp_telemetry_offsets *poffsets,
+       FILE *fp);
+
+/**
+ * @brief parses a single event fifo data to text or json formats
+ *
+ * @param fifo_num, input event fifo number
+ * @param pfifo_start, event fifo start pointer
+ * @param pevent_fifos_object, event fifos json object pointer
+ * @param ptelemetry_das_offset, input telemetry offsets pointer
+ * @param fifo_size, input event fifo size
+ * @param fp, input file pointer
+ *
+ * @return 0 success
+ */
+int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
+       struct json_object *pevent_fifos_object, unsigned char *pstring_buffer,
+       struct nvme_ocp_telemetry_offsets *poffsets, __u64 fifo_size, FILE *fp);
+
+/**
+ * @brief parses event fifos data to text or json formats
+ *
+ * @return 0 success
+ */
+int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options);
+
+/**
+ * @brief parses event fifos data to text or json formats
+ *
+ * @return 0 success
+ */
+int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options);
+
+/**
+ * @brief gets statistic id ascii string
+ *
+ * @param identifier, string id
+ * @param description, string description
+ *
+ * @return 0 success
+ */
+int get_static_id_ascii_string(int identifier, char *description);
+
+/**
+ * @brief gets event id ascii string
+ *
+ * @param identifier, string id
+ * @param debug_event_class, debug event class
+ * @param description, string description
+ *
+ * @return 0 success
+ */
+int get_event_id_ascii_string(int identifier, int debug_event_class, char *description);
+
+/**
+ * @brief gets vu event id ascii string
+ *
+ * @param identifier, string id
+ * @param debug_event_class, debug event class
+ * @param description, string description
+ *
+ * @return 0 success
+ */
+int get_vu_event_id_ascii_string(int identifier, int debug_event_class, char *description);
+
+/**
+ * @brief parses a time-stamp event fifo data to text or json formats
+ *
+ * @param pevent_descriptor, input event descriptor data
+ * @param pevent_descriptor_obj, event descriptor json object pointer
+ * @param pevent_specific_data, input event specific data
+ * @param pevent_fifos_object, event fifos json object pointer
+ * @param fp, input file pointer
+ *
+ * @return
+ */
+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);
+
+/**
+ * @brief parses a pcie event fifo data to text or json formats
+ *
+ * @param pevent_descriptor, input event descriptor data
+ * @param pevent_descriptor_obj, event descriptor json object pointer
+ * @param pevent_specific_data, input event specific data
+ * @param pevent_fifos_object, event fifos json object pointer
+ * @param fp, input file pointer
+ *
+ * @return
+ */
+void parse_pcie_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);
+
+/**
+ * @brief parses a nvme event fifo data to text or json formats
+ *
+ * @param pevent_descriptor, input event descriptor data
+ * @param pevent_descriptor_obj, event descriptor json object pointer
+ * @param pevent_specific_data, input event specific data
+ * @param pevent_fifos_object, event fifos json object pointer
+ * @param fp, input file pointer
+ *
+ * @return
+ */
+void parse_nvme_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);
+
+/**
+ * @brief parses common event fifo data to text or json formats
+ *
+ * @param pevent_descriptor, input event descriptor data
+ * @param pevent_descriptor_obj, event descriptor json object pointer
+ * @param pevent_specific_data, input event specific data
+ * @param pevent_fifos_object, event fifos json object pointer
+ * @param fp, input file pointer
+ *
+ * @return
+ */
+void parse_common_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);
+
+/**
+ * @brief parses a media-wear event fifo data to text or json formats
+ *
+ * @param pevent_descriptor, input event descriptor data
+ * @param pevent_descriptor_obj, event descriptor json object pointer
+ * @param pevent_specific_data, input event specific data
+ * @param pevent_fifos_object, event fifos json object pointer
+ * @param fp, input file pointer
+ *
+ * @return
+ */
+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);
index 0065b863c5abfe2c673e76e18ea6fcdb43fcb528..f5474cdb381ae5f7ae7d09b2c69468f8ca8dc2cc 100644 (file)
@@ -8,6 +8,7 @@ sources += [
   'util/mem.c',
   'util/suffix.c',
   'util/types.c',
+  'util/utils.c'
 ]
 
 if json_c_dep.found()
similarity index 95%
rename from plugins/micron/micron-utils.c
rename to util/utils.c
index e19b7c22f8f00336c7550c655952b08f9860f9f6..ca9a6bf98d66cdfa459146509afa352514703374 100644 (file)
@@ -3,12 +3,11 @@
  * Copyright (c) Micron, Inc 2024.
  *
  * @file: micron-utils.h
- * @brief: This module contains all the utilities needed for micron nvme plugin
- *         and other micron modules.
+ * @brief: This module contains all the utilities needed for other modules.
  * @author: Chaithanya Shoba <ashoba@micron.com>
  */
 
-#include "micron-utils.h"
+#include "utils.h"
 
 int hex_to_int(char c)
 {
@@ -247,15 +246,15 @@ void process_field_size_default(int offset, char *sfield, __u8 *buf, int size, c
        sprintf(datastr, "%s", description_str);
 }
 
-void print_micron_vs_logs(__u8 *buf, struct micron_vs_logpage *log_page, int field_count,
+void generic_structure_parser(__u8 *buf, struct request_data *req_data, int field_count,
        struct json_object *stats, __u8 spec, FILE *fp)
 {
        int offset = 0;
 
        for (int field = 0; field < field_count; field++) {
                char datastr[1024] = { 0 };
-               char *sfield = log_page[field].field;
-               int size = !spec ? log_page[field].size : log_page[field].size2;
+               char *sfield = req_data[field].field;
+               int size = !spec ? req_data[field].size : req_data[field].size2;
 
                if (!size || sfield == NULL)
                        continue;
similarity index 89%
rename from plugins/micron/micron-utils.h
rename to util/utils.h
index 289c836f38142d7e582f33fe8f8425e8a2597226..9afa103ff396afe514f89f50f246ed34dcf04a77 100644 (file)
@@ -3,8 +3,7 @@
  * Copyright (c) Micron, Inc 2024.
  *
  * @file: micron-utils.h
- * @brief: This module contains all the utilities needed for micron nvme plugin
- *         and other micron modules.
+ * @brief: This module contains all the utilities needed for other modules.
  * @author: Chaithanya Shoba <ashoba@micron.com>
  */
 
 #include "nvme-print.h"
 #include "util/cleanup.h"
 
-/* OCP and Vendor specific log data format */
-struct __packed micron_vs_logpage {
+/*Request data format*/
+struct __packed request_data {
        char *field;
-       int  size; /* FB client spec version 1.0 sizes - M5410 models */
-       int  size2; /* FB client spec version 0.7 sizes - M5407 models */
+       int  size;
+       int  size2;
 };
 
 enum field_size {
@@ -81,7 +80,7 @@ unsigned char *read_binary_file(char *data_dir_path, const char *bin_path, long
                                int retry_count);
 
 /**
- * @brief prints Micron VS log pages
+ * @brief prints generic structure parser
  *
  * @param buf, input raw log data
  * @param log_page, input format of the data
@@ -92,7 +91,7 @@ unsigned char *read_binary_file(char *data_dir_path, const char *bin_path, long
  *
  * @return 0 success
  */
-void print_micron_vs_logs(__u8 *buf, struct micron_vs_logpage *log_page, int field_count,
+void generic_structure_parser(__u8 *buf, struct request_data *req_data, int field_count,
                          struct json_object *stats, __u8 spec, FILE *fp);
 
 /**