From 9d4e98e9609bc19d4a8ac4a5c3218358d1820114 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 13 Sep 2008 19:02:07 +0900 Subject: mmc_block: handle error from mmc_register_driver() Check error from mmc_register_driver() and properly unwind block device registration. Signed-off-by: Akinobu Mita Signed-off-by: Pierre Ossman --- drivers/mmc/card/block.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 86dbb366415a..43d9a5b53e8d 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -613,14 +613,19 @@ static struct mmc_driver mmc_driver = { static int __init mmc_blk_init(void) { - int res = -ENOMEM; + int res; res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); if (res) goto out; - return mmc_register_driver(&mmc_driver); + res = mmc_register_driver(&mmc_driver); + if (res) + goto out2; + return 0; + out2: + unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); out: return res; } -- cgit v1.2.3 From a650031a6bd16cb6789da9b3c27fc97341239f12 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 13 Sep 2008 19:03:32 +0900 Subject: mmc_test: initialize mmc_test_lock statically The mutex mmc_test_lock is initialized at every time mmc_test device is probed. Probing another mmc_test device may break the mutex, if the probe function is called while the mutex is locked. This patch fixes it by statically initializing mmc_test_lock. Signed-off-by: Akinobu Mita Signed-off-by: Pierre Ossman --- drivers/mmc/card/mmc_test.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index f26b01d811ae..b92b172074ee 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -1040,7 +1040,7 @@ static const struct mmc_test_case mmc_test_cases[] = { }; -static struct mutex mmc_test_lock; +static DEFINE_MUTEX(mmc_test_lock); static void mmc_test_run(struct mmc_test_card *test, int testcase) { @@ -1171,8 +1171,6 @@ static int mmc_test_probe(struct mmc_card *card) if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD)) return -ENODEV; - mutex_init(&mmc_test_lock); - ret = device_create_file(&card->dev, &dev_attr_test); if (ret) return ret; -- cgit v1.2.3 From a7bbb57333447d0cf950992653b6b079585f3531 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 6 Sep 2008 10:57:57 +0200 Subject: [SCSI] mmc_block: use generic helper to print capacities Signed-off-by: Pierre Ossman Signed-off-by: James Bottomley --- drivers/mmc/card/block.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index ebc8b9d77613..a9b6146807db 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -532,6 +533,8 @@ static int mmc_blk_probe(struct mmc_card *card) struct mmc_blk_data *md; int err; + char cap_str[10]; + /* * Check that the card supports the command class(es) we need. */ @@ -546,10 +549,11 @@ static int mmc_blk_probe(struct mmc_card *card) if (err) goto out; - printk(KERN_INFO "%s: %s %s %lluKiB %s\n", + string_get_size(get_capacity(md->disk) << 9, STRING_UNITS_2, + cap_str, sizeof(cap_str)); + printk(KERN_INFO "%s: %s %s %s %s\n", md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), - (unsigned long long)(get_capacity(md->disk) >> 1), - md->read_only ? "(ro)" : ""); + cap_str, md->read_only ? "(ro)" : ""); mmc_set_drvdata(card, md); add_disk(md->disk); -- cgit v1.2.3 From f331c0296f2a9fee0d396a70598b954062603015 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 3 Sep 2008 09:01:48 +0200 Subject: block: don't depend on consecutive minor space * Implement disk_devt() and part_devt() and use them to directly access devt instead of computing it from ->major and ->first_minor. Note that all references to ->major and ->first_minor outside of block layer is used to determine devt of the disk (the part0) and as ->major and ->first_minor will continue to represent devt for the disk, converting these users aren't strictly necessary. However, convert them for consistency. * Implement disk_max_parts() to avoid directly deferencing genhd->minors. * Update bdget_disk() such that it doesn't assume consecutive minor space. * Move devt computation from register_disk() to add_disk() and make it the only one (all other usages use the initially determined value). These changes clean up the code and will help disk->part dereference fix and extended block device numbers. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/mmc/card/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index ebc8b9d77613..97156b689e82 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -83,7 +83,7 @@ static void mmc_blk_put(struct mmc_blk_data *md) mutex_lock(&open_lock); md->usage--; if (md->usage == 0) { - int devidx = md->disk->first_minor >> MMC_SHIFT; + int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT; __clear_bit(devidx, dev_use); put_disk(md->disk); -- cgit v1.2.3 From f3eb0aaa0211fd804057070bee1fd067cd65cb13 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 16 Aug 2008 21:34:02 +0200 Subject: mmc_block: inform block layer about sector count restriction Make sure we consider the maximum block count when we tell the block layer about the maximum sector count. That way we don't have to chop up the request ourselves. Signed-off-by: Pierre Ossman --- drivers/mmc/card/block.c | 23 +---------------------- drivers/mmc/card/queue.c | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 28 deletions(-) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index ebc8b9d77613..d73cac84d9f2 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -215,8 +215,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_blk_request brq; - int ret = 1, data_size, i; - struct scatterlist *sg; + int ret = 1; mmc_claim_host(card->host); @@ -237,8 +236,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.stop.arg = 0; brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); - if (brq.data.blocks > card->host->max_blk_count) - brq.data.blocks = card->host->max_blk_count; if (brq.data.blocks > 1) { /* SPI multiblock writes terminate using a special @@ -270,24 +267,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) mmc_queue_bounce_pre(mq); - /* - * Adjust the sg list so it is the same size as the - * request. - */ - if (brq.data.blocks != - (req->nr_sectors >> (md->block_bits - 9))) { - data_size = brq.data.blocks * brq.data.blksz; - for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) { - data_size -= sg->length; - if (data_size <= 0) { - sg->length += data_size; - i++; - break; - } - } - brq.data.sg_len = i; - } - mmc_wait_for_req(card->host, &brq.mrq); mmc_queue_bounce_post(mq); diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 3dee97e7d165..5c8f037dca6b 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -142,12 +142,19 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock bouncesz = host->max_req_size; if (bouncesz > host->max_seg_size) bouncesz = host->max_seg_size; + if (bouncesz > (host->max_blk_count * 512)) + bouncesz = host->max_blk_count * 512; + + if (bouncesz > 512) { + mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL); + if (!mq->bounce_buf) { + printk(KERN_WARNING "%s: unable to " + "allocate bounce buffer\n", + mmc_card_name(card)); + } + } - mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL); - if (!mq->bounce_buf) { - printk(KERN_WARNING "%s: unable to allocate " - "bounce buffer\n", mmc_card_name(card)); - } else { + if (mq->bounce_buf) { blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); blk_queue_max_sectors(mq->queue, bouncesz / 512); blk_queue_max_phys_segments(mq->queue, bouncesz / 512); @@ -175,7 +182,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock if (!mq->bounce_buf) { blk_queue_bounce_limit(mq->queue, limit); - blk_queue_max_sectors(mq->queue, host->max_req_size / 512); + blk_queue_max_sectors(mq->queue, + min(host->max_blk_count, host->max_req_size / 512)); blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); blk_queue_max_segment_size(mq->queue, host->max_seg_size); -- cgit v1.2.3 From 91028954119e464ae42350658d46c204d781b484 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 16 Aug 2008 21:15:50 +0200 Subject: mmc_block: indicate strict ordering The MMC block driver services requests one at a time and in strict order. Indicate this to the block layer so that it can handle barriers in an efficient manner. Signed-off-by: Pierre Ossman --- drivers/mmc/card/queue.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 5c8f037dca6b..c25c975bdc3b 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -131,6 +131,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock mq->req = NULL; blk_queue_prep_rq(mq->queue, mmc_prep_request); + blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL); #ifdef CONFIG_MMC_BLOCK_BOUNCE if (host->max_hw_segs == 1) { -- cgit v1.2.3 From d6d8de33415ca7598fe66d933b6556fa8f89afe2 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 16 Aug 2008 20:43:48 +0200 Subject: mmc_block: filter out PC requests We do not support PC (SCSI) commands, so don't pretend we do by letting them through. Signed-off-by: Pierre Ossman --- drivers/mmc/card/queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index c25c975bdc3b..406989e992ba 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -31,7 +31,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) /* * We only like normal block requests. */ - if (!blk_fs_request(req) && !blk_pc_request(req)) { + if (!blk_fs_request(req)) { blk_dump_rq_flags(req, "MMC bad request"); return BLKPREP_KILL; } -- cgit v1.2.3 From 08846698703dedae6c6915eb4b4d0a36188c5635 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 31 Aug 2008 14:10:08 +0200 Subject: mmc_block: hard code 512 byte block size We use 512 byte blocks on all cards, and newer cards support nothing else, so hard code it and make the code less complex. Signed-off-by: Pierre Ossman --- drivers/mmc/card/block.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index d73cac84d9f2..1d1e469e08ea 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -57,7 +57,6 @@ struct mmc_blk_data { struct mmc_queue queue; unsigned int usage; - unsigned int block_bits; unsigned int read_only; }; @@ -231,11 +230,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) if (!mmc_card_blockaddr(card)) brq.cmd.arg <<= 9; brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - brq.data.blksz = 1 << md->block_bits; + brq.data.blksz = 512; brq.stop.opcode = MMC_STOP_TRANSMISSION; brq.stop.arg = 0; brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); + brq.data.blocks = req->nr_sectors; if (brq.data.blocks > 1) { /* SPI multiblock writes terminate using a special @@ -351,16 +350,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) if (rq_data_dir(req) != READ) { if (mmc_card_sd(card)) { u32 blocks; - unsigned int bytes; blocks = mmc_sd_num_wr_blocks(card); if (blocks != (u32)-1) { - if (card->csd.write_partial) - bytes = blocks << md->block_bits; - else - bytes = blocks << 9; spin_lock_irq(&md->lock); - ret = __blk_end_request(req, 0, bytes); + ret = __blk_end_request(req, 0, blocks << 9); spin_unlock_irq(&md->lock); } } else { @@ -410,13 +404,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) */ md->read_only = mmc_blk_readonly(card); - /* - * Both SD and MMC specifications state (although a bit - * unclearly in the MMC case) that a block size of 512 - * bytes must always be supported by the card. - */ - md->block_bits = 9; - md->disk = alloc_disk(1 << MMC_SHIFT); if (md->disk == NULL) { ret = -ENOMEM; @@ -454,7 +441,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) sprintf(md->disk->disk_name, "mmcblk%d", devidx); - blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); + blk_queue_hardsect_size(md->queue.queue, 512); if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { /* @@ -492,7 +479,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) mmc_claim_host(card->host); cmd.opcode = MMC_SET_BLOCKLEN; - cmd.arg = 1 << md->block_bits; + cmd.arg = 512; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(card->host, &cmd, 5); mmc_release_host(card->host); -- cgit v1.2.3 From 1ea4f444f3a9721babd5d22cbd15092f9da6b51a Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 7 Sep 2008 13:07:57 +0200 Subject: mmc: remove redundant "depends on" Signed-off-by: Pierre Ossman --- drivers/mmc/card/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index dd0f398ee2f5..ffd2198e515f 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig @@ -34,7 +34,6 @@ config MMC_BLOCK_BOUNCE config SDIO_UART tristate "SDIO UART/GPS class support" - depends on MMC help SDIO function driver for SDIO cards that implements the UART class, as well as the GPS class which appears like a UART. -- cgit v1.2.3 From 57105737f6a0b39305a85ac176cc9fd4a236d8c2 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 7 Sep 2008 13:16:58 +0200 Subject: mmc: explicitly mention SDIO support in Kconfig Signed-off-by: Pierre Ossman --- drivers/mmc/card/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc/card') diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index ffd2198e515f..3f2a912659af 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig @@ -2,7 +2,7 @@ # MMC/SD card drivers # -comment "MMC/SD Card Drivers" +comment "MMC/SD/SDIO Card Drivers" config MMC_BLOCK tristate "MMC block device driver" -- cgit v1.2.3