summaryrefslogtreecommitdiffstats
path: root/plugins/wdc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2022-07-14 18:28:04 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2022-07-16 15:12:07 +0000
commit589986012c4b3ab68e299a2eadca18f90080113b (patch)
treef29a53b04a1950cdddae69344bccb3f0146fa728 /plugins/wdc
parentReleasing debian version 1.16-4. (diff)
downloadnvme-cli-589986012c4b3ab68e299a2eadca18f90080113b.tar.xz
nvme-cli-589986012c4b3ab68e299a2eadca18f90080113b.zip
Merging upstream version 2.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins/wdc')
-rw-r--r--plugins/wdc/wdc-nvme.c2499
-rw-r--r--plugins/wdc/wdc-nvme.h5
2 files changed, 1695 insertions, 809 deletions
diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c
index d5e17b8..486ee36 100644
--- a/plugins/wdc/wdc-nvme.c
+++ b/plugins/wdc/wdc-nvme.c
@@ -30,18 +30,13 @@
#include <fcntl.h>
#include <unistd.h>
-#include "linux/nvme_ioctl.h"
-
#include "common.h"
#include "nvme.h"
-#include "nvme-print.h"
-#include "nvme-ioctl.h"
+#include "libnvme.h"
#include "plugin.h"
-#include "nvme-status.h"
+#include "linux/types.h"
+#include "nvme-print.h"
-#include "argconfig.h"
-#include "suffix.h"
-#include <sys/ioctl.h>
#define CREATE_CMD
#include "wdc-nvme.h"
#include "wdc-utils.h"
@@ -80,19 +75,27 @@
#define WDC_NVME_SN650_DEV_ID_2 0x2702
#define WDC_NVME_SN650_DEV_ID_3 0x2720
#define WDC_NVME_SN650_DEV_ID_4 0x2721
-#define WDC_NVME_SN450_DEV_ID_1 0x2712
-#define WDC_NVME_SN450_DEV_ID_2 0x2713
+#define WDC_NVME_SN655_DEV_ID 0x2722
+#define WDC_NVME_SN560_DEV_ID_1 0x2712
+#define WDC_NVME_SN560_DEV_ID_2 0x2713
+#define WDC_NVME_SN560_DEV_ID_3 0x2714
#define WDC_NVME_SXSLCL_DEV_ID 0x2001
#define WDC_NVME_SN520_DEV_ID 0x5003
#define WDC_NVME_SN520_DEV_ID_1 0x5004
#define WDC_NVME_SN520_DEV_ID_2 0x5005
+#define WDC_NVME_SN530_DEV_ID 0x5009
#define WDC_NVME_SN720_DEV_ID 0x5002
#define WDC_NVME_SN730A_DEV_ID 0x5006
#define WDC_NVME_SN730B_DEV_ID 0x3714
#define WDC_NVME_SN730B_DEV_ID_1 0x3734
+#define WDC_NVME_SN740_DEV_ID 0x5015
+#define WDC_NVME_SN740_DEV_ID_1 0x5016
+#define WDC_NVME_SN740_DEV_ID_2 0x5017
+#define WDC_NVME_SN740_DEV_ID_3 0x5025
#define WDC_NVME_SN340_DEV_ID 0x500d
#define WDC_NVME_ZN350_DEV_ID 0x5010
#define WDC_NVME_ZN350_DEV_ID_1 0x5018
+#define WDC_NVME_SN810_DEV_ID 0x5011
#define WDC_DRIVE_CAP_CAP_DIAG 0x0000000000000001
#define WDC_DRIVE_CAP_INTERNAL_LOG 0x0000000000000002
@@ -129,7 +132,10 @@
#define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000
#define WDC_SN730B_CAP_VUC_LOG 0x0000000400000000
#define WDC_DRIVE_CAP_DUI 0x0000000800000000
-#define WDC_DRIVE_CAP_PURGE 0x0000001000000000
+#define WDC_DRIVE_CAP_PURGE 0x0000001000000000
+#define WDC_DRIVE_CAP_OCP_C1_LOG_PAGE 0x0000002000000000
+#define WDC_DRIVE_CAP_OCP_C4_LOG_PAGE 0x0000004000000000
+#define WDC_DRIVE_CAP_OCP_C5_LOG_PAGE 0x0000008000000000
#define WDC_DRIVE_CAP_SMART_LOG_MASK (WDC_DRIVE_CAP_C0_LOG_PAGE | WDC_DRIVE_CAP_C1_LOG_PAGE | \
WDC_DRIVE_CAP_CA_LOG_PAGE | WDC_DRIVE_CAP_D0_LOG_PAGE)
#define WDC_DRIVE_CAP_CLEAR_PCIE_MASK (WDC_DRIVE_CAP_CLEAR_PCIE | \
@@ -164,6 +170,7 @@
#define WDC_CUSTOMER_ID_0x1004 0x1004
#define WDC_CUSTOMER_ID_0x1008 0x1008
#define WDC_CUSTOMER_ID_0x1304 0x1304
+#define WDC_INVALID_CUSTOMER_ID -1
#define WDC_ALL_PAGE_MASK 0xFFFF
#define WDC_C0_PAGE_MASK 0x0001
@@ -305,7 +312,7 @@
/* CA Log Page */
#define WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE 0xCA
#define WDC_FB_CA_LOG_BUF_LEN 0x80
-#define WDC_BD_CA_LOG_BUF_LEN 0x9C
+#define WDC_BD_CA_LOG_BUF_LEN 0xA0 /* Added 4 padding bytes to resolve build warning messages */
/* C0 EOL Status Log Page */
#define WDC_NVME_GET_EOL_STATUS_LOG_OPCODE 0xC0
@@ -323,6 +330,7 @@
#define WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID 0xC2
#define WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN 0x1000
#define WDC_MAX_NUM_ACT_HIST_ENTRIES 20
+#define WDC_C2_GUID_LENGTH 16
/* C3 Latency Monitor Log Page */
#define WDC_LATENCY_MON_LOG_BUF_LEN 0x200
@@ -512,14 +520,14 @@ typedef enum
SCAO_NUSE = 152, /* NUSE - Namespace utilization */
SCAO_PSC = 160, /* PLP start count */
SCAO_EEST = 176, /* Endurance estimate */
- SCAO_PLRC = 192, /* PCIe Link Retraining Count */
+ SCAO_PLRC = 192, /* PCIe Link Retraining Count */
SCAO_LPV = 494, /* Log page version */
SCAO_LPG = 496, /* Log page GUID */
} SMART_CLOUD_ATTRIBUTE_OFFSETS;
-#define WDC_C2_GUID_LENGTH 16
+#define WDC_C0_GUID_LENGTH 16
-static __u8 scao_guid[WDC_C2_GUID_LENGTH] = { 0xC5, 0xAF, 0x10, 0x28, 0xEA, 0xBF, 0xF2, 0xA4,
+static __u8 scao_guid[WDC_C0_GUID_LENGTH] = { 0xC5, 0xAF, 0x10, 0x28, 0xEA, 0xBF, 0xF2, 0xA4,
0x9C, 0x4F, 0x6F, 0x7C, 0xC9, 0x14, 0xD5, 0xAF };
typedef enum
@@ -632,10 +640,10 @@ static int wdc_purge(int argc, char **argv,
struct command *command, struct plugin *plugin);
static int wdc_purge_monitor(int argc, char **argv,
struct command *command, struct plugin *plugin);
-static bool wdc_nvme_check_supported_log_page(int fd, __u8 log_id);
+static bool wdc_nvme_check_supported_log_page(nvme_root_t r, int fd, __u8 log_id);
static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct command *command,
struct plugin *plugin);
-static int wdc_do_drive_essentials(int fd, char *dir, char *key);
+static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key);
static int wdc_drive_essentials(int argc, char **argv, struct command *command,
struct plugin *plugin);
static int wdc_drive_status(int argc, char **argv, struct command *command,
@@ -653,7 +661,6 @@ static int wdc_reason_identifier(int argc, char **argv,
static int wdc_do_get_reason_id(int fd, char *file, int log_id);
static int wdc_save_reason_id(int fd, __u8 *rsn_ident, int size);
static int wdc_clear_reason_id(int fd);
-static int wdc_dump_telemetry_hdr(int fd, int log_id, struct nvme_telemetry_log_page_hdr *log_hdr);
static int wdc_log_page_directory(int argc, char **argv, struct command *command,
struct plugin *plugin);
static int wdc_do_drive_info(int fd, __u32 *result);
@@ -661,10 +668,11 @@ static int wdc_vs_drive_info(int argc, char **argv, struct command *command,
struct plugin *plugin);
static int wdc_vs_temperature_stats(int argc, char **argv, struct command *command,
struct plugin *plugin);
-static __u64 wdc_get_enc_drive_capabilities(int fd);
+static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, int fd);
static int wdc_enc_get_nic_log(int fd, __u8 log_id, __u32 xfer_size, __u32 data_len, FILE *out);
static int wdc_enc_submit_move_data(int fd, char *cmd, int len, int xfer_size, FILE *out, int data_id, int cdw14, int cdw15);
-static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data);
+static bool get_dev_mgment_cbs_data(nvme_root_t r, int fd, __u8 log_id, void **cbs_data);
+static __u32 wdc_get_fw_cust_id(nvme_root_t r, int fd);
/* Drive log data size */
struct wdc_log_size {
@@ -802,12 +810,11 @@ struct wdc_c2_cbs_data {
__u8 data[];
};
-struct wdc_bd_ca_log_format {
+struct __attribute__((__packed__)) wdc_bd_ca_log_format {
__u8 field_id;
__u8 reserved1[2];
__u8 normalized_value;
- __u8 reserved2;
- __u8 raw_value[7];
+ __u8 raw_value[8];
};
#define READ 0
@@ -904,6 +911,32 @@ struct __attribute__((__packed__)) wdc_ssd_d0_smart_log {
__u8 rsvd[408]; /* 0x68 - 408 Reserved bytes */
};
+#define WDC_OCP_C1_GUID_LENGTH 16
+#define WDC_ERROR_REC_LOG_BUF_LEN 512
+#define WDC_ERROR_REC_LOG_ID 0xC1
+#define WDC_ERROR_REC_LOG_VERSION 0002
+
+struct __attribute__((__packed__)) wdc_ocp_c1_error_recovery_log {
+ __le16 panic_reset_wait_time; /* 000 - Panic Reset Wait Time */
+ __u8 panic_reset_action; /* 002 - Panic Reset Action */
+ __u8 dev_recovery_action1; /* 003 - Device Recovery Action 1 */
+ __le64 panic_id; /* 004 - Panic ID */
+ __le32 dev_capabilities; /* 012 - Device Capabilities */
+ __u8 vs_recovery_opc; /* 016 - Vendor Specific Recovery Opcode */
+ __u8 rsvd1[3]; /* 017 - 3 Reserved Bytes */
+ __le32 vs_cmd_cdw12; /* 020 - Vendor Specific Command CDW12 */
+ __le32 vs_cmd_cdw13; /* 024 - Vendor Specific Command CDW13 */
+ __u8 vs_cmd_to; /* 028 - Vendor Specific Command Timeout */
+ __u8 dev_recovery_action2; /* 029 - Device Recovery Action 2 */
+ __u8 dev_recovery_action2_to; /* 030 - Device Recovery Action 2 Timeout */
+ __u8 rsvd2[463]; /* 031 - 463 Reserved Bytes */
+ __le16 log_page_version; /* 494 - Log Page Version */
+ __u8 log_page_guid[WDC_OCP_C1_GUID_LENGTH]; /* 496 - Log Page GUID */
+};
+
+static __u8 wdc_ocp_c1_guid[WDC_OCP_C1_GUID_LENGTH] = { 0x44, 0xD9, 0x31, 0x21, 0xFE, 0x30, 0x34, 0xAE,
+ 0xAB, 0x4D, 0xFD, 0x3D, 0xBA, 0x83, 0x19, 0x5A };
+
/* NAND Stats */
struct __attribute__((__packed__)) wdc_nand_stats {
__u8 nand_write_tlc[16];
@@ -1015,6 +1048,49 @@ struct __attribute__((__packed__)) wdc_fw_act_history_log_format_c2 {
__u8 log_page_guid[WDC_C2_GUID_LENGTH];
};
+#define WDC_OCP_C4_GUID_LENGTH 16
+#define WDC_DEV_CAP_LOG_BUF_LEN 4096
+#define WDC_DEV_CAP_LOG_ID 0xC4
+#define WDC_DEV_CAP_LOG_VERSION 0001
+#define WDC_OCP_C4_NUM_PS_DESCR 127
+
+struct __attribute__((__packed__)) wdc_ocp_C4_dev_cap_log {
+ __le16 num_pcie_ports; /* 0000 - Number of PCI Express Ports */
+ __le16 oob_mgmt_support; /* 0002 - OOB Management Interfaces Supported */
+ __le16 wrt_zeros_support; /* 0004 - Write Zeros Commmand Support */
+ __le16 sanitize_support; /* 0006 - Sanitize Command Support */
+ __le16 dsm_support; /* 0008 - Dataset Management Command Support */
+ __le16 wrt_uncor_support; /* 0010 - Write Uncorrectable Command Support */
+ __le16 fused_support; /* 0012 - Fused Operation Support */
+ __le16 min_dssd_ps; /* 0014 - Minimum Valid DSSD Power State */
+ __u8 rsvd1; /* 0016 - Reserved must be cleared to zero */
+ __u8 dssd_ps_descr[WDC_OCP_C4_NUM_PS_DESCR];/* 0017 - DSSD Power State Descriptors */
+ __u8 rsvd2[3934]; /* 0144 - Reserved must be cleared to zero */
+ __le16 log_page_version; /* 4078 - Log Page Version */
+ __u8 log_page_guid[WDC_OCP_C4_GUID_LENGTH]; /* 4080 - Log Page GUID */
+};
+
+static __u8 wdc_ocp_c4_guid[WDC_OCP_C4_GUID_LENGTH] = { 0x97, 0x42, 0x05, 0x0D, 0xD1, 0xE1, 0xC9, 0x98,
+ 0x5D, 0x49, 0x58, 0x4B, 0x91, 0x3C, 0x05, 0xB7 };
+
+#define WDC_OCP_C5_GUID_LENGTH 16
+#define WDC_UNSUPPORTED_REQS_LOG_BUF_LEN 4096
+#define WDC_UNSUPPORTED_REQS_LOG_ID 0xC5
+#define WDC_UNSUPPORTED_REQS_LOG_VERSION 0001
+#define WDC_NUM_UNSUPPORTED_REQ_ENTRIES 253
+
+struct __attribute__((__packed__)) wdc_ocp_C5_unsupported_reqs {
+ __le16 unsupported_count; /* 0000 - Number of Unsupported Requirement IDs */
+ __u8 rsvd1[14]; /* 0002 - Reserved must be cleared to zero */
+ __u8 unsupported_req_list[WDC_NUM_UNSUPPORTED_REQ_ENTRIES][16]; /* 0016 - Unsupported Requirements List */
+ __u8 rsvd2[14]; /* 4064 - Reserved must be cleared to zero */
+ __le16 log_page_version; /* 4078 - Log Page Version */
+ __u8 log_page_guid[WDC_OCP_C5_GUID_LENGTH]; /* 4080 - Log Page GUID */
+};
+
+static __u8 wdc_ocp_c5_guid[WDC_OCP_C5_GUID_LENGTH] = { 0x2F, 0x72, 0x9C, 0x0E, 0x99, 0x23, 0x2C, 0xBB,
+ 0x63, 0x48, 0x32, 0xD0, 0xB7, 0x98, 0xBB, 0xC7 };
+
#define WDC_REASON_INDEX_MAX 16
#define WDC_REASON_ID_ENTRY_LEN 128
#define WDC_REASON_ID_PATH_NAME "/usr/local/nvmecli"
@@ -1043,80 +1119,74 @@ static long double int128_to_double(__u8 *data)
return result;
}
-static int wdc_get_pci_ids(uint32_t *device_id, uint32_t *vendor_id)
+static int wdc_get_pci_ids(nvme_root_t r, uint32_t *device_id,
+ uint32_t *vendor_id)
{
- int fd, ret = -1;
- char *block, path[512], *id;
-
- id = calloc(1, 32);
- if (!id) {
- fprintf(stderr, "ERROR : WDC : %s : calloc failed\n", __func__);
- return -1;
- }
-
- block = nvme_char_from_block((char *)devicename);
+ char vid[256], did[256], id[32];
+ nvme_ctrl_t c = NULL;
+ nvme_ns_t n = NULL;
+ int fd, ret;
- /* read the vendor ID from sys fs */
- sprintf(path, "/sys/class/nvme/%s/device/vendor", block);
+ c = nvme_scan_ctrl(r, devicename);
+ if (c) {
+ snprintf(vid, sizeof(vid), "%s/device/vendor",
+ nvme_ctrl_get_sysfs_dir(c));
+ snprintf(did, sizeof(did), "%s/device/device",
+ nvme_ctrl_get_sysfs_dir(c));
+ nvme_free_ctrl(c);
+ } else {
+ n = nvme_scan_namespace(devicename);
+ if (!n) {
+ fprintf(stderr, "Unable to find %s\n", devicename);
+ return -1;
+ }
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- sprintf(path, "/sys/class/misc/%s/device/vendor", block);
- fd = open(path, O_RDONLY);
+ snprintf(vid, sizeof(vid), "%s/device/device/vendor",
+ nvme_ns_get_sysfs_dir(n));
+ snprintf(did, sizeof(did), "%s/device/device/device",
+ nvme_ns_get_sysfs_dir(n));
+ nvme_free_ns(n);
}
+
+ fd = open(vid, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "ERROR : WDC : %s : Open vendor file failed\n", __func__);
- ret = -1;
- goto free_id;
+ return -1;
}
ret = read(fd, id, 32);
+ close(fd);
+
if (ret < 0) {
fprintf(stderr, "%s: Read of pci vendor id failed\n", __func__);
- ret = -1;
- goto close_fd;
- } else {
- if (id[strlen(id) - 1] == '\n')
- id[strlen(id) - 1] = '\0';
-
- /* convert the device id string to an int */
- *vendor_id = (int)strtol(&id[2], NULL, 16);
- ret = 0;
+ return -1;
}
- /* read the device ID from sys fs */
- sprintf(path, "/sys/class/nvme/%s/device/device", block);
+ if (id[strlen(id) - 1] == '\n')
+ id[strlen(id) - 1] = '\0';
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- sprintf(path, "/sys/class/misc/%s/device/device", block);
- fd = open(path, O_RDONLY);
- }
+ *vendor_id = strtol(id, NULL, 0);
+ ret = 0;
+
+ fd = open(did, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "ERROR : WDC : %s : Open device file failed\n", __func__);
- ret = -1;
- goto close_fd;
+ return -1;
}
ret = read(fd, id, 32);
+ close(fd);
+
if (ret < 0) {
fprintf(stderr, "%s: Read of pci device id failed\n", __func__);
- ret = -1;
- } else {
- if (id[strlen(id) - 1] == '\n')
- id[strlen(id) - 1] = '\0';
-
- /* convert the device id string to an int */
- *device_id = strtol(&id[2], NULL, 16);
- ret = 0;
+ return -1;
}
-close_fd:
- close(fd);
-free_id:
- free(block);
- free(id);
- return ret;
+ if (id[strlen(id) - 1] == '\n')
+ id[strlen(id) - 1] = '\0';
+
+ *device_id = strtol(id, NULL, 0);
+ return 0;
}
static int wdc_get_vendor_id(int fd, uint32_t *vendor_id)
@@ -1164,13 +1234,13 @@ static int wdc_get_model_number(int fd, char *model)
return ret;
}
-static bool wdc_check_device(int fd)
+static bool wdc_check_device(nvme_root_t r, int fd)
{
int ret;
bool supported;
uint32_t read_device_id = -1, read_vendor_id = -1;
- ret = wdc_get_pci_ids(&read_device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, &read_device_id, &read_vendor_id);
if (ret < 0) {
/* Use the identify nvme command to get vendor id due to NVMeOF device. */
if (wdc_get_vendor_id(fd, &read_vendor_id) < 0)
@@ -1210,14 +1280,13 @@ static bool wdc_enc_check_model(int fd)
return supported;
}
-static __u64 wdc_get_drive_capabilities(int fd) {
+static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
int ret;
uint32_t read_device_id = -1, read_vendor_id = -1;
__u64 capabilities = 0;
- __u8 *data;
- __u32 *cust_id;
+ __u32 cust_id;
- ret = wdc_get_pci_ids(&read_device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, &read_device_id, &read_vendor_id);
if (ret < 0)
{
if (wdc_get_vendor_id(fd, &read_vendor_id) < 0)
@@ -1227,7 +1296,7 @@ static __u64 wdc_get_drive_capabilities(int fd) {
/* below check condition is added due in NVMeOF device we dont have device_id so we need to use only vendor_id*/
if (read_device_id == -1 && read_vendor_id != -1)
{
- capabilities = wdc_get_enc_drive_capabilities(fd);
+ capabilities = wdc_get_enc_drive_capabilities(r, fd);
return capabilities;
}
@@ -1245,11 +1314,11 @@ static __u64 wdc_get_drive_capabilities(int fd) {
WDC_DRIVE_CAP_PURGE);
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xC1 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_ADD_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_ADD_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_C1_LOG_PAGE;
break;
default:
@@ -1265,11 +1334,11 @@ static __u64 wdc_get_drive_capabilities(int fd) {
WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_CLEAR_PCIE);
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
break;
case WDC_NVME_SN640_DEV_ID:
@@ -1280,7 +1349,7 @@ static __u64 wdc_get_drive_capabilities(int fd) {
/* FALLTHRU */
case WDC_NVME_SN640_DEV_ID_3:
/* verify the 0xC0 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE;
}
@@ -1290,27 +1359,38 @@ static __u64 wdc_get_drive_capabilities(int fd) {
WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG | WDC_DRIVE_CAP_REASON_ID |
WDC_DRIVE_CAP_LOG_PAGE_DIR);
- /* verify the 0xC3 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_LATENCY_MON_OPCODE) == true)
+ /* verify the 0xC1 (OCP Error Recovery) log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_ERROR_REC_LOG_ID) == true)
+ capabilities |= WDC_DRIVE_CAP_OCP_C1_LOG_PAGE;
+
+ /* verify the 0xC3 (OCP Latency Monitor) log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_LATENCY_MON_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_C3_LOG_PAGE;
+ /* verify the 0xC4 (OCP Device Capabilities) log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_DEV_CAP_LOG_ID) == true)
+ capabilities |= WDC_DRIVE_CAP_OCP_C4_LOG_PAGE;
+
+ /* verify the 0xC5 (OCP Unsupported Requirments) log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_UNSUPPORTED_REQS_LOG_ID) == true)
+ capabilities |= WDC_DRIVE_CAP_OCP_C5_LOG_PAGE;
+
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
- if (!get_dev_mgment_cbs_data(fd, WDC_C2_CUSTOMER_ID_ID, (void*)&data)) {
- fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID);
+ cust_id = wdc_get_fw_cust_id(r, fd);
+ if (cust_id == WDC_INVALID_CUSTOMER_ID) {
+ fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
return -1;
}
- cust_id = (__u32*)data;
-
- if ((*cust_id == WDC_CUSTOMER_ID_0x1004) || (*cust_id == WDC_CUSTOMER_ID_0x1008) ||
- (*cust_id == WDC_CUSTOMER_ID_0x1005) || (*cust_id == WDC_CUSTOMER_ID_0x1304))
+ if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) ||
+ (cust_id == WDC_CUSTOMER_ID_0x1005) || (cust_id == WDC_CUSTOMER_ID_0x1304))
capabilities |= (WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE |
WDC_DRIVE_CAP_INFO | WDC_DRIVE_CAP_CLOUD_SSD_VERSION);
else
@@ -1321,7 +1401,7 @@ static __u64 wdc_get_drive_capabilities(int fd) {
/* FALLTHRU */
case WDC_NVME_SN840_DEV_ID_1:
/* verify the 0xC0 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE;
}
/* FALLTHRU */
@@ -1337,11 +1417,11 @@ static __u64 wdc_get_drive_capabilities(int fd) {
WDC_DRIVE_CAP_LOG_PAGE_DIR );
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
break;
case WDC_NVME_SN650_DEV_ID:
@@ -1349,17 +1429,19 @@ static __u64 wdc_get_drive_capabilities(int fd) {
case WDC_NVME_SN650_DEV_ID_2:
case WDC_NVME_SN650_DEV_ID_3:
case WDC_NVME_SN650_DEV_ID_4:
- case WDC_NVME_SN450_DEV_ID_1:
- case WDC_NVME_SN450_DEV_ID_2:
+ case WDC_NVME_SN655_DEV_ID:
+ case WDC_NVME_SN560_DEV_ID_1:
+ case WDC_NVME_SN560_DEV_ID_2:
+ case WDC_NVME_SN560_DEV_ID_3:
/* verify the 0xC0 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE;
}
capabilities |= (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG |
WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE |
- WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY | WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY |
+ WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY | WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY |
WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG | WDC_DRIVE_CAP_REASON_ID |
WDC_DRIVE_CAP_LOG_PAGE_DIR | WDC_DRIVE_CAP_INFO |
WDC_DRIVE_CAP_CLOUD_SSD_VERSION);
@@ -1384,6 +1466,8 @@ static __u64 wdc_get_drive_capabilities(int fd) {
case WDC_NVME_SN520_DEV_ID_1:
/* FALLTHRU */
case WDC_NVME_SN520_DEV_ID_2:
+ case WDC_NVME_SN530_DEV_ID:
+ case WDC_NVME_SN810_DEV_ID:
capabilities = WDC_DRIVE_CAP_DUI_DATA;
break;
case WDC_NVME_SN720_DEV_ID:
@@ -1393,6 +1477,10 @@ static __u64 wdc_get_drive_capabilities(int fd) {
capabilities = WDC_DRIVE_CAP_DUI | WDC_DRIVE_CAP_NAND_STATS | WDC_DRIVE_CAP_INFO_2
| WDC_DRIVE_CAP_TEMP_STATS | WDC_DRIVE_CAP_VUC_CLEAR_PCIE | WDC_DRIVE_CAP_PCIE_STATS;
break;
+ case WDC_NVME_SN740_DEV_ID:
+ case WDC_NVME_SN740_DEV_ID_1:
+ case WDC_NVME_SN740_DEV_ID_2:
+ case WDC_NVME_SN740_DEV_ID_3:
case WDC_NVME_SN340_DEV_ID:
capabilities = WDC_DRIVE_CAP_DUI;
break;
@@ -1414,12 +1502,11 @@ static __u64 wdc_get_drive_capabilities(int fd) {
return capabilities;
}
-static __u64 wdc_get_enc_drive_capabilities(int fd) {
+static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, int fd) {
int ret;
uint32_t read_vendor_id;
__u64 capabilities = 0;
- __u8 *data;
- __u32 *cust_id;
+ __u32 cust_id;
ret = wdc_get_vendor_id(fd, &read_vendor_id);
if (ret < 0)
@@ -1431,11 +1518,11 @@ static __u64 wdc_get_enc_drive_capabilities(int fd) {
WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP);
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xC1 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_ADD_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_ADD_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_C1_LOG_PAGE;
break;
case WDC_NVME_VID_2:
@@ -1444,30 +1531,29 @@ static __u64 wdc_get_enc_drive_capabilities(int fd) {
WDC_DRIVE_CAP_RESIZE);
/* verify the 0xC3 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_LATENCY_MON_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_LATENCY_MON_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_C3_LOG_PAGE;
/* verify the 0xCB log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == true)
capabilities |= WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY;
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
- if (!get_dev_mgment_cbs_data(fd, WDC_C2_CUSTOMER_ID_ID, (void*)&data)) {
- fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID);
+ cust_id = wdc_get_fw_cust_id(r, fd);
+ if (cust_id == WDC_INVALID_CUSTOMER_ID) {
+ fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
return -1;
}
- cust_id = (__u32*)data;
-
- if ((*cust_id == WDC_CUSTOMER_ID_0x1004) || (*cust_id == WDC_CUSTOMER_ID_0x1008) ||
- (*cust_id == WDC_CUSTOMER_ID_0x1005) || (*cust_id == WDC_CUSTOMER_ID_0x1304))
+ if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) ||
+ (cust_id == WDC_CUSTOMER_ID_0x1005) || (cust_id == WDC_CUSTOMER_ID_0x1304))
capabilities |= (WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE);
else
capabilities |= (WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_CLEAR_PCIE);
@@ -1655,10 +1741,10 @@ bool wdc_get_dev_mng_log_entry(__u32 log_length,
return valid_log;
}
-static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
+static bool get_dev_mgment_cbs_data(nvme_root_t r, int fd, __u8 log_id, void **cbs_data)
{
int ret = -1;
- __u8* data;
+ void* data;
struct wdc_c2_log_page_header *hdr_ptr;
struct wdc_c2_log_subpage_header *sph;
__u32 length = 0;
@@ -1668,10 +1754,10 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
*cbs_data = NULL;
__u32 device_id, read_vendor_id;
- ret = wdc_get_pci_ids(&device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, &device_id, &read_vendor_id);
if(device_id == WDC_NVME_ZN350_DEV_ID || device_id == WDC_NVME_ZN350_DEV_ID_1) {
lid = WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8;
- uuid_ix = 0;
+ uuid_ix = 0;
} else
lid = WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE;
@@ -1682,18 +1768,36 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
memset(data, 0, sizeof (__u8) * WDC_C2_LOG_BUF_LEN);
/* get the log page length */
- ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, 0, false, WDC_C2_LOG_BUF_LEN, data);
+ struct nvme_get_log_args args_len = {
+ .args_size = sizeof(args_len),
+ .fd = fd,
+ .lid = lid,
+ .nsid = 0xFFFFFFFF,
+ .lpo = 0,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = 0,
+ .rae = false,
+ .uuidx = uuid_ix,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = WDC_C2_LOG_BUF_LEN,
+ .log = data,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args_len);
if (ret) {
fprintf(stderr, "ERROR : WDC : Unable to get 0x%x Log Page length, ret = 0x%x\n", lid, ret);
goto end;
}
hdr_ptr = (struct wdc_c2_log_page_header *)data;
+ length = le32_to_cpu(hdr_ptr->length);
- if (le32_to_cpu(hdr_ptr->length) > WDC_C2_LOG_BUF_LEN) {
+ if (length > WDC_C2_LOG_BUF_LEN) {
/* Log Page buffer too small, free and reallocate the necessary size */
free(data);
- data = calloc(le32_to_cpu(hdr_ptr->length), sizeof(__u8));
+ data = calloc(length, sizeof(__u8));
if (data == NULL) {
fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
return false;
@@ -1701,7 +1805,25 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
}
/* get the log page data */
- ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, 0, false, le32_to_cpu(hdr_ptr->length), data);
+ struct nvme_get_log_args args_data = {
+ .args_size = sizeof(args_data),
+ .fd = fd,
+ .lid = lid,
+ .nsid = 0xFFFFFFFF,
+ .lpo = 0,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = 0,
+ .rae = false,
+ .uuidx = uuid_ix,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = length,
+ .log = data,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args_data);
+
if (ret) {
fprintf(stderr, "ERROR : WDC : Unable to read 0x%x Log Page data, ret = 0x%x\n", lid, ret);
goto end;
@@ -1712,20 +1834,48 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
length = sizeof(struct wdc_c2_log_page_header);
hdr_ptr = (struct wdc_c2_log_page_header *)data;
sph = (struct wdc_c2_log_subpage_header *)(data + length);
- found = wdc_get_dev_mng_log_entry(hdr_ptr->length, log_id, hdr_ptr, &sph);
-
+ found = wdc_get_dev_mng_log_entry(le32_to_cpu(hdr_ptr->length), log_id, hdr_ptr, &sph);
if (found) {
- *cbs_data = (void *)&sph->data;
+ *cbs_data = calloc(le32_to_cpu(sph->length), sizeof(__u8));
+ if (*cbs_data == NULL) {
+ fprintf(stderr, "ERROR : WDC : calloc : %s\n", strerror(errno));
+ goto end;
+ }
+ memcpy((void *)*cbs_data, (void *)&sph->data, le32_to_cpu(sph->length));
} else {
/* not found with uuid = 1 try with uuid = 0 */
uuid_ix = 0;
/* get the log page data */
- ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, 0, false, le32_to_cpu(hdr_ptr->length), data);
+ struct nvme_get_log_args args = {
+ .args_size = sizeof(args),
+ .fd = fd,
+ .lid = lid,
+ .nsid = 0xFFFFFFFF,
+ .lpo = 0,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = 0,
+ .rae = false,
+ .uuidx = uuid_ix,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = le32_to_cpu(hdr_ptr->length),
+ .log = data,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args);
+
hdr_ptr = (struct wdc_c2_log_page_header *)data;
sph = (struct wdc_c2_log_subpage_header *)(data + length);
- found = wdc_get_dev_mng_log_entry(hdr_ptr->length, log_id, hdr_ptr, &sph);
+ found = wdc_get_dev_mng_log_entry(le32_to_cpu(hdr_ptr->length), log_id, hdr_ptr, &sph);
if (found) {
- *cbs_data = (void *)&sph->data;
+ *cbs_data = calloc(le32_to_cpu(sph->length), sizeof(__u8));
+ if (*cbs_data == NULL) {
+ fprintf(stderr, "ERROR : WDC : calloc : %s\n", strerror(errno));
+ goto end;
+ }
+ memcpy((void *)*cbs_data, (void *)&sph->data, le32_to_cpu(sph->length));
+
} else {
/* WD version not found */
fprintf(stderr, "ERROR : WDC : Unable to find correct version of page 0x%x, entry id = %d\n", lid, log_id);
@@ -1736,13 +1886,13 @@ end:
return found;
}
-static bool wdc_nvme_check_supported_log_page(int fd, __u8 log_id)
+static bool wdc_nvme_check_supported_log_page(nvme_root_t r, int fd, __u8 log_id)
{
int i;
bool found = false;
struct wdc_c2_cbs_data *cbs_data = NULL;
- if (get_dev_mgment_cbs_data(fd, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
+ if (get_dev_mgment_cbs_data(r, fd, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
if (cbs_data != NULL) {
for (i = 0; i < le32_to_cpu(cbs_data->length); i++) {
if (log_id == cbs_data->data[i]) {
@@ -1759,6 +1909,7 @@ static bool wdc_nvme_check_supported_log_page(int fd, __u8 log_id)
d((__u8 *)cbs_data->data, le32_to_cpu(cbs_data->length), 16, 1);
}
#endif
+ free(cbs_data);
} else
fprintf(stderr, "ERROR : WDC : cbs_data ptr = NULL\n");
} else
@@ -1767,14 +1918,16 @@ static bool wdc_nvme_check_supported_log_page(int fd, __u8 log_id)
return found;
}
-static bool wdc_nvme_get_dev_status_log_data(int fd, __le32 *ret_data,
+static bool wdc_nvme_get_dev_status_log_data(nvme_root_t r, int fd, __le32 *ret_data,
__u8 log_id)
{
__u32 *cbs_data = NULL;
- if (get_dev_mgment_cbs_data(fd, log_id, (void *)&cbs_data)) {
+ if (get_dev_mgment_cbs_data(r, fd, log_id, (void *)&cbs_data)) {
if (cbs_data != NULL) {
memcpy((void *)ret_data, (void *)cbs_data, 4);
+ free(cbs_data);
+
return true;
}
}
@@ -1786,16 +1939,16 @@ static bool wdc_nvme_get_dev_status_log_data(int fd, __le32 *ret_data,
static int wdc_do_clear_dump(int fd, __u8 opcode, __u32 cdw12)
{
int ret;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = opcode;
admin_cmd.cdw12 = cdw12;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret != 0) {
fprintf(stdout, "ERROR : WDC : Crash dump erase failed\n");
}
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
return ret;
}
@@ -1804,22 +1957,22 @@ static __u32 wdc_dump_length(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, __u
int ret;
__u8 buf[WDC_NVME_LOG_SIZE_DATA_LEN] = {0};
struct wdc_log_size *l;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
l = (struct wdc_log_size *) buf;
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = opcode;
admin_cmd.addr = (__u64)(uintptr_t)buf;
admin_cmd.data_len = WDC_NVME_LOG_SIZE_DATA_LEN;
admin_cmd.cdw10 = cdw10;
admin_cmd.cdw12 = cdw12;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret != 0) {
l->log_size = 0;
ret = -1;
fprintf(stderr, "ERROR : WDC : reading dump length failed\n");
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
return ret;
}
@@ -1833,19 +1986,19 @@ static __u32 wdc_dump_length(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, __u
static __u32 wdc_dump_length_e6(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, struct wdc_e6_log_hdr *dump_hdr)
{
int ret;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = opcode;
admin_cmd.addr = (__u64)(uintptr_t)dump_hdr;
admin_cmd.data_len = WDC_NVME_LOG_SIZE_HDR_LEN;
admin_cmd.cdw10 = cdw10;
admin_cmd.cdw12 = cdw12;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret != 0) {
fprintf(stderr, "ERROR : WDC : reading dump length failed\n");
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
}
return ret;
@@ -1854,9 +2007,9 @@ static __u32 wdc_dump_length_e6(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12,
static __u32 wdc_dump_dui_data(int fd, __u32 dataLen, __u32 offset, __u8 *dump_data, bool last_xfer)
{
int ret;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_CAP_DUI_OPCODE;
admin_cmd.nsid = 0xFFFFFFFF;
admin_cmd.addr = (__u64)(uintptr_t)dump_data;
@@ -1869,10 +2022,10 @@ static __u32 wdc_dump_dui_data(int fd, __u32 dataLen, __u32 offset, __u8 *dump_d
admin_cmd.cdw14 = WDC_NVME_CAP_DUI_DISABLE_IO;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret != 0) {
fprintf(stderr, "ERROR : WDC : reading DUI data failed\n");
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
}
return ret;
@@ -1881,10 +2034,10 @@ static __u32 wdc_dump_dui_data(int fd, __u32 dataLen, __u32 offset, __u8 *dump_d
static __u32 wdc_dump_dui_data_v2(int fd, __u32 dataLen, __u64 offset, __u8 *dump_data, bool last_xfer)
{
int ret;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
__u64 offset_lo, offset_hi;
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_CAP_DUI_OPCODE;
admin_cmd.nsid = 0xFFFFFFFF;
admin_cmd.addr = (__u64)(uintptr_t)dump_data;
@@ -1900,10 +2053,10 @@ static __u32 wdc_dump_dui_data_v2(int fd, __u32 dataLen, __u64 offset, __u8 *dum
else
admin_cmd.cdw14 = WDC_NVME_CAP_DUI_DISABLE_IO;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret != 0) {
fprintf(stderr, "ERROR : WDC : reading DUI data V2 failed\n");
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
}
return ret;
@@ -1916,7 +2069,7 @@ static int wdc_do_dump(int fd, __u32 opcode,__u32 data_len,
__u8 *dump_data;
__u32 curr_data_offset, curr_data_len;
int i;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
__u32 dump_length = data_len;
dump_data = (__u8 *) malloc(sizeof (__u8) * dump_length);
@@ -1925,7 +2078,7 @@ static int wdc_do_dump(int fd, __u32 opcode,__u32 data_len,
return -1;
}
memset(dump_data, 0, sizeof (__u8) * dump_length);
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
curr_data_offset = 0;
curr_data_len = xfer_size;
i = 0;
@@ -1938,10 +2091,9 @@ static int wdc_do_dump(int fd, __u32 opcode,__u32 data_len,
admin_cmd.cdw13 = curr_data_offset;
while (curr_data_offset < data_len) {
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret != 0) {
- fprintf(stderr, "%s: ERROR : WDC : NVMe Status:%s(%x)\n",
- __func__, nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
__func__, i, admin_cmd.data_len, curr_data_offset, (long unsigned int)admin_cmd.addr);
break;
@@ -1961,7 +2113,7 @@ static int wdc_do_dump(int fd, __u32 opcode,__u32 data_len,
}
if (ret == 0) {
- fprintf(stderr, "%s: NVMe Status:%s(%x)\n", __func__, nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
ret = wdc_create_log_file(file, dump_data, dump_length);
}
free(dump_data);
@@ -1975,7 +2127,7 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
__u8 *dump_data;
__u32 curr_data_offset, log_size;
int i;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
dump_data = (__u8 *) malloc(sizeof (__u8) * data_len);
@@ -1984,7 +2136,7 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
return -1;
}
memset(dump_data, 0, sizeof (__u8) * data_len);
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
curr_data_offset = WDC_NVME_LOG_SIZE_HDR_LEN;
i = 0;
@@ -2003,9 +2155,9 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
admin_cmd.cdw10 = xfer_size >> 2;
admin_cmd.cdw13 = curr_data_offset >> 2;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret != 0) {
- fprintf(stderr, "%s: ERROR : WDC : NVMe Status:%s(%x)\n", __func__, nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
__func__, i, admin_cmd.data_len, curr_data_offset, (long unsigned int)admin_cmd.addr);
break;
@@ -2017,9 +2169,11 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
}
if (ret == 0) {
- fprintf(stderr, "%s: NVMe Status:%s(%x)\n", __func__, nvme_status_to_string(ret), ret);
+ fprintf(stderr, "%s: ", __func__);
+ nvme_show_status(ret);
} else {
- fprintf(stderr, "%s: FAILURE: NVMe Status:%s(%x)\n", __func__, nvme_status_to_string(ret), ret);
+ fprintf(stderr, "%s: FAILURE: ", __func__);
+ nvme_show_status(ret);
fprintf(stderr, "%s: Partial data may have been captured\n", __func__);
snprintf(file + strlen(file), PATH_MAX, "%s", "-PARTIAL");
}
@@ -2032,40 +2186,66 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int data_area)
{
- struct nvme_telemetry_log_page_hdr *hdr;
- struct nvme_id_ctrl ctrl;
- size_t full_size, offset = WDC_TELEMETRY_HEADER_LENGTH;
+ struct nvme_telemetry_log *log;
+ size_t full_size = 0;
int err = 0, output;
- void *page_log;
__u32 host_gen = 1;
int ctrl_init = 0;
__u32 result;
void *buf = NULL;
+ __u8 *data_ptr = NULL;
+ int data_written = 0, data_remaining = 0;
+ struct nvme_id_ctrl ctrl;
+ __u64 capabilities = 0;
+ nvme_root_t r;
+ memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
+ err = nvme_identify_ctrl(fd, &ctrl);
+ if (err) {
+ fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
+ "0x%x\n", err);
+ goto close_fd;
+ }
+
+ if (!(ctrl.lpa & 0x8)) {
+ fprintf(stderr, "Telemetry Host-Initiated and Telemetry Controller-Initiated log pages not supported\n");
+ err = -EINVAL;
+ goto close_fd;
+ }
+
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if (type == WDC_TELEMETRY_TYPE_HOST) {
host_gen = 1;
ctrl_init = 0;
} else if (type == WDC_TELEMETRY_TYPE_CONTROLLER) {
- /* Verify the Controller Initiated Option is enabled */
- err = nvme_get_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 0,
- 0, 4, buf, &result);
- if (err == 0) {
- if (result == 0) {
- /* enabled */
- host_gen = 0;
- ctrl_init = 1;
+ if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) {
+ /* Verify the Controller Initiated Option is enabled */
+ err = nvme_get_features_data(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0,
+ 4, buf, &result);
+ if (err == 0) {
+ if (result == 0) {
+ /* enabled */
+ host_gen = 0;
+ ctrl_init = 1;
+ }
+ else {
+ fprintf(stderr, "%s: Controller initiated option telemetry log page disabled\n", __func__);
+ err = -EINVAL;
+ goto close_fd;
+ }
}
else {
- fprintf(stderr, "%s: Controller initiated option telemetry log page disabled\n", __func__);
- err = -EINVAL;
+ fprintf(stderr, "ERROR : WDC: Get telemetry option feature failed.");
+ nvme_show_status(err);
+ err = -EPERM;
goto close_fd;
}
- } else {
- fprintf(stderr, "ERROR : WDC: Get telemetry option feature failed. NVMe Status:%s(%x)\n",
- nvme_status_to_string(err), err);
- err = -EPERM;
- goto close_fd;
+ }
+ else {
+ host_gen = 0;
+ ctrl_init = 1;
}
} else {
fprintf(stderr, "%s: Invalid type parameter; type = %d\n", __func__, type);
@@ -2079,25 +2259,21 @@ static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int
goto close_fd;
}
- hdr = malloc(bs);
- page_log = malloc(bs);
- if (!hdr || !page_log) {
- fprintf(stderr, "%s: Failed to allocate 0x%x bytes for log: %s\n",
- __func__, bs, strerror(errno));
- err = -ENOMEM;
- goto free_mem;
- }
- memset(hdr, 0, bs);
-
output = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (output < 0) {
fprintf(stderr, "%s: Failed to open output file %s: %s!\n",
__func__, file, strerror(errno));
err = output;
- goto free_mem;
+ goto close_fd;
}
- err = nvme_get_telemetry_log(fd, hdr, host_gen, ctrl_init, WDC_TELEMETRY_HEADER_LENGTH, 0);
+ if (ctrl_init)
+ err = nvme_get_ctrl_telemetry(fd, true, &log, data_area, &full_size);
+ else if (host_gen)
+ err = nvme_get_new_host_telemetry(fd, &log, data_area, &full_size);
+ else
+ err = nvme_get_host_telemetry(fd, &log, data_area, &full_size);
+
if (err < 0)
perror("get-telemetry-log");
else if (err > 0) {
@@ -2106,102 +2282,39 @@ static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int
goto close_output;
}
- err = write(output, (void *) hdr, WDC_TELEMETRY_HEADER_LENGTH);
- if (err != WDC_TELEMETRY_HEADER_LENGTH) {
- fprintf(stderr, "%s: Failed to flush header data to file!, err = %d\n", __func__, err);
- goto close_output;
- }
-
- switch (data_area) {
- case 1:
- full_size = (le16_to_cpu(hdr->dalb1) * WDC_TELEMETRY_BLOCK_SIZE) + WDC_TELEMETRY_HEADER_LENGTH;
- break;
- case 2:
- full_size = (le16_to_cpu(hdr->dalb2) * WDC_TELEMETRY_BLOCK_SIZE) + WDC_TELEMETRY_HEADER_LENGTH;
- break;
- case 3:
- full_size = (le16_to_cpu(hdr->dalb3) * WDC_TELEMETRY_BLOCK_SIZE) + WDC_TELEMETRY_HEADER_LENGTH;
- break;
- case 4:
- err = nvme_identify_ctrl(fd, &ctrl);
- if (err) {
- perror("identify-ctrl");
- goto close_output;
- }
-
- if (posix_memalign(&buf, getpagesize(), get_feat_buf_len(NVME_FEAT_HOST_BEHAVIOR))) {
- fprintf(stderr, "can not allocate feature payload\n");
- errno = ENOMEM;
- err = -1;
- goto close_output;
- }
- memset(buf, 0, get_feat_buf_len(NVME_FEAT_HOST_BEHAVIOR));
-
- err = nvme_get_feature(fd, NVME_NSID_ALL, NVME_FEAT_HOST_BEHAVIOR, 0, 0,
- 0, get_feat_buf_len(NVME_FEAT_HOST_BEHAVIOR), buf, &result);
- if (err > 0) {
- nvme_show_status(err);
- } else if (err < 0) {
- perror("get-feature");
- } else {
- if ((ctrl.lpa & 0x40)) {
- if (((unsigned char *)buf)[1] == 1)
- full_size = (le32_to_cpu(hdr->dalb4) * WDC_TELEMETRY_BLOCK_SIZE) + WDC_TELEMETRY_HEADER_LENGTH;
- else {
- fprintf(stderr, "Data area 4 unsupported, Host Behavior Support ETDAS not set to 1\n");
- errno = EINVAL;
- err = -1;
- }
- } else {
- fprintf(stderr, "Data area 4 unsupported, bit 6 of Log Page Attributes not set\n");
- errno = EINVAL;
- err = -1;
- }
- }
- free(buf);
- if (err)
- goto close_output;
- break;
- default:
- fprintf(stderr, "%s: Invalid data area requested, data area = %d\n", __func__, data_area);
- err = -EINVAL;
- goto close_output;
- }
-
/*
* Continuously pull data until the offset hits the end of the last
* block.
*/
- while (offset < full_size) {
- if ((full_size - offset) < bs)
- bs = (full_size - offset);
+ data_written = 0;
+ data_remaining = full_size;
+ data_ptr = (__u8 *)log;
+ while (data_remaining) {
+ data_written = write(output, data_ptr, data_remaining);
- err = nvme_get_telemetry_log(fd, page_log, 0, ctrl_init, bs, offset);
- if (err < 0) {
- perror("get-telemetry-log");
+ if (data_written < 0) {
+ data_remaining = data_written;
break;
- } else if (err > 0) {
- nvme_show_status(err);
- fprintf(stderr, "%s: Failed to acquire full telemetry log!\n", __func__);
- nvme_show_status(err);
+ } else if (data_written <= data_remaining) {
+ data_remaining -= data_written;
+ data_ptr += data_written;
+ } else {
+ /* Unexpected overwrite */
+ fprintf(stderr, "Failure: Unexpected telemetry log overwrite - data_remaining = 0x%x, data_written = 0x%x\n",
+ data_remaining, data_written);
break;
}
+ }
- err = write(output, (void *) page_log, bs);
- if (err != bs) {
- fprintf(stderr, "%s: Failed to flush telemetry data to file!, err = %d\n", __func__, err);
- break;
- }
- err = 0;
- offset += bs;
+ if (fsync(output) < 0) {
+ fprintf(stderr, "ERROR : %s: fsync : %s\n", __func__, strerror(errno));
+ return -1;
}
+ free(log);
close_output:
close(output);
-free_mem:
- free(hdr);
- free(page_log);
close_fd:
close(fd);
@@ -2209,7 +2322,8 @@ close_fd:
}
-static int wdc_do_cap_diag(int fd, char *file, __u32 xfer_size, int type, int data_area)
+static int wdc_do_cap_diag(nvme_root_t r, int fd, char *file,
+ __u32 xfer_size, int type, int data_area)
{
int ret = -1;
__u32 e6_log_hdr_size = WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE;
@@ -2287,7 +2401,8 @@ static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, in
ret = wdc_dump_dui_data(fd, WDC_NVME_CAP_DUI_HEADER_SIZE, 0x00, (__u8 *)log_hdr, last_xfer);
if (ret != 0) {
fprintf(stderr, "%s: ERROR : WDC : Get DUI headers failed\n", __func__);
- fprintf(stderr, "%s: ERROR : WDC : NVMe Status:%s(%x)\n", __func__, nvme_status_to_string(ret), ret);
+ fprintf(stderr, "%s: ERROR : WDC : ", __func__);
+ nvme_show_status(ret);
goto out;
}
@@ -2368,7 +2483,9 @@ static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, in
if (ret != 0) {
fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%"PRIx64", offset = 0x%x, addr = %p\n",
__func__, i, (uint64_t)log_size, curr_data_offset, buffer_addr);
- fprintf(stderr, "%s: ERROR : WDC : NVMe Status:%s(%x)\n", __func__, nvme_status_to_string(ret), ret);
+ fprintf(stderr, "%s: ERROR : WDC : ",
+ __func__);
+ nvme_show_status(ret);
break;
}
@@ -2480,7 +2597,8 @@ static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, in
if (ret != 0) {
fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%"PRIx64", offset = 0x%"PRIx64", addr = %p\n",
__func__, i, (uint64_t)total_size, (uint64_t)curr_data_offset, buffer_addr);
- fprintf(stderr, "%s: ERROR : WDC : NVMe Status:%s(%x)\n", __func__, nvme_status_to_string(ret), ret);
+ fprintf(stderr, "%s: ERROR : WDC : ", __func__);
+ nvme_show_status(ret);
break;
}
@@ -2594,7 +2712,8 @@ static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, in
if (ret != 0) {
fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%"PRIx64", offset = 0x%"PRIx64", addr = %p\n",
__func__, i, (uint64_t)log_size, (uint64_t)curr_data_offset, buffer_addr);
- fprintf(stderr, "%s: ERROR : WDC : NVMe Status:%s(%x)\n", __func__, nvme_status_to_string(ret), ret);
+ fprintf(stderr, "%s: ERROR : WDC :", __func__);
+ nvme_show_status(ret);
break;
}
@@ -2616,8 +2735,7 @@ static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, in
goto out;
}
-
- fprintf(stderr, "%s: NVMe Status:%s(%x)\n", __func__, nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (verbose)
fprintf(stderr, "INFO : WDC : Capture Device Unit Info log, length = 0x%"PRIx64"\n", (uint64_t)total_size);
@@ -2633,6 +2751,7 @@ static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, in
static int wdc_cap_diag(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
+ nvme_root_t r;
char *desc = "Capture Diagnostics Log.";
char *file = "Output file pathname.";
char *size = "Data retrieval transfer size.";
@@ -2657,6 +2776,8 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
OPT_END()
};
+ r = nvme_scan(NULL);
+
fd = parse_and_open(argc, argv, desc, opts);
if (fd < 0)
return fd;
@@ -2672,11 +2793,12 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
if (cfg.file == NULL)
snprintf(f + strlen(f), PATH_MAX, "%s", ".bin");
- capabilities = wdc_get_drive_capabilities(fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_CAP_DIAG) == WDC_DRIVE_CAP_CAP_DIAG)
- return wdc_do_cap_diag(fd, f, xfer_size, 0, 0);
+ return wdc_do_cap_diag(r, fd, f, xfer_size, 0, 0);
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ nvme_free_tree(r);
return 0;
}
@@ -2684,14 +2806,14 @@ static int wdc_do_get_sn730_log_len(int fd, uint32_t *len_buf, uint32_t subopcod
{
int ret;
uint32_t *output = NULL;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
if ((output = (uint32_t*)malloc(sizeof(uint32_t))) == NULL) {
fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
return -1;
}
memset(output, 0, sizeof (uint32_t));
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.data_len = 8;
admin_cmd.opcode = SN730_NVME_GET_LOG_OPCODE;
@@ -2699,7 +2821,7 @@ static int wdc_do_get_sn730_log_len(int fd, uint32_t *len_buf, uint32_t subopcod
admin_cmd.cdw12 = subopcode;
admin_cmd.cdw10 = SN730_LOG_CHUNK_SIZE / 4;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret == 0)
*len_buf = *output;
free(output);
@@ -2710,13 +2832,13 @@ static int wdc_do_get_sn730_log(int fd, void * log_buf, uint32_t offset, uint32_
{
int ret;
uint8_t *output = NULL;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
if ((output = (uint8_t*)calloc(SN730_LOG_CHUNK_SIZE, sizeof(uint8_t))) == NULL) {
fprintf(stderr, "ERROR : WDC : calloc : %s\n", strerror(errno));
return -1;
}
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.data_len = SN730_LOG_CHUNK_SIZE;
admin_cmd.opcode = SN730_NVME_GET_LOG_OPCODE;
admin_cmd.addr = (uintptr_t)output;
@@ -2724,7 +2846,7 @@ static int wdc_do_get_sn730_log(int fd, void * log_buf, uint32_t offset, uint32_
admin_cmd.cdw13 = offset;
admin_cmd.cdw10 = SN730_LOG_CHUNK_SIZE / 4;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (!ret)
memcpy(log_buf, output, SN730_LOG_CHUNK_SIZE);
return ret;
@@ -2816,22 +2938,22 @@ static int wdc_do_sn730_get_and_tar(int fd, char * outputName)
ret = wdc_do_get_sn730_log_len(fd, &full_log_len, SN730_GET_FULL_LOG_LENGTH);
if (ret) {
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
goto free_buf;
}
ret = wdc_do_get_sn730_log_len(fd, &key_log_len, SN730_GET_KEY_LOG_LENGTH);
if (ret) {
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
goto free_buf;
}
ret = wdc_do_get_sn730_log_len(fd, &core_dump_log_len, SN730_GET_COREDUMP_LOG_LENGTH);
if (ret) {
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
goto free_buf;
}
ret = wdc_do_get_sn730_log_len(fd, &extended_log_len, SN730_GET_EXTENDED_LOG_LENGTH);
if (ret) {
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
goto free_buf;
}
@@ -2849,28 +2971,28 @@ static int wdc_do_sn730_get_and_tar(int fd, char * outputName)
/* Get the full log */
ret = get_sn730_log_chunks(fd, full_log_buf, full_log_len, SN730_GET_FULL_LOG_SUBOPCODE);
if (ret) {
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
goto free_buf;
}
/* Get the key log */
ret = get_sn730_log_chunks(fd, key_log_buf, key_log_len, SN730_GET_KEY_LOG_SUBOPCODE);
if (ret) {
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
goto free_buf;
}
/* Get the core dump log */
ret = get_sn730_log_chunks(fd, core_dump_log_buf, core_dump_log_len, SN730_GET_CORE_LOG_SUBOPCODE);
if (ret) {
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
goto free_buf;
}
/* Get the extended log */
ret = get_sn730_log_chunks(fd, extended_log_buf, extended_log_len, SN730_GET_EXTEND_LOG_SUBOPCODE);
if (ret) {
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
goto free_buf;
}
@@ -2919,10 +3041,11 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
char *data_area = "Data area to retrieve up to. Currently only supported on the SN340, SN640, SN730, and SN840 devices.";
char *file_size = "Output file size. Currently only supported on the SN340 device.";
char *offset = "Output file data offset. Currently only supported on the SN340 device.";
- char *type = "Telemetry type - NONE, HOST, or CONTROLLER. Currently only supported on the SN640 and SN840 devices.";
+ char *type = "Telemetry type - NONE, HOST, or CONTROLLER. Currently only supported on the SN530, SN640, SN730, SN740, SN810, SN840 and ZN350 devices.";
char *verbose = "Display more debug messages.";
char f[PATH_MAX] = {0};
char fileSuffix[PATH_MAX] = {0};
+ nvme_root_t r;
__u32 xfer_size = 0;
int fd;
int telemetry_type = 0, telemetry_data_area = 0;
@@ -2937,7 +3060,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
__u64 file_size;
__u64 offset;
char *type;
- int verbose;
+ bool verbose;
};
struct config cfg = {
@@ -2947,7 +3070,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
.file_size = 0,
.offset = 0,
.type = NULL,
- .verbose = 0,
+ .verbose = false,
};
OPT_ARGS(opts) = {
@@ -2965,12 +3088,16 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
if (fd < 0)
return fd;
- if (!wdc_check_device(fd))
+ r = nvme_scan(NULL);
+ if (!wdc_check_device(r, fd)) {
+ nvme_free_tree(r);
return -1;
+ }
if (cfg.xfer_size != 0)
xfer_size = cfg.xfer_size;
else {
fprintf(stderr, "ERROR : WDC : Invalid length\n");
+ nvme_free_tree(r);
return -1;
}
@@ -3010,43 +3137,64 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
}
}
- capabilities = wdc_get_drive_capabilities(fd);
+ if ((cfg.type == NULL) ||
+ (!strcmp(cfg.type, "NONE")) ||
+ (!strcmp(cfg.type, "none"))) {
+ telemetry_type = WDC_TELEMETRY_TYPE_NONE;
+ data_area = 0;
+ } else if ((!strcmp(cfg.type, "HOST")) ||
+ (!strcmp(cfg.type, "host"))) {
+ telemetry_type = WDC_TELEMETRY_TYPE_HOST;
+ telemetry_data_area = cfg.data_area;
+ } else if ((!strcmp(cfg.type, "CONTROLLER")) ||
+ (!strcmp(cfg.type, "controller"))) {
+ telemetry_type = WDC_TELEMETRY_TYPE_CONTROLLER;
+ telemetry_data_area = cfg.data_area;
+ } else {
+ fprintf(stderr, "ERROR : WDC: Invalid type - Must be NONE, HOST or CONTROLLER\n");
+ return -1;
+ }
+
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) {
- if (cfg.data_area == 0)
- cfg.data_area = 3; /* Set the default DA to 3 if not specified */
-
- if ((cfg.type == NULL) ||
- (!strcmp(cfg.type, "NONE")) ||
- (!strcmp(cfg.type, "none"))) {
- telemetry_type = WDC_TELEMETRY_TYPE_NONE;
- data_area = 0;
- } else if ((!strcmp(cfg.type, "HOST")) ||
- (!strcmp(cfg.type, "host"))) {
- telemetry_type = WDC_TELEMETRY_TYPE_HOST;
- telemetry_data_area = cfg.data_area;
- } else if ((!strcmp(cfg.type, "CONTROLLER")) ||
- (!strcmp(cfg.type, "controller"))) {
- telemetry_type = WDC_TELEMETRY_TYPE_CONTROLLER;
- telemetry_data_area = cfg.data_area;
- } else {
- fprintf(stderr, "ERROR : WDC: Invalid type - Must be NONE, HOST or CONTROLLER\n");
- return -1;
- }
+ if (telemetry_data_area == 0)
+ telemetry_data_area = 3; /* Set the default DA to 3 if not specified */
- return wdc_do_cap_diag(fd, f, xfer_size, telemetry_type, telemetry_data_area);
+ return wdc_do_cap_diag(r, fd, f, xfer_size,
+ telemetry_type, telemetry_data_area);
}
if ((capabilities & WDC_DRIVE_CAP_DUI) == WDC_DRIVE_CAP_DUI) {
- if (cfg.data_area == 0) {
- cfg.data_area = 1;
+ if ((telemetry_type == WDC_TELEMETRY_TYPE_HOST) ||
+ (telemetry_type == WDC_TELEMETRY_TYPE_CONTROLLER)) {
+ if (telemetry_data_area == 0)
+ telemetry_data_area = 3; /* Set the default DA to 3 if not specified */
+ /* Get the desired telemetry log page */
+ return wdc_do_cap_telemetry_log(fd, f, xfer_size, telemetry_type, telemetry_data_area);
}
+ else {
+ if (cfg.data_area == 0) {
+ cfg.data_area = 1;
+ }
- /* FW requirement - xfer size must be 256k for data area 4 */
- if (cfg.data_area >= 4)
- xfer_size = 0x40000;
- return wdc_do_cap_dui(fd, f, xfer_size, cfg.data_area, cfg.verbose, cfg.file_size, cfg.offset);
+ /* FW requirement - xfer size must be 256k for data area 4 */
+ if (cfg.data_area >= 4)
+ xfer_size = 0x40000;
+ return wdc_do_cap_dui(fd, f, xfer_size, cfg.data_area,
+ cfg.verbose, cfg.file_size, cfg.offset);
+ }
+ }
+ if ((capabilities & WDC_DRIVE_CAP_DUI_DATA) == WDC_DRIVE_CAP_DUI_DATA){
+ if ((telemetry_type == WDC_TELEMETRY_TYPE_HOST) ||
+ (telemetry_type == WDC_TELEMETRY_TYPE_CONTROLLER)) {
+ if (telemetry_data_area == 0)
+ telemetry_data_area = 3; /* Set the default DA to 3 if not specified */
+ /* Get the desired telemetry log page */
+ return wdc_do_cap_telemetry_log(fd, f, xfer_size, telemetry_type, telemetry_data_area);
+ }
+ else {
+ return wdc_do_cap_dui(fd, f, xfer_size, WDC_NVME_DUI_MAX_DATA_AREA, cfg.verbose, 0, 0);
+ }
}
- if ((capabilities & WDC_DRIVE_CAP_DUI_DATA) == WDC_DRIVE_CAP_DUI_DATA)
- return wdc_do_cap_dui(fd, f, xfer_size, WDC_NVME_DUI_MAX_DATA_AREA, cfg.verbose, 0, 0);
if ((capabilities & WDC_SN730B_CAP_VUC_LOG) == WDC_SN730B_CAP_VUC_LOG)
return wdc_do_sn730_get_and_tar(fd, f);
@@ -3151,7 +3299,7 @@ static int wdc_do_drive_log(int fd, char *file)
int ret;
__u8 *drive_log_data;
__u32 drive_log_length;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
ret = wdc_dump_length(fd, WDC_NVME_DRIVE_LOG_SIZE_OPCODE,
WDC_NVME_DRIVE_LOG_SIZE_NDT,
@@ -3169,7 +3317,7 @@ static int wdc_do_drive_log(int fd, char *file)
}
memset(drive_log_data, 0, sizeof (__u8) * drive_log_length);
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_DRIVE_LOG_OPCODE;
admin_cmd.addr = (__u64)(uintptr_t)drive_log_data;
admin_cmd.data_len = drive_log_length;
@@ -3177,9 +3325,8 @@ static int wdc_do_drive_log(int fd, char *file)
admin_cmd.cdw12 = ((WDC_NVME_DRIVE_LOG_SUBCMD <<
WDC_NVME_SUBCMD_SHIFT) | WDC_NVME_DRIVE_LOG_SIZE_CMD);
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret),
- ret);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ nvme_show_status(ret);
if (ret == 0) {
ret = wdc_create_log_file(file, drive_log_data, drive_log_length);
}
@@ -3195,6 +3342,7 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
char f[PATH_MAX] = {0};
int fd;
int ret;
+ nvme_root_t r;
__u64 capabilities = 0;
struct config {
char *file;
@@ -3213,9 +3361,13 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- if (!wdc_check_device(fd))
+ r = nvme_scan(NULL);
+
+ if (!wdc_check_device(r, fd)) {
+ nvme_free_tree(r);
return -1;
- capabilities = wdc_get_drive_capabilities(fd);
+ }
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_DRIVE_LOG) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -3226,10 +3378,12 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
}
if (wdc_get_serial_name(fd, f, PATH_MAX, "drive_log") == -1) {
fprintf(stderr, "ERROR : WDC : failed to generate file name\n");
+ nvme_free_tree(r);
return -1;
}
ret = wdc_do_drive_log(fd, f);
}
+ nvme_free_tree(r);
return ret;
}
@@ -3239,6 +3393,7 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
const char *desc = "Get Crash Dump.";
const char *file = "Output file pathname.";
int fd, ret;
+ nvme_root_t r;
__u64 capabilities = 0;
struct config {
@@ -3258,10 +3413,15 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- if (!wdc_check_device(fd))
+ r = nvme_scan(NULL);
+
+ if (!wdc_check_device(r, fd)) {
+ nvme_free_tree(r);
return -1;
- capabilities = wdc_get_drive_capabilities(fd);
+ }
+
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_CRASH_DUMP) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -3272,6 +3432,7 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
fprintf(stderr, "ERROR : WDC : failed to read crash dump\n");
}
}
+ nvme_free_tree(r);
return ret;
}
@@ -3282,6 +3443,7 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
char *file = "Output file pathname.";
int fd;
int ret;
+ nvme_root_t r;
__u64 capabilities = 0;
struct config {
char *file;
@@ -3300,10 +3462,14 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- if (!wdc_check_device(fd))
+ r = nvme_scan(NULL);
+
+ if (!wdc_check_device(r, fd)) {
+ nvme_free_tree(r);
return -1;
+ }
- capabilities = wdc_get_drive_capabilities(fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_PFAIL_DUMP) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -3313,7 +3479,7 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
fprintf(stderr, "ERROR : WDC : failed to read pfail crash dump\n");
}
}
-
+ nvme_free_tree(r);
return ret;
}
@@ -3371,6 +3537,7 @@ static int wdc_purge(int argc, char **argv,
const char *desc = "Send a Purge command.";
char *err_str;
int fd, ret;
+ nvme_root_t r;
struct nvme_passthru_cmd admin_cmd;
__u64 capabilities = 0;
@@ -3382,10 +3549,14 @@ static int wdc_purge(int argc, char **argv,
if (fd < 0)
return fd;
- if (!wdc_check_device(fd))
+ r = nvme_scan(NULL);
+
+ if (!wdc_check_device(r, fd)) {
+ nvme_free_tree(r);
return -1;
+ }
- capabilities = wdc_get_drive_capabilities(fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
ret = -1;
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -3394,7 +3565,7 @@ static int wdc_purge(int argc, char **argv,
memset(&admin_cmd, 0, sizeof (admin_cmd));
admin_cmd.opcode = WDC_NVME_PURGE_CMD_OPCODE;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret > 0) {
switch (ret) {
case WDC_NVME_PURGE_CMD_SEQ_ERR:
@@ -3410,8 +3581,9 @@ static int wdc_purge(int argc, char **argv,
}
fprintf(stderr, "%s", err_str);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
}
+ nvme_free_tree(r);
return ret;
}
@@ -3420,11 +3592,12 @@ static int wdc_purge_monitor(int argc, char **argv,
{
const char *desc = "Send a Purge Monitor command.";
int fd, ret;
+ nvme_root_t r;
__u8 output[WDC_NVME_PURGE_MONITOR_DATA_LEN];
double progress_percent;
struct nvme_passthru_cmd admin_cmd;
struct wdc_nvme_purge_monitor_data *mon;
- __u64 capabilities = 0;
+ __u64 capabilities;
OPT_ARGS(opts) = {
OPT_END()
@@ -3434,23 +3607,26 @@ static int wdc_purge_monitor(int argc, char **argv,
if (fd < 0)
return fd;
- if (!wdc_check_device(fd))
+ r = nvme_scan(NULL);
+ if (!wdc_check_device(r, fd)) {
+ nvme_free_tree(r);
return -1;
+ }
- capabilities = wdc_get_drive_capabilities(fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
ret = -1;
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
} else {
memset(output, 0, sizeof (output));
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_PURGE_MONITOR_OPCODE;
admin_cmd.addr = (__u64)(uintptr_t)output;
admin_cmd.data_len = WDC_NVME_PURGE_MONITOR_DATA_LEN;
admin_cmd.cdw10 = WDC_NVME_PURGE_MONITOR_CMD_CDW10;
admin_cmd.timeout_ms = WDC_NVME_PURGE_MONITOR_TIMEOUT;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (ret == 0) {
mon = (struct wdc_nvme_purge_monitor_data *) output;
printf("Purge state = 0x%0x\n", admin_cmd.result);
@@ -3463,8 +3639,9 @@ static int wdc_purge_monitor(int argc, char **argv,
}
}
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
}
+ nvme_free_tree(r);
return ret;
}
@@ -3762,6 +3939,168 @@ static void wdc_print_latency_monitor_log_json(struct wdc_ssd_latency_monitor_lo
json_free_object(root);
}
+static void wdc_print_error_rec_log_normal(int fd, struct wdc_ocp_c1_error_recovery_log *log_data)
+{
+ int j;
+ printf("Error Recovery/C1 Log Page Data \n");
+
+ printf(" Panic Reset Wait Time : 0x%x \n", le16_to_cpu(log_data->panic_reset_wait_time));
+ printf(" Panic Reset Action : 0x%x \n", log_data->panic_reset_action);
+ printf(" Device Recovery Action 1 : 0x%x \n", log_data->dev_recovery_action1);
+ printf(" Panic ID : 0x%lx \n", le64_to_cpu(log_data->panic_id));
+ printf(" Device Capabilities : 0x%x \n", le32_to_cpu(log_data->dev_capabilities));
+ printf(" Vendor Specific Recovery Opcode : 0x%x \n", log_data->vs_recovery_opc);
+ printf(" Vendor Specific Command CDW12 : 0x%x \n", le32_to_cpu(log_data->vs_cmd_cdw12));
+ printf(" Vendor Specific Command CDW13 : 0x%x \n", le32_to_cpu(log_data->vs_cmd_cdw13));
+ printf(" Vendor Specific Command Timeout : 0x%x \n", log_data->vs_cmd_to);
+ printf(" Device Recovery Action 2 : 0x%x \n", log_data->dev_recovery_action2);
+ printf(" Device Recovery Action 2 Timeout : 0x%x \n", log_data->dev_recovery_action2_to);
+ printf(" Log Page Version : 0x%x \n", le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (j = 0; j < WDC_OCP_C1_GUID_LENGTH; j++) {
+ printf("%x", log_data->log_page_guid[j]);
+ }
+ printf("\n");
+}
+
+static void wdc_print_error_rec_log_json(struct wdc_ocp_c1_error_recovery_log *log_data)
+{
+ struct json_object *root;
+ root = json_create_object();
+
+ json_object_add_value_int(root, "Panic Reset Wait Time", le16_to_cpu(log_data->panic_reset_wait_time));
+ json_object_add_value_int(root, "Panic Reset Action", log_data->panic_reset_wait_time);
+ json_object_add_value_int(root, "Device Recovery Action 1", log_data->dev_recovery_action1);
+ json_object_add_value_int(root, "Panic ID", le64_to_cpu(log_data->panic_id));
+ json_object_add_value_int(root, "Device Capabilities", le32_to_cpu(log_data->dev_capabilities));
+ json_object_add_value_int(root, "Vendor Specific Recovery Opcode", log_data->vs_recovery_opc);
+ json_object_add_value_int(root, "Vendor Specific Command CDW12", le32_to_cpu(log_data->vs_cmd_cdw12));
+ json_object_add_value_int(root, "Vendor Specific Command CDW13", le32_to_cpu(log_data->vs_cmd_cdw13));
+ json_object_add_value_int(root, "Vendor Specific Command Timeout", log_data->vs_cmd_to);
+ json_object_add_value_int(root, "Device Recovery Action 2", log_data->dev_recovery_action2);
+ json_object_add_value_int(root, "Device Recovery Action 2 Timeout", log_data->dev_recovery_action2_to);
+ json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
+
+ char guid[40];
+ memset((void*)guid, 0, 40);
+ sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
+ json_object_add_value_string(root, "Log page GUID", guid);
+
+ json_print_object(root, NULL);
+ printf("\n");
+
+ json_free_object(root);
+}
+
+static void wdc_print_dev_cap_log_normal(int fd, struct wdc_ocp_C4_dev_cap_log *log_data)
+{
+ int j;
+ printf("Device Capabilities/C4 Log Page Data \n");
+
+ printf(" Number PCIE Ports : 0x%x \n", le16_to_cpu(log_data->num_pcie_ports));
+ printf(" Number OOB Management Interfaces : 0x%x \n", le16_to_cpu(log_data->oob_mgmt_support));
+ printf(" Write Zeros Command Support : 0x%x \n", le16_to_cpu(log_data->wrt_zeros_support));
+ printf(" Sanitize Command Support : 0x%x \n", le16_to_cpu(log_data->sanitize_support));
+ printf(" DSM Command Support : 0x%x \n", le16_to_cpu(log_data->dsm_support));
+ printf(" Write Uncorr Command Support : 0x%x \n", le16_to_cpu(log_data->wrt_uncor_support));
+ printf(" Fused Command Support : 0x%x \n", le16_to_cpu(log_data->fused_support));
+ printf(" Minimum DSSD Power State : 0x%x \n", le16_to_cpu(log_data->min_dssd_ps));
+
+ for (j = 0; j < WDC_OCP_C4_NUM_PS_DESCR; j++) {
+ printf(" DSSD Power State %d Desriptor : 0x%x \n", j, log_data->dssd_ps_descr[j]);
+ }
+
+ printf(" Log Page Version : 0x%x \n", le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (j = 0; j < WDC_OCP_C4_GUID_LENGTH; j++) {
+ printf("%x", log_data->log_page_guid[j]);
+ }
+ printf("\n");
+}
+
+static void wdc_print_dev_cap_log_json(struct wdc_ocp_C4_dev_cap_log *log_data)
+{
+ int j;
+ struct json_object *root;
+ root = json_create_object();
+
+ json_object_add_value_int(root, "Number PCIE Ports", le16_to_cpu(log_data->num_pcie_ports));
+ json_object_add_value_int(root, "Number OOB Management Interfaces", le16_to_cpu(log_data->num_pcie_ports));
+ json_object_add_value_int(root, "Write Zeros Command Support", le16_to_cpu(log_data->num_pcie_ports));
+ json_object_add_value_int(root, "Sanitize Command Support", le16_to_cpu(log_data->num_pcie_ports));
+ json_object_add_value_int(root, "DSM Command Support", le16_to_cpu(log_data->num_pcie_ports));
+ json_object_add_value_int(root, "Write Uncorr Command Support", le16_to_cpu(log_data->num_pcie_ports));
+ json_object_add_value_int(root, "Fused Command Support", le16_to_cpu(log_data->num_pcie_ports));
+ json_object_add_value_int(root, "Minimum DSSD Power State", le16_to_cpu(log_data->num_pcie_ports));
+
+ char dssd_descr_str[40];
+ memset((void *)dssd_descr_str, 0, 40);
+ for (j = 0; j < WDC_OCP_C4_NUM_PS_DESCR; j++) {
+ sprintf((char *)dssd_descr_str, "DSSD Power State %d Descriptor", j);
+ json_object_add_value_int(root, dssd_descr_str, log_data->dssd_ps_descr[j]);
+ }
+
+ json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
+ char guid[40];
+ memset((void*)guid, 0, 40);
+ sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
+ json_object_add_value_string(root, "Log page GUID", guid);
+
+ json_print_object(root, NULL);
+ printf("\n");
+
+ json_free_object(root);
+}
+
+static void wdc_print_unsupported_reqs_log_normal(int fd, struct wdc_ocp_C5_unsupported_reqs *log_data)
+{
+ int j;
+ printf("Unsupported Requirements/C5 Log Page Data \n");
+
+ printf(" Number Unsupported Req IDs : 0x%x \n", le16_to_cpu(log_data->unsupported_count));
+
+ for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++) {
+ printf(" Unsupported Requirement List %d : %s \n", j, log_data->unsupported_req_list[j]);
+ }
+
+ printf(" Log Page Version : 0x%x \n", le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID : 0x");
+ for (j = 0; j < WDC_OCP_C5_GUID_LENGTH; j++) {
+ printf("%x", log_data->log_page_guid[j]);
+ }
+ printf("\n");
+}
+
+static void wdc_print_unsupported_reqs_log_json(struct wdc_ocp_C5_unsupported_reqs *log_data)
+{
+ int j;
+ struct json_object *root;
+ root = json_create_object();
+
+ json_object_add_value_int(root, "Number Unsupported Req IDs", le16_to_cpu(log_data->unsupported_count));
+
+ char unsup_req_list_str[40];
+ memset((void *)unsup_req_list_str, 0, 40);
+ for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++) {
+ sprintf((char *)unsup_req_list_str, "Unsupported Requirement List %d", j);
+ json_object_add_value_string(root, unsup_req_list_str, (char *)log_data->unsupported_req_list[j]);
+ }
+
+ json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
+ char guid[40];
+ memset((void*)guid, 0, 40);
+ sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[8]),
+ (uint64_t)le64_to_cpu(*(uint64_t *)&log_data->log_page_guid[0]));
+ json_object_add_value_string(root, "Log page GUID", guid);
+
+ json_print_object(root, NULL);
+ printf("\n");
+
+ json_free_object(root);
+}
+
static void wdc_print_fb_ca_log_normal(struct wdc_ssd_ca_perf_stats *perf)
{
uint64_t converted = 0;
@@ -3895,7 +4234,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
__u8 *byte_raw;
if (bd_data->field_id == 0x00) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("Additional Smart Log for NVME device:%s namespace-id:%x\n",
devicename, WDC_DE_GLOBAL_NSID);
printf("key normalized raw\n");
@@ -3906,7 +4245,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x01) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("erase_fail_count : %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -3914,9 +4253,9 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x02) {
- word_raw1 = (__u16*)bd_data->raw_value;
- word_raw2 = (__u16*)&bd_data->raw_value[2];
- word_raw3 = (__u16*)&bd_data->raw_value[4];
+ word_raw1 = (__u16*)&bd_data->raw_value[1];
+ word_raw2 = (__u16*)&bd_data->raw_value[3];
+ word_raw3 = (__u16*)&bd_data->raw_value[5];
printf("wear_leveling : %3"PRIu8"%% min: %"PRIu16", max: %"PRIu16", avg: %"PRIu16"\n",
bd_data->normalized_value,
le16_to_cpu(*word_raw1),
@@ -3927,7 +4266,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x03) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("end_to_end_error_detection_count: %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -3935,7 +4274,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x04) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("crc_error_count : %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -3943,7 +4282,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x05) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("timed_workload_media_wear : %3"PRIu8"%% %-.3f%%\n",
bd_data->normalized_value,
safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 1024.0));
@@ -3952,7 +4291,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x06) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("timed_workload_host_reads : %3"PRIu8"%% %"PRIu64"%%\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -3960,7 +4299,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x07) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("timed_workload_timer : %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -3968,8 +4307,8 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x08) {
- byte_raw = (__u8*)bd_data->raw_value;
- dword_raw = (__u32*)&bd_data->raw_value[1];
+ byte_raw = (__u8*)&bd_data->raw_value[1];
+ dword_raw = (__u32*)&bd_data->raw_value[2];
printf("thermal_throttle_status : %3"PRIu8"%% %"PRIu16"%%, cnt: %"PRIu16"\n",
bd_data->normalized_value, *byte_raw, le32_to_cpu(*dword_raw));
} else {
@@ -3977,7 +4316,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x09) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("retry_buffer_overflow_count : %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -3985,7 +4324,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x0A) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("pll_lock_loss_count : %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -3993,19 +4332,17 @@ static void wdc_print_bd_ca_log_normal(void *data)
}
bd_data++;
if (bd_data->field_id == 0x0B) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("nand_bytes_written : %3"PRIu8"%% sectors: %.f\n",
bd_data->normalized_value, safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 0xFFFF));
- raw = (__u64*)bd_data->raw_value;
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x0C) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
printf("host_bytes_written : %3"PRIu8"%% sectors: %.f\n",
bd_data->normalized_value, safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 0xFFFF));
- raw = (__u64*)bd_data->raw_value;
} else {
goto invalid_id;
}
@@ -4031,71 +4368,81 @@ static void wdc_print_bd_ca_log_json(void *data)
root = json_create_object();
if (bd_data->field_id == 0x00) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_int(root, "program_fail_count",
- le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
- json_object_add_value_int(root, "normalized",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "program_fail_count normalized",
bd_data->normalized_value);
+ json_object_add_value_int(root, "program_fail_count raw",
+ le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x01) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_int(root, "erase_fail_count",
- le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
- json_object_add_value_int(root, "normalized",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "erase_fail_count normalized",
bd_data->normalized_value);
+ json_object_add_value_int(root, "erase_fail_count raw",
+ le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x02) {
- word_raw = (__u16*)bd_data->raw_value;
- json_object_add_value_int(root, "min", le16_to_cpu(*word_raw));
- word_raw = (__u16*)&bd_data->raw_value[2];
- json_object_add_value_int(root, "max", le16_to_cpu(*word_raw));
- word_raw = (__u16*)&bd_data->raw_value[4];
- json_object_add_value_int(root, "avg", le16_to_cpu(*word_raw));
- json_object_add_value_int(root, "wear_leveling-normalized", bd_data->normalized_value);
+ word_raw = (__u16*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "wear_leveling normalized", bd_data->normalized_value);
+ json_object_add_value_int(root, "wear_leveling min", le16_to_cpu(*word_raw));
+ word_raw = (__u16*)&bd_data->raw_value[3];
+ json_object_add_value_int(root, "wear_leveling max", le16_to_cpu(*word_raw));
+ word_raw = (__u16*)&bd_data->raw_value[5];
+ json_object_add_value_int(root, "wear_leveling avg", le16_to_cpu(*word_raw));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x03) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_int(root, "end_to_end_error_detection_count",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "end_to_end_error_detection_count normalized",
+ bd_data->normalized_value);
+ json_object_add_value_int(root, "end_to_end_error_detection_count raw",
le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x04) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_int(root, "crc_error_count",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "crc_error_count normalized",
+ bd_data->normalized_value);
+ json_object_add_value_int(root, "crc_error_count raw",
le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x05) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_float(root, "timed_workload_media_wear",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "timed_workload_media_wear normalized",
+ bd_data->normalized_value);
+ json_object_add_value_float(root, "timed_workload_media_wear raw",
safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 1024.0));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x06) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_int(root, "timed_workload_host_reads",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "timed_workload_host_reads normalized",
+ bd_data->normalized_value);
+ json_object_add_value_int(root, "timed_workload_host_reads raw",
le64_to_cpu(*raw & 0x00000000000000FF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x07) {
- raw = (__u64*)bd_data->raw_value;
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "timed_workload_timer normalized",
+ bd_data->normalized_value);
json_object_add_value_int(root, "timed_workload_timer",
le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
@@ -4103,54 +4450,67 @@ static void wdc_print_bd_ca_log_json(void *data)
}
bd_data++;
if (bd_data->field_id == 0x08) {
- byte_raw = (__u8*)bd_data->raw_value;
+ byte_raw = (__u8*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "thermal_throttle_status normalized",
+ bd_data->normalized_value);
json_object_add_value_int(root, "thermal_throttle_status", *byte_raw);
- dword_raw = (__u32*)&bd_data->raw_value[1];
- json_object_add_value_int(root, "cnt", le32_to_cpu(*dword_raw));
+ dword_raw = (__u32*)&bd_data->raw_value[2];
+ json_object_add_value_int(root, "thermal_throttle_cnt", le32_to_cpu(*dword_raw));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x09) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_int(root, "retry_buffer_overflow_count",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "retry_buffer_overflow_count normalized",
+ bd_data->normalized_value);
+ json_object_add_value_int(root, "retry_buffer_overflow_count raw",
le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x0A) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_int(root, "pll_lock_loss_count",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "pll_lock_loss_count normalized",
+ bd_data->normalized_value);
+ json_object_add_value_int(root, "pll_lock_loss_count raw",
le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x0B) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_float(root, "nand_bytes_written",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "nand_bytes_written normalized",
+ bd_data->normalized_value);
+ json_object_add_value_float(root, "nand_bytes_written raw",
safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 0xFFFF));
} else {
goto invalid_id;
}
bd_data++;
if (bd_data->field_id == 0x0C) {
- raw = (__u64*)bd_data->raw_value;
- json_object_add_value_float(root, "host_bytes_written",
+ raw = (__u64*)&bd_data->raw_value[1];
+ json_object_add_value_int(root, "host_bytes_written normalized",
+ bd_data->normalized_value);
+ json_object_add_value_float(root, "host_bytes_written raw",
safe_div_fp((*raw & 0x00FFFFFFFFFFFFFF), 0xFFFF));
- raw = (__u64*)bd_data->raw_value;
} else {
goto invalid_id;
}
goto done;
- invalid_id:
- printf(" Invalid Field ID = %d\n", bd_data->field_id);
+ invalid_id:
+ printf(" Invalid Field ID = %d\n", bd_data->field_id);
- done:
- return;
+ done:
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+
+ return;
}
@@ -4617,77 +4977,71 @@ static void wdc_print_smart_cloud_attr_C0_normal(void *data)
printf(" SMART Cloud Attributes :- \n");
- printf(" Physical media units written - %"PRIu64" %"PRIu64"\n",
+ printf(" Physical media units written : %"PRIu64" %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW+8] & 0xFFFFFFFFFFFFFFFF),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
- printf(" Physical media units read - %"PRIu64" %"PRIu64"\n",
+ printf(" Physical media units read : %"PRIu64" %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR+8] & 0xFFFFFFFFFFFFFFFF),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
- printf(" Bad user nand blocks - Raw %"PRIu64"\n",
+ printf(" Bad user nand blocks Raw : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
- printf(" Bad user nand blocks - Normalized %d\n",
+ printf(" Bad user nand blocks Normalized : %d\n",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
- printf(" Bad system nand blocks - Raw %"PRIu64"\n",
+ printf(" Bad system nand blocks Raw : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
- printf(" Bad system nand blocks - Normalized %d\n",
+ printf(" Bad system nand blocks Normalized : %d\n",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
- printf(" XOR recovery count %"PRIu64"\n",
+ printf(" XOR recovery count : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
- printf(" Uncorrectable read error count %"PRIu64"\n",
+ printf(" Uncorrectable read error count : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
- printf(" Soft ecc error count %"PRIu64"\n",
+ printf(" Soft ecc error count : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
- printf(" End to end corrected errors %"PRIu32"\n",
+ printf(" End to end corrected errors : %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
- printf(" End to end detected errors %"PRIu32"\n",
+ printf(" End to end detected errors : %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
- printf(" System data percent used %d\n",
- (__u8)log_data[SCAO_SDPU]);
- printf(" Refresh counts %"PRIu64"\n",
+ printf(" System data percent used : %d\n", (__u8)log_data[SCAO_SDPU]);
+ printf(" Refresh counts : %"PRIu64"\n",
(uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC])& 0x00FFFFFFFFFFFFFF));
- printf(" Max User data erase counts %"PRIu32"\n",
+ printf(" Max User data erase counts : %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
- printf(" Min User data erase counts %"PRIu32"\n",
+ printf(" Min User data erase counts : %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
- printf(" Number of Thermal throttling events %d\n",
- (__u8)log_data[SCAO_NTTE]);
- printf(" Current throttling status 0x%x\n",
- (__u8)log_data[SCAO_CTS]);
- printf(" PCIe correctable error count %"PRIu64"\n",
+ printf(" Number of Thermal throttling events : %d\n", (__u8)log_data[SCAO_NTTE]);
+ printf(" Current throttling status : 0x%x\n", (__u8)log_data[SCAO_CTS]);
+ printf(" PCIe correctable error count : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
- printf(" Incomplete shutdowns %"PRIu32"\n",
+ printf(" Incomplete shutdowns : %"PRIu32"\n",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
- printf(" Percent free blocks %d\n",
- (__u8)log_data[SCAO_PFB]);
- printf(" Capacitor health %"PRIu16"\n",
+ printf(" Percent free blocks : %d\n", (__u8)log_data[SCAO_PFB]);
+ printf(" Capacitor health : %"PRIu16"\n",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
- printf(" Unaligned I/O %"PRIu64"\n",
+ printf(" Unaligned I/O : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
- printf(" Security Version Number %"PRIu64"\n",
+ printf(" Security Version Number : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
- printf(" NUSE - Namespace utilization %"PRIu64"\n",
+ printf(" NUSE Namespace utilization : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
- printf(" PLP start count %.0Lf\n",
- int128_to_double(&log_data[SCAO_PSC]));
- printf(" Endurance estimate %.0Lf\n",
- int128_to_double(&log_data[SCAO_EEST]));
+ printf(" PLP start count : %.0Lf\n", int128_to_double(&log_data[SCAO_PSC]));
+ printf(" Endurance estimate : %.0Lf\n", int128_to_double(&log_data[SCAO_EEST]));
smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
- printf(" Log page version %"PRIu16"\n",smart_log_ver);
- printf(" Log page GUID 0x");
+ printf(" Log page version : %"PRIu16"\n",smart_log_ver);
+ printf(" Log page GUID : 0x");
printf("0x%"PRIx64"%"PRIx64"\n",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
if(smart_log_ver > 2) {
- printf(" Errata Version Field %d\n",
+ printf(" Errata Version Field : %d\n",
(__u8)log_data[SCAO_EVF]);
- printf(" Point Version Field %"PRIu16"\n",
+ printf(" Point Version Field : %"PRIu16"\n",
(uint16_t)log_data[SCAO_PVF]);
- printf(" Minor Version Field %"PRIu16"\n",
+ printf(" Minor Version Field : %"PRIu16"\n",
(uint16_t)log_data[SCAO_MIVF]);
- printf(" Major Version Field %d\n",
+ printf(" Major Version Field : %d\n",
(__u8)log_data[SCAO_MAVF]);
- printf(" NVMe Errata Version %d\n",
+ printf(" NVMe Errata Version : %d\n",
(__u8)log_data[SCAO_NEV]);
- printf(" PCIe Link Retraining Count %"PRIu64"\n",
+ printf(" PCIe Link Retraining Count : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
}
printf("\n");
@@ -4700,27 +5054,27 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
uint16_t smart_log_ver = 0;
root = json_create_object();
- json_object_add_value_int(root, "Physical media units written hi",
+ json_object_add_value_uint64(root, "Physical media units written hi",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW+8] & 0xFFFFFFFFFFFFFFFF));
- json_object_add_value_int(root, "Physical media units written lo",
+ json_object_add_value_uint64(root, "Physical media units written lo",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
- json_object_add_value_int(root, "Physical media units read hi",
+ json_object_add_value_uint64(root, "Physical media units read hi",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR+8] & 0xFFFFFFFFFFFFFFFF));
- json_object_add_value_int(root, "Physical media units read lo",
+ json_object_add_value_uint64(root, "Physical media units read lo",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
- json_object_add_value_uint(root, "Bad user nand blocks - Raw",
+ json_object_add_value_uint64(root, "Bad user nand blocks - Raw",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
json_object_add_value_uint(root, "Bad user nand blocks - Normalized",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
- json_object_add_value_uint(root, "Bad system nand blocks - Raw",
+ json_object_add_value_uint64(root, "Bad system nand blocks - Raw",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
json_object_add_value_uint(root, "Bad system nand blocks - Normalized",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
- json_object_add_value_uint(root, "XOR recovery count",
+ json_object_add_value_uint64(root, "XOR recovery count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
- json_object_add_value_uint(root, "Uncorrectable read error count",
+ json_object_add_value_uint64(root, "Uncorrectable read error count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
- json_object_add_value_uint(root, "Soft ecc error count",
+ json_object_add_value_uint64(root, "Soft ecc error count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
json_object_add_value_uint(root, "End to end corrected errors",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
@@ -4728,7 +5082,7 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
json_object_add_value_uint(root, "System data percent used",
(__u8)log_data[SCAO_SDPU]);
- json_object_add_value_uint(root, "Refresh counts",
+ json_object_add_value_uint64(root, "Refresh counts",
(uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC])& 0x00FFFFFFFFFFFFFF));
json_object_add_value_uint(root, "Max User data erase counts",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
@@ -4738,7 +5092,7 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
(__u8)log_data[SCAO_NTTE]);
json_object_add_value_uint(root, "Current throttling status",
(__u8)log_data[SCAO_CTS]);
- json_object_add_value_uint(root, "PCIe correctable error count",
+ json_object_add_value_uint64(root, "PCIe correctable error count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
json_object_add_value_uint(root, "Incomplete shutdowns",
(uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
@@ -4746,11 +5100,11 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
(__u8)log_data[SCAO_PFB]);
json_object_add_value_uint(root, "Capacitor health",
(uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
- json_object_add_value_uint(root, "Unaligned I/O",
+ json_object_add_value_uint64(root, "Unaligned I/O",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
- json_object_add_value_uint(root, "Security Version Number",
+ json_object_add_value_uint64(root, "Security Version Number",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
- json_object_add_value_uint(root, "NUSE - Namespace utilization",
+ json_object_add_value_uint64(root, "NUSE - Namespace utilization",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
json_object_add_value_uint(root, "PLP start count",
int128_to_double(&log_data[SCAO_PSC]));
@@ -4774,7 +5128,7 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
(__u8)log_data[SCAO_MAVF]);
json_object_add_value_uint(root, "NVMe Errata Version",
(__u8)log_data[SCAO_NEV]);
- json_object_add_value_uint(root, "PCIe Link Retraining Count",
+ json_object_add_value_uint64(root, "PCIe Link Retraining Count",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
}
json_print_object(root, NULL);
@@ -4867,16 +5221,17 @@ static int wdc_print_c0_eol_log(void *data, int fmt)
return 0;
}
-static int wdc_get_c0_log_page(int fd, char *format, int uuid_index, __u32 namespace_id)
+static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
+ int uuid_index, __u32 namespace_id)
{
int ret = 0;
int fmt = -1;
int i = 0;
__u8 *data;
- __u32 *cust_id;
+ __u32 cust_id;
uint32_t device_id, read_vendor_id;
- if (!wdc_check_device(fd))
+ if (!wdc_check_device(r, fd))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -4884,7 +5239,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index, __u32 names
return fmt;
}
- ret = wdc_get_pci_ids(&device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, &device_id, &read_vendor_id);
switch (device_id) {
@@ -4894,15 +5249,19 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index, __u32 names
case WDC_NVME_SN640_DEV_ID_3:
case WDC_NVME_SN840_DEV_ID:
case WDC_NVME_SN840_DEV_ID_1:
- if (!get_dev_mgment_cbs_data(fd, WDC_C2_CUSTOMER_ID_ID, (void*)&data)) {
- fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID);
+ case WDC_NVME_SN650_DEV_ID:
+ case WDC_NVME_SN650_DEV_ID_1:
+ case WDC_NVME_SN650_DEV_ID_2:
+ case WDC_NVME_SN650_DEV_ID_3:
+ case WDC_NVME_SN650_DEV_ID_4:
+ case WDC_NVME_SN655_DEV_ID:
+ cust_id = wdc_get_fw_cust_id(r, fd);
+ if (cust_id == WDC_INVALID_CUSTOMER_ID) {
+ fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
return -1;
}
- cust_id = (__u32*)data;
-
- if ((*cust_id == WDC_CUSTOMER_ID_0x1004) || (*cust_id == WDC_CUSTOMER_ID_0x1008) ||
- (*cust_id == WDC_CUSTOMER_ID_0x1005) || (*cust_id == WDC_CUSTOMER_ID_0x1304))
+ if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) || (cust_id == WDC_CUSTOMER_ID_0x1005))
{
if (uuid_index == 0)
{
@@ -4912,18 +5271,34 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index, __u32 names
}
if (namespace_id == NVME_NSID_ALL) {
- ret = namespace_id = nvme_get_nsid(fd);
+ ret = nvme_get_nsid(fd, &namespace_id);
if (ret < 0) {
namespace_id = NVME_NSID_ALL;
}
}
/* Get the 0xC0 log data */
- ret = nvme_get_log14(fd, namespace_id, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
- NVME_NO_LOG_LSP, 0, 0, false, uuid_index, 0, false, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
+ struct nvme_get_log_args args = {
+ .args_size = sizeof(args),
+ .fd = fd,
+ .lid = WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
+ .nsid = namespace_id,
+ .lpo = 0,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = 0,
+ .rae = false,
+ .uuidx = uuid_index,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = WDC_NVME_SMART_CLOUD_ATTR_LEN,
+ .log = data,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
@@ -4966,11 +5341,27 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index, __u32 names
}
/* Get the 0xC0 log data */
- ret = nvme_get_log14(fd, NVME_NSID_ALL, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
- NVME_NO_LOG_LSP, 0, 0, false, uuid_index, 0, false, WDC_NVME_EOL_STATUS_LOG_LEN, data);
+ struct nvme_get_log_args args = {
+ .args_size = sizeof(args),
+ .fd = fd,
+ .lid = WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
+ .nsid = NVME_NSID_ALL,
+ .lpo = 0,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = 0,
+ .rae = false,
+ .uuidx = uuid_index,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = WDC_NVME_EOL_STATUS_LOG_LEN,
+ .log = data,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
@@ -4993,11 +5384,11 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index, __u32 names
}
/* Get the 0xC0 log data */
- ret = nvme_get_log(fd, NVME_NSID_ALL, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
- false, NVME_NO_LOG_LSP, WDC_NVME_EOL_STATUS_LOG_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
+ WDC_NVME_EOL_STATUS_LOG_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
@@ -5019,11 +5410,11 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index, __u32 names
}
/* Get the 0xC0 log data */
- ret = nvme_get_log(fd, NVME_NSID_ALL, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
- false, NVME_NO_LOG_LSP, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
+ WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
@@ -5064,6 +5455,57 @@ static int wdc_print_latency_monitor_log(int fd, struct wdc_ssd_latency_monitor_
return 0;
}
+static int wdc_print_error_rec_log(int fd, struct wdc_ocp_c1_error_recovery_log *log_data, int fmt)
+{
+ if (!log_data) {
+ fprintf(stderr, "ERROR : WDC : Invalid C1 log data buffer\n");
+ return -1;
+ }
+ switch (fmt) {
+ case NORMAL:
+ wdc_print_error_rec_log_normal(fd, log_data);
+ break;
+ case JSON:
+ wdc_print_error_rec_log_json(log_data);
+ break;
+ }
+ return 0;
+}
+
+static int wdc_print_dev_cap_log(int fd, struct wdc_ocp_C4_dev_cap_log *log_data, int fmt)
+{
+ if (!log_data) {
+ fprintf(stderr, "ERROR : WDC : Invalid C4 log data buffer\n");
+ return -1;
+ }
+ switch (fmt) {
+ case NORMAL:
+ wdc_print_dev_cap_log_normal(fd, log_data);
+ break;
+ case JSON:
+ wdc_print_dev_cap_log_json(log_data);
+ break;
+ }
+ return 0;
+}
+
+static int wdc_print_unsupported_reqs_log(int fd, struct wdc_ocp_C5_unsupported_reqs *log_data, int fmt)
+{
+ if (!log_data) {
+ fprintf(stderr, "ERROR : WDC : Invalid C5 log data buffer\n");
+ return -1;
+ }
+ switch (fmt) {
+ case NORMAL:
+ wdc_print_unsupported_reqs_log_normal(fd, log_data);
+ break;
+ case JSON:
+ wdc_print_unsupported_reqs_log_json(log_data);
+ break;
+ }
+ return 0;
+}
+
static int wdc_print_fb_ca_log(struct wdc_ssd_ca_perf_stats *perf, int fmt)
{
if (!perf) {
@@ -5094,6 +5536,9 @@ static int wdc_print_bd_ca_log(void *bd_data, int fmt)
case JSON:
wdc_print_bd_ca_log_json(bd_data);
break;
+ default:
+ fprintf(stderr, "ERROR : WDC : Unknown format - %d\n", fmt);
+ return -1;
}
return 0;
}
@@ -5133,16 +5578,16 @@ static int wdc_print_fw_act_history_log(__u8 *data, int num_entries, int fmt, __
return 0;
}
-static int wdc_get_ca_log_page(int fd, char *format)
+static int wdc_get_ca_log_page(nvme_root_t r, int fd, char *format)
{
int ret = 0;
int fmt = -1;
__u8 *data;
- __u32 *cust_id;
struct wdc_ssd_ca_perf_stats *perf;
uint32_t read_device_id, read_vendor_id;
+ __u32 cust_id;
- if (!wdc_check_device(fd))
+ if (!wdc_check_device(r, fd))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -5151,25 +5596,25 @@ static int wdc_get_ca_log_page(int fd, char *format)
}
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == false) {
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == false) {
fprintf(stderr, "ERROR : WDC : 0xCA Log Page not supported\n");
return -1;
}
- if (!get_dev_mgment_cbs_data(fd, WDC_C2_CUSTOMER_ID_ID, (void*)&data)) {
- fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID);
+ /* get the FW customer id */
+ cust_id = wdc_get_fw_cust_id(r, fd);
+ if (cust_id == WDC_INVALID_CUSTOMER_ID) {
+ fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
return -1;
}
- ret = wdc_get_pci_ids(&read_device_id, &read_vendor_id);
-
- cust_id = (__u32*)data;
+ ret = wdc_get_pci_ids(r, &read_device_id, &read_vendor_id);
switch (read_device_id) {
case WDC_NVME_SN200_DEV_ID:
- if (*cust_id == WDC_CUSTOMER_ID_0x1005) {
+ if (cust_id == WDC_CUSTOMER_ID_0x1005) {
if ((data = (__u8*) malloc(sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN)) == NULL) {
fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
@@ -5178,10 +5623,10 @@ static int wdc_get_ca_log_page(int fd, char *format)
memset(data, 0, sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN);
- ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
- false, NVME_NO_LOG_LSP, WDC_FB_CA_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
+ WDC_FB_CA_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
@@ -5193,7 +5638,7 @@ static int wdc_get_ca_log_page(int fd, char *format)
}
} else {
- fprintf(stderr, "ERROR : WDC : Unsupported Customer id, id = 0x%x\n", *cust_id);
+ fprintf(stderr, "ERROR : WDC : Unsupported Customer id, id = 0x%x\n", cust_id);
return -1;
}
break;
@@ -5205,7 +5650,7 @@ static int wdc_get_ca_log_page(int fd, char *format)
case WDC_NVME_SN840_DEV_ID:
case WDC_NVME_SN840_DEV_ID_1:
- if (*cust_id == WDC_CUSTOMER_ID_0x1005) {
+ if (cust_id == WDC_CUSTOMER_ID_0x1005) {
if ((data = (__u8*) malloc(sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN)) == NULL) {
fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
@@ -5214,10 +5659,10 @@ static int wdc_get_ca_log_page(int fd, char *format)
memset(data, 0, sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN);
- ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
- false, NVME_NO_LOG_LSP, WDC_FB_CA_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
+ WDC_FB_CA_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
@@ -5227,19 +5672,18 @@ static int wdc_get_ca_log_page(int fd, char *format)
fprintf(stderr, "ERROR : WDC : Unable to read CA Log Page data\n");
ret = -1;
}
- } else if ((*cust_id == WDC_CUSTOMER_ID_GN) || (*cust_id == WDC_CUSTOMER_ID_GD) ||
- (*cust_id == WDC_CUSTOMER_ID_BD)) {
-
+ } else if ((cust_id == WDC_CUSTOMER_ID_GN) || (cust_id == WDC_CUSTOMER_ID_GD) ||
+ (cust_id == WDC_CUSTOMER_ID_BD)) {
if ((data = (__u8*) malloc(sizeof (__u8) * WDC_BD_CA_LOG_BUF_LEN)) == NULL) {
fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
return -1;
}
memset(data, 0, sizeof (__u8) * WDC_BD_CA_LOG_BUF_LEN);
- ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
- false, NVME_NO_LOG_LSP, WDC_BD_CA_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
+ WDC_BD_CA_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
@@ -5252,7 +5696,7 @@ static int wdc_get_ca_log_page(int fd, char *format)
break;
} else {
- fprintf(stderr, "ERROR : WDC : Unsupported Customer id, id = 0x%x\n", *cust_id);
+ fprintf(stderr, "ERROR : WDC : Unsupported Customer id, id = 0x%x\n", cust_id);
return -1;
}
break;
@@ -5268,7 +5712,8 @@ static int wdc_get_ca_log_page(int fd, char *format)
return ret;
}
-static int wdc_get_c1_log_page(int fd, char *format, uint8_t interval)
+static int wdc_get_c1_log_page(nvme_root_t r, int fd,
+ char *format, uint8_t interval)
{
int ret = 0;
int fmt = -1;
@@ -5281,7 +5726,7 @@ static int wdc_get_c1_log_page(int fd, char *format, uint8_t interval)
struct wdc_log_page_subpage_header *sph;
struct wdc_ssd_perf_stats *perf;
- if (!wdc_check_device(fd))
+ if (!wdc_check_device(r, fd))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -5300,10 +5745,10 @@ static int wdc_get_c1_log_page(int fd, char *format, uint8_t interval)
}
memset(data, 0, sizeof (__u8) * WDC_ADD_LOG_BUF_LEN);
- ret = nvme_get_log(fd, 0x01, WDC_NVME_ADD_LOG_OPCODE, false,
- NVME_NO_LOG_LSP, WDC_ADD_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_NVME_ADD_LOG_OPCODE,
+ WDC_ADD_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
l = (struct wdc_log_page_header*)data;
total_subpages = l->num_subpages + WDC_NVME_GET_STAT_PERF_INTERVAL_LIFETIME - 1;
@@ -5326,7 +5771,7 @@ static int wdc_get_c1_log_page(int fd, char *format, uint8_t interval)
return ret;
}
-static int wdc_get_c3_log_page(int fd, char *format)
+static int wdc_get_c3_log_page(nvme_root_t r, int fd, char *format)
{
int ret = 0;
int fmt = -1;
@@ -5334,7 +5779,7 @@ static int wdc_get_c3_log_page(int fd, char *format)
int i;
struct wdc_ssd_latency_monitor_log *log_data;
- if (!wdc_check_device(fd))
+ if (!wdc_check_device(r, fd))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -5348,12 +5793,11 @@ static int wdc_get_c3_log_page(int fd, char *format)
}
memset(data, 0, sizeof (__u8) * WDC_LATENCY_MON_LOG_BUF_LEN);
- ret = nvme_get_log14(fd, NVME_NSID_ALL, WDC_LATENCY_MON_OPCODE,
- NVME_NO_LOG_LSP, NVME_NO_LOG_LPO, 0, 0,
- 0, 0, 0, WDC_LATENCY_MON_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_LATENCY_MON_OPCODE,
+ WDC_LATENCY_MON_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
if (ret == 0) {
log_data = (struct wdc_ssd_latency_monitor_log*)data;
@@ -5386,7 +5830,7 @@ static int wdc_get_c3_log_page(int fd, char *format)
}
}
- /* parse the data */
+ /* parse the data */
wdc_print_latency_monitor_log(fd, log_data, fmt);
} else {
fprintf(stderr, "ERROR : WDC : Unable to read C3 data from buffer\n");
@@ -5395,16 +5839,224 @@ static int wdc_get_c3_log_page(int fd, char *format)
out:
free(data);
return ret;
+
}
-static int wdc_get_d0_log_page(int fd, char *format)
+static int wdc_get_ocp_c1_log_page(nvme_root_t r, int fd, char *format)
+{
+ int ret = 0;
+ int fmt = -1;
+ __u8 *data;
+ int i;
+ struct wdc_ocp_c1_error_recovery_log *log_data;
+
+ if (!wdc_check_device(r, fd))
+ return -1;
+ fmt = validate_output_format(format);
+ if (fmt < 0) {
+ fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ return fmt;
+ }
+
+ if ((data = (__u8 *) malloc(sizeof(__u8) * WDC_ERROR_REC_LOG_BUF_LEN)) == NULL) {
+ fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ return -1;
+ }
+ memset(data, 0, sizeof (__u8) * WDC_ERROR_REC_LOG_BUF_LEN);
+
+ ret = nvme_get_log_simple(fd, WDC_ERROR_REC_LOG_ID,
+ WDC_ERROR_REC_LOG_BUF_LEN, data);
+
+ if (strcmp(format, "json"))
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
+
+ if (ret == 0) {
+ log_data = (struct wdc_ocp_c1_error_recovery_log *)data;
+
+ /* check log page version */
+ if (log_data->log_page_version != WDC_ERROR_REC_LOG_VERSION) {
+ fprintf(stderr, "ERROR : WDC : invalid error recovery log version - %d\n", log_data->log_page_version);
+ ret = -1;
+ goto out;
+ }
+
+ /* Verify GUID matches */
+ for (i=0; i < WDC_OCP_C1_GUID_LENGTH; i++) {
+ if (wdc_ocp_c1_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR : WDC : Unknown GUID in C1 Log Page data\n");
+ int j;
+ fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
+ for (j = 0; j<16; j++) {
+ fprintf(stderr, "%x", wdc_ocp_c1_guid[j]);
+ }
+ fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
+ for (j = 0; j<16; j++) {
+ fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ }
+ fprintf(stderr, "\n");
+
+ ret = -1;
+ goto out;
+ }
+ }
+
+ /* parse the data */
+ wdc_print_error_rec_log(fd, log_data, fmt);
+ } else {
+ fprintf(stderr, "ERROR : WDC : Unable to read error recovery (C1) data from buffer\n");
+ }
+
+out:
+ free(data);
+ return ret;
+}
+
+static int wdc_get_ocp_c4_log_page(nvme_root_t r, int fd, char *format)
+{
+ int ret = 0;
+ int fmt = -1;
+ __u8 *data;
+ int i;
+ struct wdc_ocp_C4_dev_cap_log *log_data;
+
+ if (!wdc_check_device(r, fd))
+ return -1;
+ fmt = validate_output_format(format);
+ if (fmt < 0) {
+ fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ return fmt;
+ }
+
+ if ((data = (__u8 *) malloc(sizeof(__u8) * WDC_DEV_CAP_LOG_BUF_LEN)) == NULL) {
+ fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ return -1;
+ }
+ memset(data, 0, sizeof (__u8) * WDC_DEV_CAP_LOG_BUF_LEN);
+
+ ret = nvme_get_log_simple(fd, WDC_DEV_CAP_LOG_ID,
+ WDC_DEV_CAP_LOG_BUF_LEN, data);
+
+ if (strcmp(format, "json"))
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
+
+ if (ret == 0) {
+ log_data = (struct wdc_ocp_C4_dev_cap_log *)data;
+
+ /* check log page version */
+ if (log_data->log_page_version != WDC_DEV_CAP_LOG_VERSION) {
+ fprintf(stderr, "ERROR : WDC : invalid device capabilities log version - %d\n", log_data->log_page_version);
+ ret = -1;
+ goto out;
+ }
+
+ /* Verify GUID matches */
+ for (i=0; i < WDC_OCP_C4_GUID_LENGTH; i++) {
+ if (wdc_ocp_c4_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR : WDC : Unknown GUID in C4 Log Page data\n");
+ int j;
+ fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
+ for (j = 0; j<16; j++) {
+ fprintf(stderr, "%x", wdc_ocp_c1_guid[j]);
+ }
+ fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
+ for (j = 0; j<16; j++) {
+ fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ }
+ fprintf(stderr, "\n");
+
+ ret = -1;
+ goto out;
+ }
+ }
+
+ /* parse the data */
+ wdc_print_dev_cap_log(fd, log_data, fmt);
+ } else {
+ fprintf(stderr, "ERROR : WDC : Unable to read device capabilities (C4) data from buffer\n");
+ }
+
+out:
+ free(data);
+ return ret;
+}
+
+static int wdc_get_ocp_c5_log_page(nvme_root_t r, int fd, char *format)
+{
+ int ret = 0;
+ int fmt = -1;
+ __u8 *data;
+ int i;
+ struct wdc_ocp_C5_unsupported_reqs *log_data;
+
+ if (!wdc_check_device(r, fd))
+ return -1;
+ fmt = validate_output_format(format);
+ if (fmt < 0) {
+ fprintf(stderr, "ERROR : WDC : invalid output format\n");
+ return fmt;
+ }
+
+ if ((data = (__u8 *) malloc(sizeof(__u8) * WDC_UNSUPPORTED_REQS_LOG_BUF_LEN)) == NULL) {
+ fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
+ return -1;
+ }
+ memset(data, 0, sizeof (__u8) * WDC_UNSUPPORTED_REQS_LOG_BUF_LEN);
+
+ ret = nvme_get_log_simple(fd, WDC_UNSUPPORTED_REQS_LOG_ID,
+ WDC_UNSUPPORTED_REQS_LOG_BUF_LEN, data);
+
+ if (strcmp(format, "json"))
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
+
+ if (ret == 0) {
+ log_data = (struct wdc_ocp_C5_unsupported_reqs *)data;
+
+ /* check log page version */
+ if (log_data->log_page_version != WDC_UNSUPPORTED_REQS_LOG_VERSION) {
+ fprintf(stderr, "ERROR : WDC : invalid unsupported requirements log version - %d\n", log_data->log_page_version);
+ ret = -1;
+ goto out;
+ }
+
+ /* Verify GUID matches */
+ for (i=0; i < WDC_OCP_C5_GUID_LENGTH; i++) {
+ if (wdc_ocp_c5_guid[i] != log_data->log_page_guid[i]) {
+ fprintf(stderr, "ERROR : WDC : Unknown GUID in C5 Log Page data\n");
+ int j;
+ fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
+ for (j = 0; j<16; j++) {
+ fprintf(stderr, "%x", wdc_ocp_c1_guid[j]);
+ }
+ fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
+ for (j = 0; j<16; j++) {
+ fprintf(stderr, "%x", log_data->log_page_guid[j]);
+ }
+ fprintf(stderr, "\n");
+
+ ret = -1;
+ goto out;
+ }
+ }
+
+ /* parse the data */
+ wdc_print_unsupported_reqs_log(fd, log_data, fmt);
+ } else {
+ fprintf(stderr, "ERROR : WDC : Unable to read unsupported requirements (C5) data from buffer\n");
+ }
+
+out:
+ free(data);
+ return ret;
+}
+
+static int wdc_get_d0_log_page(nvme_root_t r, int fd, char *format)
{
int ret = 0;
int fmt = -1;
__u8 *data;
struct wdc_ssd_d0_smart_log *perf;
- if (!wdc_check_device(fd))
+ if (!wdc_check_device(r, fd))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -5413,7 +6065,7 @@ static int wdc_get_d0_log_page(int fd, char *format)
}
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == false) {
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == false) {
fprintf(stderr, "ERROR : WDC : 0xD0 Log Page not supported\n");
return -1;
}
@@ -5424,10 +6076,10 @@ static int wdc_get_d0_log_page(int fd, char *format)
}
memset(data, 0, sizeof (__u8) * WDC_NVME_VU_SMART_LOG_LEN);
- ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_VU_SMART_LOG_OPCODE,
- false, NVME_NO_LOG_LSP, WDC_NVME_VU_SMART_LOG_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE,
+ WDC_NVME_VU_SMART_LOG_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
@@ -5451,6 +6103,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
const char *log_page_version = "Log Page Version: 0 = vendor, 1 = WDC";
const char *log_page_mask = "Log Page Mask, comma separated list: 0xC0, 0xC1, 0xCA, 0xD0";
const char *namespace_id = "desired namespace id";
+ nvme_root_t r;
int ret = 0;
int uuid_index = 0;
int page_mask = 0, num, i;
@@ -5486,6 +6139,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
+ r = nvme_scan(NULL);
if (cfg.log_page_version == 0) {
uuid_index = 0;
} else if (cfg.log_page_version == 1) {
@@ -5530,7 +6184,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
fprintf(stderr, "ERROR : WDC: Unknown log page mask - %s\n", cfg.log_page_mask);
- capabilities = wdc_get_drive_capabilities(fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_SMART_LOG_MASK) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -5541,34 +6195,34 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
if (((capabilities & WDC_DRIVE_CAP_C0_LOG_PAGE) == WDC_DRIVE_CAP_C0_LOG_PAGE) &&
(page_mask & WDC_C0_PAGE_MASK)) {
/* Get 0xC0 log page if possible. */
- ret = wdc_get_c0_log_page(fd, cfg.output_format, uuid_index, cfg.namespace_id);
+ ret = wdc_get_c0_log_page(r, fd, cfg.output_format, uuid_index, cfg.namespace_id);
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading the C0 Log Page, ret = %d\n", ret);
}
if (((capabilities & (WDC_DRIVE_CAP_CA_LOG_PAGE)) == (WDC_DRIVE_CAP_CA_LOG_PAGE)) &&
(page_mask & WDC_CA_PAGE_MASK)) {
/* Get the CA Log Page */
- ret = wdc_get_ca_log_page(fd, cfg.output_format);
+ ret = wdc_get_ca_log_page(r, fd, cfg.output_format);
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading the CA Log Page, ret = %d\n", ret);
}
if (((capabilities & WDC_DRIVE_CAP_C1_LOG_PAGE) == WDC_DRIVE_CAP_C1_LOG_PAGE) &&
(page_mask & WDC_C1_PAGE_MASK)) {
/* Get the C1 Log Page */
- ret = wdc_get_c1_log_page(fd, cfg.output_format, cfg.interval);
+ ret = wdc_get_c1_log_page(r, fd, cfg.output_format, cfg.interval);
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading the C1 Log Page, ret = %d\n", ret);
}
if (((capabilities & WDC_DRIVE_CAP_D0_LOG_PAGE) == WDC_DRIVE_CAP_D0_LOG_PAGE) &&
(page_mask & WDC_D0_PAGE_MASK)) {
/* Get the D0 Log Page */
- ret = wdc_get_d0_log_page(fd, cfg.output_format);
+ ret = wdc_get_d0_log_page(r, fd, cfg.output_format);
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading the D0 Log Page, ret = %d\n", ret);
}
out:
-
+ nvme_free_tree(r);
return ret;
}
@@ -5576,6 +6230,7 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
struct plugin *plugin)
{
const char *desc = "Retrieve latency monitor log data.";
+ nvme_root_t r;
int fd;
int ret = 0;
__u64 capabilities = 0;
@@ -5597,7 +6252,8 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
if (fd < 0)
return fd;
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -5605,12 +6261,140 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
goto out;
}
- ret = wdc_get_c3_log_page(fd, cfg.output_format);
+ ret = wdc_get_c3_log_page(r, fd, cfg.output_format);
+ if (ret)
+ fprintf(stderr, "ERROR : WDC : Failure reading the Latency Monitor (C3) Log Page, ret = %d\n", ret);
+
+out:
+ return ret;
+}
+
+static int wdc_get_error_recovery_log(int argc, char **argv, struct command *command,
+ struct plugin *plugin)
+{
+ const char *desc = "Retrieve error recovery log data.";
+ nvme_root_t r;
+ int fd;
+ int ret = 0;
+ __u64 capabilities = 0;
+
+ struct config {
+ char *output_format;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &cfg.output_format, "Output Format: normal|json"),
+ OPT_END()
+ };
+
+ fd = parse_and_open(argc, argv, desc, opts);
+ if (fd < 0)
+ return fd;
+
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
+
+ if ((capabilities & WDC_DRIVE_CAP_OCP_C1_LOG_PAGE) == 0) {
+ fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ ret = -1;
+ goto out;
+ }
+
+ ret = wdc_get_ocp_c1_log_page(r, fd, cfg.output_format);
if (ret)
- fprintf(stderr, "ERROR : WDC : Failure reading the C3 Log Page, ret = %d\n", ret);
+ fprintf(stderr, "ERROR : WDC : Failure reading the Error Recovery (C1) Log Page, ret = 0x%x\n", ret);
out:
+ return ret;
+}
+
+static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *command,
+ struct plugin *plugin)
+{
+ const char *desc = "Retrieve device capabilities log data.";
+ nvme_root_t r;
+ int fd;
+ int ret = 0;
+ __u64 capabilities = 0;
+
+ struct config {
+ char *output_format;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &cfg.output_format, "Output Format: normal|json"),
+ OPT_END()
+ };
+
+ fd = parse_and_open(argc, argv, desc, opts);
+ if (fd < 0)
+ return fd;
+
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
+
+ if ((capabilities & WDC_DRIVE_CAP_OCP_C4_LOG_PAGE) == 0) {
+ fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ ret = -1;
+ goto out;
+ }
+
+ ret = wdc_get_ocp_c4_log_page(r, fd, cfg.output_format);
+ if (ret)
+ fprintf(stderr, "ERROR : WDC : Failure reading the Device Capabilities (C4) Log Page, ret = 0x%x\n", ret);
+out:
+ return ret;
+}
+
+static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *command,
+ struct plugin *plugin)
+{
+ const char *desc = "Retrieve unsupported requirements log data.";
+ nvme_root_t r;
+ int fd;
+ int ret = 0;
+ __u64 capabilities = 0;
+
+ struct config {
+ char *output_format;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &cfg.output_format, "Output Format: normal|json"),
+ OPT_END()
+ };
+
+ fd = parse_and_open(argc, argv, desc, opts);
+ if (fd < 0)
+ return fd;
+
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
+
+ if ((capabilities & WDC_DRIVE_CAP_OCP_C5_LOG_PAGE) == 0) {
+ fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ ret = -1;
+ goto out;
+ }
+
+ ret = wdc_get_ocp_c5_log_page(r, fd, cfg.output_format);
+ if (ret)
+ fprintf(stderr, "ERROR : WDC : Failure reading the Unsupported Requirements (C5) Log Page, ret = 0x%x\n", ret);
+
+out:
return ret;
}
@@ -5624,8 +6408,8 @@ static int wdc_do_clear_pcie_correctable_errors(int fd)
admin_cmd.cdw12 = ((WDC_NVME_CLEAR_PCIE_CORR_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_CLEAR_PCIE_CORR_CMD);
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ nvme_show_status(ret);
return ret;
}
@@ -5637,8 +6421,8 @@ static int wdc_do_clear_pcie_correctable_errors_vuc(int fd)
memset(&admin_cmd, 0, sizeof (admin_cmd));
admin_cmd.opcode = WDC_NVME_CLEAR_PCIE_CORR_OPCODE_VUC;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ nvme_show_status(ret);
return ret;
}
@@ -5648,10 +6432,10 @@ static int wdc_do_clear_pcie_correctable_errors_fid(int fd)
__u32 result;
__u32 value = 1 << 31; /* Bit 31 - clear PCIe correctable count */
- ret = nvme_set_feature(fd, 0, WDC_NVME_CLEAR_PCIE_CORR_FEATURE_ID, value,
- 0, 0, 0, 0, NULL, &result);
+ ret = nvme_set_features_simple(fd, WDC_NVME_CLEAR_PCIE_CORR_FEATURE_ID, 0, value,
+ false, &result);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
return ret;
}
@@ -5660,6 +6444,7 @@ static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct comma
{
char *desc = "Clear PCIE Correctable Errors.";
int fd, ret;
+ nvme_root_t r;
__u64 capabilities = 0;
OPT_ARGS(opts) = {
@@ -5670,12 +6455,13 @@ static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct comma
if (fd < 0)
return fd;
- if (!wdc_check_device(fd)) {
+ r = nvme_scan(NULL);
+ if (!wdc_check_device(r, fd)) {
ret = -1;
goto out;
}
- capabilities = wdc_get_drive_capabilities(fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_CLEAR_PCIE_MASK) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -5693,6 +6479,7 @@ static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct comma
}
out:
+ nvme_free_tree(r);
return ret;
}
@@ -5702,6 +6489,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
char *desc = "Get Drive Status.";
int fd;
int ret = 0;
+ nvme_root_t r;
__le32 system_eol_state;
__le32 user_eol_state;
__le32 format_corrupt_reason = cpu_to_le32(0xFFFFFFFF);
@@ -5718,7 +6506,8 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_DRIVE_STATUS) != WDC_DRIVE_CAP_DRIVE_STATUS) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -5726,46 +6515,46 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
}
/* verify the 0xC2 Device Manageability log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE) == false) {
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE) == false) {
fprintf(stderr, "ERROR : WDC : 0xC2 Log Page not supported\n");
ret = -1;
goto out;
}
/* Get the assert dump present status */
- if (!wdc_nvme_get_dev_status_log_data(fd, &assert_status,
+ if (!wdc_nvme_get_dev_status_log_data(r, fd, &assert_status,
WDC_C2_ASSERT_DUMP_PRESENT_ID))
fprintf(stderr, "ERROR : WDC : Get Assert Status Failed\n");
/* Get the thermal throttling status */
- if (!wdc_nvme_get_dev_status_log_data(fd, &thermal_status,
+ if (!wdc_nvme_get_dev_status_log_data(r, fd, &thermal_status,
WDC_C2_THERMAL_THROTTLE_STATUS_ID))
fprintf(stderr, "ERROR : WDC : Get Thermal Throttling Status Failed\n");
/* Get EOL status */
- if (!wdc_nvme_get_dev_status_log_data(fd, &eol_status,
+ if (!wdc_nvme_get_dev_status_log_data(r, fd, &eol_status,
WDC_C2_USER_EOL_STATUS_ID)) {
fprintf(stderr, "ERROR : WDC : Get User EOL Status Failed\n");
eol_status = cpu_to_le32(-1);
}
/* Get Customer EOL state */
- if (!wdc_nvme_get_dev_status_log_data(fd, &user_eol_state,
+ if (!wdc_nvme_get_dev_status_log_data(r, fd, &user_eol_state,
WDC_C2_USER_EOL_STATE_ID))
fprintf(stderr, "ERROR : WDC : Get User EOL State Failed\n");
/* Get System EOL state*/
- if (!wdc_nvme_get_dev_status_log_data(fd, &system_eol_state,
+ if (!wdc_nvme_get_dev_status_log_data(r, fd, &system_eol_state,
WDC_C2_SYSTEM_EOL_STATE_ID))
fprintf(stderr, "ERROR : WDC : Get System EOL State Failed\n");
/* Get format corrupt reason*/
- if (!wdc_nvme_get_dev_status_log_data(fd, &format_corrupt_reason,
+ if (!wdc_nvme_get_dev_status_log_data(r, fd, &format_corrupt_reason,
WDC_C2_FORMAT_CORRUPT_REASON_ID))
fprintf(stderr, "ERROR : WDC : Get Format Corrupt Reason Failed\n");
printf(" Drive Status :- \n");
- if (le32_to_cpu(eol_status) >= 0) {
+ if ((int)le32_to_cpu(eol_status) >= 0) {
printf(" Percent Used: %"PRIu32"%%\n",
le32_to_cpu(eol_status));
}
@@ -5807,6 +6596,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
printf(" Format Corrupt Reason: Unknown : 0x%08x\n", le32_to_cpu(format_corrupt_reason));
out:
+ nvme_free_tree(r);
return ret;
}
@@ -5816,6 +6606,7 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
char *desc = "Clear Assert Dump Present Status.";
int fd;
int ret = -1;
+ nvme_root_t r;
__le32 assert_status = cpu_to_le32(0xFFFFFFFF);
__u64 capabilities = 0;
struct nvme_passthru_cmd admin_cmd;
@@ -5828,13 +6619,14 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_CLEAR_ASSERT) != WDC_DRIVE_CAP_CLEAR_ASSERT) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
goto out;
}
- if (!wdc_nvme_get_dev_status_log_data(fd, &assert_status,
+ if (!wdc_nvme_get_dev_status_log_data(r, fd, &assert_status,
WDC_C2_ASSERT_DUMP_PRESENT_ID)) {
fprintf(stderr, "ERROR : WDC : Get Assert Status Failed\n");
ret = -1;
@@ -5848,23 +6640,24 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
admin_cmd.cdw12 = ((WDC_NVME_CLEAR_ASSERT_DUMP_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_CLEAR_ASSERT_DUMP_CMD);
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ nvme_show_status(ret);
} else
fprintf(stderr, "INFO : WDC : No Assert Dump Present\n");
out:
+ nvme_free_tree(r);
return ret;
}
-static int wdc_get_fw_act_history(int fd, char *format)
+static int wdc_get_fw_act_history(nvme_root_t r, int fd, char *format)
{
int ret = 0;
int fmt = -1;
__u8 *data;
struct wdc_fw_act_history_log_hdr *fw_act_history_hdr;
- if (!wdc_check_device(fd))
+ if (!wdc_check_device(r, fd))
return -1;
fmt = validate_output_format(format);
@@ -5874,7 +6667,7 @@ static int wdc_get_fw_act_history(int fd, char *format)
}
/* verify the FW Activate History log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == false) {
+ if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == false) {
fprintf(stderr, "ERROR : WDC : %d Log Page not supported\n", WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID);
return -1;
}
@@ -5886,11 +6679,11 @@ static int wdc_get_fw_act_history(int fd, char *format)
memset(data, 0, sizeof (__u8) * WDC_FW_ACT_HISTORY_LOG_BUF_LEN);
- ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID,
- false, NVME_NO_LOG_LSP, WDC_FW_ACT_HISTORY_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID,
+ WDC_FW_ACT_HISTORY_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
@@ -5915,17 +6708,33 @@ static int wdc_get_fw_act_history(int fd, char *format)
return ret;
}
-static int wdc_get_fw_act_history_C2(int fd, char *format)
+static __u32 wdc_get_fw_cust_id(nvme_root_t r, int fd)
+{
+
+ __u32 cust_id = WDC_INVALID_CUSTOMER_ID;
+ __u32 *cust_id_ptr = NULL;
+
+ if (!(get_dev_mgment_cbs_data(r, fd, WDC_C2_CUSTOMER_ID_ID, (void*)&cust_id_ptr))) {
+ fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID);
+ } else {
+ cust_id = *cust_id_ptr;
+ }
+
+ free(cust_id_ptr);
+ return cust_id;
+}
+
+static int wdc_get_fw_act_history_C2(nvme_root_t r, int fd, char *format)
{
int ret = 0;
int fmt = -1;
__u8 *data;
- __u32 *cust_id;
+ __u32 cust_id;
struct wdc_fw_act_history_log_format_c2 *fw_act_history_log;
__u32 tot_entries = 0, num_entries = 0;
__u32 vendor_id = 0, device_id = 0;
- if (!wdc_check_device(fd))
+ if (!wdc_check_device(r, fd))
return -1;
fmt = validate_output_format(format);
@@ -5933,7 +6742,8 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
fprintf(stderr, "ERROR : WDC : invalid output format\n");
return fmt;
}
- ret = wdc_get_pci_ids(&device_id, &vendor_id);
+
+ ret = wdc_get_pci_ids(r, &device_id, &vendor_id);
if ((data = (__u8*) malloc(sizeof (__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN)) == NULL) {
fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
@@ -5942,11 +6752,11 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
memset(data, 0, sizeof (__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN);
- ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID,
- false, NVME_NO_LOG_LSP, WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(fd, WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID,
+ WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
@@ -5955,14 +6765,15 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
if (tot_entries > 0) {
/* get the FW customer id */
- if (!get_dev_mgment_cbs_data(fd, WDC_C2_CUSTOMER_ID_ID, (void*)&cust_id)) {
- fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID);
+ cust_id = wdc_get_fw_cust_id(r, fd);
+ if (cust_id == WDC_INVALID_CUSTOMER_ID) {
+ fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
ret = -1;
goto freeData;
}
num_entries = (tot_entries < WDC_MAX_NUM_ACT_HIST_ENTRIES) ? tot_entries :
WDC_MAX_NUM_ACT_HIST_ENTRIES;
- ret = wdc_print_fw_act_history_log(data, num_entries, fmt, *cust_id, vendor_id);
+ ret = wdc_print_fw_act_history_log(data, num_entries, fmt, cust_id, vendor_id);
} else {
fprintf(stderr, "INFO : WDC : No FW Activate History entries found.\n");
ret = 0;
@@ -5982,6 +6793,7 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
{
int fd;
int ret = 0;
+ nvme_root_t r;
__u64 capabilities = 0;
const char *desc = "Retrieve FW activate history table.";
@@ -6004,7 +6816,8 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
if (fd < 0)
return fd;
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -6025,8 +6838,24 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
}
/* Get the 0xC0 log data */
- ret = nvme_get_log14(fd, 0xFFFFFFFF, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
- NVME_NO_LOG_LSP, 0, 0, false, uuid_index, 0, false, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
+ struct nvme_get_log_args args = {
+ .args_size = sizeof(args),
+ .fd = fd,
+ .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
+ .nsid = 0xFFFFFFFF,
+ .lpo = 0,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = 0,
+ .rae = false,
+ .uuidx = uuid_index,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = WDC_NVME_SMART_CLOUD_ATTR_LEN,
+ .log = data,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args);
if (ret == 0) {
/* Verify GUID matches */
@@ -6043,19 +6872,21 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
}
free(data);
- if (c0GuidMatch) {
- ret = wdc_get_fw_act_history_C2(fd, cfg.output_format);
- }
- else {
- ret = wdc_get_fw_act_history(fd, cfg.output_format);
- }
+ if (c0GuidMatch) {
+ ret = wdc_get_fw_act_history_C2(r, fd,
+ cfg.output_format);
+ }
+ else {
+ ret = wdc_get_fw_act_history(r, fd, cfg.output_format);
+ }
} else {
- ret = wdc_get_fw_act_history_C2(fd, cfg.output_format);
+ ret = wdc_get_fw_act_history_C2(r, fd, cfg.output_format);
}
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading the FW Activate History, ret = %d\n", ret);
out:
+ nvme_free_tree(r);
return ret;
}
@@ -6069,8 +6900,8 @@ static int wdc_do_clear_fw_activate_history_vuc(int fd)
admin_cmd.cdw12 = ((WDC_NVME_CLEAR_FW_ACT_HIST_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_CLEAR_FW_ACT_HIST_CMD);
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ nvme_show_status(ret);
return ret;
}
@@ -6081,10 +6912,10 @@ static int wdc_do_clear_fw_activate_history_fid(int fd)
__u32 result;
__u32 value = 1 << 31; /* Bit 31 - Clear Firmware Update History Log */
- ret = nvme_set_feature(fd, 0, WDC_NVME_CLEAR_FW_ACT_HIST_VU_FID, value,
- 0, 0, 0, 0, NULL, &result);
+ ret = nvme_set_features_simple(fd, WDC_NVME_CLEAR_FW_ACT_HIST_VU_FID, 0, value,
+ false, &result);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
return ret;
}
@@ -6094,6 +6925,7 @@ static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *
char *desc = "Clear FW activate history table.";
int fd;
int ret = -1;
+ nvme_root_t r;
__u64 capabilities = 0;
OPT_ARGS(opts) = {
@@ -6104,7 +6936,8 @@ static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *
if (fd < 0)
return fd;
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -6119,6 +6952,7 @@ static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *
}
out:
+ nvme_free_tree(r);
return ret;
}
@@ -6131,21 +6965,21 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
char *status = "Displays the current state of the controller initiated log page.";
int fd;
int ret = -1;
+ nvme_root_t r;
__u64 capabilities = 0;
__u32 result;
- void *buf = NULL;
struct config {
- int disable;
- int enable;
- int status;
+ bool disable;
+ bool enable;
+ bool status;
};
struct config cfg = {
- .disable = 0,
- .enable = 0,
- .status = 0,
+ .disable = false,
+ .enable = false,
+ .status = false,
};
OPT_ARGS(opts) = {
@@ -6159,7 +6993,8 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
if (fd < 0)
return fd;
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG) != WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -6175,26 +7010,26 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
}
if (cfg.disable) {
- ret = nvme_set_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 1,
- 0, 0, 0, 0, buf, &result);
+ ret = nvme_set_features_simple(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 1,
+ false, &result);
wdc_clear_reason_id(fd);
}
else {
if (cfg.enable) {
- ret = nvme_set_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0,
- 0, 0, 0, 0, buf, &result);
+ ret = nvme_set_features_simple(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 0,
+ false, &result);
}
else if (cfg.status) {
- ret = nvme_get_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 0,
- 0, 4, buf, &result);
+ ret = nvme_get_features_simple(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0,
+ &result);
if (ret == 0) {
if (result)
fprintf(stderr, "Controller Option Telemetry Log Page State: Disabled\n");
else
fprintf(stderr, "Controller Option Telemetry Log Page State: Enabled\n");
} else {
- fprintf(stderr, "ERROR : WDC: NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
}
}
else {
@@ -6207,6 +7042,7 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
}
out:
+ nvme_free_tree(r);
return ret;
}
@@ -6261,7 +7097,7 @@ static int wdc_get_max_transfer_len(int fd, __u32 *maxTransferLen)
static int wdc_de_VU_read_size(int fd, __u32 fileId, __u16 spiDestn, __u32* logSize)
{
int ret = WDC_STATUS_FAILURE;
- struct nvme_admin_cmd cmd;
+ struct nvme_passthru_cmd cmd;
if(!fd || !logSize )
{
@@ -6269,18 +7105,20 @@ static int wdc_de_VU_read_size(int fd, __u32 fileId, __u16 spiDestn, __u32* logS
goto end;
}
- memset(&cmd,0,sizeof(struct nvme_admin_cmd));
+ memset(&cmd,0,sizeof(struct nvme_passthru_cmd));
cmd.opcode = WDC_DE_VU_READ_SIZE_OPCODE;
cmd.nsid = WDC_DE_DEFAULT_NAMESPACE_ID;
cmd.cdw13 = fileId<<16;
cmd.cdw14 = spiDestn;
- ret = nvme_submit_admin_passthru(fd, &cmd);
+ ret = nvme_submit_admin_passthru(fd, &cmd, NULL);
if (!ret && logSize)
*logSize = cmd.result;
- if( ret != WDC_STATUS_SUCCESS)
- fprintf(stderr, "ERROR : WDC : VUReadSize() failed, status:%s(0x%x)\n", nvme_status_to_string(ret), ret);
+ if( ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "ERROR : WDC : VUReadSize() failed, ");
+ nvme_show_status(ret);
+ }
end:
return ret;
@@ -6289,7 +7127,7 @@ static int wdc_de_VU_read_size(int fd, __u32 fileId, __u16 spiDestn, __u32* logS
static int wdc_de_VU_read_buffer(int fd, __u32 fileId, __u16 spiDestn, __u32 offsetInDwords, __u8* dataBuffer, __u32* bufferSize)
{
int ret = WDC_STATUS_FAILURE;
- struct nvme_admin_cmd cmd;
+ struct nvme_passthru_cmd cmd;
__u32 noOfDwordExpected = 0;
if(!fd || !dataBuffer || !bufferSize)
@@ -6298,7 +7136,7 @@ static int wdc_de_VU_read_buffer(int fd, __u32 fileId, __u16 spiDestn, __u32 off
goto end;
}
- memset(&cmd,0,sizeof(struct nvme_admin_cmd));
+ memset(&cmd,0,sizeof(struct nvme_passthru_cmd));
noOfDwordExpected = *bufferSize/sizeof(__u32);
cmd.opcode = WDC_DE_VU_READ_BUFFER_OPCODE;
cmd.nsid = WDC_DE_DEFAULT_NAMESPACE_ID;
@@ -6310,10 +7148,12 @@ static int wdc_de_VU_read_buffer(int fd, __u32 fileId, __u16 spiDestn, __u32 off
cmd.addr = (__u64)(__u64)(uintptr_t)dataBuffer;
cmd.data_len = *bufferSize;
- ret = nvme_submit_admin_passthru(fd, &cmd);
+ ret = nvme_submit_admin_passthru(fd, &cmd, NULL);
- if( ret != WDC_STATUS_SUCCESS)
- fprintf(stderr, "ERROR : WDC : VUReadBuffer() failed, status:%s(0x%x)\n", nvme_status_to_string(ret), ret);
+ if( ret != WDC_STATUS_SUCCESS) {
+ fprintf(stderr, "ERROR : WDC : VUReadBuffer() failed, ");
+ nvme_show_status(ret);
+ }
end:
return ret;
@@ -6620,7 +7460,7 @@ static int wdc_de_get_dump_trace(int fd, char * filePath, __u16 binFileNameLen,
return ret;
}
-static int wdc_do_drive_essentials(int fd, char *dir, char *key)
+static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
{
int ret = 0;
void *retPtr;
@@ -6649,7 +7489,7 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
struct nvme_id_ns ns;
struct nvme_error_log_page *elogBuffer;
struct nvme_smart_log smart_log;
- struct nvme_firmware_log_page fw_log;
+ struct nvme_firmware_slot fw_log;
PWDC_NVME_DE_VU_LOGPAGES vuLogInput = NULL;
WDC_DE_VU_LOG_DIRECTORY deEssentialsList;
@@ -6725,7 +7565,7 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
}
memset(&ns, 0, sizeof (struct nvme_id_ns));
- ret = nvme_identify_ns(fd, 1, 0, &ns);
+ ret = nvme_identify_ns(fd, 1, &ns);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ns() failed, ret = %d\n", ret);
} else {
@@ -6740,7 +7580,7 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
dataBuffer = calloc(1, elogBufferSize);
elogBuffer = (struct nvme_error_log_page *)dataBuffer;
- ret = nvme_error_log(fd, elogNumEntries, elogBuffer);
+ ret = nvme_get_log_error(fd, elogNumEntries, false, elogBuffer);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_error_log() failed, ret = %d\n", ret);
} else {
@@ -6754,7 +7594,7 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
/* Get Smart log page */
memset(&smart_log, 0, sizeof (struct nvme_smart_log));
- ret = nvme_smart_log(fd, NVME_NSID_ALL, &smart_log);
+ ret = nvme_get_log_smart(fd, NVME_NSID_ALL, false, &smart_log);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_smart_log() failed, ret = %d\n", ret);
} else {
@@ -6764,14 +7604,14 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
}
/* Get FW Slot log page */
- memset(&fw_log, 0, sizeof (struct nvme_firmware_log_page));
- ret = nvme_fw_log(fd, &fw_log);
+ memset(&fw_log, 0, sizeof (struct nvme_firmware_slot));
+ ret = nvme_get_log_fw_slot(fd, true, &fw_log);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_fw_log() failed, ret = %d\n", ret);
} else {
wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char*)bufferFolderPath, WDC_DE_PATH_SEPARATOR,
"FwSLotLog", (char*)serialNo, (char*)timeString);
- wdc_WriteToFile(fileName, (char*)&fw_log, sizeof(struct nvme_firmware_log_page));
+ wdc_WriteToFile(fileName, (char*)&fw_log, sizeof(struct nvme_firmware_slot));
}
/* Get VU log pages */
@@ -6785,8 +7625,8 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
dataBuffer = calloc(1, dataBufferSize);
memset(dataBuffer, 0, dataBufferSize);
- ret = nvme_get_log(fd, WDC_DE_GLOBAL_NSID, deVULogPagesList[vuLogIdx].logPageId,
- false, NVME_NO_LOG_LSP, dataBufferSize, dataBuffer);
+ ret = nvme_get_log_simple(fd, deVULogPagesList[vuLogIdx].logPageId,
+ dataBufferSize, dataBuffer);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_get_log() for log page 0x%x failed, ret = %d\n",
deVULogPagesList[vuLogIdx].logPageId, ret);
@@ -6810,8 +7650,8 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
/* skipping LbaRangeType as it is an optional nvme command and not supported */
if (deFeatureIdList[listIdx].featureId == FID_LBA_RANGE_TYPE)
continue;
- ret = nvme_get_feature(fd, WDC_DE_GLOBAL_NSID, deFeatureIdList[listIdx].featureId, FS_CURRENT, 0,
- 0, sizeof(featureIdBuff), &featureIdBuff, &result);
+ ret = nvme_get_features_data(fd, deFeatureIdList[listIdx].featureId, WDC_DE_GLOBAL_NSID,
+ sizeof(featureIdBuff), &featureIdBuff, &result);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_get_feature id 0x%x failed, ret = %d\n",
@@ -6905,6 +7745,7 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
}
fprintf(stderr, "Get of Drive Essentials data successful\n");
+ nvme_free_tree(r);
return 0;
}
@@ -6917,6 +7758,7 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
char k[PATH_MAX] = {0};
char *d_ptr;
int fd;
+ nvme_root_t r;
__u64 capabilities = 0;
struct config {
@@ -6937,9 +7779,11 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_DRIVE_ESSENTIALS) != WDC_DRIVE_CAP_DRIVE_ESSENTIALS) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ nvme_free_tree(r);
return -1;
}
@@ -6950,49 +7794,49 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
d_ptr = NULL;
}
- return wdc_do_drive_essentials(fd, d_ptr, k);
+ return wdc_do_drive_essentials(r, fd, d_ptr, k);
}
static int wdc_do_drive_resize(int fd, uint64_t new_size)
{
int ret;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_DRIVE_RESIZE_OPCODE;
admin_cmd.cdw12 = ((WDC_NVME_DRIVE_RESIZE_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_DRIVE_RESIZE_CMD);
admin_cmd.cdw13 = new_size;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
return ret;
}
static int wdc_do_namespace_resize(int fd, __u32 nsid, __u32 op_option)
{
int ret;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_NAMESPACE_RESIZE_OPCODE;
admin_cmd.nsid = nsid;
admin_cmd.cdw10 = op_option;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
return ret;
}
static int wdc_do_drive_info(int fd, __u32 *result)
{
int ret;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_DRIVE_INFO_OPCODE;
admin_cmd.cdw12 = ((WDC_NVME_DRIVE_INFO_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_DRIVE_INFO_CMD);
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
if (!ret && result)
*result = admin_cmd.result;
@@ -7005,6 +7849,7 @@ static int wdc_drive_resize(int argc, char **argv,
{
const char *desc = "Send a Resize command.";
const char *size = "The new size (in GB) to resize the drive to.";
+ nvme_root_t r;
uint64_t capabilities = 0;
int fd, ret;
@@ -7025,8 +7870,9 @@ static int wdc_drive_resize(int argc, char **argv,
if (fd < 0)
return fd;
- wdc_check_device(fd);
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ wdc_check_device(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_RESIZE) == WDC_DRIVE_CAP_RESIZE) {
ret = wdc_do_drive_resize(fd, cfg.size);
} else {
@@ -7037,7 +7883,8 @@ static int wdc_drive_resize(int argc, char **argv,
if (!ret)
printf("New size: %" PRIu64 " GB\n", cfg.size);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
+ nvme_free_tree(r);
return ret;
}
@@ -7047,6 +7894,7 @@ static int wdc_namespace_resize(int argc, char **argv,
const char *desc = "Send a Namespace Resize command.";
const char *namespace_id = "The namespace id to resize.";
const char *op_option = "The over provisioning option to set for namespace.";
+ nvme_root_t r;
uint64_t capabilities = 0;
int fd, ret;
@@ -7079,8 +7927,9 @@ static int wdc_namespace_resize(int argc, char **argv,
return -1;
}
- wdc_check_device(fd);
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ wdc_check_device(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_NS_RESIZE) == WDC_DRIVE_CAP_NS_RESIZE) {
ret = wdc_do_namespace_resize(fd, cfg.namespace_id, cfg.op_option);
@@ -7091,7 +7940,8 @@ static int wdc_namespace_resize(int argc, char **argv,
ret = -1;
}
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
+ nvme_free_tree(r);
return ret;
}
@@ -7101,6 +7951,7 @@ static int wdc_reason_identifier(int argc, char **argv,
const char *desc = "Retrieve telemetry log reason identifier.";
const char *log_id = "Log ID to retrieve - host - 7 or controller - 8";
const char *fname = "File name to save raw binary identifier";
+ nvme_root_t r;
int fd;
int ret;
uint64_t capabilities = 0;
@@ -7130,7 +7981,9 @@ static int wdc_reason_identifier(int argc, char **argv,
if (fd < 0)
return fd;
- if (cfg.log_id != NVME_LOG_TELEMETRY_HOST && cfg.log_id != NVME_LOG_TELEMETRY_CTRL) {
+ r = nvme_scan(NULL);
+
+ if (cfg.log_id != NVME_LOG_LID_TELEMETRY_HOST&& cfg.log_id != NVME_LOG_LID_TELEMETRY_CTRL) {
fprintf(stderr, "ERROR : WDC: Invalid Log ID. It must be 7 (Host) or 8 (Controller)\n");
ret = -1;
goto close_fd;
@@ -7154,7 +8007,7 @@ static int wdc_reason_identifier(int argc, char **argv,
wdc_UtilsSnprintf((char*)timeStamp, MAX_PATH_LEN, "%02u%02u%02u_%02u%02u%02u",
timeInfo.year, timeInfo.month, timeInfo.dayOfMonth,
timeInfo.hour, timeInfo.minute, timeInfo.second);
- if (cfg.log_id == NVME_LOG_TELEMETRY_CTRL)
+ if (cfg.log_id == NVME_LOG_LID_TELEMETRY_CTRL)
snprintf(fileSuffix, PATH_MAX, "_error_reason_identifier_ctlr_%s", (char*)timeStamp);
else
snprintf(fileSuffix, PATH_MAX, "_error_reason_identifier_host_%s", (char*)timeStamp);
@@ -7170,7 +8023,7 @@ static int wdc_reason_identifier(int argc, char **argv,
fprintf(stderr, "%s: filename = %s\n", __func__, f);
- capabilities = wdc_get_drive_capabilities(fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_REASON_ID) == WDC_DRIVE_CAP_REASON_ID) {
ret = wdc_do_get_reason_id(fd, f, cfg.log_id);
} else {
@@ -7178,50 +8031,51 @@ static int wdc_reason_identifier(int argc, char **argv,
ret = -1;
}
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
close_fd:
- close(fd);
- return ret;
+ close(fd);
+ nvme_free_tree(r);
+ return ret;
}
static const char *nvme_log_id_to_string(__u8 log_id)
{
switch (log_id) {
- case NVME_LOG_ERROR: return "Error Information Log ID";
- case NVME_LOG_SMART: return "Smart/Health Information Log ID";
- case NVME_LOG_FW_SLOT: return "Firmware Slot Information Log ID";
- case NVME_LOG_CHANGED_NS: return "Namespace Changed Log ID";
- case NVME_LOG_CMD_EFFECTS: return "Commamds Supported and Effects Log ID";
- case NVME_LOG_DEVICE_SELF_TEST: return "Device Self Test Log ID";
- case NVME_LOG_TELEMETRY_HOST: return "Telemetry Host Initiated Log ID";
- case NVME_LOG_TELEMETRY_CTRL: return "Telemetry Controller Generated Log ID";
- case NVME_LOG_ENDURANCE_GROUP: return "Endurance Group Log ID";
- case NVME_LOG_ANA: return "ANA Log ID";
- case NVME_LOG_PERSISTENT_EVENT: return "Persistent Event Log ID";
- case NVME_LOG_DISC: return "Discovery Log ID";
- case NVME_LOG_RESERVATION: return "Reservation Notification Log ID";
- case NVME_LOG_SANITIZE: return "Sanitize Status Log ID";
-
- case WDC_LOG_ID_C0: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_C1: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_C2: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_C4: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_C5: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_C6: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_C8: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_CA: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_CB: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_D0: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_D1: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_D6: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_D7: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_D8: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_DE: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_F0: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_F1: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_F2: return "WDC Vendor Unique Log ID";
- case WDC_LOG_ID_FA: return "WDC Vendor Unique Log ID";
+ case NVME_LOG_LID_ERROR: return "Error Information Log ID";
+ case NVME_LOG_LID_SMART: return "Smart/Health Information Log ID";
+ case NVME_LOG_LID_FW_SLOT: return "Firmware Slot Information Log ID";
+ case NVME_LOG_LID_CHANGED_NS: return "Namespace Changed Log ID";
+ case NVME_LOG_LID_CMD_EFFECTS: return "Commamds Supported and Effects Log ID";
+ case NVME_LOG_LID_DEVICE_SELF_TEST: return "Device Self Test Log ID";
+ case NVME_LOG_LID_TELEMETRY_HOST: return "Telemetry Host Initiated Log ID";
+ case NVME_LOG_LID_TELEMETRY_CTRL: return "Telemetry Controller Generated Log ID";
+ case NVME_LOG_LID_ENDURANCE_GROUP: return "Endurance Group Log ID";
+ case NVME_LOG_LID_ANA: return "ANA Log ID";
+ case NVME_LOG_LID_PERSISTENT_EVENT: return "Persistent Event Log ID";
+ case NVME_LOG_LID_DISCOVER: return "Discovery Log ID";
+ case NVME_LOG_LID_RESERVATION: return "Reservation Notification Log ID";
+ case NVME_LOG_LID_SANITIZE: return "Sanitize Status Log ID";
+
+ case WDC_LOG_ID_C0: return "WDC Vendor Unique Log ID C0";
+ case WDC_LOG_ID_C1: return "WDC Vendor Unique Log ID C1";
+ case WDC_LOG_ID_C2: return "WDC Vendor Unique Log ID C2";
+ case WDC_LOG_ID_C4: return "WDC Vendor Unique Log ID C4";
+ case WDC_LOG_ID_C5: return "WDC Vendor Unique Log ID C5";
+ case WDC_LOG_ID_C6: return "WDC Vendor Unique Log ID C6";
+ case WDC_LOG_ID_C8: return "WDC Vendor Unique Log ID C8";
+ case WDC_LOG_ID_CA: return "WDC Vendor Unique Log ID CA";
+ case WDC_LOG_ID_CB: return "WDC Vendor Unique Log ID CB";
+ case WDC_LOG_ID_D0: return "WDC Vendor Unique Log ID D0";
+ case WDC_LOG_ID_D1: return "WDC Vendor Unique Log ID D1";
+ case WDC_LOG_ID_D6: return "WDC Vendor Unique Log ID D6";
+ case WDC_LOG_ID_D7: return "WDC Vendor Unique Log ID D7";
+ case WDC_LOG_ID_D8: return "WDC Vendor Unique Log ID D8";
+ case WDC_LOG_ID_DE: return "WDC Vendor Unique Log ID DE";
+ case WDC_LOG_ID_F0: return "WDC Vendor Unique Log ID F0";
+ case WDC_LOG_ID_F1: return "WDC Vendor Unique Log ID F1";
+ case WDC_LOG_ID_F2: return "WDC Vendor Unique Log ID F2";
+ case WDC_LOG_ID_FA: return "WDC Vendor Unique Log ID FA";
default: return "Unknown Log ID";
}
@@ -7233,9 +8087,10 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
const char *desc = "Retrieve Log Page Directory.";
int fd;
int ret = 0;
+ nvme_root_t r;
__u64 capabilities = 0;
struct wdc_c2_cbs_data *cbs_data = NULL;
- int i;
+ int i;
__u8 log_id = 0;
__u32 device_id, read_vendor_id;
@@ -7261,25 +8116,26 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
fprintf(stderr, "%s: ERROR : WDC : invalid output format\n", __func__);
return ret;
}
+ ret = 0;
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_LOG_PAGE_DIR) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
- }
- else {
- ret = wdc_get_pci_ids(&device_id, &read_vendor_id);
+ } else {
+ ret = wdc_get_pci_ids(r, &device_id, &read_vendor_id);
log_id = (device_id == WDC_NVME_ZN350_DEV_ID || device_id == WDC_NVME_ZN350_DEV_ID_1) ?
WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8 : WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE;
/* verify the 0xC2 Device Manageability log page is supported */
- if (wdc_nvme_check_supported_log_page(fd, log_id) == false) {
+ if (wdc_nvme_check_supported_log_page(r, fd, log_id) == false) {
fprintf(stderr, "%s: ERROR : WDC : 0x%x Log Page not supported\n", __func__, log_id);
ret = -1;
goto out;
}
- if (get_dev_mgment_cbs_data(fd, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
+ if (get_dev_mgment_cbs_data(r, fd, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
if (cbs_data != NULL) {
printf("Log Page Directory\n");
/* print the supported pages */
@@ -7304,6 +8160,8 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
json_free_object(root);
} else
fprintf(stderr, "%s: ERROR : WDC : Invalid format, format = %s\n", __func__, cfg.output_format);
+
+ free(cbs_data);
} else
fprintf(stderr, "%s: ERROR : WDC : NULL_data ptr\n", __func__);
} else
@@ -7313,6 +8171,7 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
}
out:
+ nvme_free_tree(r);
return ret;
}
@@ -7419,14 +8278,33 @@ static int wdc_clear_reason_id(int fd)
return ret;
}
+static int wdc_dump_telemetry_hdr(int fd, int log_id, struct nvme_telemetry_log *log_hdr)
+{
+ int ret = 0;
+
+ if (log_id == NVME_LOG_LID_TELEMETRY_HOST)
+ ret = nvme_get_log_create_telemetry_host(fd, log_hdr);
+ else
+ ret = nvme_get_log_telemetry_ctrl(fd, false, 0, 512, (void *)log_hdr);
+
+ if (ret < 0)
+ perror("get-telemetry-log");
+ else if (ret > 0) {
+ nvme_show_status(ret);
+ fprintf(stderr, "%s: ERROR : Failed to acquire telemetry header, ret = %d!\n", __func__, ret);
+ }
+
+ return ret;
+}
+
static int wdc_do_get_reason_id(int fd, char *file, int log_id)
{
int ret;
- struct nvme_telemetry_log_page_hdr *log_hdr;
- __u32 log_hdr_size = sizeof(struct nvme_telemetry_log_page_hdr);
+ struct nvme_telemetry_log *log_hdr;
+ __u32 log_hdr_size = sizeof(struct nvme_telemetry_log);
__u32 reason_id_size = 0;
- log_hdr = (struct nvme_telemetry_log_page_hdr *) malloc(log_hdr_size);
+ log_hdr = (struct nvme_telemetry_log *) malloc(log_hdr_size);
if (log_hdr == NULL) {
fprintf(stderr, "%s: ERROR : malloc failed, size : 0x%x, status : %s\n", __func__, log_hdr_size, strerror(errno));
ret = -1;
@@ -7443,7 +8321,7 @@ static int wdc_do_get_reason_id(int fd, char *file, int log_id)
reason_id_size = sizeof(log_hdr->rsnident);
- if (log_id == NVME_LOG_TELEMETRY_CTRL)
+ if (log_id == NVME_LOG_LID_TELEMETRY_CTRL)
wdc_save_reason_id(fd, log_hdr->rsnident, reason_id_size);
ret = wdc_create_log_file(file, (__u8 *)log_hdr->rsnident, reason_id_size);
@@ -7453,27 +8331,6 @@ out:
return ret;
}
-static int wdc_dump_telemetry_hdr(int fd, int log_id, struct nvme_telemetry_log_page_hdr *log_hdr)
-{
- int ret = 0;
- int host_gen = 0, ctrl_init = 0;
-
- if (log_id == NVME_LOG_TELEMETRY_HOST)
- host_gen = 1;
- else
- ctrl_init = 1;
-
- ret = nvme_get_telemetry_log(fd, log_hdr, host_gen, ctrl_init, 512, 0);
- if (ret < 0)
- perror("get-telemetry-log");
- else if (ret > 0) {
- nvme_show_status(ret);
- fprintf(stderr, "%s: ERROR : Failed to acquire telemetry header, ret = %d!\n", __func__, ret);
- }
-
- return ret;
-}
-
static void wdc_print_nand_stats_normal(__u16 version, void *data)
{
struct wdc_nand_stats *nand_stats = (struct wdc_nand_stats *)(data);
@@ -7625,11 +8482,11 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
le32_to_cpu(nand_stats->nand_erase_failure));
json_object_add_value_uint(root, "Bad Block Count",
le32_to_cpu(nand_stats->bad_block_count));
- json_object_add_value_uint(root, "NAND XOR/RAID Recovery Trigger Events",
+ json_object_add_value_uint64(root, "NAND XOR/RAID Recovery Trigger Events",
le64_to_cpu(nand_stats->nand_rec_trigger_event));
- json_object_add_value_uint(root, "E2E Error Counter",
+ json_object_add_value_uint64(root, "E2E Error Counter",
le64_to_cpu(nand_stats->e2e_error_counter));
- json_object_add_value_uint(root, "Number Successful NS Resizing Events",
+ json_object_add_value_uint64(root, "Number Successful NS Resizing Events",
le64_to_cpu(nand_stats->successful_ns_resize_event));
json_print_object(root, NULL);
@@ -7647,13 +8504,13 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
temp_raw = ((*temp_ptr & 0xFFFFFFFFFFFF0000) >> 16);
json_object_add_value_uint(root, "Bad NAND Blocks Count - Normalized",
le16_to_cpu(temp_norm));
- json_object_add_value_uint(root, "Bad NAND Blocks Count - Raw",
+ json_object_add_value_uint64(root, "Bad NAND Blocks Count - Raw",
le64_to_cpu(temp_raw));
- json_object_add_value_uint(root, "NAND XOR Recovery count",
+ json_object_add_value_uint64(root, "NAND XOR Recovery count",
le64_to_cpu(nand_stats_v3->xor_recovery_count));
- json_object_add_value_uint(root, "UECC Read Error count",
+ json_object_add_value_uint64(root, "UECC Read Error count",
le64_to_cpu(nand_stats_v3->uecc_read_error_count));
- json_object_add_value_uint(root, "SSD End to End corrected errors",
+ json_object_add_value_uint64(root, "SSD End to End corrected errors",
le64_to_cpu(nand_stats_v3->ssd_correction_counts[0]));
json_object_add_value_uint(root, "SSD End to End detected errors",
le32_to_cpu(nand_stats_v3->ssd_correction_counts[8]));
@@ -7661,54 +8518,54 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
le32_to_cpu(nand_stats_v3->ssd_correction_counts[12]));
json_object_add_value_uint(root, "System data % life-used",
nand_stats_v3->percent_life_used);
- json_object_add_value_uint(root, "User Data Erase Counts - SLC Min",
+ json_object_add_value_uint64(root, "User Data Erase Counts - SLC Min",
le64_to_cpu(nand_stats_v3->user_data_erase_counts[0]));
- json_object_add_value_uint(root, "User Data Erase Counts - SLC Max",
+ json_object_add_value_uint64(root, "User Data Erase Counts - SLC Max",
le64_to_cpu(nand_stats_v3->user_data_erase_counts[1]));
- json_object_add_value_uint(root, "User Data Erase Counts - TLC Min",
+ json_object_add_value_uint64(root, "User Data Erase Counts - TLC Min",
le64_to_cpu(nand_stats_v3->user_data_erase_counts[2]));
- json_object_add_value_uint(root, "User Data Erase Counts - TLC Max",
+ json_object_add_value_uint64(root, "User Data Erase Counts - TLC Max",
le64_to_cpu(nand_stats_v3->user_data_erase_counts[3]));
temp_ptr = (__u64 *)nand_stats_v3->program_fail_count;
temp_norm = (__u16)(*temp_ptr & 0x000000000000FFFF);
temp_raw = ((*temp_ptr & 0xFFFFFFFFFFFF0000) >> 16);
json_object_add_value_uint(root, "Program Fail Count - Normalized",
le16_to_cpu(temp_norm));
- json_object_add_value_uint(root, "Program Fail Count - Raw",
+ json_object_add_value_uint64(root, "Program Fail Count - Raw",
le64_to_cpu(temp_raw));
temp_ptr = (__u64 *)nand_stats_v3->erase_fail_count;
temp_norm = (__u16)(*temp_ptr & 0x000000000000FFFF);
temp_raw = ((*temp_ptr & 0xFFFFFFFFFFFF0000) >> 16);
json_object_add_value_uint(root, "Erase Fail Count - Normalized",
le16_to_cpu(temp_norm));
- json_object_add_value_uint(root, "Erase Fail Count - Raw",
+ json_object_add_value_uint64(root, "Erase Fail Count - Raw",
le64_to_cpu(temp_raw));
json_object_add_value_uint(root, "PCIe Correctable Error Count",
le16_to_cpu(nand_stats_v3->correctable_error_count));
json_object_add_value_uint(root, "% Free Blocks (User)",
nand_stats_v3->percent_free_blocks_user);
- json_object_add_value_uint(root, "Security Version Number",
+ json_object_add_value_uint64(root, "Security Version Number",
le64_to_cpu(nand_stats_v3->security_version_number));
json_object_add_value_uint(root, "% Free Blocks (System)",
nand_stats_v3->percent_free_blocks_system);
json_object_add_value_float(root, "Data Set Management Commands",
int128_to_double(nand_stats_v3->trim_completions));
- json_object_add_value_uint(root, "Estimate of Incomplete Trim Data",
+ json_object_add_value_uint64(root, "Estimate of Incomplete Trim Data",
le64_to_cpu(nand_stats_v3->trim_completions[16]));
json_object_add_value_uint(root, "%% of completed trim",
nand_stats_v3->trim_completions[24]);
json_object_add_value_uint(root, "Background Back-Pressure-Guage",
nand_stats_v3->back_pressure_guage);
- json_object_add_value_uint(root, "Soft ECC Error Count",
+ json_object_add_value_uint64(root, "Soft ECC Error Count",
le64_to_cpu(nand_stats_v3->soft_ecc_error_count));
- json_object_add_value_uint(root, "Refresh Count",
+ json_object_add_value_uint64(root, "Refresh Count",
le64_to_cpu(nand_stats_v3->refresh_count));
temp_ptr = (__u64 *)nand_stats_v3->bad_sys_nand_block_count;
temp_norm = (__u16)(*temp_ptr & 0x000000000000FFFF);
temp_raw = ((*temp_ptr & 0xFFFFFFFFFFFF0000) >> 16);
json_object_add_value_uint(root, "Bad System Nand Block Count - Normalized",
le16_to_cpu(temp_norm));
- json_object_add_value_uint(root, "Bad System Nand Block Count - Raw",
+ json_object_add_value_uint64(root, "Bad System Nand Block Count - Raw",
le64_to_cpu(temp_raw));
json_object_add_value_float(root, "Endurance Estimate",
int128_to_double(nand_stats_v3->endurance_estimate));
@@ -7716,7 +8573,7 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
nand_stats_v3->thermal_throttling_st_ct[0]);
json_object_add_value_uint(root, "Thermal Throttling Count",
nand_stats_v3->thermal_throttling_st_ct[1]);
- json_object_add_value_uint(root, "Unaligned I/O",
+ json_object_add_value_uint64(root, "Unaligned I/O",
le64_to_cpu(nand_stats_v3->unaligned_IO));
json_object_add_value_float(root, "Physical Media Units Read",
int128_to_double(nand_stats_v3->physical_media_units));
@@ -7780,38 +8637,38 @@ static void wdc_print_pcie_stats_json(struct wdc_vs_pcie_stats *pcie_stats)
struct json_object *root;
root = json_create_object();
- json_object_add_value_uint(root, "Unsupported Request Error Counter",
+ json_object_add_value_uint64(root, "Unsupported Request Error Counter",
le64_to_cpu(pcie_stats->unsupportedRequestErrorCount));
- json_object_add_value_uint(root, "ECRC Error Status Counter",
+ json_object_add_value_uint64(root, "ECRC Error Status Counter",
le64_to_cpu(pcie_stats->ecrcErrorStatusCount));
- json_object_add_value_uint(root, "Malformed TLP Status Counter",
+ json_object_add_value_uint64(root, "Malformed TLP Status Counter",
le64_to_cpu(pcie_stats->malformedTlpStatusCount));
- json_object_add_value_uint(root, "Receiver Overflow Status Counter",
+ json_object_add_value_uint64(root, "Receiver Overflow Status Counter",
le64_to_cpu(pcie_stats->receiverOverflowStatusCount));
- json_object_add_value_uint(root, "Unexpected Completion Status Counter",
+ json_object_add_value_uint64(root, "Unexpected Completion Status Counter",
le64_to_cpu(pcie_stats->unexpectedCmpltnStatusCount));
- json_object_add_value_uint(root, "Complete Abort Status Counter",
+ json_object_add_value_uint64(root, "Complete Abort Status Counter",
le64_to_cpu(pcie_stats->completeAbortStatusCount));
- json_object_add_value_uint(root, "Completion Timeout Status Counter",
+ json_object_add_value_uint64(root, "Completion Timeout Status Counter",
le64_to_cpu(pcie_stats->cmpltnTimoutStatusCount));
- json_object_add_value_uint(root, "Flow Control Error Status Counter",
+ json_object_add_value_uint64(root, "Flow Control Error Status Counter",
le64_to_cpu(pcie_stats->flowControlErrorStatusCount));
- json_object_add_value_uint(root, "Poisoned TLP Status Counter",
+ json_object_add_value_uint64(root, "Poisoned TLP Status Counter",
le64_to_cpu(pcie_stats->poisonedTlpStatusCount));
- json_object_add_value_uint(root, "Dlink Protocol Error Status Counter",
+ json_object_add_value_uint64(root, "Dlink Protocol Error Status Counter",
le64_to_cpu(pcie_stats->dLinkPrtclErrorStatusCount));
- json_object_add_value_uint(root, "Advisory Non Fatal Error Status Counter",
+ json_object_add_value_uint64(root, "Advisory Non Fatal Error Status Counter",
le64_to_cpu(pcie_stats->advsryNFatalErrStatusCount));
- json_object_add_value_uint(root, "Replay Timer TO Status Counter",
+ json_object_add_value_uint64(root, "Replay Timer TO Status Counter",
le64_to_cpu(pcie_stats->replayTimerToStatusCount));
- json_object_add_value_uint(root, "Replay Number Rollover Status Counter",
+ json_object_add_value_uint64(root, "Replay Number Rollover Status Counter",
le64_to_cpu(pcie_stats->replayNumRolloverStCount));
- json_object_add_value_uint(root, "Bad DLLP Status Counter",
+ json_object_add_value_uint64(root, "Bad DLLP Status Counter",
le64_to_cpu(pcie_stats->badDllpStatusCount));
- json_object_add_value_uint(root, "Bad TLP Status Counter",
+ json_object_add_value_uint64(root, "Bad TLP Status Counter",
le64_to_cpu(pcie_stats->badTlpStatusCount));
- json_object_add_value_uint(root, "Receiver Error Status Counter",
+ json_object_add_value_uint64(root, "Receiver Error Status Counter",
le64_to_cpu(pcie_stats->receiverErrStatusCount));
json_print_object(root, NULL);
@@ -7833,8 +8690,8 @@ static int wdc_do_vs_nand_stats(int fd, char *format)
goto out;
}
- ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_NAND_STATS_LOG_ID,
- false, NVME_NO_LOG_LSP, WDC_NVME_NAND_STATS_SIZE, (void*)output);
+ ret = nvme_get_log_simple(fd, WDC_NVME_NAND_STATS_LOG_ID,
+ WDC_NVME_NAND_STATS_SIZE, (void*)output);
if (ret) {
fprintf(stderr, "ERROR : WDC : %s : Failed to retreive NAND stats\n", __func__);
goto out;
@@ -7871,6 +8728,7 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
int fd;
int ret = 0;
+ nvme_root_t r;
__u64 capabilities = 0;
struct config {
@@ -7890,7 +8748,8 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_NAND_STATS) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7901,6 +8760,7 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
fprintf(stderr, "ERROR : WDC : Failure reading NAND statistics, ret = %d\n", ret);
}
+ nvme_free_tree(r);
return ret;
}
@@ -7908,15 +8768,15 @@ static int wdc_do_vs_pcie_stats(int fd,
struct wdc_vs_pcie_stats *pcieStatsPtr)
{
int ret;
- struct nvme_admin_cmd admin_cmd;
+ struct nvme_passthru_cmd admin_cmd;
int pcie_stats_size = sizeof(struct wdc_vs_pcie_stats);
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
admin_cmd.opcode = WDC_NVME_PCIE_STATS_OPCODE;
admin_cmd.addr = (__u64)(uintptr_t)pcieStatsPtr;
admin_cmd.data_len = pcie_stats_size;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
return ret;
}
@@ -7928,6 +8788,7 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
int fd;
int ret = 0;
+ nvme_root_t r;
__u64 capabilities = 0;
int fmt = -1;
struct wdc_vs_pcie_stats *pcieStatsPtr = NULL;
@@ -7951,6 +8812,8 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
if (fd < 0)
return fd;
+
+ r = nvme_scan(NULL);
fmt = validate_output_format(cfg.output_format);
if (fmt < 0) {
fprintf(stderr, "ERROR : WDC : invalid output format\n");
@@ -7967,7 +8830,7 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
memset((void *)pcieStatsPtr, 0, pcie_stats_size);
- capabilities = wdc_get_drive_capabilities(fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_PCIE_STATS) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7992,6 +8855,7 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
nvme_free(pcieStatsPtr, huge);
out:
+ nvme_free_tree(r);
return ret;
}
@@ -7999,6 +8863,7 @@ static int wdc_vs_drive_info(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
const char *desc = "Send a vs-drive-info command.";
+ nvme_root_t r;
uint64_t capabilities = 0;
int fd, ret;
__le32 result;
@@ -8043,8 +8908,9 @@ static int wdc_vs_drive_info(int argc, char **argv,
return ret;
}
- wdc_check_device(fd);
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ wdc_check_device(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_INFO) == WDC_DRIVE_CAP_INFO) {
ret = wdc_do_drive_info(fd, &result);
@@ -8097,11 +8963,13 @@ static int wdc_vs_drive_info(int argc, char **argv,
}
} else {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ nvme_free_tree(r);
return -1;
}
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
+ nvme_free_tree(r);
return ret;
}
@@ -8111,6 +8979,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
const char *desc = "Send a vs-temperature-stats command.";
struct nvme_smart_log smart_log;
struct nvme_id_ctrl id_ctrl;
+ nvme_root_t r;
uint64_t capabilities = 0;
__u32 hctm_tmt;
int fd, ret;
@@ -8134,6 +9003,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
if (fd < 0)
return fd;
+ r = nvme_scan(NULL);
fmt = validate_output_format(cfg.output_format);
if (fmt < 0) {
fprintf(stderr, "ERROR : WDC : invalid output format\n");
@@ -8142,10 +9012,11 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
}
/* check if command is supported */
- wdc_check_device(fd);
- capabilities = wdc_get_drive_capabilities(fd);
+ wdc_check_device(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_TEMP_STATS) != WDC_DRIVE_CAP_TEMP_STATS) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ nvme_free_tree(r);
return -1;
}
@@ -8153,7 +9024,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
ret = nvme_identify_ctrl(fd, &id_ctrl);
if (ret != 0)
goto END;
- ret = nvme_smart_log(fd, NVME_NSID_ALL, &smart_log);
+ ret = nvme_get_log_smart(fd, NVME_NSID_ALL, false, &smart_log);
if (ret != 0)
goto END;
@@ -8161,7 +9032,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]) - 273;
/* retrieve HCTM Thermal Management Temperatures */
- nvme_get_feature(fd, 0, 0x10, 0, 0, 0, 0, 0, &hctm_tmt);
+ nvme_get_features_simple(fd, 0x10, 0, &hctm_tmt);
temp_tmt1 = ((hctm_tmt >> 16) & 0xffff) ? ((hctm_tmt >> 16) & 0xffff) - 273 : 0;
temp_tmt2 = (hctm_tmt & 0xffff) ? (hctm_tmt & 0xffff) - 273 : 0;
@@ -8213,7 +9084,8 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
printf("%s: Invalid format\n", __func__);
END:
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ nvme_show_status(ret);
+ nvme_free_tree(r);
return ret;
}
@@ -8221,6 +9093,7 @@ static int wdc_capabilities(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
const char *desc = "Send a capabilities command.";
+ nvme_root_t r;
uint64_t capabilities = 0;
int fd;
@@ -8234,8 +9107,9 @@ static int wdc_capabilities(int argc, char **argv,
return fd;
/* get capabilities */
- wdc_check_device(fd);
- capabilities = wdc_get_drive_capabilities(fd);
+ r = nvme_scan(NULL);
+ wdc_check_device(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
/* print command and supported status */
printf("WDC Plugin Capabilities for NVME device:%s\n", devicename);
@@ -8298,29 +9172,37 @@ static int wdc_capabilities(int argc, char **argv,
capabilities & WDC_DRIVE_CAP_CLOUD_SSD_VERSION ? "Supported" : "Not Supported");
printf("vs-pcie-stats : %s\n",
capabilities & WDC_DRIVE_CAP_PCIE_STATS ? "Supported" : "Not Supported");
+ printf("get-error-recovery-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_OCP_C1_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("get-dev-capabilities-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_OCP_C4_LOG_PAGE ? "Supported" : "Not Supported");
+ printf("get-unsupported-reqs-log : %s\n",
+ capabilities & WDC_DRIVE_CAP_OCP_C5_LOG_PAGE ? "Supported" : "Not Supported");
printf("capabilities : Supported\n");
+ nvme_free_tree(r);
return 0;
}
static int wdc_cloud_ssd_plugin_version(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
- const char *desc = "Get Cloud SSD Plugin Version command.";
- uint64_t capabilities = 0;
- int fd;
+ const char *desc = "Get Cloud SSD Plugin Version command.";
+ nvme_root_t r;
+ uint64_t capabilities = 0;
+ int fd;
- OPT_ARGS(opts) =
- {
- OPT_END()
- };
+ OPT_ARGS(opts) = {
+ OPT_END()
+ };
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ fd = parse_and_open(argc, argv, desc, opts);
+ if (fd < 0)
+ return fd;
- /* get capabilities */
- wdc_check_device(fd);
- capabilities = wdc_get_drive_capabilities(fd);
+ /* get capabilities */
+ r = nvme_scan(NULL);
+ wdc_check_device(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, fd);
if ((capabilities & WDC_DRIVE_CAP_CLOUD_SSD_VERSION) == WDC_DRIVE_CAP_CLOUD_SSD_VERSION) {
/* print command and supported status */
@@ -8329,7 +9211,8 @@ static int wdc_cloud_ssd_plugin_version(int argc, char **argv,
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
}
- return 0;
+ nvme_free_tree(r);
+ return 0;
}
static int wdc_enc_get_log(int argc, char **argv, struct command *command,
@@ -8421,7 +9304,7 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
closed_fd:
close(fd);
ret:
- return nvme_status_to_errno(err, false);
+ return err;
}
static int wdc_enc_submit_move_data(int fd, char *cmd, int len, int xfer_size, FILE *out, int log_id, int cdw14, int cdw15)
@@ -8442,7 +9325,7 @@ static int wdc_enc_submit_move_data(int fd, char *cmd, int len, int xfer_size, F
cmd = (len) ? cmd : buf;
len = (len) ? len : 0x20;
- struct nvme_admin_cmd nvme_cmd = {
+ struct nvme_passthru_cmd nvme_cmd = {
.opcode = WDC_NVME_ADMIN_ENC_MGMT_SND,
.nsid = 0,
.addr = (__u64)(uintptr_t) cmd,
@@ -8475,14 +9358,14 @@ static int wdc_enc_submit_move_data(int fd, char *cmd, int len, int xfer_size, F
d);
#endif
nvme_cmd.result = 0;
- err = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd);
+ err = nvme_submit_admin_passthru(fd, &nvme_cmd, NULL);
if (err == NVME_SC_INTERNAL) {
fprintf(stderr, "%s: WARNING : WDC : No log ID:x%x available\n",
__func__, log_id);
}
else if (err != 0) {
- fprintf(stderr, "%s: ERROR : WDC : NVMe Snd Mgmt Status:%s(x%x)\n",
- __func__, nvme_status_to_string(err), err );
+ fprintf(stderr, "%s: ERROR : WDC : NVMe Snd Mgmt\n", __func__);
+ nvme_show_status(err);
} else {
if (nvme_cmd.result == WDC_RESULT_NOT_AVAILABLE)
{
@@ -8503,11 +9386,11 @@ static int wdc_enc_submit_move_data(int fd, char *cmd, int len, int xfer_size, F
nvme_cmd.cdw14 = cdw14;
nvme_cmd.cdw15 = cdw15;
nvme_cmd.result = 0; /* returned result !=0 indicates more data available */
- err = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd);
+ err = nvme_submit_admin_passthru(fd, &nvme_cmd, NULL);
if (err != 0) {
more = 0;
- fprintf(stderr, "%s: ERROR : WDC : NVMe Rcv Mgmt Status:%s(x%x)\n",
- __func__, nvme_status_to_string(err), err);
+ fprintf(stderr, "%s: ERROR : WDC : NVMe Rcv Mgmt ", __func__);
+ nvme_show_status(err);
} else {
more = nvme_cmd.result & WDC_RESULT_MORE_DATA;
response_size = nvme_cmd.result & ~WDC_RESULT_MORE_DATA;
@@ -8529,8 +9412,8 @@ static int wdc_enc_get_nic_log(int fd, __u8 log_id, __u32 xfer_size, __u32 data_
{
__u8 *dump_data;
__u32 curr_data_offset, curr_data_len;
- int i, ret;
- struct nvme_admin_cmd admin_cmd;
+ int i, ret = -1;
+ struct nvme_passthru_cmd admin_cmd;
__u32 dump_length = data_len;
__u32 numd;
__u16 numdu, numdl;
@@ -8541,7 +9424,7 @@ static int wdc_enc_get_nic_log(int fd, __u8 log_id, __u32 xfer_size, __u32 data_
return -1;
}
memset(dump_data, 0, sizeof (__u8) * dump_length);
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ memset(&admin_cmd, 0, sizeof (struct nvme_passthru_cmd));
curr_data_offset = 0;
curr_data_len = xfer_size;
i = 0;
@@ -8560,9 +9443,9 @@ static int wdc_enc_get_nic_log(int fd, __u8 log_id, __u32 xfer_size, __u32 data_
#ifdef WDC_NVME_CLI_DEBUG
fprintf(stderr, "nsid 0x%08x addr 0x%08llx, data_len 0x%08x, cdw10 0x%08x, cdw11 0x%08x, cdw12 0x%08x, cdw13 0x%08x, cdw14 0x%08x \n", admin_cmd.nsid, admin_cmd.addr, admin_cmd.data_len, admin_cmd.cdw10, admin_cmd.cdw11, admin_cmd.cdw12, admin_cmd.cdw13, admin_cmd.cdw14);
#endif
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
- if (ret !=0 ) {
- fprintf(stderr, "%s: ERROR : WDC : NVMe Status:%s(%x)\n",__func__, nvme_status_to_string(ret), ret);
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ if (ret != 0) {
+ nvme_show_status(ret);
fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
__func__, i, admin_cmd.data_len, curr_data_offset, (long unsigned int)admin_cmd.addr);
break;
diff --git a/plugins/wdc/wdc-nvme.h b/plugins/wdc/wdc-nvme.h
index e046007..da21692 100644
--- a/plugins/wdc/wdc-nvme.h
+++ b/plugins/wdc/wdc-nvme.h
@@ -4,7 +4,7 @@
#if !defined(WDC_NVME) || defined(CMD_HEADER_MULTI_READ)
#define WDC_NVME
-#define WDC_PLUGIN_VERSION "1.15.4"
+#define WDC_PLUGIN_VERSION "1.16.4"
#include "cmd.h"
PLUGIN(NAME("wdc", "Western Digital vendor specific extensions", WDC_PLUGIN_VERSION),
@@ -37,6 +37,9 @@ PLUGIN(NAME("wdc", "Western Digital vendor specific extensions", WDC_PLUGIN_VERS
ENTRY("cloud-SSD-plugin-version", "WDC Cloud SSD Plugin Version", wdc_cloud_ssd_plugin_version)
ENTRY("vs-pcie-stats", "WDC VS PCIE Statistics", wdc_vs_pcie_stats)
ENTRY("get-latency-monitor-log", "WDC Get Latency Monitor Log Page", wdc_get_latency_monitor_log)
+ ENTRY("get-error-recovery-log", "WDC Get Error Recovery Log Page", wdc_get_error_recovery_log)
+ ENTRY("get-dev-capabilities-log", "WDC Get Device Capabilities Log Page", wdc_get_dev_capabilities_log)
+ ENTRY("get-unsupported-reqs-log", "WDC Get Unsupported Requirements Log Page", wdc_get_unsupported_reqs_log)
)
);