diff options
author | Quoc-Son Anh <quoc-sonx.anh@intel.com> | 2012-02-21 16:50:53 -0700 |
---|---|---|
committer | Matthew Wilcox <matthew.r.wilcox@intel.com> | 2012-07-31 13:31:34 -0400 |
commit | cd58ad7d188c643cf572b038909c2f7dd96fdafe (patch) | |
tree | 187986ed44f50b6a71b33819561a98754efe04c9 | |
parent | 0ac13140d796eb1e2f8956aea97a6e5e4ebcf981 (diff) | |
download | blackbird-op-linux-cd58ad7d188c643cf572b038909c2f7dd96fdafe.tar.gz blackbird-op-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>
-rw-r--r-- | drivers/block/nvme.c | 31 |
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); |