]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Initial checkin for Seagate Plugin
authormuhammad.ahmad@seagate.com <muhammad.ahmad@seagate.com>
Wed, 23 May 2018 04:51:06 +0000 (23:51 -0500)
committermuhammad.ahmad@seagate.com <muhammad.ahmad@seagate.com>
Wed, 23 May 2018 04:51:06 +0000 (23:51 -0500)
Makefile
seagate-diag.h [new file with mode: 0755]
seagate-nvme.c [new file with mode: 0755]
seagate-nvme.h [new file with mode: 0755]

index 2e5d631de8f05ec174c413e80c078de661723b58..6c8ba7ae87eac88886c75b89006a791614aad2d6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,7 @@ NVME_DPKG_VERSION=1~`lsb_release -sc`
 OBJS := argconfig.o suffix.o parser.o nvme-print.o nvme-ioctl.o \
        nvme-lightnvm.o fabrics.o json.o plugin.o intel-nvme.o \
        lnvm-nvme.o memblaze-nvme.o wdc-nvme.o wdc-utils.o nvme-models.o \
-       huawei-nvme.o netapp-nvme.o  toshiba-nvme.o
+       huawei-nvme.o netapp-nvme.o  toshiba-nvme.o seagate-nvme.o
 
 nvme: nvme.c nvme.h $(OBJS) NVME-VERSION-FILE
        $(CC) $(CPPFLAGS) $(CFLAGS) nvme.c -o $(NVME) $(OBJS) $(LDFLAGS)
diff --git a/seagate-diag.h b/seagate-diag.h
new file mode 100755 (executable)
index 0000000..a4eda4b
--- /dev/null
@@ -0,0 +1,268 @@
+//
+// Do NOT modify or remove this copyright and license
+//
+// Copyright (c) 2017-2018 Seagate Technology LLC and/or its Affiliates, All Rights Reserved
+//
+// ******************************************************************************************
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// \file seagate-diag.h
+// \brief This file defines the functions and macros to make building a nvme-cli seagate plug-in.
+
+
+#ifndef SEAGATE_NVME_H
+#define SEAGATE_NVME_H
+
+#define SEAGATE_PLUGIN_VERSION_MAJOR 0
+#define SEAGATE_PLUGIN_VERSION_MINOR 9 
+
+#define PERSIST_FILE_SIZE    (2764800)
+#define ONE_MB               (1048576)  // (1024 * 1024)
+#define PERSIST_CHUNK        (65536)    // (1024 * 64)
+#define FOUR_KB               (4096)
+
+/***************************
+*Supported Log-Pages from FW 
+***************************/
+
+typedef struct log_page_map_entry {
+   __u32 LogPageID;
+   __u32 LogPageSignature;
+   __u32 LogPageVersion;
+} log_page_map_entry;
+
+#define MAX_SUPPORTED_LOG_PAGE_ENTRIES ((4096 - sizeof(__u32)) / sizeof(log_page_map_entry))
+
+typedef struct log_page_map {
+   __u32 NumLogPages;
+   log_page_map_entry LogPageEntry[ MAX_SUPPORTED_LOG_PAGE_ENTRIES ];
+} log_page_map;
+/* EOF Supported Log-Pages from FW */
+
+
+/***************************
+* Extended-SMART Information
+***************************/
+#pragma pack(1)
+#define NUMBER_EXTENDED_SMART_ATTRIBUTES      42
+
+typedef enum _EXTENDED_SMART_VERSION_
+{
+    EXTENDED_SMART_VERSION_NONE,    // 0
+    EXTENDED_SMART_VERSION_GEN,     // 1
+    EXTENDED_SMART_VERSION_VENDOR1,      // 2
+} EXTENDED_SMART_VERSION;
+
+typedef struct _SmartVendorSpecific
+{
+   __u8  AttributeNumber;                                      
+   __u16 SmartStatus;                                          
+   __u8  NominalValue;                                     
+   __u8  LifetimeWorstValue;                               
+   __u32 Raw0_3;                                                           
+   __u8  RawHigh[3];                                               
+} SmartVendorSpecific;
+
+typedef struct _EXTENDED_SMART_INFO_T
+{
+   __u16 Version;                                                                                       
+   SmartVendorSpecific vendorData[NUMBER_EXTENDED_SMART_ATTRIBUTES];            
+   __u8  vendor_specific_reserved[6];                                                                           
+}  EXTENDED_SMART_INFO_T;
+
+typedef struct vendor_smart_attribute_data
+{
+   __u8  AttributeNumber;         // 00
+   __u8  Rsvd[3];                 // 01 -03
+   __u32 LSDword;                 // 04-07
+   __u32 MSDword;                 // 08 - 11
+} vendor_smart_attribute_data;
+
+struct nvme_temetry_log_hdr
+{
+    __u8        log_id;
+    __u8        rsvd1[4];
+    __u8        ieee_id[3];
+    __le16      tele_data_area1;
+    __le16      tele_data_area2;
+    __le16      tele_data_area3;
+    __u8        rsvd14[368];
+    __u8        tele_data_aval;
+    __u8        tele_data_gen_num;
+    __u8        reason_identifier[128];
+};
+
+typedef struct _U128
+{
+    __u64 LS__u64;
+    __u64 MS__u64;
+} U128;
+
+typedef struct _vendor_log_page_CF_Attr
+{
+   __u16      SuperCapCurrentTemperature;        // 00-01
+   __u16      SuperCapMaximumTemperature;        // 02-03
+   __u8       SuperCapStatus;                    // 04
+   __u8       Reserved5to7[3];                   // 05-07
+   U128     DataUnitsReadToDramNamespace;      // 08-23
+   U128     DataUnitsWrittenToDramNamespace;   // 24-39
+   __u64      DramCorrectableErrorCount;         // 40-47
+   __u64      DramUncorrectableErrorCount;       // 48-55
+}vendor_log_page_CF_Attr;
+
+typedef struct _vendor_log_page_CF
+{
+   vendor_log_page_CF_Attr      AttrCF;
+   __u8                         Vendor_Specific_Reserved[ 456 ];     // 56-511
+}vendor_log_page_CF;
+
+#pragma pack()
+/* EOF Extended-SMART Information*/
+
+
+/**************************
+* PCIE ERROR INFORMATION
+**************************/
+typedef struct pcie_error_log_page
+{
+   __u32   Version;
+   __u32   BadDllpErrCnt;
+   __u32   BadTlpErrCnt;
+   __u32   RcvrErrCnt;
+   __u32   ReplayTOErrCnt;
+   __u32   ReplayNumRolloverErrCnt;
+   __u32   FCProtocolErrCnt;
+   __u32   DllpProtocolErrCnt;
+   __u32   CmpltnTOErrCnt;
+   __u32   RcvrQOverflowErrCnt;
+   __u32   UnexpectedCplTlpErrCnt;
+   __u32   CplTlpURErrCnt;
+   __u32   CplTlpCAErrCnt;
+   __u32   ReqCAErrCnt;
+   __u32   ReqURErrCnt;
+   __u32   EcrcErrCnt;
+   __u32   MalformedTlpErrCnt;
+   __u32   CplTlpPoisonedErrCnt;
+   __u32   MemRdTlpPoisonedErrCnt;
+} pcie_error_log_page;
+//EOF PCIE ERROR INFORMATION
+
+typedef enum
+{
+   VS_ATTR_SOFT_READ_ERROR_RATE,                // 0     OFFSET : 02 -13     bytes
+   VS_ATTR_REALLOCATED_SECTOR_COUNT,            // 1     OFFSET : 14 -25     bytes
+   VS_ATTR_POWER_ON_HOURS,                      // 2     OFFSET : 26 -37     bytes
+   VS_ATTR_POWER_FAIL_EVENT_COUNT,              // 3    OFFSET : 38 -49     bytes
+   VS_ATTR_DEVICE_POWER_CYCLE_COUNT,            // 4    OFFSET : 50 -61     bytes
+   VS_ATTR_GB_ERASED,                           // 5   OFFSET : 62 -73     bytes
+   VS_ATTR_LIFETIME_DEVSLEEP_EXIT_COUNT,        // 6    OFFSET : 74 -85     bytes
+   VS_ATTR_LIFETIME_ENTERING_PS4_COUNT,         // 7   OFFSET : 86 -97     bytes
+   VS_ATTR_LIFETIME_ENTERING_PS3_COUNT,         // 8   OFFSET : 98 -109   bytes
+   VS_ATTR_RETIRED_BLOCK_COUNT,                 // 9   OFFSET : 110 -121 bytes
+   VS_ATTR_PROGRAM_FAILURE_COUNT,               // 10   OFFSET : 122 -133 bytes
+   VS_ATTR_ERASE_FAIL_COUNT,                    // 11   OFFSET : 134 -145 bytes
+   VS_ATTR_AVG_ERASE_COUNT,                     // 12    OFFSET : 146 -157 bytes
+   VS_ATTR_UNEXPECTED_POWER_LOSS_COUNT,         // 13   OFFSET : 158 -169 bytes
+   VS_ATTR_WEAR_RANGE_DELTA,                    // 14    OFFSET : 170 -181 bytes
+   VS_ATTR_SATA_INTERFACE_DOWNSHIFT_COUNT,      // 15    OFFSET : 182 -193 bytes
+   VS_ATTR_END_TO_END_CRC_ERROR_COUNT,          // 16    OFFSET : 194 -205 bytes
+   VS_ATTR_MAX_LIFE_TEMPERATURE,                // 17   OFFSET : 206 -217 bytes
+   VS_ATTR_UNCORRECTABLE_RAISE_ERRORS,          // 18    OFFSET : 218 -229 bytes
+   VS_ATTR_DRIVE_LIFE_PROTECTION_STATUS,        // 19   OFFSET : 230 -241 bytes
+   VS_ATTR_REMAINING_SSD_LIFE,                  // 20   OFFSET : 242 -253 bytes
+   VS_ATTR_LIFETIME_WRITES_TO_FLASH,            // 21   OFFSET : 254 -265 bytes
+   VS_ATTR_LIFETIME_WRITES_FROM_HOST,           // 22   OFFSET : 266 -277 bytes
+   VS_ATTR_LIFETIME_READS_TO_HOST,              // 23   OFFSET : 278 -289 bytes
+   VS_ATTR_FREE_SPACE,                          // 24   OFFSET : 290 -301 bytes
+   VS_ATTR_TRIM_COUNT_LSB,                      // 25  OFFSET : 302 -313 bytes
+   VS_ATTR_TRIM_COUNT_MSB,                      // 26  OFFSET : 314 -325 bytes
+   VS_ATTR_OP_PERCENTAGE,                       // 27  OFFSET : 326 -337 bytes
+   VS_ATTR_RAISE_ECC_CORRECTABLE_ERROR_COUNT,  // 28  OFFSET : 338 -349 bytes
+   VS_ATTR_UNCORRECTABLE_ECC_ERRORS ,           // 29  OFFSET : 350 -361 bytes
+   VS_ATTR_LIFETIME_WRITES0_TO_FLASH,           // 30  362-372
+   VS_ATTR_LIFETIME_WRITES1_TO_FLASH,           // 31  374-385
+   VS_ATTR_LIFETIME_WRITES0_FROM_HOST,          // 32  386-397
+   VS_ATTR_LIFETIME_WRITES1_FROM_HOST,          // 33  398-409
+   VS_ATTR_LIFETIME_READ0_FROM_HOST,            // 34  410-421
+   VS_ATTR_LIFETIME_READ1_FROM_HOST,            // 35  422-433
+   VS_ATTR_PCIE_PHY_CRC_ERROR,                  // 36  434-445
+   VS_ATTR_BAD_BLOCK_COUNT_SYSTEM,              // 37  446-457
+   VS_ATTR_BAD_BLOCK_COUNT_USER,                // 38  458-469
+   VS_ATTR_THERMAL_THROTTLING_STATUS,           // 39  470-481
+   VS_ATTR_POWER_CONSUMPTION,                   // 40  482-493
+   VS_ATTR_MAX_SOC_LIFE_TEMPERATURE,            // 41  494-505
+
+   VS_MAX_ATTR_NUMBER,
+
+} extended_smart_attributes;
+
+//Smart attribute IDs
+
+typedef enum
+{
+   VS_ATTR_ID_SOFT_READ_ERROR_RATE = 1,
+   VS_ATTR_ID_REALLOCATED_SECTOR_COUNT  = 5,
+   VS_ATTR_ID_POWER_ON_HOURS = 9,
+   VS_ATTR_ID_POWER_FAIL_EVENT_COUNT = 11,
+   VS_ATTR_ID_DEVICE_POWER_CYCLE_COUNT = 12,
+   VS_ATTR_ID_RAW_READ_ERROR_RATE = 13,
+   VS_ATTR_ID_GROWN_BAD_BLOCK_COUNT = 40,
+   VS_ATTR_ID_END_2_END_CORRECTION_COUNT = 41,
+   VS_ATTR_ID_MIN_MAX_WEAR_RANGE_COUNT = 42,
+   VS_ATTR_ID_REFRESH_COUNT = 43,
+   VS_ATTR_ID_BAD_BLOCK_COUNT_USER = 44,
+   VS_ATTR_ID_BAD_BLOCK_COUNT_SYSTEM = 45,
+   VS_ATTR_ID_THERMAL_THROTTLING_STATUS = 46,
+   VS_ATTR_ID_ALL_PCIE_CORRECTABLE_ERROR_COUNT = 47,
+   VS_ATTR_ID_ALL_PCIE_UNCORRECTABLE_ERROR_COUNT = 48,
+   VS_ATTR_ID_INCOMPLETE_SHUTDOWN_COUNT = 49,
+   VS_ATTR_ID_GB_ERASED_LSB = 100,
+   VS_ATTR_ID_GB_ERASED_MSB = 101,
+   VS_ATTR_ID_LIFETIME_ENTERING_PS4_COUNT = 102,
+   VS_ATTR_ID_LIFETIME_ENTERING_PS3_COUNT = 103,
+   VS_ATTR_ID_LIFETIME_DEVSLEEP_EXIT_COUNT = 104,
+   VS_ATTR_ID_RETIRED_BLOCK_COUNT = 170,
+   VS_ATTR_ID_PROGRAM_FAILURE_COUNT = 171,
+   VS_ATTR_ID_ERASE_FAIL_COUNT = 172,
+   VS_ATTR_ID_AVG_ERASE_COUNT = 173,
+   VS_ATTR_ID_UNEXPECTED_POWER_LOSS_COUNT = 174,
+   VS_ATTR_ID_WEAR_RANGE_DELTA = 177,
+   VS_ATTR_ID_SATA_INTERFACE_DOWNSHIFT_COUNT = 183,
+   VS_ATTR_ID_END_TO_END_CRC_ERROR_COUNT = 184,
+   VS_ATTR_ID_UNCORRECTABLE_READ_ERRORS = 188,
+   VS_ATTR_ID_MAX_LIFE_TEMPERATURE = 194,
+   VS_ATTR_ID_RAISE_ECC_CORRECTABLE_ERROR_COUNT = 195,
+   VS_ATTR_ID_UNCORRECTABLE_RAISE_ERRORS = 198,
+   VS_ATTR_ID_DRIVE_LIFE_PROTECTION_STATUS = 230,
+   VS_ATTR_ID_REMAINING_SSD_LIFE  = 231,
+   VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB = 233,
+   VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB = 234,
+   VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB = 241,
+   VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB = 242,
+   VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB = 243,
+   VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB = 244,
+   VS_ATTR_ID_FREE_SPACE = 245,
+   VS_ATTR_ID_TRIM_COUNT_LSB = 250,
+   VS_ATTR_ID_TRIM_COUNT_MSB = 251,
+   VS_ATTR_ID_OP_PERCENTAGE = 252,
+   VS_ATTR_ID_MAX_SOC_LIFE_TEMPERATURE = 253,
+} smart_attributes_ids;
+
+#define TELEMETRY_BLOCKS_TO_READ       8
+
+void seaget_d_raw(unsigned char *buf, int len, int fd);
+
+
+#define DP_CLASS_ID_FULL 0
+
+#endif
diff --git a/seagate-nvme.c b/seagate-nvme.c
new file mode 100755 (executable)
index 0000000..4ced91e
--- /dev/null
@@ -0,0 +1,1500 @@
+//
+// Do NOT modify or remove this copyright and license
+//
+// Copyright (c) 2017-2018 Seagate Technology LLC and/or its Affiliates, All Rights Reserved
+//
+// ******************************************************************************************
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// \file seagate-nvme.c
+// \brief This file defines the functions and macros to make building a nvme-cli seagate plug-in.
+
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/fs.h>
+#include <inttypes.h>
+#include <asm/byteorder.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
+#include "linux/nvme_ioctl.h"
+#include "nvme.h"
+#include "nvme-print.h"
+#include "nvme-ioctl.h"
+#include "plugin.h"
+#include "argconfig.h"
+#include "suffix.h"
+#include "json.h"
+
+#define CREATE_CMD
+
+#include "seagate-nvme.h"
+#include "seagate-diag.h"
+
+
+/***************************************
+*Command for "log-pages-supp"
+***************************************/
+char* log_pages_supp_print(__u32 pageID)
+{
+       switch(pageID) {
+               case 0x01:
+                       return "ERROR_INFORMATION";
+               break;
+               case 0x02:
+                       return "SMART_INFORMATION";
+               break;
+               case 0x03:
+                       return "FW_SLOT_INFORMATION";
+               break;
+               case 0x04:
+                       return "CHANGED_NAMESPACE_LIST";
+               break;
+       case 0x05:
+                       return "COMMANDS_SUPPORTED_AND_EFFECTS";
+               break;
+        case 0x06:
+                       return "DEVICE_SELF_TEST";
+               break;
+        case 0x07:
+                       return "TELEMETRY_HOST_INITIATED";
+               break;
+        case 0x08:
+                       return "TELEMETRY_CONTROLLER_INITIATED";
+               break;
+               case 0xC0:
+                       return "VS_MEDIA_SMART_LOG";
+               break;
+               case 0xC1:
+                       return "VS_DEBUG_LOG1";
+               break;
+               case 0xC2:
+                       return "VS_SEC_ERROR_LOG_PAGE";
+               break;
+               case 0xC3:
+                       return "VS_LIFE_TIME_DRIVE_HISTORY";
+               break;
+               case 0xC4:
+                       return "VS_EXTENDED_SMART_INFO";
+               break;
+               case 0xC5:
+                       return "VS_LIST_SUPPORTED_LOG_PAGE";
+               break;
+               case 0xC6:
+                       return "VS_POWER_MONITOR_LOG_PAGE";
+               break;
+               case 0xC7:
+                       return "VS_CRITICAL_EVENT_LOG_PAGE";
+               break;
+               case 0xC8:
+                       return "VS_RECENT_DRIVE_HISTORY";
+               break;
+               case 0xC9:
+                       return "VS_SEC_ERROR_LOG_PAGE";
+               break;
+               case 0xCA:
+                       return "VS_LIFE_TIME_DRIVE_HISTORY";
+               break;
+               case 0xCB:
+                       return "VS_PCIE_ERROR_LOG_PAGE";
+               break;
+        case 0xCF:
+            return "DRAM Supercap SMART Attributes";
+            break;
+               case 0xD6:
+                       return "VS_HPE_WORK_LOAD";
+               break;
+               case 0xD7:
+                       return "VS_HPE_FW_SECURITY";
+               break;
+               case 0xD8:
+                       return "VS_HPE_REVISION"; 
+               break;
+
+               default:
+                       return "UNKNOWN";
+                       break;
+       }
+}
+
+
+void json_log_pages_supp(log_page_map *logPageMap)
+{
+        struct json_object *root;
+        struct json_array *logPages;
+        __u32 i = 0;
+
+        root = json_create_object();
+        logPages = json_create_array();
+        json_object_add_value_array(root, "supported_log_pages", logPages);
+
+        for(i =0; i < logPageMap->NumLogPages; i++) {
+                       struct json_object *lbaf = json_create_object();        
+               json_object_add_value_int(lbaf, "logpage_id", logPageMap->LogPageEntry[i].LogPageID);
+               json_object_add_value_string(lbaf, "logpage_name", log_pages_supp_print(logPageMap->LogPageEntry[i].LogPageID));
+
+            json_array_add_value_object(logPages, lbaf);
+        }
+        json_print_object(root, NULL);
+        printf("\n");
+}
+
+static int log_pages_supp(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+        int err = 0;
+       int fd = 0;
+       __u32 i = 0;
+        log_page_map logPageMap;
+    
+        const char *desc = "Retrieve Seagate Supported Log-Page information for the given device ";
+       const char *output_format = "output in binary format";
+    
+        struct config {
+            char *output_format;
+        };
+    
+        struct config cfg = {
+            .output_format = "normal",
+        };
+    
+        const struct argconfig_commandline_options command_line_options[] = {
+       {"output-format", 'o', "FMT", CFG_STRING, &cfg.output_format, required_argument, output_format },
+        {0}
+        };
+    
+        fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+    
+        int fmt;
+    
+        err = nvme_get_log(fd, 1, 0xc5, sizeof(logPageMap), &logPageMap);
+        if (!err) {
+            if(strcmp(cfg.output_format,"json")) {
+                printf ("Seagate Supported Log-pages count :%d\n", logPageMap.NumLogPages);
+                printf ("%-15s %-30s\n", "LogPage-Id", "LogPage-Name");
+        
+                for(fmt=0; fmt<45; fmt++)
+                    printf ("-");
+        
+                printf("\n");
+            } else
+                json_log_pages_supp(&logPageMap);
+        
+            for(i = 0; i<logPageMap.NumLogPages; i++) {
+                if(strcmp(cfg.output_format,"json")) {
+                    printf("0x%-15X", logPageMap.LogPageEntry[i].LogPageID); 
+                                printf("%-30s\n", log_pages_supp_print(logPageMap.LogPageEntry[i].LogPageID));
+                }
+            }
+        }
+    
+        if (err > 0)
+                fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(err), err);
+    
+        return err;
+}
+
+//EOF Command for "log-pages-supp"
+
+
+/***************************************
+* Extended-SMART Information
+***************************************/
+char* print_ext_smart_id(__u8 attrId)
+{
+       switch(attrId) {
+               case VS_ATTR_ID_SOFT_READ_ERROR_RATE:
+            return "Soft ECC error count";
+                       break;
+               case VS_ATTR_ID_REALLOCATED_SECTOR_COUNT:
+            return "Bad NAND block count";
+                       break;
+               case VS_ATTR_ID_POWER_ON_HOURS:
+            return "Power On Hours";
+                       break;
+               case VS_ATTR_ID_POWER_FAIL_EVENT_COUNT:
+            return "Power Fail Event Count";
+                       break;
+               case VS_ATTR_ID_DEVICE_POWER_CYCLE_COUNT:
+            return "Device Power Cycle Count";
+                       break;
+        case VS_ATTR_ID_RAW_READ_ERROR_RATE:
+            return "Raw Read Error Count";
+            break;
+               case VS_ATTR_ID_GROWN_BAD_BLOCK_COUNT:
+            return "Bad NAND block count";
+                       break;
+        case VS_ATTR_ID_END_2_END_CORRECTION_COUNT:
+            return "SSD End to end correction counts";
+            break;
+        case VS_ATTR_ID_MIN_MAX_WEAR_RANGE_COUNT:
+            return "User data erase counts";
+            break;
+        case VS_ATTR_ID_REFRESH_COUNT:
+            return "Refresh count";
+            break;
+        case VS_ATTR_ID_BAD_BLOCK_COUNT_USER:
+            return "User data erase fail count";
+            break;
+        case VS_ATTR_ID_BAD_BLOCK_COUNT_SYSTEM:
+            return "System area erase fail count";
+            break;
+        case VS_ATTR_ID_THERMAL_THROTTLING_STATUS:
+            return "Thermal throttling status and count";
+            break;
+        case VS_ATTR_ID_ALL_PCIE_CORRECTABLE_ERROR_COUNT:
+            return "PCIe Correctable Error count";
+            break;
+        case VS_ATTR_ID_ALL_PCIE_UNCORRECTABLE_ERROR_COUNT:
+            return "PCIe Uncorrectable Error count";
+            break;
+        case VS_ATTR_ID_INCOMPLETE_SHUTDOWN_COUNT:
+            return "Incomplete shutdowns";
+            break;
+               case VS_ATTR_ID_GB_ERASED_LSB:
+            return "LSB of Flash GB erased";
+                       break;
+               case VS_ATTR_ID_GB_ERASED_MSB:
+            return "MSB of Flash GB erased";
+                       break;
+               case VS_ATTR_ID_LIFETIME_DEVSLEEP_EXIT_COUNT:
+            return "LIFETIME_DEV_SLEEP_EXIT_COUNT";
+                       break;
+               case VS_ATTR_ID_LIFETIME_ENTERING_PS4_COUNT:
+            return "LIFETIME_ENTERING_PS4_COUNT";
+                       break;
+               case VS_ATTR_ID_LIFETIME_ENTERING_PS3_COUNT:
+            return "LIFETIME_ENTERING_PS3_COUNT";
+                       break;
+               case VS_ATTR_ID_RETIRED_BLOCK_COUNT:
+            return "Retired block count"; /*VS_ATTR_ID_RETIRED_BLOCK_COUNT*/
+                       break;
+               case VS_ATTR_ID_PROGRAM_FAILURE_COUNT:
+            return "Program fail count";
+                       break;
+               case VS_ATTR_ID_ERASE_FAIL_COUNT:
+            return "Erase Fail Count";
+                       break;
+               case VS_ATTR_ID_AVG_ERASE_COUNT:
+            return "System data % used";
+                       break;
+               case VS_ATTR_ID_UNEXPECTED_POWER_LOSS_COUNT:
+            return "Unexpected power loss count";
+                       break;
+               case VS_ATTR_ID_WEAR_RANGE_DELTA:
+            return "Wear range delta";
+                       break;
+               case VS_ATTR_ID_SATA_INTERFACE_DOWNSHIFT_COUNT:
+            return "PCIE_INTF_DOWNSHIFT_COUNT";
+                       break;
+               case VS_ATTR_ID_END_TO_END_CRC_ERROR_COUNT:
+            return "E2E_CRC_ERROR_COUNT";
+                       break;
+               case VS_ATTR_ID_UNCORRECTABLE_READ_ERRORS:
+            return "Uncorrectable Read Error Count";
+                       break;
+               case VS_ATTR_ID_MAX_LIFE_TEMPERATURE:
+            return "Max lifetime temperature";/*VS_ATTR_ID_MAX_LIFE_TEMPERATURE for extended*/
+                       break;
+               case VS_ATTR_ID_RAISE_ECC_CORRECTABLE_ERROR_COUNT:
+            return "RAIS_ECC_CORRECT_ERR_COUNT";
+                       break;
+               case VS_ATTR_ID_UNCORRECTABLE_RAISE_ERRORS:
+            return "Uncorrectable read error count";/*VS_ATTR_ID_UNCORRECTABLE_RAISE_ERRORS*/
+                       break;
+               case VS_ATTR_ID_DRIVE_LIFE_PROTECTION_STATUS:
+            return "DRIVE_LIFE_PROTECTION_STATUS";
+                       break;
+               case VS_ATTR_ID_REMAINING_SSD_LIFE:
+            return "Remaining SSD life";
+                       break;
+               case VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB:
+            return "LSB of Physical (NAND) bytes written";
+                       break;
+               case VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB:
+            return "MSB of Physical (NAND) bytes written";
+                       break;
+               case VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB:
+            return "LSB of Physical (HOST) bytes written";
+                       break;
+               case VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB:
+            return "MSB of Physical (HOST) bytes written";
+                       break;
+               case VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB:
+            return "LSB of Physical (NAND) bytes read";
+                       break;
+               case VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB:
+            return "MSB of Physical (NAND) bytes read";
+                       break;
+               case VS_ATTR_ID_FREE_SPACE:
+            return "Free Space";
+                       break;
+               case VS_ATTR_ID_TRIM_COUNT_LSB:
+            return "LSB of Trim count";
+                       break;
+               case VS_ATTR_ID_TRIM_COUNT_MSB:
+            return "MSB of Trim count";
+                       break;
+               case VS_ATTR_ID_OP_PERCENTAGE:
+            return "OP percentage";
+                       break;
+               case VS_ATTR_ID_MAX_SOC_LIFE_TEMPERATURE:
+            return "Max lifetime SOC temperature";
+                       break;
+        default:
+                       return "Un-Known";
+       }
+}
+
+__u64 smart_attribute_vs(__u16 verNo, SmartVendorSpecific attr)
+{      
+       __u64 val = 0;
+       vendor_smart_attribute_data *attrVendor;
+
+    /**
+     * These are all Vendor A specific attributes.
+     */
+    if(verNo >= EXTENDED_SMART_VERSION_VENDOR1)
+    {
+        attrVendor = (vendor_smart_attribute_data *)&attr;
+        val = attrVendor->MSDword;
+        val = (val << 32) | attrVendor->LSDword ;
+        return val;
+    }
+
+       else
+               return attr.Raw0_3;
+}
+
+void print_smart_log(__u16 verNo, SmartVendorSpecific attr, int lastAttr) 
+{
+    static __u64 lsbGbErased = 0, msbGbErased = 0, lsbLifWrtToFlash = 0, msbLifWrtToFlash = 0, 
+        lsbLifWrtFrmHost = 0, msbLifWrtFrmHost = 0, lsbLifRdToHost = 0, msbLifRdToHost = 0, lsbTrimCnt = 0, msbTrimCnt = 0;
+    char buf[40] = {0};
+    char strBuf[35] = {0};
+    int hideAttr = 0;
+
+    if(attr.AttributeNumber == VS_ATTR_ID_GB_ERASED_LSB)
+    {
+        lsbGbErased = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if(attr.AttributeNumber == VS_ATTR_ID_GB_ERASED_MSB)
+    {
+        msbGbErased = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if(attr.AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB)
+    {
+        lsbLifWrtToFlash = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if(attr.AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB)
+    {
+        msbLifWrtToFlash = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if(attr.AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB)
+    {
+        lsbLifWrtFrmHost = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if(attr.AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB)
+    {
+        msbLifWrtFrmHost = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if(attr.AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB)
+    {
+        lsbLifRdToHost = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if(attr.AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB)
+    {
+        msbLifRdToHost = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if(attr.AttributeNumber == VS_ATTR_ID_TRIM_COUNT_LSB)
+    {
+        lsbTrimCnt = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if(attr.AttributeNumber == VS_ATTR_ID_TRIM_COUNT_MSB)
+    {
+        msbTrimCnt = smart_attribute_vs(verNo, attr);
+        hideAttr = 1;
+    }
+
+    if((attr.AttributeNumber != 0) &&(hideAttr != 1)) {
+        printf("%-40s", print_ext_smart_id(attr.AttributeNumber));
+        printf("%-15d", attr.AttributeNumber  );
+        printf(" 0x%016llx", smart_attribute_vs(verNo, attr));
+        printf("\n");
+    }
+
+    if( lastAttr == 1 ) {
+
+        sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_GB_ERASED_LSB) + 7));
+        printf("%-40s", strBuf);
+
+        printf("%-15d", VS_ATTR_ID_GB_ERASED_MSB << 8 | VS_ATTR_ID_GB_ERASED_LSB);
+
+        sprintf(buf, "0x%016llx%016llx", msbGbErased, lsbGbErased);
+        printf(" %s", buf);
+        printf("\n");
+
+        sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB) + 7));
+        printf("%-40s", strBuf);
+
+        printf("%-15d", VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB);
+
+        sprintf(buf, "0x%016llx%016llx", msbLifWrtToFlash, lsbLifWrtToFlash);
+        printf(" %s", buf);
+        printf("\n");
+
+        sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB) + 7));
+        printf("%-40s", strBuf);
+
+        printf("%-15d", VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB);
+
+        sprintf(buf, "0x%016llx%016llx", msbLifWrtFrmHost, lsbLifWrtFrmHost);
+        printf(" %s", buf);
+        printf("\n");
+
+        sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB) + 7));
+        printf("%-40s", strBuf);
+
+        printf("%-15d", VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB);
+
+        sprintf(buf, "0x%016llx%016llx", msbLifRdToHost, lsbLifRdToHost);
+        printf(" %s", buf);
+        printf("\n");
+
+        sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_TRIM_COUNT_LSB) + 7));
+        printf("%-40s", strBuf);
+
+        printf("%-15d", VS_ATTR_ID_TRIM_COUNT_MSB << 8 | VS_ATTR_ID_TRIM_COUNT_LSB);
+
+        sprintf(buf, "0x%016llx%016llx", msbTrimCnt, lsbTrimCnt);
+        printf(" %s", buf);
+        printf("\n");
+
+    }
+}
+
+void json_print_smart_log(struct json_object *root, EXTENDED_SMART_INFO_T* ExtdSMARTInfo )
+{
+    /*struct json_object *root; */
+    struct json_array *lbafs;
+       int index = 0;
+
+    static __u64 lsbGbErased = 0, msbGbErased = 0, lsbLifWrtToFlash = 0, msbLifWrtToFlash = 0, 
+        lsbLifWrtFrmHost = 0, msbLifWrtFrmHost = 0, lsbLifRdToHost = 0, msbLifRdToHost = 0, lsbTrimCnt = 0, msbTrimCnt = 0;
+    char buf[40] = {0};
+    //char strBuf[35] = {0};
+
+       /*root = json_create_object();*/
+       lbafs = json_create_array();
+       json_object_add_value_array(root, "Extended-SMART-Attributes", lbafs);
+       
+       for(index =0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) {
+               struct json_object *lbaf = json_create_object();
+               if(ExtdSMARTInfo->vendorData[index].AttributeNumber != 0) {
+                       json_object_add_value_string(lbaf, "attribute_name", print_ext_smart_id(ExtdSMARTInfo->vendorData[index].AttributeNumber));
+                       json_object_add_value_int(lbaf, "attribute_id",ExtdSMARTInfo->vendorData[index].AttributeNumber);
+                       json_object_add_value_int(lbaf, "attribute_value", smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]));
+                       json_array_add_value_object(lbafs, lbaf);
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_GB_ERASED_LSB)
+            {
+                lsbGbErased = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_GB_ERASED_MSB)
+            {
+                msbGbErased = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB)
+            {
+                lsbLifWrtToFlash = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB)
+            {
+                msbLifWrtToFlash = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB)
+            {
+                lsbLifWrtFrmHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB)
+            {
+                msbLifWrtFrmHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB)
+            {
+                lsbLifRdToHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB)
+            {
+                msbLifRdToHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_TRIM_COUNT_LSB)
+            {
+                lsbTrimCnt = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+
+            if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_TRIM_COUNT_MSB)
+            {
+                msbTrimCnt = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
+            }
+        }
+       }
+
+    struct json_object *lbaf = json_create_object();
+
+    json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_GB_ERASED_LSB) + 7));
+
+    json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_GB_ERASED_MSB << 8 | VS_ATTR_ID_GB_ERASED_LSB);
+
+    sprintf(buf, "0x%016llx%016llx", msbGbErased, lsbGbErased);
+    json_object_add_value_string(lbaf, "attribute_value", buf);
+    json_array_add_value_object(lbafs, lbaf);
+    
+
+    lbaf = json_create_object();
+
+    json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB) + 7));
+
+    json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB);
+
+    sprintf(buf, "0x%016llx%016llx", msbLifWrtToFlash, lsbLifWrtToFlash);
+    json_object_add_value_string(lbaf, "attribute_value", buf);
+    json_array_add_value_object(lbafs, lbaf);
+
+
+    lbaf = json_create_object();
+
+    json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB) + 7));
+
+    json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB);
+
+    sprintf(buf, "0x%016llx%016llx", msbLifWrtFrmHost, lsbLifWrtFrmHost);
+    json_object_add_value_string(lbaf, "attribute_value", buf);
+    json_array_add_value_object(lbafs, lbaf);
+
+
+    lbaf = json_create_object();
+
+    json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB) + 7));
+
+    json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB);
+
+    sprintf(buf, "0x%016llx%016llx", msbLifRdToHost, lsbLifRdToHost);
+    json_object_add_value_string(lbaf, "attribute_value", buf);
+    json_array_add_value_object(lbafs, lbaf);
+
+
+    lbaf = json_create_object();
+
+    json_object_add_value_string(lbaf, "attribute_name", (print_ext_smart_id(VS_ATTR_ID_TRIM_COUNT_LSB) + 7));
+
+    json_object_add_value_int(lbaf, "attribute_id", VS_ATTR_ID_TRIM_COUNT_MSB << 8 | VS_ATTR_ID_TRIM_COUNT_LSB);
+
+    sprintf(buf, "0x%016llx%016llx", msbTrimCnt, lsbTrimCnt);
+    json_object_add_value_string(lbaf, "attribute_value", buf);
+    json_array_add_value_object(lbafs, lbaf);
+
+    /*
+       json_print_object(root, NULL);
+    printf("\n"); 
+    */ 
+}
+
+void print_smart_log_CF(vendor_log_page_CF *pLogPageCF)
+{
+    __u64 currentTemp, maxTemp;
+    printf("\n\nSeagate DRAM Supercap SMART Attributes :\n");
+    printf("%-39s %-19s \n", "Description", "Supercap Attributes");
+
+    printf("%-40s", "Super-cap current temperature");
+    currentTemp = pLogPageCF->AttrCF.SuperCapCurrentTemperature;
+    /*currentTemp = currentTemp ? currentTemp - 273 : 0;*/
+    printf(" 0x%016llx", currentTemp);
+    printf("\n");              
+
+    maxTemp = pLogPageCF->AttrCF.SuperCapMaximumTemperature;
+    /*maxTemp = maxTemp ? maxTemp - 273 : 0;*/
+    printf("%-40s", "Super-cap maximum temperature");
+    printf(" 0x%016llx", maxTemp);
+    printf("\n");
+
+    printf("%-40s", "Super-cap status");
+    printf(" 0x%016llx", (__u64)pLogPageCF->AttrCF.SuperCapStatus);
+    printf("\n");
+
+    printf("%-40s", "Data units read to DRAM namespace");
+    printf(" 0x%016llx%016llx", pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.MS__u64,
+           pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.LS__u64);
+    printf("\n");
+
+    printf("%-40s", "Data units written to DRAM namespace");
+    printf(" 0x%016llx%016llx", pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.MS__u64, 
+           pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.LS__u64);
+    printf("\n");
+
+    printf("%-40s", "DRAM correctable error count");
+    printf(" 0x%016llx", pLogPageCF->AttrCF.DramCorrectableErrorCount);
+    printf("\n");
+
+    printf("%-40s", "DRAM uncorrectable error count");
+    printf(" 0x%016llx", pLogPageCF->AttrCF.DramUncorrectableErrorCount);
+    printf("\n");
+
+}
+
+void json_print_smart_log_CF(struct json_object *root, vendor_log_page_CF *pLogPageCF)
+{
+        /*struct json_object *root;*/
+        struct json_array *logPages;
+        unsigned int currentTemp, maxTemp;
+        char buf[40];
+
+        /*root = json_create_object(); */
+         
+        logPages = json_create_array();
+        json_object_add_value_array(root, "DRAM Supercap SMART Attributes", logPages);
+        struct json_object *lbaf = json_create_object();
+   
+        currentTemp = pLogPageCF->AttrCF.SuperCapCurrentTemperature;
+        /*currentTemp = currentTemp ? currentTemp - 273 : 0;*/
+        json_object_add_value_string(lbaf, "attribute_name", "Super-cap current temperature");
+        json_object_add_value_int(lbaf, "attribute_value", currentTemp);
+        json_array_add_value_object(logPages, lbaf);
+        
+        lbaf = json_create_object();
+        maxTemp = pLogPageCF->AttrCF.SuperCapMaximumTemperature;
+        /*maxTemp = maxTemp ? maxTemp - 273 : 0;*/
+        json_object_add_value_string(lbaf, "attribute_name", "Super-cap maximum temperature");
+        json_object_add_value_int(lbaf, "attribute_value", maxTemp);
+        json_array_add_value_object(logPages, lbaf);
+
+        lbaf = json_create_object();
+        json_object_add_value_string(lbaf, "attribute_name", "Super-cap status");
+        json_object_add_value_int(lbaf, "attribute_value", pLogPageCF->AttrCF.SuperCapStatus);
+        json_array_add_value_object(logPages, lbaf);
+
+        lbaf = json_create_object();
+        json_object_add_value_string(lbaf, "attribute_name", "Data units read to DRAM namespace");
+        memset(buf, 0, sizeof(buf));
+        sprintf(buf, "0x%016llx%016llx", pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.MS__u64,
+               pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.LS__u64);
+        json_object_add_value_string(lbaf, "attribute_value", buf);
+        json_array_add_value_object(logPages, lbaf);
+
+        lbaf = json_create_object();
+        json_object_add_value_string(lbaf, "attribute_name", "Data units written to DRAM namespace");
+        memset(buf, 0, sizeof(buf));
+        sprintf(buf, "0x%016llx%016llx", pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.MS__u64, 
+               pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.LS__u64);
+        json_object_add_value_string(lbaf, "attribute_value", buf);
+        json_array_add_value_object(logPages, lbaf);
+
+        lbaf = json_create_object();
+        json_object_add_value_string(lbaf, "attribute_name", "DRAM correctable error count");
+        json_object_add_value_int(lbaf, "attribute_value", pLogPageCF->AttrCF.DramCorrectableErrorCount);
+        json_array_add_value_object(logPages, lbaf);
+
+        lbaf = json_create_object();
+        json_object_add_value_string(lbaf, "attribute_name", "DRAM uncorrectable error count");
+        json_object_add_value_int(lbaf, "attribute_value", pLogPageCF->AttrCF.DramUncorrectableErrorCount);
+        json_array_add_value_object(logPages, lbaf);
+
+        /*
+        json_print_object(root, NULL);
+        printf("\n"); 
+        */ 
+}
+
+static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+       EXTENDED_SMART_INFO_T   ExtdSMARTInfo;
+    vendor_log_page_CF      logPageCF;
+    int fd;
+    struct json_object *root;
+    struct json_array *lbafs;
+    struct json_object *lbafs_ExtSmart, *lbafs_DramSmart;
+    root = json_create_object();
+    lbafs = json_create_array();
+
+    const char *desc = "Retrieve Seagate Extended SMART information for the given device ";
+    const char *output_format = "output in binary format";
+    int err, index=0;
+    struct config {
+    char *output_format;
+    };
+
+    struct config cfg = {
+    .output_format = "normal",
+    };
+
+    const struct argconfig_commandline_options command_line_options[] = {
+    {"output-format", 'o', "FMT", CFG_STRING, &cfg.output_format, required_argument, output_format },
+    {0}
+    };
+
+       fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+       if(strcmp(cfg.output_format,"json")) {
+               printf("Seagate Extended SMART Information :\n");
+    } 
+
+        err = nvme_get_log(fd, 1, 0xC4, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+        if (!err) {
+               if(strcmp(cfg.output_format,"json")) {
+                       printf("%-39s %-15s %-19s \n", "Description", "Ext-Smart-Id", "Ext-Smart-Value");
+                       for(index=0; index<80; index++)
+                               printf("-");    
+                       printf("\n");
+                       for(index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++)
+                               print_smart_log(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index], index == (NUMBER_EXTENDED_SMART_ATTRIBUTES - 1));
+                       
+               }
+               else {
+            lbafs_ExtSmart = json_create_object();
+            json_print_smart_log(lbafs_ExtSmart, &ExtdSMARTInfo);
+               
+               json_object_add_value_array(root, "SMART-Attributes", lbafs);
+            json_array_add_value_object(lbafs, lbafs_ExtSmart);
+        }
+
+        /**
+         * Next get Log Page 0xCF
+         */
+
+        err = nvme_get_log(fd, 1, 0xCF, sizeof(logPageCF), &logPageCF);
+        if (!err) {
+               if(strcmp(cfg.output_format,"json")) {
+                /*printf("Seagate DRAM Supercap SMART Attributes :\n");*/
+                
+                print_smart_log_CF(&logPageCF);
+               }
+               else {
+                lbafs_DramSmart = json_create_object();
+                json_print_smart_log_CF(lbafs_DramSmart, &logPageCF);
+                json_array_add_value_object(lbafs, lbafs_DramSmart);
+                json_print_object(root, NULL);
+            }
+        }
+        else
+        {
+            if(!strcmp(cfg.output_format, "json")) {
+                json_print_object(root, NULL);
+            }
+        }
+       }
+       else if (err > 0)
+               fprintf(stderr, "NVMe Status:%s(%x)\n",
+                               nvme_status_to_string(err), err);
+
+       return err;
+}
+//EOF Extended-SMART Information
+
+static int vs_smart_log_wrapper(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+    return vs_smart_log(argc, argv, cmd, plugin);
+}
+
+/***************************************
+* Temperature-Stats information 
+***************************************/
+static void json_temp_stats(__u32 temperature, __u32 PcbTemp, __u32 SocTemp, __u32 maxTemperature,
+                             __u32 MaxSocTemp, __u32 cf_err, __u32 scCurrentTemp, __u32 scMaxTem)
+{
+       struct json_object *root;
+       root = json_create_object();
+
+       json_object_add_value_int(root, "Current temperature", temperature);
+    json_object_add_value_int(root, "Current PCB temperature", PcbTemp);
+    json_object_add_value_int(root, "Current SOC temperature", SocTemp);
+       json_object_add_value_int(root, "Highest temperature", maxTemperature);
+    json_object_add_value_int(root, "Max SOC temperature", MaxSocTemp);
+    if(!cf_err) {
+        json_object_add_value_int(root, "SuperCap Current temperature", scCurrentTemp);
+        json_object_add_value_int(root, "SuperCap Max temperature", scMaxTem);
+    }
+
+    json_print_object(root, NULL);
+    printf("\n");
+
+}
+static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+       struct nvme_smart_log smart_log;
+       EXTENDED_SMART_INFO_T ExtdSMARTInfo;
+    vendor_log_page_CF    logPageCF;
+
+    int fd;
+    int err, cf_err;
+       int index;
+        const char *desc = "Retrieve Seagate Temperature Stats information for the given device ";
+        const char *output_format = "output in binary format";
+       unsigned int temperature = 0, PcbTemp = 0, SocTemp = 0, scCurrentTemp = 0, scMaxTemp = 0;
+    unsigned long long maxTemperature = 0, MaxSocTemp = 0;
+       struct config {
+               char *output_format;
+       };
+        
+       struct config cfg = {
+               .output_format = "normal",
+       };
+
+       const struct argconfig_commandline_options command_line_options[] = {
+       {"output-format", 'o', "FMT", CFG_STRING, &cfg.output_format, required_argument, output_format },
+       {0}
+       };
+
+       fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+        if (fd < 0) {
+                printf ("\nDevice not found \n");;
+                return -1;
+        }
+
+       if(strcmp(cfg.output_format,"json"))
+               printf("Seagate Temperature Stats Information :\n");
+       //STEP-1 : Get Current Temperature from SMART
+       err = nvme_smart_log(fd, 0xffffffff, &smart_log);
+        if (!err) 
+        {
+            temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]);
+            temperature = temperature ? temperature - 273 : 0;
+            PcbTemp = le16_to_cpu(smart_log.temp_sensor[0]);
+            PcbTemp = PcbTemp ? PcbTemp - 273 : 0;
+            SocTemp = le16_to_cpu(smart_log.temp_sensor[1]);
+            SocTemp = SocTemp ? SocTemp - 273 : 0;
+            if(strcmp(cfg.output_format,"json"))
+            {
+                printf("%-20s : %u C\n", "Current Temperature", temperature);
+                printf("%-20s : %u C\n", "Current PCB Temperature", PcbTemp);
+                printf("%-20s : %u C\n", "Current SOC Temperature", SocTemp);
+            }
+        }
+
+       // STEP-2 : Get Max temperature form Ext SMART-id 194
+    err = nvme_get_log(fd, 1, 0xC4, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+    if (!err) 
+    {
+        for(index =0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) 
+        {
+            if(ExtdSMARTInfo.vendorData[index].AttributeNumber == VS_ATTR_ID_MAX_LIFE_TEMPERATURE) 
+            {
+                maxTemperature = smart_attribute_vs(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index]);
+                maxTemperature = maxTemperature ? maxTemperature - 273 : 0;
+                if(strcmp(cfg.output_format,"json")) 
+                {
+                    printf("%-20s : %d C\n", "Highest Temperature", (unsigned int)maxTemperature);
+                }
+            }
+
+            if(ExtdSMARTInfo.vendorData[index].AttributeNumber == VS_ATTR_ID_MAX_SOC_LIFE_TEMPERATURE) 
+            {
+                MaxSocTemp = smart_attribute_vs(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index]);
+                MaxSocTemp = MaxSocTemp ? MaxSocTemp - 273 : 0;
+                if(strcmp(cfg.output_format,"json")) 
+                {
+                    printf("%-20s : %d C\n", "Max SOC Temperature", (unsigned int)MaxSocTemp);
+                }
+            }
+               }
+       }
+       else if (err > 0)
+               fprintf(stderr, "NVMe Status:%s(%x)\n",
+                               nvme_status_to_string(err), err);
+
+    cf_err = nvme_get_log(fd, 1, 0xCF, sizeof(ExtdSMARTInfo), &logPageCF);
+
+    if(!cf_err) {
+        scCurrentTemp = logPageCF.AttrCF.SuperCapCurrentTemperature;
+        scCurrentTemp = scCurrentTemp ? scCurrentTemp - 273 : 0;
+        printf("%-20s : %d C\n", "Super-cap Current Temperature", scCurrentTemp);              
+
+        scMaxTemp = logPageCF.AttrCF.SuperCapMaximumTemperature;
+        scMaxTemp = scMaxTemp ? scMaxTemp - 273 : 0;
+        printf("%-20s : %d C\n", "Super-cap Max Temperature", scMaxTemp);
+    }
+
+       if(!strcmp(cfg.output_format,"json"))
+               json_temp_stats(temperature, PcbTemp, SocTemp, maxTemperature, MaxSocTemp, cf_err, scCurrentTemp, scMaxTemp);
+
+       return err;                             
+}      
+//EOF Temperature Stats information
+
+static int temp_stats_wrapper(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+    return temp_stats(argc, argv, cmd, plugin);
+}
+
+
+/***************************************
+* PCIe error-log information 
+***************************************/
+void print_vs_pcie_error_log(pcie_error_log_page  pcieErrorLog)
+{
+       __u32 correctPcieEc = 0;
+       __u32 uncorrectPcieEc = 0;
+       correctPcieEc = pcieErrorLog.BadDllpErrCnt + pcieErrorLog.BadTlpErrCnt 
+                       + pcieErrorLog.RcvrErrCnt + pcieErrorLog.ReplayTOErrCnt 
+                       + pcieErrorLog.ReplayNumRolloverErrCnt;
+
+       uncorrectPcieEc = pcieErrorLog.FCProtocolErrCnt + pcieErrorLog.DllpProtocolErrCnt 
+                       + pcieErrorLog.CmpltnTOErrCnt + pcieErrorLog.RcvrQOverflowErrCnt 
+                       + pcieErrorLog.UnexpectedCplTlpErrCnt + pcieErrorLog.CplTlpURErrCnt 
+                       + pcieErrorLog.CplTlpCAErrCnt + pcieErrorLog.ReqCAErrCnt  
+                       + pcieErrorLog.ReqURErrCnt + pcieErrorLog.EcrcErrCnt 
+                       + pcieErrorLog.MalformedTlpErrCnt + pcieErrorLog.CplTlpPoisonedErrCnt 
+                       + pcieErrorLog.MemRdTlpPoisonedErrCnt;
+
+       printf("%-45s : %u\n", "PCIe Correctable Error Count", correctPcieEc);
+       printf("%-45s : %u\n", "PCIe Un-Correctable Error Count", uncorrectPcieEc); 
+       printf("%-45s : %u\n", "Unsupported Request Error Status (URES)", pcieErrorLog.ReqURErrCnt);
+       printf("%-45s : %u\n", "ECRC Error Status (ECRCES)", pcieErrorLog.EcrcErrCnt);
+       printf("%-45s : %u\n", "Malformed TLP Status (MTS)", pcieErrorLog.MalformedTlpErrCnt);
+       printf("%-45s : %u\n", "Receiver Overflow Status (ROS)", pcieErrorLog.RcvrQOverflowErrCnt);
+       printf("%-45s : %u\n", "Unexpected Completion Status(UCS)", pcieErrorLog.UnexpectedCplTlpErrCnt);
+       printf("%-45s : %u\n", "Completion Timeout Status (CTS)", pcieErrorLog.CmpltnTOErrCnt);
+       printf("%-45s : %u\n", "Flow Control Protocol Error Status (FCPES)", pcieErrorLog.FCProtocolErrCnt);
+       printf("%-45s : %u\n", "Poisoned TLP Status (PTS)", pcieErrorLog.MemRdTlpPoisonedErrCnt);
+       printf("%-45s : %u\n", "Data Link Protocol Error Status(DLPES)", pcieErrorLog.DllpProtocolErrCnt);
+       printf("%-45s : %u\n", "Replay Timer Timeout Status(RTS)", pcieErrorLog.ReplayTOErrCnt);
+       printf("%-45s : %u\n", "Replay_NUM Rollover Status(RRS)", pcieErrorLog.ReplayNumRolloverErrCnt);
+       printf("%-45s : %u\n", "Bad DLLP Status (BDS)", pcieErrorLog.BadDllpErrCnt);
+       printf("%-45s : %u\n", "Bad TLP Status (BTS)", pcieErrorLog.BadTlpErrCnt);
+       printf("%-45s : %u\n", "Receiver Error Status (RES)", pcieErrorLog.RcvrErrCnt);
+       printf("%-45s : %u\n", "Cpl TLP Unsupported Request Error Count", pcieErrorLog.CplTlpURErrCnt);
+       printf("%-45s : %u\n", "Cpl TLP Completion Abort Error Count", pcieErrorLog.CplTlpCAErrCnt);
+       printf("%-45s : %u\n", "Cpl TLP Poisoned Error Count", pcieErrorLog.CplTlpPoisonedErrCnt);
+       printf("%-45s : %u\n", "Request Completion Abort Error Count", pcieErrorLog.ReqCAErrCnt);
+       printf("%-45s : %s\n", "Advisory Non-Fatal Error Status(ANFES)", "Not Supported");
+       printf("%-45s : %s\n", "Completer Abort Status (CAS)", "Not Supported");
+}
+
+void json_vs_pcie_error_log(pcie_error_log_page  pcieErrorLog)
+{
+       struct json_object *root;
+        root = json_create_object();
+        __u32 correctPcieEc = 0;
+        __u32 uncorrectPcieEc = 0;
+        correctPcieEc = pcieErrorLog.BadDllpErrCnt + pcieErrorLog.BadTlpErrCnt
+                        + pcieErrorLog.RcvrErrCnt + pcieErrorLog.ReplayTOErrCnt
+                        + pcieErrorLog.ReplayNumRolloverErrCnt;
+
+        uncorrectPcieEc = pcieErrorLog.FCProtocolErrCnt + pcieErrorLog.DllpProtocolErrCnt
+                        + pcieErrorLog.CmpltnTOErrCnt + pcieErrorLog.RcvrQOverflowErrCnt
+                        + pcieErrorLog.UnexpectedCplTlpErrCnt + pcieErrorLog.CplTlpURErrCnt
+                        + pcieErrorLog.CplTlpCAErrCnt + pcieErrorLog.ReqCAErrCnt
+                        + pcieErrorLog.ReqURErrCnt + pcieErrorLog.EcrcErrCnt
+                        + pcieErrorLog.MalformedTlpErrCnt + pcieErrorLog.CplTlpPoisonedErrCnt
+                        + pcieErrorLog.MemRdTlpPoisonedErrCnt;
+
+       json_object_add_value_int(root, "PCIe Correctable Error Count", correctPcieEc);
+       json_object_add_value_int(root, "PCIe Un-Correctable Error Count", uncorrectPcieEc);
+       json_object_add_value_int(root, "Unsupported Request Error Status (URES)", pcieErrorLog.ReqURErrCnt);
+        json_object_add_value_int(root, "ECRC Error Status (ECRCES)", pcieErrorLog.EcrcErrCnt);
+        json_object_add_value_int(root, "Malformed TLP Status (MTS)", pcieErrorLog.MalformedTlpErrCnt);
+        json_object_add_value_int(root, "Receiver Overflow Status (ROS)", pcieErrorLog.RcvrQOverflowErrCnt);
+        json_object_add_value_int(root, "Unexpected Completion Status(UCS)", pcieErrorLog.UnexpectedCplTlpErrCnt);
+        json_object_add_value_int(root, "Completion Timeout Status (CTS)", pcieErrorLog.CmpltnTOErrCnt);
+        json_object_add_value_int(root, "Flow Control Protocol Error Status (FCPES)", pcieErrorLog.FCProtocolErrCnt);
+        json_object_add_value_int(root, "Poisoned TLP Status (PTS)", pcieErrorLog.MemRdTlpPoisonedErrCnt);
+        json_object_add_value_int(root, "Data Link Protocol Error Status(DLPES)", pcieErrorLog.DllpProtocolErrCnt);
+        json_object_add_value_int(root, "Replay Timer Timeout Status(RTS)", pcieErrorLog.ReplayTOErrCnt);
+        json_object_add_value_int(root, "Replay_NUM Rollover Status(RRS)", pcieErrorLog.ReplayNumRolloverErrCnt);
+        json_object_add_value_int(root, "Bad DLLP Status (BDS)", pcieErrorLog.BadDllpErrCnt);
+        json_object_add_value_int(root, "Bad TLP Status (BTS)", pcieErrorLog.BadTlpErrCnt);
+        json_object_add_value_int(root, "Receiver Error Status (RES)", pcieErrorLog.RcvrErrCnt);
+        json_object_add_value_int(root, "Cpl TLP Unsupported Request Error Count", pcieErrorLog.CplTlpURErrCnt);
+        json_object_add_value_int(root, "Cpl TLP Completion Abort Error Count", pcieErrorLog.CplTlpCAErrCnt);
+        json_object_add_value_int(root, "Cpl TLP Poisoned Error Count", pcieErrorLog.CplTlpPoisonedErrCnt);
+        json_object_add_value_int(root, "Request Completion Abort Error Count", pcieErrorLog.ReqCAErrCnt);
+       json_print_object(root, NULL);
+        printf("\n");
+}
+
+static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+        pcie_error_log_page pcieErrorLog;
+        int fd;
+
+        const char *desc = "Retrieve Seagate PCIe error counters for the given device ";
+        const char *output_format = "output in binary format";
+        int err;
+        struct config {
+            char *output_format;
+        };
+
+        struct config cfg = {
+            .output_format = "normal",
+        };
+
+        const struct argconfig_commandline_options command_line_options[] = {
+            {"output-format", 'o', "FMT", CFG_STRING, &cfg.output_format, required_argument, output_format },
+            {0}
+        };
+
+        fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+        if(strcmp(cfg.output_format,"json"))
+            printf("Seagate PCIe error counters Information :\n");
+        
+        err = nvme_get_log(fd, 1, 0xCB, sizeof(pcieErrorLog), &pcieErrorLog);
+        if (!err) {
+            if(strcmp(cfg.output_format,"json")) {
+                print_vs_pcie_error_log(pcieErrorLog);
+            }
+            else
+                json_vs_pcie_error_log(pcieErrorLog);
+
+        }
+        else if (err > 0)
+            fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(err), err);
+                               
+        return err;
+}
+//EOF PCIE error-log information
+
+static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+    const char *desc = "Clear Seagate PCIe Correctable counters for the given device ";
+    const char *save = "specifies that the controller shall save the attribute";
+    int err, fd;
+    __u32 result;
+    void *buf = NULL;
+
+    struct config {
+        int   save;
+    };
+
+    struct config cfg = {
+        .save         = 0,
+    };
+
+    const struct argconfig_commandline_options command_line_options[] = {
+        {"save",         's', "FLAG", CFG_NONE,     &cfg.save,         no_argument, save},
+        {NULL}
+    };
+
+    fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+
+    err = nvme_set_feature(fd, 0, 0xE1, 0xCB, 0, cfg.save, 0, buf, &result);
+
+    if (err < 0) {
+        perror("set-feature");
+        return errno;
+    }
+
+    return err;
+
+}
+
+static int vs_clr_pcie_correctable_errs_wrapper(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+    return vs_clr_pcie_correctable_errs(argc, argv, cmd, plugin);
+}
+
+int nvme_get_log_with_offset(int fd, __u32 nsid, __u16 log_id, __u32 data_len, __u64 offset, void *data)
+{
+       struct nvme_admin_cmd cmd = {
+               .opcode         = nvme_admin_get_log_page,
+               .nsid           = nsid,
+               .addr           = (__u64)(uintptr_t) data,
+               .data_len       = data_len,
+       };
+       __u32 numd = (data_len >> 2) - 1;
+       __u16 numdu = numd >> 16, numdl = numd & 0xffff;
+
+       cmd.cdw10 = log_id | (numdl << 16);
+       cmd.cdw11 = numdu;
+    cmd.cdw12 = (__u32)(offset & 0xffffffff);
+    cmd.cdw13 = (__u32)((offset >> 32) & 0xffffffff);
+
+    /***************************************************************************
+    printf("nvme_get_log_with_offset Parameter Details - \n");
+    printf("data_len : %d cdw10 : %x cdw11 : %x cdw12 : %x cdw13 : %x\n", cmd.data_len, cmd.cdw10, cmd.cdw11, cmd.cdw12, cmd.cdw13);
+    ***************************************************************************/
+    return nvme_passthru_admin(fd, cmd.opcode, 0, 0,
+                               cmd.nsid, 0, 0,
+                               cmd.cdw10, cmd.cdw11, cmd.cdw12,
+                               cmd.cdw13, 0, 0,
+                               cmd.data_len, data, 0,
+                               NULL, 100);
+}
+
+static int get_host_tele(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+    const char *desc = "Capture the Telemetry Host-Initiated Data in either "\
+        "hex-dump (default) or binary format";
+    const char *namespace_id = "desired namespace";
+    const char *log_specific = "1 - controller shall capture Data representing the internal "\
+        "state of the controller at the time the command is processed. "\
+        "0 - controller shall not update the Telemetry Host Initiated Data.";
+    const char *raw_binary = "output in raw format";
+    int err, fd, dump_fd;
+    struct nvme_temetry_log_hdr tele_log;
+    __le64  offset = 0;
+    int blkCnt, maxBlk = 0, blksToGet;
+    unsigned char  *log;
+
+    struct config {
+        __u32 namespace_id;
+        __u32 log_id;
+        int   raw_binary;
+    };
+
+    struct config cfg = {
+        .namespace_id = 0xffffffff,
+        .log_id       = 0,
+    };
+
+    const struct argconfig_commandline_options command_line_options[] = {
+        {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace_id},
+        {"log_specific", 'i', "NUM", CFG_POSITIVE, &cfg.log_id,       required_argument, log_specific},
+        {"raw-binary",   'b', "",    CFG_NONE,     &cfg.raw_binary,   no_argument,       raw_binary},
+        {NULL}
+    };
+
+    fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+    if (fd < 0)
+        return fd;
+
+    dump_fd = STDOUT_FILENO;
+
+
+    cfg.log_id = (cfg.log_id << 8) | 0x07;
+    
+    err = nvme_get_log_with_offset(fd, cfg.namespace_id, cfg.log_id, sizeof(tele_log), offset, (void *)(&tele_log));
+    if (!err) {
+        
+        maxBlk = tele_log.tele_data_area3;
+        offset += 512;
+
+        if (!cfg.raw_binary) {
+            printf("Device:%s log-id:%d namespace-id:%#x\n",
+                   devicename, cfg.log_id,
+                   cfg.namespace_id);
+            printf("Data Block 1 Last Block:%d Data Block 2 Last Block:%d Data Block 3 Last Block:%d\n",
+                   tele_log.tele_data_area1, tele_log.tele_data_area2, tele_log.tele_data_area3);
+
+            d((unsigned char *)(&tele_log), sizeof(tele_log), 16, 1);
+        } else
+            seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd);
+    } else if (err > 0)
+        fprintf(stderr, "NVMe Status:%s(%x)\n",
+                    nvme_status_to_string(err), err);
+    else
+        perror("log page");
+
+    blkCnt = 0;
+    
+    while(blkCnt < maxBlk) 
+    {
+        blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
+
+        if(blksToGet == 0) {
+            return err;
+        }
+
+        log = malloc(blksToGet * 512);
+        
+        if (!log) {
+            fprintf(stderr, "could not alloc buffer for log\n");
+            return EINVAL;
+        }
+
+        memset(log, 0, blksToGet * 512);
+
+        err = nvme_get_log_with_offset(fd, cfg.namespace_id, cfg.log_id, blksToGet * 512, offset, (void *)log);
+        if (!err) {
+            offset += blksToGet * 512;
+        
+            if (!cfg.raw_binary) {
+                printf("\nBlock # :%d to %d\n", blkCnt + 1, blkCnt + blksToGet);
+    
+                d((unsigned char *)log, blksToGet * 512, 16, 1);
+            } else
+                seaget_d_raw((unsigned char *)log, blksToGet * 512, dump_fd);
+        } else if (err > 0)
+            fprintf(stderr, "NVMe Status:%s(%x)\n",
+                        nvme_status_to_string(err), err);
+        else
+            perror("log page");
+
+        blkCnt += blksToGet;
+
+        free(log);
+    }
+
+    return err;
+    
+}
+
+static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+    const char *desc = "Capture the Telemetry Controller-Initiated Data in either "\
+        "hex-dump (default) or binary format";
+    const char *namespace_id = "desired namespace";
+    const char *raw_binary = "output in raw format";
+    int err, fd, dump_fd;
+    struct nvme_temetry_log_hdr tele_log;
+    __le64  offset = 0;
+    __u16 log_id;
+    int blkCnt, maxBlk = 0, blksToGet;
+    unsigned char  *log;
+
+    struct config {
+        __u32 namespace_id;
+        int   raw_binary;
+    };
+
+    struct config cfg = {
+        .namespace_id = 0xffffffff,
+    };
+
+    const struct argconfig_commandline_options command_line_options[] = {
+        {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace_id},
+        {"raw-binary",   'b', "",    CFG_NONE,     &cfg.raw_binary,   no_argument,       raw_binary},
+        {NULL}
+    };
+
+    fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+    if (fd < 0)
+        return fd;
+
+    dump_fd = STDOUT_FILENO;
+
+    log_id = 0x08;
+    err = nvme_get_log_with_offset(fd, cfg.namespace_id, log_id, sizeof(tele_log), offset, (void *)(&tele_log));
+    if (!err) {
+
+        maxBlk = tele_log.tele_data_area3;
+        offset += 512;
+
+        if (!cfg.raw_binary) {
+            printf("Device:%s namespace-id:%#x\n",
+                   devicename, cfg.namespace_id);
+            printf("Data Block 1 Last Block:%d Data Block 2 Last Block:%d Data Block 3 Last Block:%d\n",
+                   tele_log.tele_data_area1, tele_log.tele_data_area2, tele_log.tele_data_area3);
+
+            d((unsigned char *)(&tele_log), sizeof(tele_log), 16, 1);
+        } else
+            seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd);
+    } else if (err > 0)
+        fprintf(stderr, "NVMe Status:%s(%x)\n",
+                    nvme_status_to_string(err), err);
+    else
+        perror("log page");
+
+    blkCnt = 0;
+
+    while(blkCnt < maxBlk) 
+    {
+        blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
+
+        if(blksToGet == 0) {
+            return err;
+        }
+
+        log = malloc(blksToGet * 512);
+
+        if (!log) {
+            fprintf(stderr, "could not alloc buffer for log\n");
+            return EINVAL;
+        }
+
+        memset(log, 0, blksToGet * 512);
+
+        err = nvme_get_log_with_offset(fd, cfg.namespace_id, log_id, blksToGet * 512, offset, (void *)log);
+        if (!err) {
+            offset += blksToGet * 512;
+
+            if (!cfg.raw_binary) {
+                printf("\nBlock # :%d to %d\n", blkCnt + 1, blkCnt + blksToGet);
+
+                d((unsigned char *)log, blksToGet * 512, 16, 1);
+            } else
+                seaget_d_raw((unsigned char *)log, blksToGet * 512, dump_fd);
+        } else if (err > 0)
+            fprintf(stderr, "NVMe Status:%s(%x)\n",
+                        nvme_status_to_string(err), err);
+        else
+            perror("log page");
+
+        blkCnt += blksToGet;
+
+        free(log);
+    }
+    return err;
+
+}
+
+void seaget_d_raw(unsigned char *buf, int len, int fd)
+{
+    /*********************
+       int i;
+    fflush(stdout);
+       for (i = 0; i < len; i++)
+               putchar(*(buf+i));
+    *********************/
+
+    if(write(fd, (void *)buf, len) <=0)
+    {
+        printf("%s: Write Failed\n",__FUNCTION__);
+    }
+
+}
+
+
+static int vs_internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+    const char *desc = "Capture the Telemetry Controller-Initiated Data in "\
+        "binary format";
+    const char *namespace_id = "desired namespace";
+
+    const char *file = "dump file";
+    int err, fd, dump_fd;
+    int flags = O_WRONLY | O_CREAT;
+    int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
+    struct nvme_temetry_log_hdr tele_log;
+    __le64  offset = 0;
+    __u16 log_id;
+    int blkCnt, maxBlk = 0, blksToGet;
+    unsigned char  *log;
+
+    struct config {
+        __u32 namespace_id;
+        char  *file;
+    };
+
+    struct config cfg = {
+        .namespace_id = 0xffffffff,
+        .file         = "",
+    };
+
+    const struct argconfig_commandline_options command_line_options[] = {
+        {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace_id},
+        {"dump-file",    'f', "FILE", CFG_STRING,  &cfg.file,         required_argument, file},
+        {NULL}
+    };
+
+    fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+    if (fd < 0)
+        return fd;
+
+    dump_fd = STDOUT_FILENO;
+
+    if(strlen(cfg.file)) {
+        dump_fd = open(cfg.file, flags, mode);
+        if (dump_fd < 0) {
+            perror(cfg.file);
+            return EINVAL;
+        }
+    }
+
+    log_id = 0x08;
+    err = nvme_get_log_with_offset(fd, cfg.namespace_id, log_id, sizeof(tele_log), offset, (void *)(&tele_log));
+    if (!err) {
+
+        maxBlk = tele_log.tele_data_area3;
+        offset += 512;
+
+        /***************************************************************************
+        printf("Data Block 1 Last Block:%d Data Block 2 Last Block:%d Data Block 3 Last Block:%d\n",
+                   tele_log.tele_data_area1, tele_log.tele_data_area2, tele_log.tele_data_area3);
+        ***************************************************************************/
+
+        seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd);
+
+    } else if (err > 0)
+        fprintf(stderr, "NVMe Status:%s(%x)\n",
+                    nvme_status_to_string(err), err);
+    else
+        perror("log page");
+
+    blkCnt = 0;
+
+    while(blkCnt < maxBlk) 
+    {
+        blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
+
+        if(blksToGet == 0) {
+            return err;
+        }
+
+        log = malloc(blksToGet * 512);
+
+        if (!log) {
+            fprintf(stderr, "could not alloc buffer for log\n");
+            return EINVAL;
+        }
+
+        memset(log, 0, blksToGet * 512);
+
+        err = nvme_get_log_with_offset(fd, cfg.namespace_id, log_id, blksToGet * 512, offset, (void *)log);
+        if (!err) {
+            offset += blksToGet * 512;
+
+            seaget_d_raw((unsigned char *)log, blksToGet * 512, dump_fd);
+
+        } else if (err > 0)
+            fprintf(stderr, "NVMe Status:%s(%x)\n",
+                        nvme_status_to_string(err), err);
+        else
+            perror("log page");
+
+        blkCnt += blksToGet;
+
+        free(log);
+    }
+
+    if(strlen(cfg.file)) {
+        close(dump_fd);
+    }
+
+
+    return err;
+
+}
+
+
+//SEAGATE-PLUGIN Version
+int seagate_plugin_version(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+       printf("Seagate-Plugin version : %d.%d \n", SEAGATE_PLUGIN_VERSION_MAJOR, SEAGATE_PLUGIN_VERSION_MINOR);       
+       return 0;
+}
+//EOF SEAGATE-PLUGIN Version
diff --git a/seagate-nvme.h b/seagate-nvme.h
new file mode 100755 (executable)
index 0000000..78c9f58
--- /dev/null
@@ -0,0 +1,47 @@
+//
+// Do NOT modify or remove this copyright and license
+//
+// Copyright (c) 2017-2018 Seagate Technology LLC and/or its Affiliates, All Rights Reserved
+//
+// ******************************************************************************************
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// \file seagate-nvme.h
+// \brief This file defines the functions and macros to make building a nvme-cli seagate plug-in.
+#undef CMD_INC_FILE
+#define CMD_INC_FILE seagate-nvme
+
+#if !defined(SEAGATE_NVME) || defined(CMD_HEADER_MULTI_READ)
+#define SEAGATE_NVME
+
+#include "cmd.h"
+
+PLUGIN(NAME("seagate", "Seagate vendor specific extensions"),
+       COMMAND_LIST(
+               ENTRY("vs-temp-stats",      "Retrieve Seagate temperature statistics ", temp_stats)             
+               ENTRY("vs-temperature-stats",      "Retrieve Seagate temperature statistics ",             temp_stats_wrapper)          
+               ENTRY("vs-log-page-sup",    "Retrieve Seagate Supported Log-pages Information ", log_pages_supp)                
+               ENTRY("vs-smart-log",       "Retrieve Seagate extended-SMART Information ", vs_smart_log)               
+        ENTRY("vs-smart-add-log",       "Retrieve Seagate extended-SMART Information ",         vs_smart_log_wrapper)          
+               ENTRY("vs-pcie-stats",      "Retrieve Seagate PCIe error statistics ", vs_pcie_error_log)               
+        ENTRY("clr-pcie-errs",      "Clear Seagate PCIe error statistics ",             vs_clr_pcie_correctable_errs)
+        ENTRY("clear-pcie-correctable-errors",      "Clear Seagate PCIe error statistics  ",             vs_clr_pcie_correctable_errs_wrapper)
+        ENTRY("get-host-tele",       "Retrieve Seagate Host-Initiated Telemetry ",          get_host_tele)
+        ENTRY("get-ctrl-tele",       "Retrieve Seagate Controller-Initiated Telemetry ",    get_ctrl_tele)
+        ENTRY("vs-internal-log",       "Retrieve Seagate Controller-Initiated Telemetry in binary format",  vs_internal_log)           
+               ENTRY("plugin-version",     "Shows Seagate plugin's version information ", seagate_plugin_version)              
+       )
+);
+
+#endif
+#include "define_cmd.h"