diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2016-04-07 14:36:46 +0200 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2016-05-02 10:33:37 +0200 |
commit | b10fa99e9a5f8b37a4eae1522048a327fe7ce480 (patch) | |
tree | bf50b2483f0e2e0f92d420f594483a128a7c6144 /drivers | |
parent | 06b5cca5e7f797b8fffa269fa6298a84256c3295 (diff) |
mmc: block: Convert to IDA for partition device indexes
Instead of using an mmc specific implementation to deal with indexes
through a BITMAP, let's convert to use the IDA library.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/card/block.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 9aaf22e676c4..9ce679255775 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -35,6 +35,7 @@ #include <linux/capability.h> #include <linux/compat.h> #include <linux/pm_runtime.h> +#include <linux/idr.h> #include <linux/mmc/ioctl.h> #include <linux/mmc/card.h> @@ -78,14 +79,14 @@ static int perdev_minors = CONFIG_MMC_BLOCK_MINORS; /* * We've only got one major, so number of mmcblk devices is * limited to (1 << 20) / number of minors per device. It is also - * currently limited by the size of the static bitmaps below. + * limited by the MAX_DEVICES below. */ static int max_devices; #define MAX_DEVICES 256 -/* TODO: Replace these with struct ida */ -static DECLARE_BITMAP(dev_use, MAX_DEVICES); +static DEFINE_IDA(mmc_blk_ida); +static DEFINE_SPINLOCK(mmc_blk_lock); /* * There is one mmc_blk_data per slot. @@ -178,7 +179,9 @@ static void mmc_blk_put(struct mmc_blk_data *md) int devidx = mmc_get_devidx(md->disk); blk_cleanup_queue(md->queue.queue); - __clear_bit(devidx, dev_use); + spin_lock(&mmc_blk_lock); + ida_remove(&mmc_blk_ida, devidx); + spin_unlock(&mmc_blk_lock); put_disk(md->disk); kfree(md); @@ -2189,10 +2192,23 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, struct mmc_blk_data *md; int devidx, ret; - devidx = find_first_zero_bit(dev_use, max_devices); - if (devidx >= max_devices) - return ERR_PTR(-ENOSPC); - __set_bit(devidx, dev_use); +again: + if (!ida_pre_get(&mmc_blk_ida, GFP_KERNEL)) + return ERR_PTR(-ENOMEM); + + spin_lock(&mmc_blk_lock); + ret = ida_get_new(&mmc_blk_ida, &devidx); + spin_unlock(&mmc_blk_lock); + + if (ret == -EAGAIN) + goto again; + else if (ret) + return ERR_PTR(ret); + + if (devidx >= max_devices) { + ret = -ENOSPC; + goto out; + } md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL); if (!md) { @@ -2289,7 +2305,9 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, err_kfree: kfree(md); out: - __clear_bit(devidx, dev_use); + spin_lock(&mmc_blk_lock); + ida_remove(&mmc_blk_ida, devidx); + spin_unlock(&mmc_blk_lock); return ERR_PTR(ret); } |