diff options
author | Bin Meng <bmeng.cn@gmail.com> | 2017-08-22 08:15:11 -0700 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-08-28 07:17:12 -0400 |
commit | 04d2a3840110e495a119e6226b5c38936b48988a (patch) | |
tree | 8e7a8f85fad4e1eefde64dd0a0b62b766af269f6 /drivers/nvme/nvme.c | |
parent | b65c6921433c8fcf306b4671f9f9f7c68c36cefc (diff) |
nvme: Respect timeout when en/disabling the controller
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>
Diffstat (limited to 'drivers/nvme/nvme.c')
-rw-r--r-- | drivers/nvme/nvme.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index d92273e67f..88679773a7 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, |