nvme: add quirk to delay checking device readiness (#56)

This commit is contained in:
Wenbo Wang 2016-10-27 14:34:32 +08:00 committed by Daniel Verkamp
parent f78bcc4821
commit c257e5b4ad
4 changed files with 30 additions and 0 deletions

View File

@ -46,6 +46,7 @@ extern "C" {
#define SPDK_PCI_ANY_ID 0xffff
#define SPDK_PCI_VID_INTEL 0x8086
#define SPDK_PCI_VID_MEMBLAZE 0x1c5f
/**
* PCI class code for NVMe devices.

View File

@ -731,6 +731,17 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr)
uint32_t ready_timeout_in_ms;
int rc;
/*
* May need to avoid accessing any register on the target controller
* for a while. Return early without touching the FSM.
* Check sleep_timeout_tsc > 0 for unit test.
*/
if ((ctrlr->sleep_timeout_tsc > 0) &&
(spdk_get_ticks() <= ctrlr->sleep_timeout_tsc)) {
return 0;
}
ctrlr->sleep_timeout_tsc = 0;
if (nvme_ctrlr_get_cc(ctrlr, &cc) ||
nvme_ctrlr_get_csts(ctrlr, &csts)) {
SPDK_TRACELOG(SPDK_TRACE_NVME, "get registers failed\n");
@ -766,6 +777,14 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr)
return -EIO;
}
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0, ready_timeout_in_ms);
/*
* Wait 2 secsonds before accessing PCI registers.
* Not using sleep() to avoid blocking other controller's initialization.
*/
if (ctrlr->quirks & NVME_QUIRK_DELAY_BEFORE_CHK_RDY) {
ctrlr->sleep_timeout_tsc = spdk_get_ticks() + 2 * spdk_get_ticks_hz();
}
return 0;
} else {
if (csts.bits.rdy == 1) {

View File

@ -70,6 +70,12 @@
*/
#define NVME_INTEL_QUIRK_WRITE_LATENCY 0x2
/*
* The controller needs a delay before starts checking the device
* readiness, which is done by reading the NVME_CSTS_RDY bit.
*/
#define NVME_QUIRK_DELAY_BEFORE_CHK_RDY 0x4
#define NVME_MAX_ASYNC_EVENTS (8)
#define NVME_MIN_TIMEOUT_PERIOD (5)
@ -390,6 +396,9 @@ struct spdk_nvme_ctrlr {
struct spdk_pci_addr pci_addr;
uint64_t quirks;
/* Extra sleep time during controller initialization */
uint64_t sleep_timeout_tsc;
};
struct nvme_driver {

View File

@ -45,6 +45,7 @@ static const struct nvme_quirk nvme_quirks[] = {
{{SPDK_PCI_VID_INTEL, 0x0953, SPDK_PCI_VID_INTEL, 0x3705}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY },
{{SPDK_PCI_VID_INTEL, 0x0953, SPDK_PCI_VID_INTEL, 0x3709}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY },
{{SPDK_PCI_VID_INTEL, 0x0953, SPDK_PCI_VID_INTEL, 0x370a}, NVME_INTEL_QUIRK_READ_LATENCY | NVME_INTEL_QUIRK_WRITE_LATENCY },
{{SPDK_PCI_VID_MEMBLAZE, 0x0540, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, NVME_QUIRK_DELAY_BEFORE_CHK_RDY },
{{0x0000, 0x0000, 0x0000, 0x0000}, 0 }
};