From 5df15facd2d3d033493b0423ee81508fe43c5402 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Mon, 18 Jun 2018 14:47:24 -0700 Subject: [PATCH] nvme: add path status codes (TP 4028) Change-Id: Ifac14f74f6b7681fccbf463f744d145ae8299240 Signed-off-by: Daniel Verkamp Reviewed-on: https://review.gerrithub.io/415892 Reviewed-by: Ben Walker Reviewed-by: Jim Harris Tested-by: SPDK Automated Test System --- include/spdk/nvme_spec.h | 21 ++++++++++++++++-- lib/nvme/nvme_qpair.c | 22 +++++++++++++++++++ .../lib/nvme/nvme_qpair.c/nvme_qpair_ut.c | 10 +++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/spdk/nvme_spec.h b/include/spdk/nvme_spec.h index c1812f8c8..dacf6d1d2 100644 --- a/include/spdk/nvme_spec.h +++ b/include/spdk/nvme_spec.h @@ -562,7 +562,8 @@ enum spdk_nvme_status_code_type { SPDK_NVME_SCT_GENERIC = 0x0, SPDK_NVME_SCT_COMMAND_SPECIFIC = 0x1, SPDK_NVME_SCT_MEDIA_ERROR = 0x2, - /* 0x3-0x6 - reserved */ + SPDK_NVME_SCT_PATH = 0x3, + /* 0x4-0x6 - reserved */ SPDK_NVME_SCT_VENDOR_SPECIFIC = 0x7, }; @@ -669,6 +670,18 @@ enum spdk_nvme_media_error_status_code { SPDK_NVME_SC_DEALLOCATED_OR_UNWRITTEN_BLOCK = 0x87, }; +/** + * Path related status codes + */ +enum spdk_nvme_path_status_code { + SPDK_NVME_SC_INTERNAL_PATH_ERROR = 0x00, + + SPDK_NVME_SC_CONTROLLER_PATH_ERROR = 0x60, + + SPDK_NVME_SC_HOST_PATH_ERROR = 0x70, + SPDK_NVME_SC_ABORTED_BY_HOST = 0x71, +}; + /** * Admin opcodes */ @@ -1728,7 +1741,11 @@ struct spdk_nvme_error_information_entry { uint64_t lba; uint32_t nsid; uint8_t vendor_specific; - uint8_t reserved[35]; + uint8_t trtype; + uint8_t reserved30[2]; + uint64_t command_specific; + uint16_t trtype_specific; + uint8_t reserved42[22]; }; SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_error_information_entry) == 64, "Incorrect size"); diff --git a/lib/nvme/nvme_qpair.c b/lib/nvme/nvme_qpair.c index af99ca8da..b738ed2f4 100644 --- a/lib/nvme/nvme_qpair.c +++ b/lib/nvme/nvme_qpair.c @@ -249,6 +249,14 @@ static const struct nvme_string media_error_status[] = { { 0xFFFF, "MEDIA ERROR" } }; +static const struct nvme_string path_status[] = { + { SPDK_NVME_SC_INTERNAL_PATH_ERROR, "INTERNAL PATH ERROR" }, + { SPDK_NVME_SC_CONTROLLER_PATH_ERROR, "CONTROLLER PATH ERROR" }, + { SPDK_NVME_SC_HOST_PATH_ERROR, "HOST PATH ERROR" }, + { SPDK_NVME_SC_ABORTED_BY_HOST, "ABORTED BY HOST" }, + { 0xFFFF, "PATH ERROR" } +}; + static const char * get_status_string(uint16_t sct, uint16_t sc) { @@ -264,6 +272,9 @@ get_status_string(uint16_t sct, uint16_t sc) case SPDK_NVME_SCT_MEDIA_ERROR: entry = media_error_status; break; + case SPDK_NVME_SCT_PATH: + entry = path_status; + break; case SPDK_NVME_SCT_VENDOR_SPECIFIC: return "VENDOR SPECIFIC"; default: @@ -319,6 +330,17 @@ nvme_completion_is_retry(const struct spdk_nvme_cpl *cpl) default: return false; } + case SPDK_NVME_SCT_PATH: + /* + * Per NVMe TP 4028 (Path and Transport Error Enhancments), retries should be + * based on the setting of the DNR bit for Internal Path Error + */ + switch ((int)cpl->status.sc) { + case SPDK_NVME_SC_INTERNAL_PATH_ERROR: + return !cpl->status.dnr; + default: + return false; + } case SPDK_NVME_SCT_COMMAND_SPECIFIC: case SPDK_NVME_SCT_MEDIA_ERROR: case SPDK_NVME_SCT_VENDOR_SPECIFIC: diff --git a/test/unit/lib/nvme/nvme_qpair.c/nvme_qpair_ut.c b/test/unit/lib/nvme/nvme_qpair.c/nvme_qpair_ut.c index 72dd5d6ae..75cd147fa 100644 --- a/test/unit/lib/nvme/nvme_qpair.c/nvme_qpair_ut.c +++ b/test/unit/lib/nvme/nvme_qpair.c/nvme_qpair_ut.c @@ -278,6 +278,16 @@ static void test_nvme_completion_is_retry(void) cpl.status.sct = SPDK_NVME_SCT_MEDIA_ERROR; CU_ASSERT_FALSE(nvme_completion_is_retry(&cpl)); + cpl.status.sct = SPDK_NVME_SCT_PATH; + cpl.status.sc = SPDK_NVME_SC_INTERNAL_PATH_ERROR; + cpl.status.dnr = 0; + CU_ASSERT_TRUE(nvme_completion_is_retry(&cpl)); + + cpl.status.sct = SPDK_NVME_SCT_PATH; + cpl.status.sc = SPDK_NVME_SC_INTERNAL_PATH_ERROR; + cpl.status.dnr = 1; + CU_ASSERT_FALSE(nvme_completion_is_retry(&cpl)); + cpl.status.sct = SPDK_NVME_SCT_VENDOR_SPECIFIC; CU_ASSERT_FALSE(nvme_completion_is_retry(&cpl));