summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorQuoc-Son Anh <quoc-sonx.anh@intel.com>2012-02-22 00:50:53 +0100
committerMatthew Wilcox <matthew.r.wilcox@intel.com>2012-07-31 19:31:34 +0200
commitcd58ad7d188c643cf572b038909c2f7dd96fdafe (patch)
tree187986ed44f50b6a71b33819561a98754efe04c9 /drivers/block
parentNVMe: Fix whitespace damage in nvme_init (diff)
downloadlinux-cd58ad7d188c643cf572b038909c2f7dd96fdafe.tar.xz
linux-cd58ad7d188c643cf572b038909c2f7dd96fdafe.zip
NVMe: Use ida for nvme device instance
Signed-off-by: Quoc-Son Anh <quoc-sonx.anh@intel.com> Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/nvme.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index 0ba6b7cb344b..3278fbdb8dc0 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -1576,15 +1576,33 @@ static void nvme_release_prp_pools(struct nvme_dev *dev)
dma_pool_destroy(dev->prp_small_pool);
}
-/* XXX: Use an ida or something to let remove / add work correctly */
-static void nvme_set_instance(struct nvme_dev *dev)
+static DEFINE_IDA(nvme_instance_ida);
+
+static int nvme_set_instance(struct nvme_dev *dev)
{
- static int instance;
- dev->instance = instance++;
+ int instance, error;
+
+ do {
+ if (!ida_pre_get(&nvme_instance_ida, GFP_KERNEL))
+ return -ENODEV;
+
+ spin_lock(&dev_list_lock);
+ error = ida_get_new(&nvme_instance_ida, &instance);
+ spin_unlock(&dev_list_lock);
+ } while (error == -EAGAIN);
+
+ if (error)
+ return -ENODEV;
+
+ dev->instance = instance;
+ return 0;
}
static void nvme_release_instance(struct nvme_dev *dev)
{
+ spin_lock(&dev_list_lock);
+ ida_remove(&nvme_instance_ida, dev->instance);
+ spin_unlock(&dev_list_lock);
}
static int __devinit nvme_probe(struct pci_dev *pdev,
@@ -1617,7 +1635,10 @@ static int __devinit nvme_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, dev);
dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
- nvme_set_instance(dev);
+ result = nvme_set_instance(dev);
+ if (result)
+ goto disable;
+
dev->entry[0].vector = pdev->irq;
result = nvme_setup_prp_pools(dev);