|
99 | 99 | #define WDC_DRIVE_CAP_REASON_ID 0x0000000000010000 |
100 | 100 | #define WDC_DRIVE_CAP_LOG_PAGE_DIR 0x0000000000020000 |
101 | 101 | #define WDC_DRIVE_CAP_NS_RESIZE 0x0000000000040000 |
| 102 | +#define WDC_DRIVE_CAP_INFO 0x0000000000080000 |
102 | 103 |
|
103 | 104 | #define WDC_DRIVE_CAP_DRIVE_ESSENTIALS 0x0000000100000000 |
104 | 105 | #define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000 |
|
128 | 129 | /* Namespace Resize */ |
129 | 130 | #define WDC_NVME_NAMESPACE_RESIZE_OPCODE 0xFB |
130 | 131 |
|
| 132 | +/* Drive Info */ |
| 133 | +#define WDC_NVME_DRIVE_INFO_OPCODE 0xC6 |
| 134 | +#define WDC_NVME_DRIVE_INFO_CMD 0x22 |
| 135 | +#define WDC_NVME_DRIVE_INFO_SUBCMD 0x06 |
| 136 | + |
131 | 137 | /* Capture Diagnostics */ |
132 | 138 | #define WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE WDC_NVME_LOG_SIZE_DATA_LEN |
133 | 139 | #define WDC_NVME_CAP_DIAG_OPCODE 0xE6 |
@@ -498,6 +504,9 @@ static int wdc_clear_reason_id(int fd); |
498 | 504 | static int wdc_dump_telemetry_hdr(int fd, int log_id, struct nvme_telemetry_log_page_hdr *log_hdr); |
499 | 505 | static int wdc_log_page_directory(int argc, char **argv, struct command *command, |
500 | 506 | struct plugin *plugin); |
| 507 | +static int wdc_do_drive_info(int fd, __u32 *result); |
| 508 | +static int wdc_vs_drive_info(int argc, char **argv, struct command *command, |
| 509 | + struct plugin *plugin); |
501 | 510 |
|
502 | 511 | /* Drive log data size */ |
503 | 512 | struct wdc_log_size { |
@@ -899,7 +908,7 @@ static __u64 wdc_get_drive_capabilities(int fd) { |
899 | 908 | WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_CLEAR_PCIE | |
900 | 909 | WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY | WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY | |
901 | 910 | WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG | WDC_DRIVE_CAP_REASON_ID | |
902 | | - WDC_DRIVE_CAP_LOG_PAGE_DIR); |
| 911 | + WDC_DRIVE_CAP_LOG_PAGE_DIR | WDC_DRIVE_CAP_INFO); |
903 | 912 |
|
904 | 913 | /* verify the 0xCA log page is supported */ |
905 | 914 | if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true) |
@@ -4581,6 +4590,25 @@ static int wdc_do_namespace_resize(int fd, __u32 nsid, __u32 op_option) |
4581 | 4590 | return ret; |
4582 | 4591 | } |
4583 | 4592 |
|
| 4593 | +static int wdc_do_drive_info(int fd, __u32 *result) |
| 4594 | +{ |
| 4595 | + int ret; |
| 4596 | + struct nvme_admin_cmd admin_cmd; |
| 4597 | + |
| 4598 | + memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd)); |
| 4599 | + admin_cmd.opcode = WDC_NVME_DRIVE_INFO_OPCODE; |
| 4600 | + admin_cmd.cdw12 = ((WDC_NVME_DRIVE_INFO_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | |
| 4601 | + WDC_NVME_DRIVE_INFO_CMD); |
| 4602 | + |
| 4603 | + ret = nvme_submit_admin_passthru(fd, &admin_cmd); |
| 4604 | + |
| 4605 | + if (!ret && result) |
| 4606 | + *result = admin_cmd.result; |
| 4607 | + |
| 4608 | + return ret; |
| 4609 | +} |
| 4610 | + |
| 4611 | + |
4584 | 4612 | static int wdc_drive_resize(int argc, char **argv, |
4585 | 4613 | struct command *command, struct plugin *plugin) |
4586 | 4614 | { |
@@ -5175,3 +5203,44 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command, |
5175 | 5203 |
|
5176 | 5204 | return ret; |
5177 | 5205 | } |
| 5206 | + |
| 5207 | +static int wdc_vs_drive_info(int argc, char **argv, |
| 5208 | + struct command *command, struct plugin *plugin) |
| 5209 | +{ |
| 5210 | + const char *desc = "Send a vs-drive-info command."; |
| 5211 | + uint64_t capabilities = 0; |
| 5212 | + int fd, ret; |
| 5213 | + __le32 result; |
| 5214 | + __u16 size; |
| 5215 | + double rev; |
| 5216 | + |
| 5217 | + OPT_ARGS(opts) = { |
| 5218 | + OPT_END() |
| 5219 | + }; |
| 5220 | + |
| 5221 | + fd = parse_and_open(argc, argv, desc, opts); |
| 5222 | + if (fd < 0) |
| 5223 | + return fd; |
| 5224 | + |
| 5225 | + wdc_check_device(fd); |
| 5226 | + capabilities = wdc_get_drive_capabilities(fd); |
| 5227 | + if ((capabilities & WDC_DRIVE_CAP_INFO) == WDC_DRIVE_CAP_INFO) { |
| 5228 | + ret = wdc_do_drive_info(fd, &result); |
| 5229 | + } else { |
| 5230 | + fprintf(stderr, "ERROR : WDC: unsupported device for this command\n"); |
| 5231 | + ret = -1; |
| 5232 | + } |
| 5233 | + |
| 5234 | + if (!ret) { |
| 5235 | + size = (__u16)((cpu_to_le32(result) & 0xffff0000) >> 16); |
| 5236 | + rev = (double)(cpu_to_le32(result) & 0x0000ffff); |
| 5237 | + |
| 5238 | + printf("Drive HW Revison: %4.1f\n", (.1 * rev)); |
| 5239 | + printf("FTL Unit Size: 0x%x KB\n", size); |
| 5240 | + } |
| 5241 | + |
| 5242 | + fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret); |
| 5243 | + return ret; |
| 5244 | +} |
| 5245 | + |
| 5246 | + |
0 commit comments