Commit b00a726a authored by Keith Busch's avatar Keith Busch Committed by Jens Axboe

NVMe: Don't unmap controller registers on reset

Unmapping the registers on reset or shutdown is not necessary. Keeping
the mapping simplifies reset handling.
Signed-off-by: default avatarKeith Busch <keith.busch@intel.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent e827091c
...@@ -1694,10 +1694,10 @@ static int nvme_dev_add(struct nvme_dev *dev) ...@@ -1694,10 +1694,10 @@ static int nvme_dev_add(struct nvme_dev *dev)
return 0; return 0;
} }
static int nvme_dev_map(struct nvme_dev *dev) static int nvme_pci_enable(struct nvme_dev *dev)
{ {
u64 cap; u64 cap;
int bars, result = -ENOMEM; int result = -ENOMEM;
struct pci_dev *pdev = to_pci_dev(dev->dev); struct pci_dev *pdev = to_pci_dev(dev->dev);
if (pci_enable_device_mem(pdev)) if (pci_enable_device_mem(pdev))
...@@ -1705,24 +1705,14 @@ static int nvme_dev_map(struct nvme_dev *dev) ...@@ -1705,24 +1705,14 @@ static int nvme_dev_map(struct nvme_dev *dev)
dev->entry[0].vector = pdev->irq; dev->entry[0].vector = pdev->irq;
pci_set_master(pdev); pci_set_master(pdev);
bars = pci_select_bars(pdev, IORESOURCE_MEM);
if (!bars)
goto disable_pci;
if (pci_request_selected_regions(pdev, bars, "nvme"))
goto disable_pci;
if (dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(64)) && if (dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(64)) &&
dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(32))) dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(32)))
goto disable; goto disable;
dev->bar = ioremap(pci_resource_start(pdev, 0), 8192);
if (!dev->bar)
goto disable;
if (readl(dev->bar + NVME_REG_CSTS) == -1) { if (readl(dev->bar + NVME_REG_CSTS) == -1) {
result = -ENODEV; result = -ENODEV;
goto unmap; goto disable;
} }
/* /*
...@@ -1732,7 +1722,7 @@ static int nvme_dev_map(struct nvme_dev *dev) ...@@ -1732,7 +1722,7 @@ static int nvme_dev_map(struct nvme_dev *dev)
if (!pdev->irq) { if (!pdev->irq) {
result = pci_enable_msix(pdev, dev->entry, 1); result = pci_enable_msix(pdev, dev->entry, 1);
if (result < 0) if (result < 0)
goto unmap; goto disable;
} }
cap = lo_hi_readq(dev->bar + NVME_REG_CAP); cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
...@@ -1759,17 +1749,19 @@ static int nvme_dev_map(struct nvme_dev *dev) ...@@ -1759,17 +1749,19 @@ static int nvme_dev_map(struct nvme_dev *dev)
pci_save_state(pdev); pci_save_state(pdev);
return 0; return 0;
unmap:
iounmap(dev->bar);
dev->bar = NULL;
disable: disable:
pci_release_regions(pdev);
disable_pci:
pci_disable_device(pdev); pci_disable_device(pdev);
return result; return result;
} }
static void nvme_dev_unmap(struct nvme_dev *dev) static void nvme_dev_unmap(struct nvme_dev *dev)
{
if (dev->bar)
iounmap(dev->bar);
pci_release_regions(to_pci_dev(dev->dev));
}
static void nvme_pci_disable(struct nvme_dev *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev->dev); struct pci_dev *pdev = to_pci_dev(dev->dev);
...@@ -1778,12 +1770,6 @@ static void nvme_dev_unmap(struct nvme_dev *dev) ...@@ -1778,12 +1770,6 @@ static void nvme_dev_unmap(struct nvme_dev *dev)
else if (pdev->msix_enabled) else if (pdev->msix_enabled)
pci_disable_msix(pdev); pci_disable_msix(pdev);
if (dev->bar) {
iounmap(dev->bar);
dev->bar = NULL;
pci_release_regions(pdev);
}
if (pci_is_enabled(pdev)) { if (pci_is_enabled(pdev)) {
pci_disable_pcie_error_reporting(pdev); pci_disable_pcie_error_reporting(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
...@@ -1842,7 +1828,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) ...@@ -1842,7 +1828,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
nvme_dev_list_remove(dev); nvme_dev_list_remove(dev);
mutex_lock(&dev->shutdown_lock); mutex_lock(&dev->shutdown_lock);
if (dev->bar) { if (pci_is_enabled(to_pci_dev(dev->dev))) {
nvme_stop_queues(&dev->ctrl); nvme_stop_queues(&dev->ctrl);
csts = readl(dev->bar + NVME_REG_CSTS); csts = readl(dev->bar + NVME_REG_CSTS);
} }
...@@ -1855,7 +1841,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) ...@@ -1855,7 +1841,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
nvme_disable_io_queues(dev); nvme_disable_io_queues(dev);
nvme_disable_admin_queue(dev, shutdown); nvme_disable_admin_queue(dev, shutdown);
} }
nvme_dev_unmap(dev); nvme_pci_disable(dev);
for (i = dev->queue_count - 1; i >= 0; i--) for (i = dev->queue_count - 1; i >= 0; i--)
nvme_clear_queue(dev->queues[i]); nvme_clear_queue(dev->queues[i]);
...@@ -1911,12 +1897,12 @@ static void nvme_reset_work(struct work_struct *work) ...@@ -1911,12 +1897,12 @@ static void nvme_reset_work(struct work_struct *work)
* If we're called to reset a live controller first shut it down before * If we're called to reset a live controller first shut it down before
* moving on. * moving on.
*/ */
if (dev->bar) if (dev->ctrl.ctrl_config & NVME_CC_ENABLE)
nvme_dev_disable(dev, false); nvme_dev_disable(dev, false);
set_bit(NVME_CTRL_RESETTING, &dev->flags); set_bit(NVME_CTRL_RESETTING, &dev->flags);
result = nvme_dev_map(dev); result = nvme_pci_enable(dev);
if (result) if (result)
goto out; goto out;
...@@ -2042,6 +2028,27 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { ...@@ -2042,6 +2028,27 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
.free_ctrl = nvme_pci_free_ctrl, .free_ctrl = nvme_pci_free_ctrl,
}; };
static int nvme_dev_map(struct nvme_dev *dev)
{
int bars;
struct pci_dev *pdev = to_pci_dev(dev->dev);
bars = pci_select_bars(pdev, IORESOURCE_MEM);
if (!bars)
return -ENODEV;
if (pci_request_selected_regions(pdev, bars, "nvme"))
return -ENODEV;
dev->bar = ioremap(pci_resource_start(pdev, 0), 8192);
if (!dev->bar)
goto release;
return 0;
release:
pci_release_regions(pdev);
return -ENODEV;
}
static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
int node, result = -ENOMEM; int node, result = -ENOMEM;
...@@ -2066,6 +2073,10 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2066,6 +2073,10 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev->dev = get_device(&pdev->dev); dev->dev = get_device(&pdev->dev);
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
result = nvme_dev_map(dev);
if (result)
goto free;
INIT_LIST_HEAD(&dev->node); INIT_LIST_HEAD(&dev->node);
INIT_WORK(&dev->scan_work, nvme_dev_scan); INIT_WORK(&dev->scan_work, nvme_dev_scan);
INIT_WORK(&dev->reset_work, nvme_reset_work); INIT_WORK(&dev->reset_work, nvme_reset_work);
...@@ -2089,6 +2100,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2089,6 +2100,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
nvme_release_prp_pools(dev); nvme_release_prp_pools(dev);
put_pci: put_pci:
put_device(dev->dev); put_device(dev->dev);
nvme_dev_unmap(dev);
free: free:
kfree(dev->queues); kfree(dev->queues);
kfree(dev->entry); kfree(dev->entry);
...@@ -2126,6 +2138,7 @@ static void nvme_remove(struct pci_dev *pdev) ...@@ -2126,6 +2138,7 @@ static void nvme_remove(struct pci_dev *pdev)
nvme_free_queues(dev, 0); nvme_free_queues(dev, 0);
nvme_release_cmb(dev); nvme_release_cmb(dev);
nvme_release_prp_pools(dev); nvme_release_prp_pools(dev);
nvme_dev_unmap(dev);
nvme_put_ctrl(&dev->ctrl); nvme_put_ctrl(&dev->ctrl);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment