diff options
-rw-r--r-- | sys/dev/nvme/nvme.h | 13 | ||||
-rw-r--r-- | sys/dev/nvme/nvme_ctrlr_cmd.c | 19 | ||||
-rw-r--r-- | sys/dev/nvme/nvme_private.h | 5 |
3 files changed, 37 insertions, 0 deletions
diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h index 748261f..6983e12 100644 --- a/sys/dev/nvme/nvme.h +++ b/sys/dev/nvme/nvme.h @@ -622,6 +622,19 @@ enum nvme_log_page { /* 0xC0-0xFF - vendor specific */ }; +struct nvme_error_information_entry { + + uint64_t error_count; + uint16_t sqid; + uint16_t cid; + struct nvme_status status; + uint16_t error_location; + uint64_t lba; + uint32_t nsid; + uint8_t vendor_specific; + uint8_t reserved[35]; +} __packed __aligned(4); + union nvme_critical_warning_state { uint8_t raw; diff --git a/sys/dev/nvme/nvme_ctrlr_cmd.c b/sys/dev/nvme/nvme_ctrlr_cmd.c index f56f9e0..240b15f 100644 --- a/sys/dev/nvme/nvme_ctrlr_cmd.c +++ b/sys/dev/nvme/nvme_ctrlr_cmd.c @@ -267,6 +267,25 @@ nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr, uint8_t log_page, nvme_ctrlr_submit_admin_request(ctrlr, req); } +void +nvme_ctrlr_cmd_get_error_page(struct nvme_controller *ctrlr, + struct nvme_error_information_entry *payload, uint32_t num_entries, + nvme_cb_fn_t cb_fn, void *cb_arg) +{ + + KASSERT(num_entries > 0, ("%s called with num_entries==0\n", __func__)); + + /* Controller's error log page entries is 0-based. */ + if (num_entries > (ctrlr->cdata.elpe + 1)) { + printf("%s num_entries=%d cdata.elpe=%d\n", + __func__, num_entries, ctrlr->cdata.elpe); + num_entries = ctrlr->cdata.elpe + 1; + } + + nvme_ctrlr_cmd_get_log_page(ctrlr, NVME_LOG_ERROR, + NVME_GLOBAL_NAMESPACE_TAG, payload, sizeof(*payload) * num_entries, + cb_fn, cb_arg); +} void nvme_ctrlr_cmd_get_health_information_page(struct nvme_controller *ctrlr, diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h index 406a2e0..d988be5 100644 --- a/sys/dev/nvme/nvme_private.h +++ b/sys/dev/nvme/nvme_private.h @@ -342,6 +342,11 @@ void nvme_ctrlr_cmd_set_interrupt_coalescing(struct nvme_controller *ctrlr, uint32_t threshold, nvme_cb_fn_t cb_fn, void *cb_arg); +void nvme_ctrlr_cmd_get_error_page(struct nvme_controller *ctrlr, + struct nvme_error_information_entry *payload, + uint32_t num_entries, /* 0 = max */ + nvme_cb_fn_t cb_fn, + void *cb_arg); void nvme_ctrlr_cmd_get_health_information_page(struct nvme_controller *ctrlr, uint32_t nsid, struct nvme_health_information_page *payload, |