diff options
Diffstat (limited to 'drivers/block/nvme.c')
-rw-r--r-- | drivers/block/nvme.c | 10 |
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"); |