NVMe: Disable admin queue on init failure
authorKeith Busch <keith.busch@intel.com>
Mon, 16 Dec 2013 18:50:00 +0000 (13:50 -0500)
committerMatthew Wilcox <matthew.r.wilcox@intel.com>
Tue, 28 Jan 2014 01:11:38 +0000 (20:11 -0500)
Disable the admin queue if device fails during initialization so the
queue's irq is freed.

Signed-off-by: Keith Busch <keith.busch@intel.com>
[rewritten to use nvme_free_queues]
Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
drivers/block/nvme-core.c

index 7b615a063e925dcaae7f9eeff9e48c6c648ff19b..89021d710ec21995f8f66a070f72fe0c5af495ec 100644 (file)
@@ -1152,11 +1152,11 @@ static void nvme_free_queue(struct nvme_queue *nvmeq)
        kfree(nvmeq);
 }
 
-static void nvme_free_queues(struct nvme_dev *dev)
+static void nvme_free_queues(struct nvme_dev *dev, int lowest)
 {
        int i;
 
-       for (i = dev->queue_count - 1; i >= 0; i--) {
+       for (i = dev->queue_count - 1; i >= lowest; i--) {
                nvme_free_queue(dev->queues[i]);
                dev->queue_count--;
                dev->queues[i] = NULL;
@@ -1991,7 +1991,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
        return 0;
 
  free_queues:
-       nvme_free_queues(dev);
+       nvme_free_queues(dev, 1);
        return result;
 }
 
@@ -2411,6 +2411,7 @@ static int nvme_dev_start(struct nvme_dev *dev)
        return result;
 
  disable:
+       nvme_disable_queue(dev, 0);
        spin_lock(&dev_list_lock);
        list_del_init(&dev->node);
        spin_unlock(&dev_list_lock);
@@ -2542,7 +2543,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  shutdown:
        nvme_dev_shutdown(dev);
  release_pools:
-       nvme_free_queues(dev);
+       nvme_free_queues(dev, 0);
        nvme_release_prp_pools(dev);
  release:
        nvme_release_instance(dev);
@@ -2566,7 +2567,7 @@ static void nvme_remove(struct pci_dev *pdev)
        misc_deregister(&dev->miscdev);
        nvme_dev_remove(dev);
        nvme_dev_shutdown(dev);
-       nvme_free_queues(dev);
+       nvme_free_queues(dev, 0);
        nvme_release_instance(dev);
        nvme_release_prp_pools(dev);
        kref_put(&dev->kref, nvme_free_dev);