nvme: handle CC.EN = 0 && CSTS.RDY = 1 on startup
This can happen if the controller is still resetting as the SPDK NVMe driver takes control. Change-Id: I263ae8f2e7b271e0448450557452a115c90c4fb6 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
20f92ad45a
commit
87a3244f97
@ -860,6 +860,15 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr)
|
|||||||
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0, ready_timeout_in_ms);
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0, ready_timeout_in_ms);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
if (csts.bits.rdy == 1) {
|
||||||
|
/*
|
||||||
|
* Controller is in the process of shutting down.
|
||||||
|
* We need to wait for RDY to become 0.
|
||||||
|
*/
|
||||||
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0, ready_timeout_in_ms);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Controller is currently disabled. We can jump straight to enabling it.
|
* Controller is currently disabled. We can jump straight to enabling it.
|
||||||
*/
|
*/
|
||||||
|
@ -425,6 +425,45 @@ test_nvme_ctrlr_init_en_0_rdy_0(void)
|
|||||||
nvme_ctrlr_destruct(&ctrlr);
|
nvme_ctrlr_destruct(&ctrlr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_nvme_ctrlr_init_en_0_rdy_1(void)
|
||||||
|
{
|
||||||
|
struct spdk_nvme_ctrlr ctrlr = {};
|
||||||
|
|
||||||
|
memset(&g_ut_nvme_regs, 0, sizeof(g_ut_nvme_regs));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initial state: CC.EN = 0, CSTS.RDY = 1
|
||||||
|
*/
|
||||||
|
g_ut_nvme_regs.cc.bits.en = 0;
|
||||||
|
g_ut_nvme_regs.csts.bits.rdy = 1;
|
||||||
|
|
||||||
|
SPDK_CU_ASSERT_FATAL(nvme_ctrlr_construct(&ctrlr, NULL) == 0);
|
||||||
|
ctrlr.cdata.nn = 1;
|
||||||
|
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_INIT);
|
||||||
|
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
||||||
|
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transition to CSTS.RDY = 0.
|
||||||
|
* init() should set CC.EN = 1.
|
||||||
|
*/
|
||||||
|
g_ut_nvme_regs.csts.bits.rdy = 0;
|
||||||
|
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
||||||
|
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_ENABLE_WAIT_FOR_READY_1);
|
||||||
|
CU_ASSERT(g_ut_nvme_regs.cc.bits.en == 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transition to CSTS.RDY = 1.
|
||||||
|
*/
|
||||||
|
g_ut_nvme_regs.csts.bits.rdy = 1;
|
||||||
|
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
||||||
|
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_READY);
|
||||||
|
|
||||||
|
g_ut_nvme_regs.csts.bits.shst = SPDK_NVME_SHST_COMPLETE;
|
||||||
|
nvme_ctrlr_destruct(&ctrlr);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_qpairs(struct spdk_nvme_ctrlr *ctrlr, uint32_t num_io_queues)
|
setup_qpairs(struct spdk_nvme_ctrlr *ctrlr, uint32_t num_io_queues)
|
||||||
{
|
{
|
||||||
@ -608,6 +647,8 @@ int main(int argc, char **argv)
|
|||||||
test_nvme_ctrlr_init_en_1_rdy_1) == NULL
|
test_nvme_ctrlr_init_en_1_rdy_1) == NULL
|
||||||
|| CU_add_test(suite, "test nvme_ctrlr init CC.EN = 0 CSTS.RDY = 0",
|
|| CU_add_test(suite, "test nvme_ctrlr init CC.EN = 0 CSTS.RDY = 0",
|
||||||
test_nvme_ctrlr_init_en_0_rdy_0) == NULL
|
test_nvme_ctrlr_init_en_0_rdy_0) == NULL
|
||||||
|
|| CU_add_test(suite, "test nvme_ctrlr init CC.EN = 0 CSTS.RDY = 1",
|
||||||
|
test_nvme_ctrlr_init_en_0_rdy_1) == NULL
|
||||||
|| CU_add_test(suite, "alloc_io_qpair 1", test_alloc_io_qpair_1) == NULL
|
|| CU_add_test(suite, "alloc_io_qpair 1", test_alloc_io_qpair_1) == NULL
|
||||||
|| CU_add_test(suite, "alloc_io_qpair 2", test_alloc_io_qpair_2) == NULL
|
|| CU_add_test(suite, "alloc_io_qpair 2", test_alloc_io_qpair_2) == NULL
|
||||||
|| CU_add_test(suite, "test nvme_ctrlr function nvme_ctrlr_fail", test_nvme_ctrlr_fail) == NULL
|
|| CU_add_test(suite, "test nvme_ctrlr function nvme_ctrlr_fail", test_nvme_ctrlr_fail) == NULL
|
||||||
|
Loading…
Reference in New Issue
Block a user