Skip to content

Commit d559650

Browse files
jeff-lien-sndkkeithbusch
authored andcommitted
Add new wdc plugin command - vs-drive-info
1 parent 4937cf7 commit d559650

2 files changed

Lines changed: 71 additions & 1 deletion

File tree

plugins/wdc/wdc-nvme.c

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
#define WDC_DRIVE_CAP_REASON_ID 0x0000000000010000
100100
#define WDC_DRIVE_CAP_LOG_PAGE_DIR 0x0000000000020000
101101
#define WDC_DRIVE_CAP_NS_RESIZE 0x0000000000040000
102+
#define WDC_DRIVE_CAP_INFO 0x0000000000080000
102103

103104
#define WDC_DRIVE_CAP_DRIVE_ESSENTIALS 0x0000000100000000
104105
#define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000
@@ -128,6 +129,11 @@
128129
/* Namespace Resize */
129130
#define WDC_NVME_NAMESPACE_RESIZE_OPCODE 0xFB
130131

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+
131137
/* Capture Diagnostics */
132138
#define WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE WDC_NVME_LOG_SIZE_DATA_LEN
133139
#define WDC_NVME_CAP_DIAG_OPCODE 0xE6
@@ -498,6 +504,9 @@ static int wdc_clear_reason_id(int fd);
498504
static int wdc_dump_telemetry_hdr(int fd, int log_id, struct nvme_telemetry_log_page_hdr *log_hdr);
499505
static int wdc_log_page_directory(int argc, char **argv, struct command *command,
500506
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);
501510

502511
/* Drive log data size */
503512
struct wdc_log_size {
@@ -899,7 +908,7 @@ static __u64 wdc_get_drive_capabilities(int fd) {
899908
WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_CLEAR_PCIE |
900909
WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY | WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY |
901910
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);
903912

904913
/* verify the 0xCA log page is supported */
905914
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)
45814590
return ret;
45824591
}
45834592

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+
45844612
static int wdc_drive_resize(int argc, char **argv,
45854613
struct command *command, struct plugin *plugin)
45864614
{
@@ -5175,3 +5203,44 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
51755203

51765204
return ret;
51775205
}
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+

plugins/wdc/wdc-nvme.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ PLUGIN(NAME("wdc", "Western Digital vendor specific extensions"),
2929
ENTRY("vs-error-reason-identifier", "WDC Telemetry Reason Identifier", wdc_reason_identifier)
3030
ENTRY("log-page-directory", "WDC Get Log Page Directory", wdc_log_page_directory)
3131
ENTRY("namespace-resize", "WDC NamespaceDrive Resize", wdc_namespace_resize)
32+
ENTRY("vs-drive-info", "WDC Get Drive Info", wdc_vs_drive_info)
3233
)
3334
);
3435

0 commit comments

Comments
 (0)