|
90 | 90 | #define WDC_DRIVE_CAP_CRASH_DUMP 0x0000000000000800 |
91 | 91 | #define WDC_DRIVE_CAP_PFAIL_DUMP 0x0000000000001000 |
92 | 92 | #define WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY 0x0000000000002000 |
| 93 | +#define WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY 0x0000000000004000 |
93 | 94 |
|
94 | 95 | #define WDC_DRIVE_CAP_DRIVE_ESSENTIALS 0x0000000100000000 |
95 | 96 | #define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000 |
|
186 | 187 | #define WDC_NVME_CLEAR_CRASH_DUMP_SUBCMD 0x05 |
187 | 188 | #define WDC_NVME_CLEAR_PF_CRASH_DUMP_SUBCMD 0x06 |
188 | 189 |
|
| 190 | +/* Clear FW Activate History */ |
| 191 | +#define WDC_NVME_CLEAR_FW_ACT_HIST_OPCODE 0xC6 |
| 192 | +#define WDC_NVME_CLEAR_FW_ACT_HIST_CMD 0x23 |
| 193 | +#define WDC_NVME_CLEAR_FW_ACT_HIST_SUBCMD 0x05 |
| 194 | + |
189 | 195 | /* Additional Smart Log */ |
190 | 196 | #define WDC_ADD_LOG_BUF_LEN 0x4000 |
191 | 197 | #define WDC_NVME_ADD_LOG_OPCODE 0xC1 |
@@ -805,7 +811,7 @@ static __u64 wdc_get_drive_capabilities(int fd) { |
805 | 811 | capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG | |
806 | 812 | WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT | |
807 | 813 | WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_CLEAR_PCIE | |
808 | | - WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY); |
| 814 | + WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY | WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY); |
809 | 815 |
|
810 | 816 | /* verify the 0xCA log page is supported */ |
811 | 817 | if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true) |
@@ -3442,6 +3448,42 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com |
3442 | 3448 | return ret; |
3443 | 3449 | } |
3444 | 3450 |
|
| 3451 | +static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *command, |
| 3452 | + struct plugin *plugin) |
| 3453 | +{ |
| 3454 | + char *desc = "Clear FW activate history table."; |
| 3455 | + int fd; |
| 3456 | + int ret = -1; |
| 3457 | + __u64 capabilities = 0; |
| 3458 | + struct nvme_passthru_cmd admin_cmd; |
| 3459 | + |
| 3460 | + OPT_ARGS(opts) = { |
| 3461 | + OPT_END() |
| 3462 | + }; |
| 3463 | + |
| 3464 | + fd = parse_and_open(argc, argv, desc, opts, NULL, 0); |
| 3465 | + if (fd < 0) |
| 3466 | + return fd; |
| 3467 | + |
| 3468 | + capabilities = wdc_get_drive_capabilities(fd); |
| 3469 | + if ((capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY) != WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY) { |
| 3470 | + fprintf(stderr, "ERROR : WDC: unsupported device for this command\n"); |
| 3471 | + ret = -1; |
| 3472 | + goto out; |
| 3473 | + } |
| 3474 | + |
| 3475 | + memset(&admin_cmd, 0, sizeof (admin_cmd)); |
| 3476 | + admin_cmd.opcode = WDC_NVME_CLEAR_FW_ACT_HIST_OPCODE; |
| 3477 | + admin_cmd.cdw12 = ((WDC_NVME_CLEAR_FW_ACT_HIST_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | |
| 3478 | + WDC_NVME_CLEAR_FW_ACT_HIST_CMD); |
| 3479 | + |
| 3480 | + ret = nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, &admin_cmd); |
| 3481 | + fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret); |
| 3482 | + |
| 3483 | +out: |
| 3484 | + return ret; |
| 3485 | +} |
| 3486 | + |
3445 | 3487 | static int wdc_get_serial_and_fw_rev(int fd, char *sn, char *fw_rev) |
3446 | 3488 | { |
3447 | 3489 | int i; |
|
0 commit comments