diff options
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r-- | drivers/mmc/card/block.c | 83 | ||||
-rw-r--r-- | drivers/mmc/card/mmc_test.c | 28 | ||||
-rw-r--r-- | drivers/mmc/card/queue.c | 16 |
3 files changed, 65 insertions, 62 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1fa4c80ff886..4409d79ed650 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) diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 0c0fc52d42c5..0a7430f94d29 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -14,6 +14,7 @@ #include <linux/mmc/host.h> #include <linux/mmc/mmc.h> #include <linux/slab.h> +#include <linux/device.h> #include <linux/scatterlist.h> #include <linux/swap.h> /* For nr_free_buffer_pages() */ @@ -32,6 +33,8 @@ #define BUFFER_ORDER 2 #define BUFFER_SIZE (PAGE_SIZE << BUFFER_ORDER) +#define TEST_ALIGN_END 8 + /* * Limit the test area size to the maximum MMC HC erase group size. Note that * the maximum SD allocation unit size is just 4MiB. @@ -1174,7 +1177,7 @@ static int mmc_test_align_write(struct mmc_test_card *test) int ret, i; struct scatterlist sg; - for (i = 1;i < 4;i++) { + for (i = 1; i < TEST_ALIGN_END; i++) { sg_init_one(&sg, test->buffer + i, 512); ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1); if (ret) @@ -1189,7 +1192,7 @@ static int mmc_test_align_read(struct mmc_test_card *test) int ret, i; struct scatterlist sg; - for (i = 1;i < 4;i++) { + for (i = 1; i < TEST_ALIGN_END; i++) { sg_init_one(&sg, test->buffer + i, 512); ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0); if (ret) @@ -1216,7 +1219,7 @@ static int mmc_test_align_multi_write(struct mmc_test_card *test) if (size < 1024) return RESULT_UNSUP_HOST; - for (i = 1;i < 4;i++) { + for (i = 1; i < TEST_ALIGN_END; i++) { sg_init_one(&sg, test->buffer + i, size); ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); if (ret) @@ -1243,7 +1246,7 @@ static int mmc_test_align_multi_read(struct mmc_test_card *test) if (size < 1024) return RESULT_UNSUP_HOST; - for (i = 1;i < 4;i++) { + for (i = 1; i < TEST_ALIGN_END; i++) { sg_init_one(&sg, test->buffer + i, size); ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); if (ret) @@ -2997,8 +3000,9 @@ err: return ret; } -static int mmc_test_probe(struct mmc_card *card) +static int mmc_test_probe(struct device *dev) { + struct mmc_card *card = mmc_dev_to_card(dev); int ret; if (!mmc_card_mmc(card) && !mmc_card_sd(card)) @@ -3013,20 +3017,22 @@ static int mmc_test_probe(struct mmc_card *card) return 0; } -static void mmc_test_remove(struct mmc_card *card) +static int mmc_test_remove(struct device *dev) { + struct mmc_card *card = mmc_dev_to_card(dev); + mmc_test_free_result(card); mmc_test_free_dbgfs_file(card); + + return 0; } -static void mmc_test_shutdown(struct mmc_card *card) +static void mmc_test_shutdown(struct device *dev) { } -static struct mmc_driver mmc_driver = { - .drv = { - .name = "mmc_test", - }, +static struct device_driver mmc_driver = { + .name = "mmc_test", .probe = mmc_test_probe, .remove = mmc_test_remove, .shutdown = mmc_test_shutdown, diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index cfa6110632c3..236d194c2883 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -232,13 +232,15 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, if (!mqrq_cur->bounce_buf) { pr_warn("%s: unable to allocate bounce cur buffer\n", mmc_card_name(card)); - } - mqrq_prev->bounce_buf = kmalloc(bouncesz, GFP_KERNEL); - if (!mqrq_prev->bounce_buf) { - pr_warn("%s: unable to allocate bounce prev buffer\n", - mmc_card_name(card)); - kfree(mqrq_cur->bounce_buf); - mqrq_cur->bounce_buf = NULL; + } else { + mqrq_prev->bounce_buf = + kmalloc(bouncesz, GFP_KERNEL); + if (!mqrq_prev->bounce_buf) { + pr_warn("%s: unable to allocate bounce prev buffer\n", + mmc_card_name(card)); + kfree(mqrq_cur->bounce_buf); + mqrq_cur->bounce_buf = NULL; + } } } |