aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/nvme-core.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index 8efa728f1eac..9f2b424c445e 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -1739,10 +1739,15 @@ static int set_queue_count(struct nvme_dev *dev, int count)
1739 return min(result & 0xffff, result >> 16) + 1; 1739 return min(result & 0xffff, result >> 16) + 1;
1740} 1740}
1741 1741
1742static size_t db_bar_size(struct nvme_dev *dev, unsigned nr_io_queues)
1743{
1744 return 4096 + ((nr_io_queues + 1) << (dev->db_stride + 3));
1745}
1746
1742static int nvme_setup_io_queues(struct nvme_dev *dev) 1747static int nvme_setup_io_queues(struct nvme_dev *dev)
1743{ 1748{
1744 struct pci_dev *pdev = dev->pci_dev; 1749 struct pci_dev *pdev = dev->pci_dev;
1745 int result, cpu, i, vecs, nr_io_queues, db_bar_size, q_depth; 1750 int result, cpu, i, vecs, nr_io_queues, size, q_depth;
1746 1751
1747 nr_io_queues = num_online_cpus(); 1752 nr_io_queues = num_online_cpus();
1748 result = set_queue_count(dev, nr_io_queues); 1753 result = set_queue_count(dev, nr_io_queues);
@@ -1751,17 +1756,24 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
1751 if (result < nr_io_queues) 1756 if (result < nr_io_queues)
1752 nr_io_queues = result; 1757 nr_io_queues = result;
1753 1758
1754 /* Deregister the admin queue's interrupt */ 1759 size = db_bar_size(dev, nr_io_queues);
1755 free_irq(dev->entry[0].vector, dev->queues[0]); 1760 if (size > 8192) {
1756
1757 db_bar_size = 4096 + ((nr_io_queues + 1) << (dev->db_stride + 3));
1758 if (db_bar_size > 8192) {
1759 iounmap(dev->bar); 1761 iounmap(dev->bar);
1760 dev->bar = ioremap(pci_resource_start(pdev, 0), db_bar_size); 1762 do {
1763 dev->bar = ioremap(pci_resource_start(pdev, 0), size);
1764 if (dev->bar)
1765 break;
1766 if (!--nr_io_queues)
1767 return -ENOMEM;
1768 size = db_bar_size(dev, nr_io_queues);
1769 } while (1);
1761 dev->dbs = ((void __iomem *)dev->bar) + 4096; 1770 dev->dbs = ((void __iomem *)dev->bar) + 4096;
1762 dev->queues[0]->q_db = dev->dbs; 1771 dev->queues[0]->q_db = dev->dbs;
1763 } 1772 }
1764 1773
1774 /* Deregister the admin queue's interrupt */
1775 free_irq(dev->entry[0].vector, dev->queues[0]);
1776
1765 vecs = nr_io_queues; 1777 vecs = nr_io_queues;
1766 for (i = 0; i < vecs; i++) 1778 for (i = 0; i < vecs; i++)
1767 dev->entry[i].entry = i; 1779 dev->entry[i].entry = i;
@@ -1799,8 +1811,10 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
1799 nr_io_queues = vecs; 1811 nr_io_queues = vecs;
1800 1812
1801 result = queue_request_irq(dev, dev->queues[0], "nvme admin"); 1813 result = queue_request_irq(dev, dev->queues[0], "nvme admin");
1802 if (result) 1814 if (result) {
1815 dev->queues[0]->q_suspended = 1;
1803 goto free_queues; 1816 goto free_queues;
1817 }
1804 1818
1805 /* Free previously allocated queues that are no longer usable */ 1819 /* Free previously allocated queues that are no longer usable */
1806 spin_lock(&dev_list_lock); 1820 spin_lock(&dev_list_lock);