nvme: add new SET_EN_0 state for ctrlr initialization
This removes some code that was duplicated in the CHECK_EN and DISABLE_WAIT_FOR_READY_1 states. Signed-off-by: Jim Harris <james.r.harris@intel.com> Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Change-Id: Ie5d175540f71c692f7784c7ff22a48f34b9b7082 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8614 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Community-CI: Mellanox Build Bot Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
parent
d953072d21
commit
fc8d861892
@ -1237,6 +1237,8 @@ nvme_ctrlr_state_string(enum nvme_ctrlr_state state)
|
|||||||
return "check en";
|
return "check en";
|
||||||
case NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1:
|
case NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1:
|
||||||
return "disable and wait for CSTS.RDY = 1";
|
return "disable and wait for CSTS.RDY = 1";
|
||||||
|
case NVME_CTRLR_STATE_SET_EN_0:
|
||||||
|
return "set CC.EN = 0";
|
||||||
case NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0:
|
case NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0:
|
||||||
return "disable and wait for CSTS.RDY = 0";
|
return "disable and wait for CSTS.RDY = 0";
|
||||||
case NVME_CTRLR_STATE_ENABLE:
|
case NVME_CTRLR_STATE_ENABLE:
|
||||||
@ -3462,56 +3464,44 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr)
|
|||||||
/* Begin the hardware initialization by making sure the controller is disabled. */
|
/* Begin the hardware initialization by making sure the controller is disabled. */
|
||||||
if (cc.bits.en) {
|
if (cc.bits.en) {
|
||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "CC.EN = 1\n");
|
NVME_CTRLR_DEBUGLOG(ctrlr, "CC.EN = 1\n");
|
||||||
/*
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1, ready_timeout_in_ms);
|
||||||
* Controller is currently enabled. We need to disable it to cause a reset.
|
|
||||||
*
|
|
||||||
* If CC.EN = 1 && CSTS.RDY = 0, the controller is in the process of becoming ready.
|
|
||||||
* Wait for the ready bit to be 1 before disabling the controller.
|
|
||||||
*/
|
|
||||||
if (csts.bits.rdy == 0) {
|
|
||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "CC.EN = 1 && CSTS.RDY = 0 - waiting for reset to complete\n");
|
|
||||||
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1, ready_timeout_in_ms);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CC.EN = 1 && CSTS.RDY == 1, so we can immediately disable the controller. */
|
|
||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "Setting CC.EN = 0\n");
|
|
||||||
cc.bits.en = 0;
|
|
||||||
if (nvme_ctrlr_set_cc(ctrlr, &cc)) {
|
|
||||||
NVME_CTRLR_ERRLOG(ctrlr, "set_cc() failed\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0, ready_timeout_in_ms);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wait 2.5 seconds before accessing PCI registers.
|
|
||||||
* Not using sleep() to avoid blocking other controller's initialization.
|
|
||||||
*/
|
|
||||||
if (ctrlr->quirks & NVME_QUIRK_DELAY_BEFORE_CHK_RDY) {
|
|
||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "Applying quirk: delay 2.5 seconds before reading registers\n");
|
|
||||||
ctrlr->sleep_timeout_tsc = ticks + (2500 * spdk_get_ticks_hz() / 1000);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else {
|
} else {
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
break;
|
return 0;
|
||||||
|
|
||||||
case NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1:
|
case NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1:
|
||||||
|
/*
|
||||||
|
* Controller is currently enabled. We need to disable it to cause a reset.
|
||||||
|
*
|
||||||
|
* If CC.EN = 1 && CSTS.RDY = 0, the controller is in the process of becoming ready.
|
||||||
|
* Wait for the ready bit to be 1 before disabling the controller.
|
||||||
|
*/
|
||||||
if (csts.bits.rdy == 1) {
|
if (csts.bits.rdy == 1) {
|
||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "CC.EN = 1 && CSTS.RDY = 1 - disabling controller\n");
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_SET_EN_0, ready_timeout_in_ms);
|
||||||
/* CC.EN = 1 && CSTS.RDY = 1, so we can set CC.EN = 0 now. */
|
} else {
|
||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "Setting CC.EN = 0\n");
|
NVME_CTRLR_DEBUGLOG(ctrlr, "CC.EN = 1 && CSTS.RDY = 0 - waiting for reset to complete\n");
|
||||||
cc.bits.en = 0;
|
|
||||||
if (nvme_ctrlr_set_cc(ctrlr, &cc)) {
|
|
||||||
NVME_CTRLR_ERRLOG(ctrlr, "set_cc() failed\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0, ready_timeout_in_ms);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
break;
|
return 0;
|
||||||
|
|
||||||
|
case NVME_CTRLR_STATE_SET_EN_0:
|
||||||
|
NVME_CTRLR_DEBUGLOG(ctrlr, "Setting CC.EN = 0\n");
|
||||||
|
cc.bits.en = 0;
|
||||||
|
if (nvme_ctrlr_set_cc(ctrlr, &cc)) {
|
||||||
|
NVME_CTRLR_ERRLOG(ctrlr, "set_cc() failed\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0, ready_timeout_in_ms);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait 2.5 seconds before accessing PCI registers.
|
||||||
|
* Not using sleep() to avoid blocking other controller's initialization.
|
||||||
|
*/
|
||||||
|
if (ctrlr->quirks & NVME_QUIRK_DELAY_BEFORE_CHK_RDY) {
|
||||||
|
NVME_CTRLR_DEBUGLOG(ctrlr, "Applying quirk: delay 2.5 seconds before reading registers\n");
|
||||||
|
ctrlr->sleep_timeout_tsc = ticks + (2500 * spdk_get_ticks_hz() / 1000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
case NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0:
|
case NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0:
|
||||||
if (csts.bits.rdy == 0) {
|
if (csts.bits.rdy == 0) {
|
||||||
|
@ -578,6 +578,11 @@ enum nvme_ctrlr_state {
|
|||||||
*/
|
*/
|
||||||
NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1,
|
NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disabling the controller by setting CC.EN to 0.
|
||||||
|
*/
|
||||||
|
NVME_CTRLR_STATE_SET_EN_0,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waiting for CSTS.RDY to transition from 1 to 0 so that CC.EN may be set to 1.
|
* Waiting for CSTS.RDY to transition from 1 to 0 so that CC.EN may be set to 1.
|
||||||
*/
|
*/
|
||||||
|
@ -724,6 +724,8 @@ test_nvme_ctrlr_init_en_1_rdy_0(void)
|
|||||||
*/
|
*/
|
||||||
g_ut_nvme_regs.csts.bits.rdy = 1;
|
g_ut_nvme_regs.csts.bits.rdy = 1;
|
||||||
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
||||||
|
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_SET_EN_0);
|
||||||
|
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
||||||
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0);
|
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0);
|
||||||
CU_ASSERT(g_ut_nvme_regs.cc.bits.en == 0);
|
CU_ASSERT(g_ut_nvme_regs.cc.bits.en == 0);
|
||||||
|
|
||||||
@ -777,7 +779,7 @@ test_nvme_ctrlr_init_en_1_rdy_1(void)
|
|||||||
ctrlr.cdata.nn = 1;
|
ctrlr.cdata.nn = 1;
|
||||||
ctrlr.page_size = 0x1000;
|
ctrlr.page_size = 0x1000;
|
||||||
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_INIT);
|
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_INIT);
|
||||||
while (ctrlr.state != NVME_CTRLR_STATE_CHECK_EN) {
|
while (ctrlr.state != NVME_CTRLR_STATE_SET_EN_0) {
|
||||||
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
||||||
}
|
}
|
||||||
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user