summaryrefslogtreecommitdiffstats
path: root/plugins/wdc
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/wdc')
-rw-r--r--plugins/wdc/wdc-nvme.c924
-rw-r--r--plugins/wdc/wdc-nvme.h2
2 files changed, 379 insertions, 547 deletions
diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c
index 7525055..fa4157d 100644
--- a/plugins/wdc/wdc-nvme.c
+++ b/plugins/wdc/wdc-nvme.c
@@ -681,44 +681,6 @@ struct __packed wdc_nvme_ext_smart_log {
__u8 ext_smart_lpg[16]; /* 496 Log page GUID */
};
-enum {
- SCAO_PMUW = 0, /* Physical media units written */
- SCAO_PMUR = 16, /* Physical media units read */
- SCAO_BUNBR = 32, /* Bad user nand blocks raw */
- SCAO_BUNBN = 38, /* Bad user nand blocks normalized */
- SCAO_BSNBR = 40, /* Bad system nand blocks raw */
- SCAO_BSNBN = 46, /* Bad system nand blocks normalized */
- SCAO_XRC = 48, /* XOR recovery count */
- SCAO_UREC = 56, /* Uncorrectable read error count */
- SCAO_SEEC = 64, /* Soft ecc error count */
- SCAO_EECE = 72, /* End to end corrected errors */
- SCAO_EEDC = 76, /* End to end detected errors */
- SCAO_SDPU = 80, /* System data percent used */
- SCAO_RFSC = 81, /* Refresh counts */
- SCAO_MXUDEC = 88, /* Max User data erase counts */
- SCAO_MNUDEC = 92, /* Min User data erase counts */
- SCAO_NTTE = 96, /* Number of Thermal throttling events */
- SCAO_CTS = 97, /* Current throttling status */
- SCAO_EVF = 98, /* Errata Version Field */
- SCAO_PVF = 99, /* Point Version Field */
- SCAO_MIVF = 101, /* Minor Version Field */
- SCAO_MAVF = 103, /* Major Version Field */
- SCAO_PCEC = 104, /* PCIe correctable error count */
- SCAO_ICS = 112, /* Incomplete shutdowns */
- SCAO_PFB = 120, /* Percent free blocks */
- SCAO_CPH = 128, /* Capacitor health */
- SCAO_NEV = 130, /* NVMe Errata Version */
- SCAO_UIO = 136, /* Unaligned I/O */
- SCAO_SVN = 144, /* Security Version Number */
- SCAO_NUSE = 152, /* NUSE - Namespace utilization */
- SCAO_PSC = 160, /* PLP start count */
- SCAO_EEST = 176, /* Endurance estimate */
- SCAO_PLRC = 192, /* PCIe Link Retraining Count */
- SCAO_PSCC = 200, /* Power State Change Count */
- SCAO_LPV = 494, /* Log page version */
- SCAO_LPG = 496, /* Log page GUID */
-};
-
struct ocp_bad_nand_block_count {
__u64 raw : 48;
__u16 normalized : 16;
@@ -766,8 +728,9 @@ struct ocp_cloud_smart_log {
__u8 percent_free_blocks;
__u8 rsvd121[7];
__u16 capacitor_health;
- __u8 nvme_errata_ver;
- __u8 rsvd131[5];
+ __u8 nvme_base_errata_ver;
+ __u8 nvme_cmd_set_errata_ver;
+ __u8 rsvd132[4];
__u64 unaligned_io;
__u64 security_version_number;
__u64 total_nuse;
@@ -775,7 +738,8 @@ struct ocp_cloud_smart_log {
__u8 endurance_estimate[16];
__u64 pcie_link_retraining_cnt;
__u64 power_state_change_cnt;
- __u8 rsvd208[286];
+ char lowest_permitted_fw_rev[8];
+ __u8 rsvd216[278];
__u16 log_page_version;
__u8 log_page_guid[16];
};
@@ -1004,6 +968,13 @@ static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len, in
static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev, __u8 log_id,
void **cbs_data);
static __u32 wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev);
+static int wdc_print_c0_cloud_attr_log(void *data,
+ int fmt,
+ struct nvme_dev *dev);
+static int wdc_print_c0_eol_log(void *data, int fmt);
+static void wdc_show_cloud_smart_log_normal(struct ocp_cloud_smart_log *log,
+ struct nvme_dev *dev);
+static void wdc_show_cloud_smart_log_json(struct ocp_cloud_smart_log *log);
/* Drive log data size */
struct wdc_log_size {
@@ -1148,14 +1119,14 @@ struct __packed wdc_bd_ca_log_format {
__u8 raw_value[8];
};
-#define LATENCY_LOG_BUCKET_READ 3
-#define LATENCY_LOG_BUCKET_WRITE 2
-#define LATENCY_LOG_BUCKET_TRIM 1
-#define LATENCY_LOG_BUCKET_RESERVED 0
+#define WDC_LATENCY_LOG_BUCKET_READ 3
+#define WDC_LATENCY_LOG_BUCKET_WRITE 2
+#define WDC_LATENCY_LOG_BUCKET_TRIM 1
+#define WDC_LATENCY_LOG_BUCKET_RESERVED 0
-#define LATENCY_LOG_MEASURED_LAT_READ 2
-#define LATENCY_LOG_MEASURED_LAT_WRITE 1
-#define LATENCY_LOG_MEASURED_LAT_TRIM 0
+#define WDC_LATENCY_LOG_MEASURED_LAT_READ 2
+#define WDC_LATENCY_LOG_MEASURED_LAT_WRITE 1
+#define WDC_LATENCY_LOG_MEASURED_LAT_TRIM 0
struct __packed wdc_ssd_latency_monitor_log {
__u8 feature_status; /* 0x00 */
@@ -1180,8 +1151,9 @@ struct __packed wdc_ssd_latency_monitor_log {
__le64 static_latency_timestamp[4][3]; /* 0x130 - 0x18F */
__le16 static_measured_latency[4][3]; /* 0x190 - 0x1A7 */
__le16 static_latency_stamp_units; /* 0x1A8 */
- __u8 rsvd4[0x16]; /* 0x1AA */
+ __u8 rsvd4[10]; /* 0x1AA */
+ __u8 debug_telemetry_log_size[12]; /* 0x1B4 */
__le16 debug_log_trigger_enable; /* 0x1C0 */
__le16 debug_log_measured_latency; /* 0x1C2 */
__le64 debug_log_latency_stamp; /* 0x1C4 */
@@ -1249,25 +1221,29 @@ struct __packed wdc_ssd_d0_smart_log {
#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_VERSION1 0001
-#define WDC_ERROR_REC_LOG_VERSION2 0002
struct __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 V2 */
- __u8 dev_recovery_action2; /* 029 - Device Recovery Action 2 V2 */
- __u8 dev_recovery_action2_to; /* 030 - Device Recovery Action 2 Timeout V2 */
- __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 */
+ __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 V2 */
+ __u8 dev_recovery_action2; /* 029 - Device Recovery Action 2 V2 */
+ __u8 dev_recovery_action2_to; /* 030 - Device Recovery Action 2 Timeout V2 */
+ __u8 panic_count; /* 031 - Number of panics encountered */
+ __le64 prev_panic_ids[4]; /* 032 - 063 Previous Panic ID's */
+ __u8 rsvd2[430]; /* 064 - 493 Reserved Bytes */
+ /* 430 reserved bytes aligns with the rest */
+ /* of the data structure. The size of 463 */
+ /* bytes mentioned in the OCP spec */
+ /* (version 2.5) would not fit here. */
+ __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,
@@ -3711,7 +3687,7 @@ free_buf:
static int dump_internal_logs(struct nvme_dev *dev, char *dir_name, int verbose)
{
- char file_path[128];
+ char file_path[PATH_MAX];
void *telemetry_log;
const size_t bs = 512;
struct nvme_telemetry_log *hdr;
@@ -4681,20 +4657,30 @@ static int wdc_print_latency_monitor_log_normal(struct nvme_dev *dev,
printf(" Active Latency Minimum Window %d ms\n", 100*log_data->active_latency_min_window);
printf(" Active Latency Stamp Units %d\n", le16_to_cpu(log_data->active_latency_stamp_units));
printf(" Static Latency Stamp Units %d\n", le16_to_cpu(log_data->static_latency_stamp_units));
- printf(" Debug Log Trigger Enable %d\n", le16_to_cpu(log_data->debug_log_trigger_enable));
+ if (le16_to_cpu(log_data->log_page_version) >= 4)
+ printf(" Debug Telemetry Log Size %"PRIu64"\n",
+ le64_to_cpu(*(uint64_t *)log_data->debug_telemetry_log_size));
+ printf(" Debug Log Trigger Enable %d\n",
+ le16_to_cpu(log_data->debug_log_trigger_enable));
+ printf(" Log Page Version %d\n",
+ le16_to_cpu(log_data->log_page_version));
+ printf(" Log page GUID 0x");
+ for (j = 0; j < WDC_C3_GUID_LENGTH; j++)
+ printf("%x", log_data->log_page_guid[j]);
+ printf("\n");
printf(" Read Write Deallocate/Trim\n");
for (i = 0; i <= 3; i++)
printf(" Active Bucket Counter: Bucket %d %27d %27d %27d\n",
- i, le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_READ]),
- le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_WRITE]),
- le32_to_cpu(log_data->active_bucket_counter[i][LATENCY_LOG_BUCKET_TRIM]));
+ i, le32_to_cpu(log_data->active_bucket_counter[i][WDC_LATENCY_LOG_BUCKET_READ]),
+ le32_to_cpu(log_data->active_bucket_counter[i][WDC_LATENCY_LOG_BUCKET_WRITE]),
+ le32_to_cpu(log_data->active_bucket_counter[i][WDC_LATENCY_LOG_BUCKET_TRIM]));
for (i = 3; i >= 0; i--)
printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
- 3-i, le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_READ]),
- le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_WRITE]),
- le16_to_cpu(log_data->active_measured_latency[i][LATENCY_LOG_MEASURED_LAT_TRIM]));
+ 3-i, le16_to_cpu(log_data->active_measured_latency[i][WDC_LATENCY_LOG_MEASURED_LAT_READ]),
+ le16_to_cpu(log_data->active_measured_latency[i][WDC_LATENCY_LOG_MEASURED_LAT_WRITE]),
+ le16_to_cpu(log_data->active_measured_latency[i][WDC_LATENCY_LOG_MEASURED_LAT_TRIM]));
for (i = 3; i >= 0; i--) {
printf(" Active Latency Time Stamp: Bucket %d ", 3-i);
@@ -4711,15 +4697,15 @@ static int wdc_print_latency_monitor_log_normal(struct nvme_dev *dev,
for (i = 0; i <= 3; i++)
printf(" Static Bucket Counter: Bucket %d %27d %27d %27d\n",
- i, le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_READ]),
- le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_WRITE]),
- le32_to_cpu(log_data->static_bucket_counter[i][LATENCY_LOG_BUCKET_TRIM]));
+ i, le32_to_cpu(log_data->static_bucket_counter[i][WDC_LATENCY_LOG_BUCKET_READ]),
+ le32_to_cpu(log_data->static_bucket_counter[i][WDC_LATENCY_LOG_BUCKET_WRITE]),
+ le32_to_cpu(log_data->static_bucket_counter[i][WDC_LATENCY_LOG_BUCKET_TRIM]));
for (i = 3; i >= 0; i--)
printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms\n",
- 3-i, le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_READ]),
- le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_WRITE]),
- le16_to_cpu(log_data->static_measured_latency[i][LATENCY_LOG_MEASURED_LAT_TRIM]));
+ 3-i, le16_to_cpu(log_data->static_measured_latency[i][WDC_LATENCY_LOG_MEASURED_LAT_READ]),
+ le16_to_cpu(log_data->static_measured_latency[i][WDC_LATENCY_LOG_MEASURED_LAT_WRITE]),
+ le16_to_cpu(log_data->static_measured_latency[i][WDC_LATENCY_LOG_MEASURED_LAT_TRIM]));
for (i = 3; i >= 0; i--) {
printf(" Static Latency Time Stamp: Bucket %d ", 3-i);
@@ -4755,7 +4741,22 @@ static void wdc_print_latency_monitor_log_json(struct wdc_ssd_latency_monitor_lo
json_object_add_value_int(root, "Active Lantency Minimum Window", 100*log_data->active_latency_min_window);
json_object_add_value_int(root, "Active Latency Stamp Units", le16_to_cpu(log_data->active_latency_stamp_units));
json_object_add_value_int(root, "Static Latency Stamp Units", le16_to_cpu(log_data->static_latency_stamp_units));
- json_object_add_value_int(root, "Debug Log Trigger Enable", le16_to_cpu(log_data->debug_log_trigger_enable));
+ if (le16_to_cpu(log_data->log_page_version) >= 4) {
+ json_object_add_value_int(root, "Debug Telemetry Log Size",
+ le64_to_cpu(*(uint64_t *)log_data->debug_telemetry_log_size));
+ }
+ json_object_add_value_int(root, "Debug Log Trigger Enable",
+ le16_to_cpu(log_data->debug_log_trigger_enable));
+ 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);
for (i = 0; i <= 3; i++) {
for (j = 2; j >= 0; j--) {
@@ -4814,13 +4815,20 @@ static void wdc_print_error_rec_log_normal(struct wdc_ocp_c1_error_recovery_log
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));
- if (le16_to_cpu(log_data->log_page_version) == WDC_ERROR_REC_LOG_VERSION2) {
+ if (le16_to_cpu(log_data->log_page_version) >= 2) {
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");
+ if (le16_to_cpu(log_data->log_page_version) >= 3) {
+ printf(" Panic Count : 0x%x\n", log_data->panic_count);
+ for (j = 0; j < 4; j++)
+ printf(" Previous Panic ID N-%d : 0x%"PRIx64"\n",
+ j+1, le64_to_cpu(log_data->prev_panic_ids[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_C1_GUID_LENGTH; j++)
printf("%x", log_data->log_page_guid[j]);
printf("\n");
@@ -4828,6 +4836,8 @@ static void wdc_print_error_rec_log_normal(struct wdc_ocp_c1_error_recovery_log
static void wdc_print_error_rec_log_json(struct wdc_ocp_c1_error_recovery_log *log_data)
{
+ int j;
+ char buf[128];
struct json_object *root = json_create_object();
json_object_add_value_int(root, "Panic Reset Wait Time", le16_to_cpu(log_data->panic_reset_wait_time));
@@ -4838,12 +4848,21 @@ static void wdc_print_error_rec_log_json(struct wdc_ocp_c1_error_recovery_log *l
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));
- if (le16_to_cpu(log_data->log_page_version) == WDC_ERROR_REC_LOG_VERSION2) {
+ if (le16_to_cpu(log_data->log_page_version) >= 2) {
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));
+ if (le16_to_cpu(log_data->log_page_version) >= 3) {
+ json_object_add_value_int(root, "Panic Count", log_data->panic_count);
+ for (j = 0; j < 4; j++) {
+ sprintf(buf, "Previous Panic ID N-%d", j+1);
+ json_object_add_value_int(root, buf,
+ le64_to_cpu(log_data->prev_panic_ids[j]));
+ }
+ }
+ json_object_add_value_int(root, "Log Page Version",
+ le16_to_cpu(log_data->log_page_version));
char guid[40];
@@ -5875,6 +5894,141 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries,
json_free_object(root);
}
+static int nvme_get_print_ocp_cloud_smart_log(struct nvme_dev *dev,
+ int uuid_index,
+ __u32 namespace_id,
+ int fmt)
+{
+ struct ocp_cloud_smart_log *log_ptr = NULL;
+ int ret, i;
+ __u32 length = WDC_NVME_SMART_CLOUD_ATTR_LEN;
+ int fd = dev_fd(dev);
+
+ log_ptr = (struct ocp_cloud_smart_log *)malloc(sizeof(__u8) * length);
+ if (!log_ptr) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (namespace_id == NVME_NSID_ALL) {
+ ret = nvme_get_nsid(fd, &namespace_id);
+ if (ret < 0)
+ namespace_id = NVME_NSID_ALL;
+ }
+
+ /* Get the 0xC0 log data */
+ struct nvme_get_log_args args = {
+ .args_size = sizeof(args),
+ .fd = fd,
+ .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
+ .nsid = namespace_id,
+ .lpo = 0,
+ .lsp = NVME_LOG_LSP_NONE,
+ .lsi = 0,
+ .rae = false,
+ .uuidx = uuid_index,
+ .csi = NVME_CSI_NVM,
+ .ot = false,
+ .len = length,
+ .log = log_ptr,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args);
+
+ if (fmt == JSON)
+ nvme_show_status(ret);
+
+ if (!ret) {
+ /* Verify GUID matches */
+ for (i = 0; i < 16; i++) {
+ if (scao_guid[i] != log_ptr->log_page_guid[i]) {
+ fprintf(stderr, "ERROR: WDC: Unknown GUID in C0 Log Page data\n");
+ int j;
+
+ fprintf(stderr, "ERROR: WDC: Expected GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", scao_guid[j]);
+ fprintf(stderr, "\nERROR: WDC: Actual GUID: 0x");
+ for (j = 0; j < 16; j++)
+ fprintf(stderr, "%x", log_ptr->log_page_guid[j]);
+ fprintf(stderr, "\n");
+
+ ret = -1;
+ break;
+ }
+ }
+
+ if (!ret)
+ /* parse the data */
+ wdc_print_c0_cloud_attr_log(log_ptr, fmt, dev);
+ } else {
+ fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n");
+ ret = -1;
+ }
+
+ free(log_ptr);
+ return ret;
+}
+
+static int nvme_get_print_c0_eol_log(struct nvme_dev *dev,
+ int uuid_index,
+ __u32 namespace_id,
+ int fmt)
+{
+ void *log_ptr = NULL;
+ int ret;
+ __u32 length = WDC_NVME_EOL_STATUS_LOG_LEN;
+ int fd = dev_fd(dev);
+
+ log_ptr = (void *)malloc(sizeof(__u8) * length);
+ if (!log_ptr) {
+ fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (namespace_id == NVME_NSID_ALL) {
+ ret = nvme_get_nsid(fd, &namespace_id);
+ if (ret < 0)
+ namespace_id = NVME_NSID_ALL;
+ }
+
+ /* Get the 0xC0 log 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 = length,
+ .log = log_ptr,
+ .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+ .result = NULL,
+ };
+ ret = nvme_get_log(&args);
+
+ if (fmt == JSON)
+ nvme_show_status(ret);
+
+ if (!ret) {
+ /* parse the data */
+ wdc_print_c0_eol_log(log_ptr, fmt);
+ } else {
+ fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data ");
+ fprintf(stderr, "with uuid index %d\n", uuid_index);
+ ret = -1;
+ }
+
+ free(log_ptr);
+ return ret;
+}
+
static int nvme_get_ext_smart_cloud_log(int fd, __u8 **data, int uuid_index, __u32 namespace_id)
{
int ret, i;
@@ -6556,177 +6710,6 @@ static void wdc_print_ext_smart_cloud_log_json(void *data, int mask)
json_free_object(root);
}
-static void wdc_print_smart_cloud_attr_C0_normal(void *data)
-{
- __u8 *log_data = (__u8 *)data;
- uint16_t smart_log_ver = 0;
-
- printf(" SMART Cloud Attributes :-\n");
-
- printf(" Physical media units written : %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PMUW])));
- printf(" Physical media units read : %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PMUR])));
- printf(" Bad user nand blocks Raw : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
- printf(" Bad user nand blocks Normalized : %d\n",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
- printf(" Bad system nand blocks Raw : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
- printf(" Bad system nand blocks Normalized : %d\n",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
- printf(" XOR recovery count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
- printf(" Uncorrectable read error count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
- printf(" Soft ecc error count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
- printf(" End to end corrected errors : %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
- 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",
- (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
- printf(" Max User data erase counts : %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
- printf(" Min User data erase counts : %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
- printf(" Number of Thermal throttling events : %d\n", (__u8)log_data[SCAO_NTTE]);
- printf(" Current throttling status : 0x%x\n", (__u8)log_data[SCAO_CTS]);
- printf(" PCIe correctable error count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
- printf(" Incomplete shutdowns : %"PRIu32"\n",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
- printf(" Percent free blocks : %d\n", (__u8)log_data[SCAO_PFB]);
- printf(" Capacitor health : %"PRIu16"\n",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
- printf(" Unaligned I/O : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
- printf(" Security Version Number : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
- printf(" NUSE Namespace utilization : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
- printf(" PLP start count : %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC])));
- printf(" Endurance estimate : %s\n",
- uint128_t_to_string(le128_to_cpu(&log_data[SCAO_EEST])));
- smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
- printf(" Log page version : %"PRIu16"\n", smart_log_ver);
- printf(" Log page GUID : 0x");
- printf("%"PRIx64"%"PRIx64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
- if (smart_log_ver > 2) {
- printf(" Errata Version Field : %d\n",
- (__u8)log_data[SCAO_EVF]);
- printf(" Point Version Field : %"PRIu16"\n",
- (uint16_t)log_data[SCAO_PVF]);
- printf(" Minor Version Field : %"PRIu16"\n",
- (uint16_t)log_data[SCAO_MIVF]);
- printf(" Major Version Field : %d\n",
- (__u8)log_data[SCAO_MAVF]);
- printf(" NVMe Errata Version : %d\n",
- (__u8)log_data[SCAO_NEV]);
- printf(" PCIe Link Retraining Count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
- }
- if (smart_log_ver > 3) {
- printf(" Power State Change Count : %"PRIu64"\n",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
- }
- printf("\n");
-}
-
-static void wdc_print_smart_cloud_attr_C0_json(void *data)
-{
- __u8 *log_data = (__u8 *)data;
- struct json_object *root = json_create_object();
- uint16_t smart_log_ver = 0;
-
- json_object_add_value_uint128(root, "Physical media units written",
- le128_to_cpu(&log_data[SCAO_PMUW]));
- json_object_add_value_uint128(root, "Physical media units read",
- le128_to_cpu(&log_data[SCAO_PMUR]));
- json_object_add_value_uint64(root, "Bad user nand blocks - Raw",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
- json_object_add_value_uint(root, "Bad user nand blocks - Normalized",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BUNBN]));
- json_object_add_value_uint64(root, "Bad system nand blocks - Raw",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BSNBR] & 0x0000FFFFFFFFFFFF));
- json_object_add_value_uint(root, "Bad system nand blocks - Normalized",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_BSNBN]));
- json_object_add_value_uint64(root, "XOR recovery count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_XRC]));
- json_object_add_value_uint64(root, "Uncorrectable read error count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UREC]));
- json_object_add_value_uint64(root, "Soft ecc error count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SEEC]));
- json_object_add_value_uint(root, "End to end corrected errors",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EECE]));
- json_object_add_value_uint(root, "End to end detected errors",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_EEDC]));
- json_object_add_value_uint(root, "System data percent used",
- (__u8)log_data[SCAO_SDPU]);
- json_object_add_value_uint64(root, "Refresh counts",
- (uint64_t)(le64_to_cpu(*(uint64_t *)&log_data[SCAO_RFSC]) & 0x00FFFFFFFFFFFFFF));
- json_object_add_value_uint(root, "Max User data erase counts",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MXUDEC]));
- json_object_add_value_uint(root, "Min User data erase counts",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_MNUDEC]));
- json_object_add_value_uint(root, "Number of Thermal throttling events",
- (__u8)log_data[SCAO_NTTE]);
- json_object_add_value_uint(root, "Current throttling status",
- (__u8)log_data[SCAO_CTS]);
- json_object_add_value_uint64(root, "PCIe correctable error count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PCEC]));
- json_object_add_value_uint(root, "Incomplete shutdowns",
- (uint32_t)le32_to_cpu(*(uint32_t *)&log_data[SCAO_ICS]));
- json_object_add_value_uint(root, "Percent free blocks",
- (__u8)log_data[SCAO_PFB]);
- json_object_add_value_uint(root, "Capacitor health",
- (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_CPH]));
- json_object_add_value_uint64(root, "Unaligned I/O",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_UIO]));
- json_object_add_value_uint64(root, "Security Version Number",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
- json_object_add_value_uint64(root, "NUSE - Namespace utilization",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
- json_object_add_value_uint128(root, "PLP start count",
- le128_to_cpu(&log_data[SCAO_PSC]));
- json_object_add_value_uint128(root, "Endurance estimate",
- le128_to_cpu(&log_data[SCAO_EEST]));
- smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
- json_object_add_value_uint(root, "Log page version", smart_log_ver);
- char guid[40];
-
- memset((void *)guid, 0, 40);
- sprintf((char *)guid, "0x%"PRIx64"%"PRIx64"",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
- json_object_add_value_string(root, "Log page GUID", guid);
- if (smart_log_ver > 2) {
- json_object_add_value_uint(root, "Errata Version Field",
- (__u8)log_data[SCAO_EVF]);
- json_object_add_value_uint(root, "Point Version Field",
- (uint16_t)log_data[SCAO_PVF]);
- json_object_add_value_uint(root, "Minor Version Field",
- (uint16_t)log_data[SCAO_MIVF]);
- json_object_add_value_uint(root, "Major Version Field",
- (__u8)log_data[SCAO_MAVF]);
- json_object_add_value_uint(root, "NVMe Errata Version",
- (__u8)log_data[SCAO_NEV]);
- json_object_add_value_uint64(root, "PCIe Link Retraining Count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PLRC]));
- }
- if (smart_log_ver > 3) {
- json_object_add_value_uint64(root, "Power State Change Count",
- (uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PSCC]));
- }
- json_print_object(root, NULL);
- printf("\n");
- json_free_object(root);
-}
static void wdc_print_eol_c0_normal(void *data)
{
@@ -6794,18 +6777,26 @@ static int wdc_print_ext_smart_cloud_log(void *data, int fmt)
return 0;
}
-static int wdc_print_c0_cloud_attr_log(void *data, int fmt)
+static int wdc_print_c0_cloud_attr_log(void *data,
+ int fmt,
+ struct nvme_dev *dev)
{
+ struct ocp_cloud_smart_log *log = (struct ocp_cloud_smart_log *)data;
+
if (!data) {
fprintf(stderr, "ERROR: WDC: Invalid buffer to read 0xC0 log\n");
return -1;
}
+
switch (fmt) {
+ case BINARY:
+ d_raw((unsigned char *)log, sizeof(struct ocp_cloud_smart_log));
+ break;
case NORMAL:
- wdc_print_smart_cloud_attr_C0_normal(data);
+ wdc_show_cloud_smart_log_normal(log, dev);
break;
case JSON:
- wdc_print_smart_cloud_attr_C0_json(data);
+ wdc_show_cloud_smart_log_json(log);
break;
}
return 0;
@@ -6818,6 +6809,9 @@ static int wdc_print_c0_eol_log(void *data, int fmt)
return -1;
}
switch (fmt) {
+ case BINARY:
+ d_raw((unsigned char *)data, WDC_NVME_EOL_STATUS_LOG_LEN);
+ break;
case NORMAL:
wdc_print_eol_c0_normal(data);
break;
@@ -6832,113 +6826,17 @@ static int wdc_get_c0_log_page_sn_customer_id_0x100X(struct nvme_dev *dev, int u
char *format, __u32 namespace_id, int fmt)
{
int ret;
- __u8 *data;
- int i;
if (!uuid_index) {
- data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN);
- if (!data) {
- fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
- return -1;
- }
-
- if (namespace_id == NVME_NSID_ALL) {
- ret = nvme_get_nsid(dev_fd(dev), &namespace_id);
- if (ret < 0)
- namespace_id = NVME_NSID_ALL;
- }
-
- /* Get the 0xC0 log data */
- struct nvme_get_log_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
- .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"))
- nvme_show_status(ret);
-
- if (!ret) {
- /* Verify GUID matches */
- for (i = 0; i < 16; i++) {
- if (scao_guid[i] != data[SCAO_LPG + i]) {
- fprintf(stderr, "ERROR: WDC: Unknown GUID in C0 Log Page data\n");
- int j;
-
- fprintf(stderr, "ERROR: WDC: Expected GUID: 0x");
- for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", scao_guid[j]);
- fprintf(stderr, "\nERROR: WDC: Actual GUID: 0x");
- for (j = 0; j < 16; j++)
- fprintf(stderr, "%x", data[SCAO_LPG + j]);
- fprintf(stderr, "\n");
-
- ret = -1;
- break;
- }
- }
-
- if (!ret)
- /* parse the data */
- wdc_print_c0_cloud_attr_log(data, fmt);
- } else {
- fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n");
- ret = -1;
- }
-
- free(data);
+ ret = nvme_get_print_ocp_cloud_smart_log(dev,
+ uuid_index,
+ namespace_id,
+ fmt);
} else if (uuid_index == 1) {
- data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_EOL_STATUS_LOG_LEN);
- if (!data) {
- fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
- return -1;
- }
-
- /* Get the 0xC0 log data */
- struct nvme_get_log_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .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"))
- nvme_show_status(ret);
-
- if (!ret) {
- /* parse the data */
- wdc_print_c0_eol_log(data, fmt);
- } else {
- fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n");
- ret = -1;
- }
-
- free(data);
+ ret = nvme_get_print_c0_eol_log(dev,
+ uuid_index,
+ namespace_id,
+ fmt);
} else {
fprintf(stderr, "ERROR: WDC: Unknown uuid index\n");
ret = -1;
@@ -6952,7 +6850,6 @@ static int wdc_get_c0_log_page_sn(nvme_root_t r, struct nvme_dev *dev, int uuid_
{
int ret = 0;
__u32 cust_id;
- __u8 *data;
cust_id = wdc_get_fw_cust_id(r, dev);
if (cust_id == WDC_INVALID_CUSTOMER_ID) {
@@ -6965,30 +6862,10 @@ static int wdc_get_c0_log_page_sn(nvme_root_t r, struct nvme_dev *dev, int uuid_
ret = wdc_get_c0_log_page_sn_customer_id_0x100X(dev, uuid_index, format,
namespace_id, fmt);
} else {
- data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_EOL_STATUS_LOG_LEN);
- if (!data) {
- fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
- return -1;
- }
-
- /* Get the 0xC0 log data */
- ret = nvme_get_log_simple(dev_fd(dev),
- WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
- WDC_NVME_EOL_STATUS_LOG_LEN,
- data);
-
- if (strcmp(format, "json"))
- nvme_show_status(ret);
-
- if (!ret) {
- /* parse the data */
- wdc_print_c0_eol_log(data, fmt);
- } else {
- fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n");
- ret = -1;
- }
-
- free(data);
+ ret = nvme_get_print_c0_eol_log(dev,
+ 0,
+ namespace_id,
+ fmt);
}
return ret;
@@ -6998,11 +6875,9 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
__u32 namespace_id)
{
uint32_t device_id, read_vendor_id;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
int ret;
__u8 *data;
- __u8 log_id;
- __u32 length;
if (!wdc_check_device(r, dev))
return -1;
@@ -7035,86 +6910,23 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
case WDC_NVME_SN650_DEV_ID_4:
case WDC_NVME_SN655_DEV_ID:
if (uuid_index == 0) {
- log_id = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID;
- length = WDC_NVME_SMART_CLOUD_ATTR_LEN;
- } else {
- log_id = WDC_NVME_GET_EOL_STATUS_LOG_OPCODE;
- length = WDC_NVME_EOL_STATUS_LOG_LEN;
- }
-
- data = (__u8 *)malloc(sizeof(__u8) * length);
- if (!data) {
- fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
- return -1;
- }
-
- if (namespace_id == NVME_NSID_ALL) {
- ret = nvme_get_nsid(dev_fd(dev), &namespace_id);
- if (ret < 0)
- namespace_id = NVME_NSID_ALL;
- }
-
- /* Get the 0xC0 log data */
- struct nvme_get_log_args args = {
- .args_size = sizeof(args),
- .fd = dev_fd(dev),
- .lid = log_id,
- .nsid = namespace_id,
- .lpo = 0,
- .lsp = NVME_LOG_LSP_NONE,
- .lsi = 0,
- .rae = false,
- .uuidx = uuid_index,
- .csi = NVME_CSI_NVM,
- .ot = false,
- .len = length,
- .log = data,
- .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
- .result = NULL,
- };
- ret = nvme_get_log(&args);
-
- if (strcmp(format, "json"))
- nvme_show_status(ret);
-
- if (!ret) {
- /* parse the data */
- if (uuid_index == 0)
- wdc_print_c0_cloud_attr_log(data, fmt);
- else
- wdc_print_c0_eol_log(data, fmt);
+ ret = nvme_get_print_ocp_cloud_smart_log(dev,
+ uuid_index,
+ namespace_id,
+ fmt);
} else {
- fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data ");
- fprintf(stderr, "with uuid index %d\n", uuid_index);
- ret = -1;
+ ret = nvme_get_print_c0_eol_log(dev,
+ uuid_index,
+ namespace_id,
+ fmt);
}
- free(data);
break;
case WDC_NVME_ZN350_DEV_ID:
case WDC_NVME_ZN350_DEV_ID_1:
- data = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN);
- if (!data) {
- fprintf(stderr, "ERROR: WDC: malloc: %s\n", strerror(errno));
- return -1;
- }
-
- /* Get the 0xC0 log data */
- ret = nvme_get_log_simple(dev_fd(dev),
- WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
- WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
-
- if (strcmp(format, "json"))
- nvme_show_status(ret);
-
- if (!ret) {
- /* parse the data */
- wdc_print_c0_cloud_attr_log(data, fmt);
- } else {
- fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n");
- ret = -1;
- }
-
- free(data);
+ ret = nvme_get_print_ocp_cloud_smart_log(dev,
+ 0,
+ NVME_NSID_ALL,
+ fmt);
break;
case WDC_NVME_SN820CL_DEV_ID:
/* Get the 0xC0 Extended Smart Cloud Attribute log data */
@@ -7296,7 +7108,7 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format
{
uint32_t read_device_id, read_vendor_id;
struct wdc_ssd_ca_perf_stats *perf;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
__u32 cust_id;
__u8 *data;
int ret;
@@ -7427,7 +7239,7 @@ static int wdc_get_c1_log_page(nvme_root_t r, struct nvme_dev *dev,
struct wdc_log_page_subpage_header *sph;
struct wdc_ssd_perf_stats *perf;
struct wdc_log_page_header *l;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
int total_subpages;
int skip_cnt = 4;
__u8 *data;
@@ -7484,7 +7296,7 @@ static int wdc_get_c1_log_page(nvme_root_t r, struct nvme_dev *dev,
static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
struct wdc_ssd_latency_monitor_log *log_data;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
__u8 *data;
int ret;
int i;
@@ -7556,7 +7368,7 @@ out:
static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
struct wdc_ocp_c1_error_recovery_log *log_data;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
__u8 *data;
int ret;
int i;
@@ -7587,9 +7399,10 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo
log_data = (struct wdc_ocp_c1_error_recovery_log *)data;
/* check log page version */
- if ((log_data->log_page_version != WDC_ERROR_REC_LOG_VERSION1) &&
- (log_data->log_page_version != WDC_ERROR_REC_LOG_VERSION2)) {
- fprintf(stderr, "ERROR: WDC: invalid error recovery log version - %d\n", log_data->log_page_version);
+ if ((log_data->log_page_version < 1) ||
+ (log_data->log_page_version > 3)) {
+ fprintf(stderr, "ERROR: WDC: invalid error recovery log version - %d\n",
+ log_data->log_page_version);
ret = -1;
goto out;
}
@@ -7627,7 +7440,7 @@ out:
static int wdc_get_ocp_c4_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
struct wdc_ocp_C4_dev_cap_log *log_data;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
__u8 *data;
int ret;
int i;
@@ -7697,7 +7510,7 @@ out:
static int wdc_get_ocp_c5_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
struct wdc_ocp_C5_unsupported_reqs *log_data;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
int ret;
__u8 *data;
int i;
@@ -7767,7 +7580,7 @@ out:
static int wdc_get_d0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
struct wdc_ssd_d0_smart_log *perf;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
int ret = 0;
__u8 *data;
@@ -7852,7 +7665,7 @@ static const char *stringify_cloud_smart_log_thermal_status(__u8 status)
return "unrecognized";
}
-static void show_cloud_smart_log_json(struct ocp_cloud_smart_log *log)
+static void wdc_show_cloud_smart_log_json(struct ocp_cloud_smart_log *log)
{
struct json_object *root;
struct json_object *bad_user_nand_blocks;
@@ -7862,6 +7675,8 @@ static void show_cloud_smart_log_json(struct ocp_cloud_smart_log *log)
struct json_object *thermal_status;
struct json_object *dssd_specific_ver;
char buf[2 * sizeof(log->log_page_guid) + 3];
+ char lowest_fr[sizeof(log->lowest_permitted_fw_rev) + 1];
+ uint16_t smart_log_ver = (uint16_t)le16_to_cpu(log->log_page_version);
bad_user_nand_blocks = json_create_object();
json_object_add_value_uint(bad_user_nand_blocks, "normalized",
@@ -7927,7 +7742,8 @@ static void show_cloud_smart_log_json(struct ocp_cloud_smart_log *log)
json_object_add_value_object(root, "user_data_erase_counts",
user_data_erase_counts);
json_object_add_value_object(root, "thermal_status", thermal_status);
- json_object_add_value_object(root, "dssd_specific_ver",
+ if (smart_log_ver >= 3)
+ json_object_add_value_object(root, "dssd_specific_ver",
dssd_specific_ver);
json_object_add_value_uint(root, "pcie_correctable_error_count",
le64_to_cpu(log->pcie_correctable_error_count));
@@ -7937,8 +7753,18 @@ static void show_cloud_smart_log_json(struct ocp_cloud_smart_log *log)
log->percent_free_blocks);
json_object_add_value_uint(root, "capacitor_health",
le16_to_cpu(log->capacitor_health));
- sprintf(buf, "%c", log->nvme_errata_ver);
- json_object_add_value_string(root, "nvme_errata_version", buf);
+ if (smart_log_ver >= 3) {
+ if (smart_log_ver >= 4) {
+ sprintf(buf, "%c", log->nvme_base_errata_ver);
+ json_object_add_value_string(root, "nvme_base_errata_version", buf);
+ sprintf(buf, "%c", log->nvme_cmd_set_errata_ver);
+ json_object_add_value_string(root, "nvme_cmd_set_errata_version", buf);
+ } else {
+ sprintf(buf, "%c", log->nvme_base_errata_ver);
+ json_object_add_value_string(root, "nvme_errata_version", buf);
+ }
+ }
+
json_object_add_value_uint(root, "unaligned_io",
le64_to_cpu(log->unaligned_io));
json_object_add_value_uint(root, "security_version_number",
@@ -7949,12 +7775,22 @@ static void show_cloud_smart_log_json(struct ocp_cloud_smart_log *log)
le_to_float(log->plp_start_count, 16));
json_object_add_value_uint64(root, "endurance_estimate",
le_to_float(log->endurance_estimate, 16));
- json_object_add_value_uint(root, "pcie_link_retraining_count",
- le64_to_cpu(log->pcie_link_retraining_cnt));
- json_object_add_value_uint(root, "power_state_change_count",
- le64_to_cpu(log->power_state_change_cnt));
+ if (smart_log_ver >= 3) {
+ json_object_add_value_uint(root, "pcie_link_retraining_count",
+ le64_to_cpu(log->pcie_link_retraining_cnt));
+ json_object_add_value_uint(root, "power_state_change_count",
+ le64_to_cpu(log->power_state_change_cnt));
+ if (smart_log_ver >= 4) {
+ snprintf(lowest_fr, sizeof(lowest_fr), "%-.*s",
+ (int)sizeof(log->lowest_permitted_fw_rev),
+ log->lowest_permitted_fw_rev);
+ json_object_add_value_string(root, "lowest_permitted_fw_rev", lowest_fr);
+ } else
+ json_object_add_value_uint128(root, "hardware_revision",
+ le128_to_cpu((__u8 *)&log->lowest_permitted_fw_rev[0]));
+ }
json_object_add_value_uint(root, "log_page_version",
- le16_to_cpu(log->log_page_version));
+ smart_log_ver);
stringify_log_page_guid(log->log_page_guid, buf);
json_object_add_value_string(root, "log_page_guid", buf);
@@ -7963,11 +7799,13 @@ static void show_cloud_smart_log_json(struct ocp_cloud_smart_log *log)
json_free_object(root);
}
-static void show_cloud_smart_log_normal(struct ocp_cloud_smart_log *log, struct nvme_dev *dev)
+static void wdc_show_cloud_smart_log_normal(struct ocp_cloud_smart_log *log,
+ struct nvme_dev *dev)
{
char buf[2 * sizeof(log->log_page_guid) + 3];
+ uint16_t smart_log_ver = (uint16_t)le16_to_cpu(log->log_page_version);
- printf("Smart Extended Log for NVME device:%s\n", dev->name);
+ printf("SMART Cloud Attributes for NVMe device : %s\n", dev->name);
printf("Physical Media Units Written : %'.0Lf\n",
le_to_float(log->physical_media_units_written, 16));
printf("Physical Media Units Read : %'.0Lf\n",
@@ -8002,14 +7840,16 @@ static void show_cloud_smart_log_normal(struct ocp_cloud_smart_log *log, struct
stringify_cloud_smart_log_thermal_status(log->thermal_status.current_status));
printf("Thermal Throttling Status (Number of Events) : %" PRIu8 "\n",
log->thermal_status.num_events);
- printf("NVMe Major Version : %" PRIu8 "\n",
- log->dssd_specific_ver.major_ver);
- printf(" Minor Version : %" PRIu16 "\n",
- le16_to_cpu(log->dssd_specific_ver.minor_ver));
- printf(" Point Version : %" PRIu16 "\n",
- le16_to_cpu(log->dssd_specific_ver.point_ver));
- printf(" Errata Version : %" PRIu8 "\n",
- log->dssd_specific_ver.errata_ver);
+ if (smart_log_ver >= 3) {
+ printf("NVMe Major Version : %" PRIu8 "\n",
+ log->dssd_specific_ver.major_ver);
+ printf(" Minor Version : %" PRIu16 "\n",
+ le16_to_cpu(log->dssd_specific_ver.minor_ver));
+ printf(" Point Version : %" PRIu16 "\n",
+ le16_to_cpu(log->dssd_specific_ver.point_ver));
+ printf(" Errata Version : %" PRIu8 "\n",
+ log->dssd_specific_ver.errata_ver);
+ }
printf("PCIe Correctable Error Count : %" PRIu64 "\n",
le64_to_cpu(log->pcie_correctable_error_count));
printf("Incomplete Shutdowns : %" PRIu32 "\n",
@@ -8018,8 +7858,17 @@ static void show_cloud_smart_log_normal(struct ocp_cloud_smart_log *log, struct
log->percent_free_blocks);
printf("Capacitor Health : %" PRIu16 "%%\n",
le16_to_cpu(log->capacitor_health));
- printf("NVMe Errata Version : %c\n",
- log->nvme_errata_ver);
+ if (smart_log_ver >= 3) {
+ if (smart_log_ver >= 4) {
+ printf("NVMe Base Errata Version : %c\n",
+ log->nvme_base_errata_ver);
+ printf("NVMe Command Set Errata Version : %c\n",
+ log->nvme_cmd_set_errata_ver);
+ } else {
+ printf("NVMe Errata Version : %c\n",
+ log->nvme_base_errata_ver);
+ }
+ }
printf("Unaligned IO : %" PRIu64 "\n",
le64_to_cpu(log->unaligned_io));
printf("Security Version Number : %" PRIu64 "\n",
@@ -8030,12 +7879,22 @@ static void show_cloud_smart_log_normal(struct ocp_cloud_smart_log *log, struct
le_to_float(log->plp_start_count, 16));
printf("Endurance Estimate : %'.0Lf\n",
le_to_float(log->endurance_estimate, 16));
- printf("PCIe Link Retraining Count : %" PRIu64 "\n",
- le64_to_cpu(log->pcie_link_retraining_cnt));
- printf("Power State Change Count : %" PRIu64 "\n",
- le64_to_cpu(log->power_state_change_cnt));
+ if (smart_log_ver >= 3) {
+ printf("PCIe Link Retraining Count : %" PRIu64 "\n",
+ le64_to_cpu(log->pcie_link_retraining_cnt));
+ printf("Power State Change Count : %" PRIu64 "\n",
+ le64_to_cpu(log->power_state_change_cnt));
+ if (smart_log_ver >= 4)
+ printf("Lowest Permitted FW Revision : %-.*s\n",
+ (int)sizeof(log->lowest_permitted_fw_rev),
+ log->lowest_permitted_fw_rev);
+ else
+ printf("Hardware Revision : %s\n",
+ uint128_t_to_string(le128_to_cpu(
+ (__u8 *)&log->lowest_permitted_fw_rev[0])));
+ }
printf("Log Page Version : %" PRIu16 "\n",
- le16_to_cpu(log->log_page_version));
+ smart_log_ver);
stringify_log_page_guid(log->log_page_guid, buf);
printf("Log Page GUID : %s\n", buf);
printf("\n\n");
@@ -8049,7 +7908,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";
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
struct nvme_dev *dev;
nvme_root_t r;
int ret = 0;
@@ -8145,43 +8004,16 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
"ERROR: WDC: Failure reading the C0 Log Page, ret = %d\n",
ret);
} else {
- struct ocp_cloud_smart_log log;
- char buf[2 * sizeof(log.log_page_guid) + 3];
-
ret = validate_output_format(cfg.output_format, &fmt);
if (ret < 0) {
fprintf(stderr, "Invalid output format: %s\n", cfg.output_format);
goto out;
}
- ret = nvme_get_log_simple(dev_fd(dev),
- WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
- sizeof(log), &log);
- if (!ret) {
- char *ptr = buf;
- int i;
- __u8 *guid = log.log_page_guid;
-
- memset(buf, 0, sizeof(char) * 19);
-
- ptr += sprintf(ptr, "0x");
- for (i = 0; i < 16; i++)
- ptr += sprintf(ptr, "%x", guid[15 - i]);
- if (strcmp(buf, "0xafd514c97c6f4f9ca4f2bfea2810afc5"))
- fprintf(stderr, "Invalid GUID: %s\n", buf);
- else {
- if (fmt == BINARY)
- d_raw((unsigned char *)&log, sizeof(log));
- else if (fmt == JSON)
- show_cloud_smart_log_json(&log);
- else
- show_cloud_smart_log_normal(&log, dev);
- }
- } else if (ret > 0) {
- nvme_show_status(ret);
- } else {
- perror("vs-smart-add-log");
- }
+ ret = nvme_get_print_ocp_cloud_smart_log(dev,
+ 0,
+ NVME_NSID_ALL,
+ fmt);
}
}
if (((capabilities & (WDC_DRIVE_CAP_CA_LOG_PAGE)) == (WDC_DRIVE_CAP_CA_LOG_PAGE)) &&
@@ -8219,7 +8051,7 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
{
const char *desc = "Retrieve Cloud Log Smart/Health Information";
const char *namespace_id = "desired namespace id";
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
__u64 capabilities = 0;
struct nvme_dev *dev;
nvme_root_t r;
@@ -8290,7 +8122,7 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
{
const char *desc = "Retrieve Hardware Revision Log Information";
const char *namespace_id = "desired namespace id";
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
__u64 capabilities = 0;
struct nvme_dev *dev;
int ret;
@@ -8375,7 +8207,7 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
const char *desc = "Retrieve Device Write Amplication Factor";
const char *namespace_id = "desired namespace id";
struct nvme_smart_log smart_log;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
struct nvme_dev *dev;
__u8 *data;
nvme_root_t r;
@@ -8932,7 +8764,7 @@ static int wdc_get_fw_act_history(nvme_root_t r, struct nvme_dev *dev,
char *format)
{
struct wdc_fw_act_history_log_hdr *fw_act_history_hdr;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
int ret;
__u8 *data;
@@ -9016,7 +8848,7 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev,
__u32 tot_entries = 0, num_entries = 0;
__u32 vendor_id = 0, device_id = 0;
__u32 cust_id = 0;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
__u8 *data;
int ret;
bool c2GuidMatch = false;
@@ -10498,7 +10330,7 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
struct plugin *plugin)
{
const char *desc = "Retrieve Log Page Directory.";
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
struct nvme_dev *dev;
int ret = 0;
nvme_root_t r;
@@ -11158,7 +10990,7 @@ static void wdc_print_pcie_stats_json(struct wdc_vs_pcie_stats *pcie_stats)
static int wdc_do_vs_nand_stats_sn810_2(struct nvme_dev *dev, char *format)
{
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
uint8_t *data = NULL;
int ret;
@@ -11197,7 +11029,7 @@ out:
static int wdc_do_vs_nand_stats(struct nvme_dev *dev, char *format)
{
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
uint8_t *output = NULL;
__u16 version = 0;
int ret;
@@ -11321,7 +11153,7 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
const char *desc = "Retrieve PCIE statistics.";
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
struct nvme_dev *dev;
nvme_root_t r;
int ret;
@@ -11396,7 +11228,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.";
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
nvme_root_t r;
uint64_t capabilities = 0;
struct nvme_dev *dev;
@@ -11663,7 +11495,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;
- enum nvme_print_flags fmt;
+ nvme_print_flags_t fmt;
struct nvme_dev *dev;
nvme_root_t r;
uint64_t capabilities = 0;
diff --git a/plugins/wdc/wdc-nvme.h b/plugins/wdc/wdc-nvme.h
index 65d2de3..a18da16 100644
--- a/plugins/wdc/wdc-nvme.h
+++ b/plugins/wdc/wdc-nvme.h
@@ -5,7 +5,7 @@
#if !defined(WDC_NVME) || defined(CMD_HEADER_MULTI_READ)
#define WDC_NVME
-#define WDC_PLUGIN_VERSION "2.8.1"
+#define WDC_PLUGIN_VERSION "2.9.1"
#include "cmd.h"
PLUGIN(NAME("wdc", "Western Digital vendor specific extensions", WDC_PLUGIN_VERSION),