diff options
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r-- | drivers/mmc/card/block.c | 83 |
1 files changed, 39 insertions, 44 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1fa4c80ff88..4409d79ed65 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -78,13 +78,16 @@ static int perdev_minors = CONFIG_MMC_BLOCK_MINORS; /* * We've only got one major, so number of mmcblk devices is - * limited to 256 / number of minors per device. + * limited to (1 << 20) / number of minors per device. It is also + * currently limited by the size of the static bitmaps below. */ static int max_devices; -/* 256 minors, so at most 256 separate devices */ -static DECLARE_BITMAP(dev_use, 256); -static DECLARE_BITMAP(name_use, 256); +#define MAX_DEVICES 256 + +/* TODO: Replace these with struct ida */ +static DECLARE_BITMAP(dev_use, MAX_DEVICES); +static DECLARE_BITMAP(name_use, MAX_DEVICES); /* * There is one mmc_blk_data per slot. @@ -112,7 +115,7 @@ struct mmc_blk_data { /* * Only set in main mmc_blk_data associated - * with mmc_card with mmc_set_drvdata, and keeps + * with mmc_card with dev_set_drvdata, and keeps * track of the current selected device partition. */ unsigned int part_curr; @@ -260,7 +263,7 @@ static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, int ret; struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); - ret = snprintf(buf, PAGE_SIZE, "%d", + ret = snprintf(buf, PAGE_SIZE, "%d\n", get_disk_ro(dev_to_disk(dev)) ^ md->read_only); mmc_blk_put(md); @@ -642,7 +645,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card, struct mmc_blk_data *md) { int ret; - struct mmc_blk_data *main_md = mmc_get_drvdata(card); + struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); if (main_md->part_curr == md->part_type) return 0; @@ -1004,7 +1007,8 @@ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host, err = mmc_hw_reset(host); /* Ensure we switch back to the correct partition */ if (err != -EOPNOTSUPP) { - struct mmc_blk_data *main_md = mmc_get_drvdata(host->card); + struct mmc_blk_data *main_md = + dev_get_drvdata(&host->card->dev); int part_err; main_md->part_curr = main_md->part_type; @@ -1308,19 +1312,11 @@ static int mmc_blk_packed_err_check(struct mmc_card *card, } if (status & R1_EXCEPTION_EVENT) { - ext_csd = kzalloc(512, GFP_KERNEL); - if (!ext_csd) { - pr_err("%s: unable to allocate buffer for ext_csd\n", - req->rq_disk->disk_name); - return -ENOMEM; - } - - err = mmc_send_ext_csd(card, ext_csd); + err = mmc_get_ext_csd(card, &ext_csd); if (err) { pr_err("%s: error %d sending ext_csd\n", req->rq_disk->disk_name, err); - check = MMC_BLK_ABORT; - goto free; + return MMC_BLK_ABORT; } if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] & @@ -1338,7 +1334,6 @@ static int mmc_blk_packed_err_check(struct mmc_card *card, req->rq_disk->disk_name, packed->nr_entries, packed->blocks, packed->idx_failure); } -free: kfree(ext_csd); } @@ -2093,7 +2088,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, /* * !subname implies we are creating main mmc_blk_data that will be - * associated with mmc_card with mmc_set_drvdata. Due to device + * associated with mmc_card with dev_set_drvdata. Due to device * partitions, devidx will not coincide with a per-physical card * index anymore so we keep track of a name index. */ @@ -2425,8 +2420,9 @@ static const struct mmc_fixup blk_fixups[] = END_FIXUP }; -static int mmc_blk_probe(struct mmc_card *card) +static int mmc_blk_probe(struct device *dev) { + struct mmc_card *card = mmc_dev_to_card(dev); struct mmc_blk_data *md, *part_md; char cap_str[10]; @@ -2451,7 +2447,7 @@ static int mmc_blk_probe(struct mmc_card *card) if (mmc_blk_alloc_parts(card, md)) goto out; - mmc_set_drvdata(card, md); + dev_set_drvdata(dev, md); if (mmc_add_disk(md)) goto out; @@ -2481,9 +2477,10 @@ static int mmc_blk_probe(struct mmc_card *card) return 0; } -static void mmc_blk_remove(struct mmc_card *card) +static int mmc_blk_remove(struct device *dev) { - struct mmc_blk_data *md = mmc_get_drvdata(card); + struct mmc_card *card = mmc_dev_to_card(dev); + struct mmc_blk_data *md = dev_get_drvdata(dev); mmc_blk_remove_parts(card, md); pm_runtime_get_sync(&card->dev); @@ -2494,13 +2491,15 @@ static void mmc_blk_remove(struct mmc_card *card) pm_runtime_disable(&card->dev); pm_runtime_put_noidle(&card->dev); mmc_blk_remove_req(md); - mmc_set_drvdata(card, NULL); + dev_set_drvdata(dev, NULL); + + return 0; } -static int _mmc_blk_suspend(struct mmc_card *card) +static int _mmc_blk_suspend(struct device *dev) { struct mmc_blk_data *part_md; - struct mmc_blk_data *md = mmc_get_drvdata(card); + struct mmc_blk_data *md = dev_get_drvdata(dev); if (md) { mmc_queue_suspend(&md->queue); @@ -2511,21 +2510,21 @@ static int _mmc_blk_suspend(struct mmc_card *card) return 0; } -static void mmc_blk_shutdown(struct mmc_card *card) +static void mmc_blk_shutdown(struct device *dev) { - _mmc_blk_suspend(card); + _mmc_blk_suspend(dev); } -#ifdef CONFIG_PM -static int mmc_blk_suspend(struct mmc_card *card) +#ifdef CONFIG_PM_SLEEP +static int mmc_blk_suspend(struct device *dev) { - return _mmc_blk_suspend(card); + return _mmc_blk_suspend(dev); } -static int mmc_blk_resume(struct mmc_card *card) +static int mmc_blk_resume(struct device *dev) { struct mmc_blk_data *part_md; - struct mmc_blk_data *md = mmc_get_drvdata(card); + struct mmc_blk_data *md = dev_get_drvdata(dev); if (md) { /* @@ -2540,19 +2539,15 @@ static int mmc_blk_resume(struct mmc_card *card) } return 0; } -#else -#define mmc_blk_suspend NULL -#define mmc_blk_resume NULL #endif -static struct mmc_driver mmc_driver = { - .drv = { - .name = "mmcblk", - }, +static SIMPLE_DEV_PM_OPS(mmc_blk_pm_ops, mmc_blk_suspend, mmc_blk_resume); + +static struct device_driver mmc_driver = { + .name = "mmcblk", + .pm = &mmc_blk_pm_ops, .probe = mmc_blk_probe, .remove = mmc_blk_remove, - .suspend = mmc_blk_suspend, - .resume = mmc_blk_resume, .shutdown = mmc_blk_shutdown, }; @@ -2563,7 +2558,7 @@ static int __init mmc_blk_init(void) if (perdev_minors != CONFIG_MMC_BLOCK_MINORS) pr_info("mmcblk: using %d minors per device\n", perdev_minors); - max_devices = 256 / perdev_minors; + max_devices = min(MAX_DEVICES, (1 << MINORBITS) / perdev_minors); res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); if (res) |