Changeset View
Changeset View
Standalone View
Standalone View
sbin/nvmecontrol/logpage.c
| Show First 20 Lines • Show All 213 Lines • ▼ Show 20 Lines | read_logpage(int fd, uint8_t log_page, uint32_t nsid, uint8_t lsp, | ||||
| pt.len = payload_size; | pt.len = payload_size; | ||||
| pt.is_read = 1; | pt.is_read = 1; | ||||
| if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) | if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) | ||||
| err(EX_IOERR, "get log page request failed"); | err(EX_IOERR, "get log page request failed"); | ||||
| /* Convert data to host endian */ | /* Convert data to host endian */ | ||||
| switch (log_page) { | switch (log_page) { | ||||
| case NVME_LOG_HEALTH_INFORMATION: | |||||
| nvme_health_information_page_swapbytes( | |||||
| (struct nvme_health_information_page *)payload); | |||||
| 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: | case NVME_LOG_DEVICE_SELF_TEST: | ||||
| nvme_device_self_test_swapbytes( | nvme_device_self_test_swapbytes( | ||||
| (struct nvme_device_self_test_page *)payload); | (struct nvme_device_self_test_page *)payload); | ||||
| break; | break; | ||||
| case NVME_LOG_COMMAND_EFFECT: | case NVME_LOG_COMMAND_EFFECT: | ||||
| Show All 26 Lines | print_log_error(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size) | ||||
| int i, nentries; | int i, nentries; | ||||
| uint16_t status; | uint16_t status; | ||||
| uint8_t p, sc, sct, m, dnr; | uint8_t p, sc, sct, m, dnr; | ||||
| struct nvme_error_information_entry *entry = buf; | struct nvme_error_information_entry *entry = buf; | ||||
| printf("Error Information Log\n"); | printf("Error Information Log\n"); | ||||
| printf("=====================\n"); | printf("=====================\n"); | ||||
| if (LE2H(entry->error_count) == 0) { | if (letoh(entry->error_count) == 0) { | ||||
| printf("No error entries found\n"); | printf("No error entries found\n"); | ||||
| return; | return; | ||||
| } | } | ||||
| nentries = size / sizeof(struct nvme_error_information_entry); | nentries = size / sizeof(struct nvme_error_information_entry); | ||||
| for (i = 0; i < nentries; i++, entry++) { | for (i = 0; i < nentries; i++, entry++) { | ||||
| if (LE2H(entry->error_count) == 0) | if (letoh(entry->error_count) == 0) | ||||
| break; | break; | ||||
| status = LE2H(entry->status); | status = letoh(entry->status); | ||||
| p = NVME_STATUS_GET_P(status); | p = NVME_STATUS_GET_P(status); | ||||
| sc = NVME_STATUS_GET_SC(status); | sc = NVME_STATUS_GET_SC(status); | ||||
| sct = NVME_STATUS_GET_SCT(status); | sct = NVME_STATUS_GET_SCT(status); | ||||
| m = NVME_STATUS_GET_M(status); | m = NVME_STATUS_GET_M(status); | ||||
| dnr = NVME_STATUS_GET_DNR(status); | dnr = NVME_STATUS_GET_DNR(status); | ||||
| printf("Entry %02d\n", i + 1); | printf("Entry %02d\n", i + 1); | ||||
| printf("=========\n"); | printf("=========\n"); | ||||
| printf(" Error count: %ju\n", LE2H(entry->error_count)); | printf(" Error count: %ju\n", letoh(entry->error_count)); | ||||
| printf(" Submission queue ID: %u\n", LE2H(entry->sqid)); | printf(" Submission queue ID: %u\n", letoh(entry->sqid)); | ||||
| printf(" Command ID: %u\n", LE2H(entry->cid)); | printf(" Command ID: %u\n", letoh(entry->cid)); | ||||
| /* TODO: Export nvme_status_string structures from kernel? */ | /* TODO: Export nvme_status_string structures from kernel? */ | ||||
| printf(" Status:\n"); | printf(" Status:\n"); | ||||
| printf(" Phase tag: %d\n", p); | printf(" Phase tag: %d\n", p); | ||||
| printf(" Status code: %d\n", sc); | printf(" Status code: %d\n", sc); | ||||
| printf(" Status code type: %d\n", sct); | printf(" Status code type: %d\n", sct); | ||||
| printf(" More: %d\n", m); | printf(" More: %d\n", m); | ||||
| printf(" DNR: %d\n", dnr); | printf(" DNR: %d\n", dnr); | ||||
| printf(" Error location: %u\n", LE2H(entry->error_location)); | printf(" Error location: %u\n", letoh(entry->error_location)); | ||||
| printf(" LBA: %ju\n", LE2H(entry->lba)); | printf(" LBA: %ju\n", letoh(entry->lba)); | ||||
| printf(" Namespace ID: %u\n", LE2H(entry->nsid)); | printf(" Namespace ID: %u\n", letoh(entry->nsid)); | ||||
| printf(" Vendor specific info: %u\n", LE2H(entry->vendor_specific)); | printf(" Vendor specific info: %u\n", letoh(entry->vendor_specific)); | ||||
| printf(" Transport type: %u\n", LE2H(entry->trtype)); | printf(" Transport type: %u\n", letoh(entry->trtype)); | ||||
| printf(" Command specific info:%ju\n", LE2H(entry->csi)); | printf(" Command specific info:%ju\n", letoh(entry->csi)); | ||||
| printf(" Transport specific: %u\n", LE2H(entry->ttsi)); | printf(" Transport specific: %u\n", letoh(entry->ttsi)); | ||||
| } | } | ||||
| } | } | ||||
| void | void | ||||
| print_temp_K(uint16_t t) | print_temp_K(uint16_t t) | ||||
| { | { | ||||
| printf("%u K, %2.2f C, %3.2f F\n", t, (float)t - 273.15, (float)t * 9 / 5 - 459.67); | printf("%u K, %2.2f C, %3.2f F\n", t, (float)t - 273.15, (float)t * 9 / 5 - 459.67); | ||||
| } | } | ||||
| void | void | ||||
| print_temp_C(uint16_t t) | print_temp_C(uint16_t t) | ||||
| { | { | ||||
| printf("%2.2f K, %u C, %3.2f F\n", (float)t + 273.15, t, (float)t * 9 / 5 + 32); | printf("%2.2f K, %u C, %3.2f F\n", (float)t + 273.15, t, (float)t * 9 / 5 + 32); | ||||
| } | } | ||||
| static void | static void | ||||
| print_log_health(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused) | print_log_health(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused) | ||||
| { | { | ||||
| struct nvme_health_information_page *health = buf; | struct nvme_health_information_page *health = buf; | ||||
| char cbuf[UINT128_DIG + 1]; | char cbuf[UINT128_DIG + 1]; | ||||
| uint8_t warning; | uint8_t warning; | ||||
| int i; | int i; | ||||
| warning = health->critical_warning; | warning = letoh(health->critical_warning); | ||||
| printf("SMART/Health Information Log\n"); | printf("SMART/Health Information Log\n"); | ||||
| printf("============================\n"); | printf("============================\n"); | ||||
| printf("Critical Warning State: 0x%02x\n", warning); | printf("Critical Warning State: 0x%02x\n", warning); | ||||
| printf(" Available spare: %d\n", | printf(" Available spare: %d\n", | ||||
| !!(warning & NVME_CRIT_WARN_ST_AVAILABLE_SPARE)); | !!(warning & NVME_CRIT_WARN_ST_AVAILABLE_SPARE)); | ||||
| printf(" Temperature: %d\n", | printf(" Temperature: %d\n", | ||||
| !!(warning & NVME_CRIT_WARN_ST_TEMPERATURE)); | !!(warning & NVME_CRIT_WARN_ST_TEMPERATURE)); | ||||
| printf(" Device reliability: %d\n", | printf(" Device reliability: %d\n", | ||||
| !!(warning & NVME_CRIT_WARN_ST_DEVICE_RELIABILITY)); | !!(warning & NVME_CRIT_WARN_ST_DEVICE_RELIABILITY)); | ||||
| printf(" Read only: %d\n", | printf(" Read only: %d\n", | ||||
| !!(warning & NVME_CRIT_WARN_ST_READ_ONLY)); | !!(warning & NVME_CRIT_WARN_ST_READ_ONLY)); | ||||
| printf(" Volatile memory backup: %d\n", | printf(" Volatile memory backup: %d\n", | ||||
| !!(warning & NVME_CRIT_WARN_ST_VOLATILE_MEMORY_BACKUP)); | !!(warning & NVME_CRIT_WARN_ST_VOLATILE_MEMORY_BACKUP)); | ||||
| printf("Temperature: "); | printf("Temperature: "); | ||||
| print_temp_K(health->temperature); | print_temp_K(letoh(health->temperature)); | ||||
| printf("Available spare: %u\n", | printf("Available spare: %u\n", | ||||
| health->available_spare); | letoh(health->available_spare)); | ||||
| printf("Available spare threshold: %u\n", | printf("Available spare threshold: %u\n", | ||||
| health->available_spare_threshold); | letoh(health->available_spare_threshold)); | ||||
| printf("Percentage used: %u\n", | printf("Percentage used: %u\n", | ||||
| health->percentage_used); | letoh(health->percentage_used)); | ||||
| printf("Data units (512,000 byte) read: %s\n", | printf("Data units (512,000 byte) read: %s\n", | ||||
| uint128_to_str(to128(health->data_units_read), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->data_units_read), cbuf, sizeof(cbuf))); | ||||
| printf("Data units written: %s\n", | printf("Data units written: %s\n", | ||||
| uint128_to_str(to128(health->data_units_written), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->data_units_written), cbuf, sizeof(cbuf))); | ||||
| printf("Host read commands: %s\n", | printf("Host read commands: %s\n", | ||||
| uint128_to_str(to128(health->host_read_commands), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->host_read_commands), cbuf, sizeof(cbuf))); | ||||
| printf("Host write commands: %s\n", | printf("Host write commands: %s\n", | ||||
| uint128_to_str(to128(health->host_write_commands), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->host_write_commands), cbuf, sizeof(cbuf))); | ||||
| printf("Controller busy time (minutes): %s\n", | printf("Controller busy time (minutes): %s\n", | ||||
| uint128_to_str(to128(health->controller_busy_time), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->controller_busy_time), cbuf, sizeof(cbuf))); | ||||
| printf("Power cycles: %s\n", | printf("Power cycles: %s\n", | ||||
| uint128_to_str(to128(health->power_cycles), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->power_cycles), cbuf, sizeof(cbuf))); | ||||
| printf("Power on hours: %s\n", | printf("Power on hours: %s\n", | ||||
| uint128_to_str(to128(health->power_on_hours), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->power_on_hours), cbuf, sizeof(cbuf))); | ||||
| printf("Unsafe shutdowns: %s\n", | printf("Unsafe shutdowns: %s\n", | ||||
| uint128_to_str(to128(health->unsafe_shutdowns), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->unsafe_shutdowns), cbuf, sizeof(cbuf))); | ||||
| printf("Media errors: %s\n", | printf("Media errors: %s\n", | ||||
| uint128_to_str(to128(health->media_errors), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->media_errors), cbuf, sizeof(cbuf))); | ||||
| printf("No. error info log entries: %s\n", | printf("No. error info log entries: %s\n", | ||||
| uint128_to_str(to128(health->num_error_info_log_entries), cbuf, sizeof(cbuf))); | uint128_to_str(to128(health->num_error_info_log_entries), cbuf, sizeof(cbuf))); | ||||
| printf("Warning Temp Composite Time: %d\n", health->warning_temp_time); | printf("Warning Temp Composite Time: %d\n", letoh(health->warning_temp_time)); | ||||
| printf("Error Temp Composite Time: %d\n", health->error_temp_time); | printf("Error Temp Composite Time: %d\n", letoh(health->error_temp_time)); | ||||
| for (i = 0; i < 8; i++) { | for (i = 0; i < 8; i++) { | ||||
| if (health->temp_sensor[i] == 0) | if (letoh(health->temp_sensor[i]) == 0) | ||||
| continue; | continue; | ||||
| printf("Temperature Sensor %d: ", i + 1); | printf("Temperature Sensor %d: ", i + 1); | ||||
| print_temp_K(health->temp_sensor[i]); | print_temp_K(letoh(health->temp_sensor[i])); | ||||
| } | } | ||||
| printf("Temperature 1 Transition Count: %d\n", health->tmt1tc); | printf("Temperature 1 Transition Count: %d\n", letoh(health->tmt1tc)); | ||||
| printf("Temperature 2 Transition Count: %d\n", health->tmt2tc); | printf("Temperature 2 Transition Count: %d\n", letoh(health->tmt2tc)); | ||||
| printf("Total Time For Temperature 1: %d\n", health->ttftmt1); | printf("Total Time For Temperature 1: %d\n", letoh(health->ttftmt1)); | ||||
| printf("Total Time For Temperature 2: %d\n", health->ttftmt2); | printf("Total Time For Temperature 2: %d\n", letoh(health->ttftmt2)); | ||||
| } | } | ||||
| static void | static void | ||||
| print_log_firmware(const struct nvme_controller_data *cdata, void *buf, uint32_t size __unused) | print_log_firmware(const struct nvme_controller_data *cdata, void *buf, uint32_t size __unused) | ||||
| { | { | ||||
| int i, slots; | int i, slots; | ||||
| const char *status; | const char *status; | ||||
| struct nvme_firmware_page *fw = buf; | struct nvme_firmware_page *fw = buf; | ||||
| ▲ Show 20 Lines • Show All 433 Lines • Show Last 20 Lines | |||||