diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 072c55b72..7a1674e4f 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -41,6 +41,7 @@ static int nvme_ctrlr_construct_and_submit_aer(struct spdk_nvme_ctrlr *ctrlr, struct nvme_async_event_request *aer); static int nvme_ctrlr_identify_ns_async(struct spdk_nvme_ns *ns); +static int nvme_ctrlr_identify_id_desc_async(struct spdk_nvme_ns *ns); static int nvme_ctrlr_get_cc(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_cc_register *cc) @@ -640,7 +641,9 @@ nvme_ctrlr_state_string(enum nvme_ctrlr_state state) case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS: return "wait for identify ns"; case NVME_CTRLR_STATE_IDENTIFY_ID_DESCS: - return "identify id descriptor"; + return "identify namespace id descriptors"; + case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_ID_DESCS: + return "wait for identify namespace id descriptors"; case NVME_CTRLR_STATE_CONFIGURE_AER: return "configure AER"; case NVME_CTRLR_STATE_WAIT_FOR_CONFIGURE_AER: @@ -1036,6 +1039,46 @@ nvme_ctrlr_identify_namespaces(struct spdk_nvme_ctrlr *ctrlr) return rc; } +static void +nvme_ctrlr_identify_id_desc_async_done(void *arg, const struct spdk_nvme_cpl *cpl) +{ + struct spdk_nvme_ns *ns = (struct spdk_nvme_ns *)arg; + struct spdk_nvme_ctrlr *ctrlr = ns->ctrlr; + uint32_t nsid; + int rc; + + if (spdk_nvme_cpl_is_error(cpl)) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); + return; + } + + /* move on to the next active NS */ + nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, ns->id); + ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid); + if (ns == NULL) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); + return; + } + + rc = nvme_ctrlr_identify_id_desc_async(ns); + if (rc) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_ERROR, NVME_TIMEOUT_INFINITE); + } +} + +static int +nvme_ctrlr_identify_id_desc_async(struct spdk_nvme_ns *ns) +{ + struct spdk_nvme_ctrlr *ctrlr = ns->ctrlr; + + memset(ns->id_desc_list, 0, sizeof(ns->id_desc_list)); + + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_ID_DESCS, NVME_TIMEOUT_INFINITE); + return nvme_ctrlr_cmd_identify(ns->ctrlr, SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST, + 0, ns->id, ns->id_desc_list, sizeof(ns->id_desc_list), + nvme_ctrlr_identify_id_desc_async_done, ns); +} + static int nvme_ctrlr_identify_id_desc_namespaces(struct spdk_nvme_ctrlr *ctrlr) { @@ -1043,19 +1086,27 @@ nvme_ctrlr_identify_id_desc_namespaces(struct spdk_nvme_ctrlr *ctrlr) struct spdk_nvme_ns *ns; int rc; - for (nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); - nsid != 0; nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, nsid)) { - ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid); - if (ns == NULL) { - continue; - } - rc = nvme_ctrlr_identify_id_desc(ns); - if (rc < 0) { - return rc; - } + if (ctrlr->vs.raw < SPDK_NVME_VERSION(1, 3, 0) || + (ctrlr->quirks & NVME_QUIRK_IDENTIFY_CNS)) { + SPDK_DEBUGLOG(SPDK_LOG_NVME, "Version < 1.3; not attempting to retrieve NS ID Descriptor List\n"); + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); + return 0; } - return 0; + nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); + ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid); + if (ns == NULL) { + /* No active NS, move on to the next state */ + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); + return 0; + } + + rc = nvme_ctrlr_identify_id_desc_async(ns); + if (rc) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_ERROR, NVME_TIMEOUT_INFINITE); + } + + return rc; } static void @@ -1952,6 +2003,10 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr) nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_CONFIGURE_AER, NVME_TIMEOUT_INFINITE); break; + case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_ID_DESCS: + spdk_nvme_qpair_process_completions(ctrlr->adminq, 0); + break; + case NVME_CTRLR_STATE_CONFIGURE_AER: rc = nvme_ctrlr_configure_aer(ctrlr); break; diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index c2c851c1d..10dc08ab6 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -469,10 +469,16 @@ enum nvme_ctrlr_state { NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS, /** - * Get Identify Namespace Identification Descriptor. + * Get Identify Namespace Identification Descriptors. */ NVME_CTRLR_STATE_IDENTIFY_ID_DESCS, + /** + * Waiting for the Identify Namespace Identification + * Descriptors to be completed. + */ + NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_ID_DESCS, + /** * Configure AER of the controller. */ @@ -807,7 +813,6 @@ int nvme_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req); int nvme_ctrlr_identify_active_ns(struct spdk_nvme_ctrlr *ctrlr); -int nvme_ctrlr_identify_id_desc(struct spdk_nvme_ns *ns); void nvme_ns_set_identify_data(struct spdk_nvme_ns *ns); int nvme_ns_construct(struct spdk_nvme_ns *ns, uint32_t id, struct spdk_nvme_ctrlr *ctrlr); diff --git a/lib/nvme/nvme_ns.c b/lib/nvme/nvme_ns.c index 799d2dfea..b88bf1746 100644 --- a/lib/nvme/nvme_ns.c +++ b/lib/nvme/nvme_ns.c @@ -130,7 +130,7 @@ nvme_ctrlr_identify_ns(struct spdk_nvme_ns *ns) return 0; } -int +static int nvme_ctrlr_identify_id_desc(struct spdk_nvme_ns *ns) { struct nvme_completion_poll_status status;