Adding upstream version 1.16.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
90b6101daf
commit
50aec1e4c5
345 changed files with 7594 additions and 7512 deletions
|
@ -79,6 +79,7 @@
|
|||
#define WDC_NVME_SN650_DEV_ID_1 0x2701
|
||||
#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_SXSLCL_DEV_ID 0x2001
|
||||
|
@ -122,6 +123,7 @@
|
|||
#define WDC_DRIVE_CAP_CLOUD_SSD_VERSION 0x0000000004000000
|
||||
#define WDC_DRIVE_CAP_PCIE_STATS 0x0000000008000000
|
||||
#define WDC_DRIVE_CAP_INFO_2 0x0000000010000000
|
||||
#define WDC_DRIVE_CAP_C3_LOG_PAGE 0x0000000020000000
|
||||
|
||||
#define WDC_DRIVE_CAP_DRIVE_ESSENTIALS 0x0000000100000000
|
||||
#define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000
|
||||
|
@ -322,6 +324,15 @@
|
|||
#define WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN 0x1000
|
||||
#define WDC_MAX_NUM_ACT_HIST_ENTRIES 20
|
||||
|
||||
/* C3 Latency Monitor Log Page */
|
||||
#define WDC_LATENCY_MON_LOG_BUF_LEN 0x200
|
||||
#define WDC_LATENCY_MON_OPCODE 0xC3
|
||||
#define WDC_LATENCY_MON_VERSION 0x0001
|
||||
|
||||
#define WDC_C3_GUID_LENGTH 16
|
||||
static __u8 wdc_lat_mon_guid[WDC_C3_GUID_LENGTH] = { 0x92, 0x7a, 0xc0, 0x8c, 0xd0, 0x84, 0x6c, 0x9c,
|
||||
0x70, 0x43, 0xe6, 0xd4, 0x58, 0x5e, 0xd4, 0x85 };
|
||||
|
||||
/* D0 Smart Log Page */
|
||||
#define WDC_NVME_GET_VU_SMART_LOG_OPCODE 0xD0
|
||||
#define WDC_NVME_VU_SMART_LOG_LEN 0x200
|
||||
|
@ -523,7 +534,6 @@ typedef enum
|
|||
EOL_RRER = 108, /* Raw Read Error Rate */
|
||||
} EOL_LOG_PAGE_C0_OFFSETS;
|
||||
|
||||
|
||||
typedef struct __attribute__((__packed__)) _WDC_DE_VU_FILE_META_DATA
|
||||
{
|
||||
__u8 fileName[WDC_DE_FILE_NAME_SIZE];
|
||||
|
@ -800,6 +810,48 @@ struct wdc_bd_ca_log_format {
|
|||
__u8 raw_value[7];
|
||||
};
|
||||
|
||||
#define READ 0
|
||||
#define WRITE 1
|
||||
#define TRIM 2
|
||||
#define RESERVED 3
|
||||
|
||||
struct __attribute__((__packed__)) wdc_ssd_latency_monitor_log {
|
||||
__u8 feature_status; /* 0x00 */
|
||||
__u8 rsvd1; /* 0x01 */
|
||||
__le16 active_bucket_timer; /* 0x02 */
|
||||
__le16 active_bucket_timer_threshold; /* 0x04 */
|
||||
__u8 active_threshold_a; /* 0x06 */
|
||||
__u8 active_threshold_b; /* 0x07 */
|
||||
__u8 active_threshold_c; /* 0x08 */
|
||||
__u8 active_threshold_d; /* 0x09 */
|
||||
__le16 active_latency_config; /* 0x0A */
|
||||
__u8 active_latency_min_window; /* 0x0C */
|
||||
__u8 rsvd2[0x13]; /* 0x0D */
|
||||
|
||||
__le32 active_bucket_counter[4][4] ; /* 0x20 - 0x5F */
|
||||
__le64 active_latency_timestamp[4][3]; /* 0x60 - 0xBF */
|
||||
__le16 active_measured_latency[4][3]; /* 0xC0 - 0xD7 */
|
||||
__le16 active_latency_stamp_units; /* 0xD8 */
|
||||
__u8 rsvd3[0x16]; /* 0xDA */
|
||||
|
||||
__le32 static_bucket_counter[4][4] ; /* 0xF0 - 0x12F */
|
||||
__le64 static_latency_timestamp[4][3]; /* 0x130 - 0x18F */
|
||||
__le16 static_measured_latency[4][3]; /* 0x190 - 0x1A7 */
|
||||
__le16 static_latency_stamp_units; /* 0x1A8 */
|
||||
__u8 rsvd4[0x16]; /* 0x1AA */
|
||||
|
||||
__le16 debug_log_trigger_enable; /* 0x1C0 */
|
||||
__le16 debug_log_measured_latency; /* 0x1C2 */
|
||||
__le64 debug_log_latency_stamp; /* 0x1C4 */
|
||||
__le16 debug_log_ptr; /* 0x1CC */
|
||||
__le16 debug_log_counter_trigger; /* 0x1CE */
|
||||
__u8 debug_log_stamp_units; /* 0x1D0 */
|
||||
__u8 rsvd5[0x1D]; /* 0x1D1 */
|
||||
|
||||
__le16 log_page_version; /* 0x1EE */
|
||||
__u8 log_page_guid[0x10]; /* 0x1F0 */
|
||||
};
|
||||
|
||||
struct __attribute__((__packed__)) wdc_ssd_ca_perf_stats {
|
||||
__le64 nand_bytes_wr_lo; /* 0x00 - NAND Bytes Written lo */
|
||||
__le64 nand_bytes_wr_hi; /* 0x08 - NAND Bytes Written hi */
|
||||
|
@ -1238,6 +1290,10 @@ 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)
|
||||
capabilities |= WDC_DRIVE_CAP_C3_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)
|
||||
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
|
||||
|
@ -1292,6 +1348,7 @@ static __u64 wdc_get_drive_capabilities(int fd) {
|
|||
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_SN450_DEV_ID_1:
|
||||
case WDC_NVME_SN450_DEV_ID_2:
|
||||
/* verify the 0xC0 log page is supported */
|
||||
|
@ -1386,6 +1443,10 @@ static __u64 wdc_get_enc_drive_capabilities(int fd) {
|
|||
WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
|
||||
WDC_DRIVE_CAP_RESIZE);
|
||||
|
||||
/* verify the 0xC3 log page is supported */
|
||||
if (wdc_nvme_check_supported_log_page(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)
|
||||
capabilities |= WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY;
|
||||
|
@ -1972,6 +2033,7 @@ 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;
|
||||
int err = 0, output;
|
||||
void *page_log;
|
||||
|
@ -2060,6 +2122,46 @@ static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int
|
|||
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;
|
||||
|
@ -3496,6 +3598,170 @@ static int wdc_print_log(struct wdc_ssd_perf_stats *perf, int fmt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wdc_convert_ts(time_t time, char *ts_buf)
|
||||
{
|
||||
struct tm gmTimeInfo;
|
||||
time_t time_Human, time_ms;
|
||||
char buf[80];
|
||||
|
||||
time_Human = time/1000;
|
||||
time_ms = time % 1000;
|
||||
|
||||
gmtime_r((const time_t *)&time_Human, &gmTimeInfo);
|
||||
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &gmTimeInfo);
|
||||
sprintf(ts_buf, "%s.%03ld GMT", buf, time_ms);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wdc_print_latency_monitor_log_normal(int fd, struct wdc_ssd_latency_monitor_log *log_data)
|
||||
{
|
||||
printf("Latency Monitor/C3 Log Page Data \n");
|
||||
printf(" Controller : %s\n", devicename);
|
||||
int err = -1, i, j;
|
||||
struct nvme_id_ctrl ctrl;
|
||||
char ts_buf[128];
|
||||
|
||||
err = nvme_identify_ctrl(fd, &ctrl);
|
||||
if (!err)
|
||||
printf(" Serial Number: %-.*s\n", (int)sizeof(ctrl.sn), ctrl.sn);
|
||||
else {
|
||||
fprintf(stderr, "ERROR : WDC : latency monitor read id ctrl failure, err = %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
printf(" Feature Status 0x%x \n", log_data->feature_status);
|
||||
printf(" Active Bucket Timer %d min \n", 5*le16_to_cpu(log_data->active_bucket_timer));
|
||||
printf(" Active Bucket Timer Threshold %d min \n", 5*le16_to_cpu(log_data->active_bucket_timer_threshold));
|
||||
printf(" Active Threshold A %d ms \n", 5*(le16_to_cpu(log_data->active_threshold_a+1)));
|
||||
printf(" Active Threshold B %d ms \n", 5*(le16_to_cpu(log_data->active_threshold_b+1)));
|
||||
printf(" Active Threshold C %d ms \n", 5*(le16_to_cpu(log_data->active_threshold_c+1)));
|
||||
printf(" Active Threshold D %d ms \n", 5*(le16_to_cpu(log_data->active_threshold_d+1)));
|
||||
printf(" Active Latency Config 0x%x \n", le16_to_cpu(log_data->active_latency_config));
|
||||
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));
|
||||
|
||||
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][READ]), le32_to_cpu(log_data->active_bucket_counter[i][WRITE]),
|
||||
le32_to_cpu(log_data->active_bucket_counter[i][TRIM]));
|
||||
}
|
||||
|
||||
for (i = 0; i <= 3; i++) {
|
||||
printf(" Active Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n",
|
||||
i, le16_to_cpu(log_data->active_measured_latency[i][READ]), le16_to_cpu(log_data->active_measured_latency[i][WRITE]),
|
||||
le16_to_cpu(log_data->active_measured_latency[i][TRIM]));
|
||||
}
|
||||
|
||||
for (i = 0; i <= 3; i++) {
|
||||
printf(" Active Latency Time Stamp: Bucket %d ", i);
|
||||
for (j = 0; j <= 2; j++) {
|
||||
if (le64_to_cpu(log_data->active_latency_timestamp[i][j]) == -1)
|
||||
printf(" N/A ");
|
||||
else {
|
||||
wdc_convert_ts(le64_to_cpu(log_data->active_latency_timestamp[i][j]), ts_buf);
|
||||
printf("%s ", ts_buf);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
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][READ]), le32_to_cpu(log_data->static_bucket_counter[i][WRITE]),
|
||||
le32_to_cpu(log_data->static_bucket_counter[i][TRIM]));
|
||||
}
|
||||
|
||||
for (i = 0; i <= 3; i++) {
|
||||
printf(" Static Measured Latency: Bucket %d %27d ms %27d ms %27d ms \n",
|
||||
i, le16_to_cpu(log_data->static_measured_latency[i][READ]), le16_to_cpu(log_data->static_measured_latency[i][WRITE]),
|
||||
le16_to_cpu(log_data->static_measured_latency[i][TRIM]));
|
||||
}
|
||||
|
||||
for (i = 0; i <= 3; i++) {
|
||||
printf(" Static Latency Time Stamp: Bucket %d ", i);
|
||||
for (j = 0; j <= 2; j++) {
|
||||
if (le64_to_cpu(log_data->static_latency_timestamp[i][j]) == -1)
|
||||
printf(" N/A ");
|
||||
else {
|
||||
wdc_convert_ts(le64_to_cpu(log_data->static_latency_timestamp[i][j]), ts_buf);
|
||||
printf("%s ", ts_buf);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wdc_print_latency_monitor_log_json(struct wdc_ssd_latency_monitor_log *log_data)
|
||||
{
|
||||
int i, j;
|
||||
char buf[128];
|
||||
char *operation[3] = {"Read", "Write", "Trim"};
|
||||
struct json_object *root;
|
||||
root = json_create_object();
|
||||
|
||||
json_object_add_value_int(root, "Feature Status", log_data->feature_status);
|
||||
json_object_add_value_int(root, "Active Bucket Timer", 5*le16_to_cpu(log_data->active_bucket_timer));
|
||||
json_object_add_value_int(root, "Active Bucket Timer Threshold", 5*le16_to_cpu(log_data->active_bucket_timer_threshold));
|
||||
json_object_add_value_int(root, "Active Threshold A", 5*le16_to_cpu(log_data->active_threshold_a+1));
|
||||
json_object_add_value_int(root, "Active Threshold B", 5*le16_to_cpu(log_data->active_threshold_b+1));
|
||||
json_object_add_value_int(root, "Active Threshold C", 5*le16_to_cpu(log_data->active_threshold_c+1));
|
||||
json_object_add_value_int(root, "Active Threshold D", 5*le16_to_cpu(log_data->active_threshold_d+1));
|
||||
json_object_add_value_int(root, "Active Latency Config", le16_to_cpu(log_data->active_latency_config));
|
||||
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));
|
||||
|
||||
for (i = 0; i <= 3; i++) {
|
||||
for (j = 0; j <= 2; j++) {
|
||||
sprintf(buf, "Active Bucket Counter: Bucket %d %s", i, operation[j]);
|
||||
json_object_add_value_int(root, buf, le32_to_cpu(log_data->active_bucket_counter[i][j]));
|
||||
}
|
||||
}
|
||||
for (i = 0; i <= 3; i++) {
|
||||
for (j = 0; j <= 2; j++) {
|
||||
sprintf(buf, "Active Measured Latency: Bucket %d %s", i, operation[j]);
|
||||
json_object_add_value_int(root, buf, le16_to_cpu(log_data->active_measured_latency[i][j]));
|
||||
}
|
||||
}
|
||||
for (i = 0; i <= 3; i++) {
|
||||
for (j = 0; j <= 2; j++) {
|
||||
sprintf(buf, "Active Latency Time Stamp: Bucket %d %s", i, operation[j]);
|
||||
json_object_add_value_int(root, buf, le64_to_cpu(log_data->active_latency_timestamp[i][j]));
|
||||
}
|
||||
}
|
||||
for (i = 0; i <= 3; i++) {
|
||||
for (j = 0; j <= 2; j++) {
|
||||
sprintf(buf, "Static Bucket Counter: Bucket %d %s", i, operation[j]);
|
||||
json_object_add_value_int(root, buf, le32_to_cpu(log_data->static_bucket_counter[i][j]));
|
||||
}
|
||||
}
|
||||
for (i = 0; i <= 3; i++) {
|
||||
for (j = 0; j <= 2; j++) {
|
||||
sprintf(buf, "Static Measured Latency: Bucket %d %s", i, operation[j]);
|
||||
json_object_add_value_int(root, buf, le16_to_cpu(log_data->static_measured_latency[i][j]));
|
||||
}
|
||||
}
|
||||
for (i = 0; i <= 3; i++) {
|
||||
for (j = 0; j <= 2; j++) {
|
||||
sprintf(buf, "Static Latency Time Stamp: Bucket %d %s", i, operation[j]);
|
||||
json_object_add_value_int(root, buf, le64_to_cpu(log_data->static_latency_timestamp[i][j]));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -4351,10 +4617,12 @@ static void wdc_print_smart_cloud_attr_C0_normal(void *data)
|
|||
|
||||
printf(" SMART Cloud Attributes :- \n");
|
||||
|
||||
printf(" Physical media units written %.0Lf\n",
|
||||
int128_to_double(&log_data[SCAO_PMUW]));
|
||||
printf(" Physical media units Read %.0Lf\n",
|
||||
int128_to_double(&log_data[SCAO_PMUR]));
|
||||
printf(" Physical media units written - %"PRIu64" %"PRIu64"\n",
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW+8] & 0xFFFFFFFFFFFFFFFF),
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
|
||||
printf(" Physical media units read - %"PRIu64" %"PRIu64"\n",
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR+8] & 0xFFFFFFFFFFFFFFFF),
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
|
||||
printf(" Bad user nand blocks - Raw %"PRIu64"\n",
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
|
||||
printf(" Bad user nand blocks - Normalized %d\n",
|
||||
|
@ -4432,10 +4700,14 @@ 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_float(root, "Physical media units written",
|
||||
int128_to_double(&log_data[SCAO_PMUW]));
|
||||
json_object_add_value_int(root, "Physical media units Read",
|
||||
int128_to_double(&log_data[SCAO_PMUR]));
|
||||
json_object_add_value_int(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",
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUW] & 0xFFFFFFFFFFFFFFFF));
|
||||
json_object_add_value_int(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",
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_PMUR] & 0xFFFFFFFFFFFFFFFF));
|
||||
json_object_add_value_uint(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",
|
||||
|
@ -4595,7 +4867,7 @@ 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)
|
||||
static int wdc_get_c0_log_page(int fd, char *format, int uuid_index, __u32 namespace_id)
|
||||
{
|
||||
int ret = 0;
|
||||
int fmt = -1;
|
||||
|
@ -4639,8 +4911,15 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (namespace_id == NVME_NSID_ALL) {
|
||||
ret = namespace_id = nvme_get_nsid(fd);
|
||||
if (ret < 0) {
|
||||
namespace_id = NVME_NSID_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the 0xC0 log data */
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
|
||||
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);
|
||||
|
||||
if (strcmp(format, "json"))
|
||||
|
@ -4687,7 +4966,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
|
|||
}
|
||||
|
||||
/* Get the 0xC0 log data */
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
|
||||
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);
|
||||
|
||||
if (strcmp(format, "json"))
|
||||
|
@ -4714,7 +4993,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
|
|||
}
|
||||
|
||||
/* Get the 0xC0 log data */
|
||||
ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
|
||||
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);
|
||||
|
||||
if (strcmp(format, "json"))
|
||||
|
@ -4740,7 +5019,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
|
|||
}
|
||||
|
||||
/* Get the 0xC0 log data */
|
||||
ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
|
||||
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);
|
||||
|
||||
if (strcmp(format, "json"))
|
||||
|
@ -4768,6 +5047,23 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int wdc_print_latency_monitor_log(int fd, struct wdc_ssd_latency_monitor_log *log_data, int fmt)
|
||||
{
|
||||
if (!log_data) {
|
||||
fprintf(stderr, "ERROR : WDC : Invalid C3 log data buffer\n");
|
||||
return -1;
|
||||
}
|
||||
switch (fmt) {
|
||||
case NORMAL:
|
||||
wdc_print_latency_monitor_log_normal(fd, log_data);
|
||||
break;
|
||||
case JSON:
|
||||
wdc_print_latency_monitor_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) {
|
||||
|
@ -5030,6 +5326,77 @@ 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)
|
||||
{
|
||||
int ret = 0;
|
||||
int fmt = -1;
|
||||
__u8 *data;
|
||||
int i;
|
||||
struct wdc_ssd_latency_monitor_log *log_data;
|
||||
|
||||
if (!wdc_check_device(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_LATENCY_MON_LOG_BUF_LEN)) == NULL) {
|
||||
fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
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);
|
||||
|
||||
if (strcmp(format, "json"))
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
|
||||
|
||||
if (ret == 0) {
|
||||
log_data = (struct wdc_ssd_latency_monitor_log*)data;
|
||||
|
||||
/* check log page version */
|
||||
if (log_data->log_page_version != WDC_LATENCY_MON_VERSION) {
|
||||
fprintf(stderr, "ERROR : WDC : invalid latency monitor version\n");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check log page guid */
|
||||
/* Verify GUID matches */
|
||||
for (i=0; i<16; i++) {
|
||||
if (wdc_lat_mon_guid[i] != log_data->log_page_guid[i]) {
|
||||
fprintf(stderr, "ERROR : WDC : Unknown GUID in C3 Log Page data\n");
|
||||
int j;
|
||||
fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
|
||||
for (j = 0; j<16; j++) {
|
||||
fprintf(stderr, "%x", wdc_lat_mon_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_latency_monitor_log(fd, log_data, fmt);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR : WDC : Unable to read C3 data from buffer\n");
|
||||
}
|
||||
|
||||
out:
|
||||
free(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wdc_get_d0_log_page(int fd, char *format)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -5083,6 +5450,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
|
|||
int fd;
|
||||
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";
|
||||
int ret = 0;
|
||||
int uuid_index = 0;
|
||||
int page_mask = 0, num, i;
|
||||
|
@ -5094,6 +5462,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
|
|||
char *output_format;
|
||||
__u8 log_page_version;
|
||||
char *log_page_mask;
|
||||
__u32 namespace_id;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
|
@ -5101,6 +5470,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
|
|||
.output_format = "normal",
|
||||
.log_page_version = 0,
|
||||
.log_page_mask = "",
|
||||
.namespace_id = NVME_NSID_ALL,
|
||||
};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
|
@ -5108,6 +5478,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
|
|||
OPT_FMT("output-format", 'o', &cfg.output_format, "Output Format: normal|json"),
|
||||
OPT_BYTE("log-page-version", 'l', &cfg.log_page_version, log_page_version),
|
||||
OPT_LIST("log-page-mask", 'p', &cfg.log_page_mask, log_page_mask),
|
||||
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
@ -5170,7 +5541,7 @@ 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);
|
||||
ret = wdc_get_c0_log_page(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);
|
||||
}
|
||||
|
@ -5201,6 +5572,48 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *command,
|
||||
struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Retrieve latency monitor log data.";
|
||||
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;
|
||||
|
||||
capabilities = wdc_get_drive_capabilities(fd);
|
||||
|
||||
if ((capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE) == 0) {
|
||||
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wdc_get_c3_log_page(fd, cfg.output_format);
|
||||
if (ret)
|
||||
fprintf(stderr, "ERROR : WDC : Failure reading the C3 Log Page, ret = %d\n", ret);
|
||||
|
||||
out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wdc_do_clear_pcie_correctable_errors(int fd)
|
||||
{
|
||||
int ret;
|
||||
|
@ -7849,6 +8262,8 @@ static int wdc_capabilities(int argc, char **argv,
|
|||
capabilities & WDC_DRIVE_CAP_C0_LOG_PAGE ? "Supported" : "Not Supported");
|
||||
printf("--C1 Log Page : %s\n",
|
||||
capabilities & WDC_DRIVE_CAP_C1_LOG_PAGE ? "Supported" : "Not Supported");
|
||||
printf("--C3 Log Page : %s\n",
|
||||
capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE ? "Supported" : "Not Supported");
|
||||
printf("--CA Log Page : %s\n",
|
||||
capabilities & WDC_DRIVE_CAP_CA_LOG_PAGE ? "Supported" : "Not Supported");
|
||||
printf("--D0 Log Page : %s\n",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue