Commit c257e5b4 authored by Wenbo Wang's avatar Wenbo Wang Committed by Daniel Verkamp
Browse files

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

parent f78bcc48
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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.
+19 −0
Original line number Diff line number Diff line
@@ -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) {
+9 −0
Original line number Diff line number Diff line
@@ -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 {
+1 −0
Original line number Diff line number Diff line
@@ -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												}
};