Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22605f96 authored by Matthew Wilcox's avatar Matthew Wilcox
Browse files

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: default avatarMatthew Wilcox <matthew.r.wilcox@intel.com>
parent aba2080f
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -893,6 +893,8 @@ static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev)
{
	int result;
	u32 aqa;
	u64 cap;
	unsigned long timeout;
	struct nvme_queue *nvmeq;

	dev->dbs = ((void __iomem *)dev->bar) + 4096;
@@ -915,10 +917,18 @@ static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev)
	writeq(nvmeq->cq_dma_addr, &dev->bar->acq);
	writel(dev->ctrl_config, &dev->bar->cc);

	cap = readq(&dev->bar->cap);
	timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;

	while (!(readl(&dev->bar->csts) & NVME_CSTS_RDY)) {
		msleep(100);
		if (fatal_signal_pending(current))
			return -EINTR;
		if (time_after(jiffies, timeout)) {
			dev_err(&dev->pci_dev->dev,
				"Device not ready; aborting initialisation\n");
			return -ENODEV;
		}
	}

	result = queue_request_irq(dev, nvmeq, "nvme admin");
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ struct nvme_bar {
	__u64			acq;	/* Admin CQ Base Address */
};

#define NVME_CAP_TIMEOUT(cap)	(((cap) >> 24) & 0xff)

enum {
	NVME_CC_ENABLE		= 1 << 0,
	NVME_CC_CSS_NVM		= 0 << 4,