diff options
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r-- | drivers/mmc/card/block.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 66e5a5487c20..efacee0404a0 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -29,6 +29,7 @@ #include <linux/blkdev.h> #include <linux/mutex.h> #include <linux/scatterlist.h> +#include <linux/string_helpers.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h> @@ -83,7 +84,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); @@ -103,8 +104,10 @@ static int mmc_blk_open(struct inode *inode, struct file *filp) check_disk_change(inode->i_bdev); ret = 0; - if ((filp->f_mode & FMODE_WRITE) && md->read_only) + if ((filp->f_mode & FMODE_WRITE) && md->read_only) { + mmc_blk_put(md); ret = -EROFS; + } } return ret; @@ -213,7 +216,8 @@ 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, sg_pos, data_size; + int ret = 1, data_size, i; + struct scatterlist *sg; mmc_claim_host(card->host); @@ -267,18 +271,22 @@ 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 (sg_pos = 0; sg_pos < brq.data.sg_len; sg_pos++) { - data_size -= mq->sg[sg_pos].length; + for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) { + data_size -= sg->length; if (data_size <= 0) { - mq->sg[sg_pos].length += data_size; - sg_pos++; + sg->length += data_size; + i++; break; } } - brq.data.sg_len = sg_pos; + brq.data.sg_len = i; } mmc_wait_for_req(card->host, &brq.mrq); @@ -525,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. */ @@ -539,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); @@ -608,14 +619,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; } |