]> git.sur5r.net Git - u-boot/commitdiff
nvme: Respect timeout when en/disabling the controller
authorBin Meng <bmeng.cn@gmail.com>
Tue, 22 Aug 2017 15:15:11 +0000 (08:15 -0700)
committerTom Rini <trini@konsulko.com>
Mon, 28 Aug 2017 11:17:12 +0000 (07:17 -0400)
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

index d92273e67f7ba61f61b12675d06cc72a393a9a97..88679773a7a7d5e7ca25534f83d9a9386c1a5161 100644 (file)
@@ -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,