aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/nvme.c
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew.r.wilcox@intel.com>2011-04-19 15:04:20 -0400
committerMatthew Wilcox <matthew.r.wilcox@intel.com>2011-11-04 15:53:02 -0400
commit22605f96810d073eb74051d0295b6577d6a6a563 (patch)
treef5af6aebe31f92cd6fe6bc343a931984ef7aa0f2 /drivers/block/nvme.c
parentaba2080f3f1639f9202f1a52993669844abcfb80 (diff)
NVMe: Time out initialisation after a few seconds
THe device reports (in its capability register) how long it will take to initialise. If that time elapses before the ready bit becomes set, conclude the device is broken and refuse to initialise it. Log a nice error message so the user knows why we did nothing. Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
Diffstat (limited to 'drivers/block/nvme.c')
-rw-r--r--drivers/block/nvme.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index bcc780ac4ec0..57f2b33a47dd 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -893,6 +893,8 @@ static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev)
893{ 893{
894 int result; 894 int result;
895 u32 aqa; 895 u32 aqa;
896 u64 cap;
897 unsigned long timeout;
896 struct nvme_queue *nvmeq; 898 struct nvme_queue *nvmeq;
897 899
898 dev->dbs = ((void __iomem *)dev->bar) + 4096; 900 dev->dbs = ((void __iomem *)dev->bar) + 4096;
@@ -915,10 +917,18 @@ static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev)
915 writeq(nvmeq->cq_dma_addr, &dev->bar->acq); 917 writeq(nvmeq->cq_dma_addr, &dev->bar->acq);
916 writel(dev->ctrl_config, &dev->bar->cc); 918 writel(dev->ctrl_config, &dev->bar->cc);
917 919
920 cap = readq(&dev->bar->cap);
921 timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
922
918 while (!(readl(&dev->bar->csts) & NVME_CSTS_RDY)) { 923 while (!(readl(&dev->bar->csts) & NVME_CSTS_RDY)) {
919 msleep(100); 924 msleep(100);
920 if (fatal_signal_pending(current)) 925 if (fatal_signal_pending(current))
921 return -EINTR; 926 return -EINTR;
927 if (time_after(jiffies, timeout)) {
928 dev_err(&dev->pci_dev->dev,
929 "Device not ready; aborting initialisation\n");
930 return -ENODEV;
931 }
922 } 932 }
923 933
924 result = queue_request_irq(dev, nvmeq, "nvme admin"); 934 result = queue_request_irq(dev, nvmeq, "nvme admin");