From a2d3ea8cb3d063748c1c940e5cf3a196d4d6421e Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Fri, 19 Feb 2021 15:03:52 +0100 Subject: [PATCH] external_code/nvme: initial controller initialization definitions After enumerating and attaching NVMe controllers, they're now initialized at the end of nvme_probe()/nvme_connect(). For now, they're immediately marked as initialized, but subsequent patches will replace it with an actual initialization. Signed-off-by: Konrad Sztyber Change-Id: I22137bb10e871c7e79c28053c8ec98a835e11147 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6672 Tested-by: SPDK CI Jenkins Community-CI: Mellanox Build Bot Reviewed-by: Tomasz Zawadzki Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- test/external_code/nvme/nvme.c | 54 ++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/test/external_code/nvme/nvme.c b/test/external_code/nvme/nvme.c index 6946e4d14..32b987ee6 100644 --- a/test/external_code/nvme/nvme.c +++ b/test/external_code/nvme/nvme.c @@ -71,6 +71,27 @@ struct nvme_qpair { uint32_t num_entries; }; +enum nvme_ctrlr_state { + /* Controller has not been initialized yet */ + NVME_CTRLR_STATE_INIT, + /* Waiting for CSTS.RDY to transition from 0 to 1 so that CC.EN may be set to 0 */ + NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1, + /* Waiting for CSTS.RDY to transition from 1 to 0 so that CC.EN may be set to 1 */ + NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0, + /* Enable the controller by writing CC.EN to 1 */ + NVME_CTRLR_STATE_ENABLE, + /* Waiting for CSTS.RDY to transition from 0 to 1 after enabling the controller */ + NVME_CTRLR_STATE_ENABLE_WAIT_FOR_READY_1, + /* Identify Controller command will be sent to then controller */ + NVME_CTRLR_STATE_IDENTIFY, + /* Waiting for Identify Controller command to be completed */ + NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY, + /* Controller initialization has completed and the controller is ready */ + NVME_CTRLR_STATE_READY, + /* Controller initialization error */ + NVME_CTRLR_STATE_ERROR, +}; + struct nvme_ctrlr { /* Underlying PCI device */ struct spdk_pci_device *pci_device; @@ -82,6 +103,8 @@ struct nvme_ctrlr { uint32_t page_size; /* Admin queue pair */ struct nvme_qpair *admin_qpair; + /* State of the controller */ + enum nvme_ctrlr_state state; TAILQ_ENTRY(nvme_ctrlr) tailq; }; @@ -336,6 +359,15 @@ pcie_enum_cb(void *ctx, struct spdk_pci_device *pci_dev) return 0; } +static int +process_ctrlr_init(struct nvme_ctrlr *ctrlr) +{ + /* Immediately mark the controller as ready for now */ + ctrlr->state = NVME_CTRLR_STATE_READY; + + return 0; +} + static void free_ctrlr(struct nvme_ctrlr *ctrlr) { @@ -372,12 +404,24 @@ probe_internal(struct spdk_pci_addr *addr, nvme_attach_cb attach_cb, void *cb_ct return rc; } - TAILQ_FOREACH_SAFE(ctrlr, &ctrlrs, tailq, tmp) { - TAILQ_REMOVE(&ctrlrs, ctrlr, tailq); - TAILQ_INSERT_TAIL(&g_nvme_ctrlrs, ctrlr, tailq); + while (!TAILQ_EMPTY(&ctrlrs)) { + TAILQ_FOREACH_SAFE(ctrlr, &ctrlrs, tailq, tmp) { + rc = process_ctrlr_init(ctrlr); + if (rc != 0) { + SPDK_ERRLOG("NVMe controller initialization failed\n"); + TAILQ_REMOVE(&ctrlrs, ctrlr, tailq); + free_ctrlr(ctrlr); + continue; + } - if (attach_cb != NULL) { - attach_cb(cb_ctx, &ctrlr->pci_device->addr, ctrlr); + if (ctrlr->state == NVME_CTRLR_STATE_READY) { + TAILQ_REMOVE(&ctrlrs, ctrlr, tailq); + TAILQ_INSERT_TAIL(&g_nvme_ctrlrs, ctrlr, tailq); + + if (attach_cb != NULL) { + attach_cb(cb_ctx, &ctrlr->pci_device->addr, ctrlr); + } + } } }