diff mbox

[U-Boot,06/14] nvme: Respect timeout when en/disabling the controller

Message ID 1503414919-30820-7-git-send-email-bmeng.cn@gmail.com
State Accepted
Commit 04d2a3840110e495a119e6226b5c38936b48988a
Delegated to: Tom Rini
Headers show

Commit Message

Bin Meng Aug. 22, 2017, 3:15 p.m. UTC
So far the driver unconditionally delays 10ms when en/disabling the
controller and still return 0 if 10ms times out. In fact, spec defines
a timeout value in the CAP register that is the worst case time that
host software shall wait for the controller to become ready.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

 drivers/nvme/nvme.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

Comments

Tom Rini Aug. 29, 2017, 2:56 a.m. UTC | #1
On Tue, Aug 22, 2017 at 08:15:11AM -0700, Bin Meng wrote:

> So far the driver unconditionally delays 10ms when en/disabling the
> controller and still return 0 if 10ms times out. In fact, spec defines
> a timeout value in the CAP register that is the worst case time that
> host software shall wait for the controller to become ready.
> 
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot/master, thanks!
diff mbox

Patch

diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index d92273e..8867977 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -47,11 +47,19 @@  struct nvme_queue {
 static int nvme_wait_ready(struct nvme_dev *dev, bool enabled)
 {
 	u32 bit = enabled ? NVME_CSTS_RDY : 0;
+	int timeout;
+	ulong start;
 
-	while ((readl(&dev->bar->csts) & NVME_CSTS_RDY) != bit)
-		udelay(10000);
+	/* Timeout field in the CAP register is in 500 millisecond units */
+	timeout = NVME_CAP_TIMEOUT(dev->cap) * 500;
 
-	return 0;
+	start = get_timer(0);
+	while (get_timer(start) < timeout) {
+		if ((readl(&dev->bar->csts) & NVME_CSTS_RDY) == bit)
+			return 0;
+	}
+
+	return -ETIME;
 }
 
 static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,