Changeset View
Changeset View
Standalone View
Standalone View
sbin/nvmecontrol/logpage.c
Show First 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | case NVME_LOG_HEALTH_INFORMATION: | ||||
break; | break; | ||||
case NVME_LOG_FIRMWARE_SLOT: | case NVME_LOG_FIRMWARE_SLOT: | ||||
nvme_firmware_page_swapbytes( | nvme_firmware_page_swapbytes( | ||||
(struct nvme_firmware_page *)payload); | (struct nvme_firmware_page *)payload); | ||||
break; | break; | ||||
case NVME_LOG_CHANGED_NAMESPACE: | case NVME_LOG_CHANGED_NAMESPACE: | ||||
nvme_ns_list_swapbytes((struct nvme_ns_list *)payload); | nvme_ns_list_swapbytes((struct nvme_ns_list *)payload); | ||||
break; | break; | ||||
case NVME_LOG_DEVICE_SELF_TEST: | |||||
nvme_device_self_test_swapbytes( | |||||
(struct nvme_device_self_test_page *)payload); | |||||
break; | |||||
case NVME_LOG_COMMAND_EFFECT: | case NVME_LOG_COMMAND_EFFECT: | ||||
nvme_command_effects_page_swapbytes( | nvme_command_effects_page_swapbytes( | ||||
(struct nvme_command_effects_page *)payload); | (struct nvme_command_effects_page *)payload); | ||||
break; | break; | ||||
case NVME_LOG_RES_NOTIFICATION: | case NVME_LOG_RES_NOTIFICATION: | ||||
nvme_res_notification_page_swapbytes( | nvme_res_notification_page_swapbytes( | ||||
(struct nvme_res_notification_page *)payload); | (struct nvme_res_notification_page *)payload); | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 333 Lines • ▼ Show 20 Lines | print_log_sanitize_status(const struct nvme_controller_data *cdata __unused, | ||||
printf("Time For Overwrite: %u sec\n", ss->etfo); | printf("Time For Overwrite: %u sec\n", ss->etfo); | ||||
printf("Time For Block Erase: %u sec\n", ss->etfbe); | printf("Time For Block Erase: %u sec\n", ss->etfbe); | ||||
printf("Time For Crypto Erase: %u sec\n", ss->etfce); | printf("Time For Crypto Erase: %u sec\n", ss->etfce); | ||||
printf("Time For Overwrite No-Deallocate: %u sec\n", ss->etfownd); | printf("Time For Overwrite No-Deallocate: %u sec\n", ss->etfownd); | ||||
printf("Time For Block Erase No-Deallocate: %u sec\n", ss->etfbewnd); | printf("Time For Block Erase No-Deallocate: %u sec\n", ss->etfbewnd); | ||||
printf("Time For Crypto Erase No-Deallocate: %u sec\n", ss->etfcewnd); | printf("Time For Crypto Erase No-Deallocate: %u sec\n", ss->etfcewnd); | ||||
} | } | ||||
static const char * | |||||
self_test_res[] = { | |||||
[0] = "completed without error", | |||||
[1] = "aborted by a Device Self-test command", | |||||
[2] = "aborted by a Controller Level Reset", | |||||
[3] = "aborted due to namespace removal", | |||||
[4] = "aborted due to Format NVM command", | |||||
[5] = "failed due to fatal or unknown test error", | |||||
[6] = "completed with an unknown segment that failed", | |||||
[7] = "completed with one or more failed segments", | |||||
[8] = "aborted for unknown reason", | |||||
[9] = "aborted due to a sanitize operation", | |||||
}; | |||||
static uint32_t self_test_res_max = nitems(self_test_res); | |||||
static void | |||||
print_log_self_test_status(const struct nvme_controller_data *cdata __unused, | |||||
void *buf, uint32_t size __unused) | |||||
{ | |||||
struct nvme_device_self_test_page *dst; | |||||
uint32_t r; | |||||
dst = buf; | |||||
printf("Device Self-test Status\n"); | |||||
printf("=======================\n"); | |||||
printf("Current Operation: "); | |||||
switch (dst->curr_operation) { | |||||
case 0x0: | |||||
printf("No device self-test operation in progress\n"); | |||||
break; | |||||
case 0x1: | |||||
printf("Short device self-test operation in progress\n"); | |||||
break; | |||||
case 0x2: | |||||
printf("Extended device self-test operation in progress\n"); | |||||
break; | |||||
case 0xe: | |||||
printf("Vendor specific\n"); | |||||
break; | |||||
default: | |||||
printf("Reserved (0x%x)\n", dst->curr_operation); | |||||
} | |||||
if (dst->curr_operation != 0) | |||||
printf("Current Completion: %u%%\n", dst->curr_compl & 0x7f); | |||||
printf("Results\n"); | |||||
for (r = 0; r < 20; r++) { | |||||
uint64_t failing_lba; | |||||
uint8_t code, res; | |||||
code = (dst->result[r].status >> 4) & 0xf; | |||||
res = dst->result[r].status & 0xf; | |||||
if (res == 0xf) | |||||
continue; | |||||
printf("[%2u] ", r); | |||||
switch (code) { | |||||
case 0x1: | |||||
printf("Short device self-test"); | |||||
break; | |||||
case 0x2: | |||||
printf("Extended device self-test"); | |||||
break; | |||||
case 0xe: | |||||
printf("Vendor specific"); | |||||
break; | |||||
default: | |||||
printf("Reserved (0x%x)", code); | |||||
} | |||||
if (res < self_test_res_max) | |||||
printf(" %s", self_test_res[res]); | |||||
else | |||||
printf(" Reserved status 0x%x", res); | |||||
if (res == 7) | |||||
printf(" starting in segment %u", dst->result[r].segment_num); | |||||
#define BIT(b) (1 << (b)) | |||||
if (dst->result[r].valid_diag_info & BIT(0)) | |||||
printf(" NSID=0x%x", dst->result[r].nsid); | |||||
if (dst->result[r].valid_diag_info & BIT(1)) { | |||||
memcpy(&failing_lba, dst->result[r].failing_lba, | |||||
sizeof(failing_lba)); | |||||
printf(" FLBA=0x%lx", failing_lba); | |||||
} | |||||
if (dst->result[r].valid_diag_info & BIT(2)) | |||||
printf(" SCT=0x%x", dst->result[r].status_code_type); | |||||
if (dst->result[r].valid_diag_info & BIT(3)) | |||||
printf(" SC=0x%x", dst->result[r].status_code); | |||||
#undef BIT | |||||
printf("\n"); | |||||
} | |||||
} | |||||
/* | /* | ||||
* Table of log page printer / sizing. | * Table of log page printer / sizing. | ||||
* | * | ||||
* Make sure you keep all the pages of one vendor together so -v help | * Make sure you keep all the pages of one vendor together so -v help | ||||
* lists all the vendors pages. | * lists all the vendors pages. | ||||
*/ | */ | ||||
NVME_LOGPAGE(error, | NVME_LOGPAGE(error, | ||||
NVME_LOG_ERROR, NULL, "Drive Error Log", | NVME_LOG_ERROR, NULL, "Drive Error Log", | ||||
print_log_error, 0); | print_log_error, 0); | ||||
NVME_LOGPAGE(health, | NVME_LOGPAGE(health, | ||||
NVME_LOG_HEALTH_INFORMATION, NULL, "Health/SMART Data", | NVME_LOG_HEALTH_INFORMATION, NULL, "Health/SMART Data", | ||||
print_log_health, sizeof(struct nvme_health_information_page)); | print_log_health, sizeof(struct nvme_health_information_page)); | ||||
NVME_LOGPAGE(fw, | NVME_LOGPAGE(fw, | ||||
NVME_LOG_FIRMWARE_SLOT, NULL, "Firmware Information", | NVME_LOG_FIRMWARE_SLOT, NULL, "Firmware Information", | ||||
print_log_firmware, sizeof(struct nvme_firmware_page)); | print_log_firmware, sizeof(struct nvme_firmware_page)); | ||||
NVME_LOGPAGE(ns, | NVME_LOGPAGE(ns, | ||||
NVME_LOG_CHANGED_NAMESPACE, NULL, "Changed Namespace List", | NVME_LOG_CHANGED_NAMESPACE, NULL, "Changed Namespace List", | ||||
print_log_ns, sizeof(struct nvme_ns_list)); | print_log_ns, sizeof(struct nvme_ns_list)); | ||||
NVME_LOGPAGE(ce, | NVME_LOGPAGE(ce, | ||||
NVME_LOG_COMMAND_EFFECT, NULL, "Commands Supported and Effects", | NVME_LOG_COMMAND_EFFECT, NULL, "Commands Supported and Effects", | ||||
print_log_command_effects, sizeof(struct nvme_command_effects_page)); | print_log_command_effects, sizeof(struct nvme_command_effects_page)); | ||||
NVME_LOGPAGE(dst, | NVME_LOGPAGE(dst, | ||||
NVME_LOG_DEVICE_SELF_TEST, NULL, "Device Self-test", | NVME_LOG_DEVICE_SELF_TEST, NULL, "Device Self-test", | ||||
NULL, 564); | print_log_self_test_status, sizeof(struct nvme_device_self_test_page)); | ||||
NVME_LOGPAGE(thi, | NVME_LOGPAGE(thi, | ||||
NVME_LOG_TELEMETRY_HOST_INITIATED, NULL, "Telemetry Host-Initiated", | NVME_LOG_TELEMETRY_HOST_INITIATED, NULL, "Telemetry Host-Initiated", | ||||
NULL, DEFAULT_SIZE); | NULL, DEFAULT_SIZE); | ||||
NVME_LOGPAGE(tci, | NVME_LOGPAGE(tci, | ||||
NVME_LOG_TELEMETRY_CONTROLLER_INITIATED, NULL, "Telemetry Controller-Initiated", | NVME_LOG_TELEMETRY_CONTROLLER_INITIATED, NULL, "Telemetry Controller-Initiated", | ||||
NULL, DEFAULT_SIZE); | NULL, DEFAULT_SIZE); | ||||
NVME_LOGPAGE(egi, | NVME_LOGPAGE(egi, | ||||
NVME_LOG_ENDURANCE_GROUP_INFORMATION, NULL, "Endurance Group Information", | NVME_LOG_ENDURANCE_GROUP_INFORMATION, NULL, "Endurance Group Information", | ||||
▲ Show 20 Lines • Show All 137 Lines • Show Last 20 Lines |