diff options
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r-- | drivers/mmc/card/block.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 513eb09a638..adc205c49fb 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -41,6 +41,8 @@ #include "queue.h" +MODULE_ALIAS("mmc:block"); + /* * max 8 partitions per card */ @@ -145,7 +147,8 @@ struct mmc_blk_request { static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) { int err; - __be32 blocks; + u32 result; + __be32 *blocks; struct mmc_request mrq; struct mmc_command cmd; @@ -197,14 +200,21 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) mrq.cmd = &cmd; mrq.data = &data; - sg_init_one(&sg, &blocks, 4); + blocks = kmalloc(4, GFP_KERNEL); + if (!blocks) + return (u32)-1; + + sg_init_one(&sg, blocks, 4); mmc_wait_for_req(card->host, &mrq); + result = ntohl(*blocks); + kfree(blocks); + if (cmd.error || data.error) - return (u32)-1; + result = (u32)-1; - return ntohl(blocks); + return result; } static u32 get_card_status(struct mmc_card *card, struct request *req) @@ -241,7 +251,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.mrq.cmd = &brq.cmd; brq.mrq.data = &brq.data; - brq.cmd.arg = req->sector; + brq.cmd.arg = blk_rq_pos(req); if (!mmc_card_blockaddr(card)) brq.cmd.arg <<= 9; brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; @@ -249,7 +259,15 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) 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; + brq.data.blocks = blk_rq_sectors(req); + + /* + * The block layer doesn't support all sector count + * restrictions, so we need to be prepared for too big + * requests. + */ + if (brq.data.blocks > card->host->max_blk_count) + brq.data.blocks = card->host->max_blk_count; /* * After a read error, we redo the request one sector at a time @@ -291,7 +309,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) * Adjust the sg list so it is the same size as the * request. */ - if (brq.data.blocks != req->nr_sectors) { + if (brq.data.blocks != blk_rq_sectors(req)) { int i, data_size = brq.data.blocks << 9; struct scatterlist *sg; @@ -342,8 +360,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) printk(KERN_ERR "%s: error %d transferring data," " sector %u, nr %u, card status %#x\n", req->rq_disk->disk_name, brq.data.error, - (unsigned)req->sector, - (unsigned)req->nr_sectors, status); + (unsigned)blk_rq_pos(req), + (unsigned)blk_rq_sectors(req), status); } if (brq.stop.error) { @@ -511,7 +529,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, 512); + blk_queue_logical_block_size(md->queue.queue, 512); if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { /* |