X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmmc%2Fmmc_block.c;h=587458b370b9a9d71c817d0375d140847f01c505;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=a0e0dad1b41944de1a59ab9b4c1c6e01c1ed42e7;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index a0e0dad1b..587458b37 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c @@ -27,10 +27,10 @@ #include #include #include +#include #include #include -#include #include #include @@ -172,6 +172,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.cmd.arg = req->sector << 9; brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + brq.data.timeout_ns = card->csd.tacc_ns * 10; + brq.data.timeout_clks = card->csd.tacc_clks * 10; brq.data.blksz_bits = md->block_bits; brq.data.blksz = 1 << md->block_bits; brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); @@ -179,8 +181,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.stop.arg = 0; brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC; - mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ); - if (rq_data_dir(req) == READ) { brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; brq.data.flags |= MMC_DATA_READ; @@ -188,6 +188,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.cmd.opcode = MMC_WRITE_BLOCK; brq.data.flags |= MMC_DATA_WRITE; brq.data.blocks = 1; + + /* + * Scale up the timeout by the r2w factor + */ + brq.data.timeout_ns <<= card->csd.r2w_factor; + brq.data.timeout_clks <<= card->csd.r2w_factor; } if (brq.data.blocks > 1) { @@ -319,11 +325,52 @@ 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. + * Figure out a workable block size. MMC cards have: + * - two block sizes, one for read and one for write. + * - may support partial reads and/or writes + * (allows block sizes smaller than specified) + */ + md->block_bits = card->csd.read_blkbits; + if (card->csd.write_blkbits != card->csd.read_blkbits) { + if (card->csd.write_blkbits < card->csd.read_blkbits && + card->csd.read_partial) { + /* + * write block size is smaller than read block + * size, but we support partial reads, so choose + * the smaller write block size. + */ + md->block_bits = card->csd.write_blkbits; + } else if (card->csd.write_blkbits > card->csd.read_blkbits && + card->csd.write_partial) { + /* + * read block size is smaller than write block + * size, but we support partial writes. Use read + * block size. + */ + } else { + /* + * We don't support this configuration for writes. + */ + printk(KERN_ERR "%s: unable to select block size for " + "writing (rb%u wb%u rp%u wp%u)\n", + mmc_card_id(card), + 1 << card->csd.read_blkbits, + 1 << card->csd.write_blkbits, + card->csd.read_partial, + card->csd.write_partial); + md->read_only = 1; + } + } + + /* + * Refuse to allow block sizes smaller than 512 bytes. */ - md->block_bits = 9; + if (md->block_bits < 9) { + printk(KERN_ERR "%s: unable to support block size %u\n", + mmc_card_id(card), 1 << md->block_bits); + ret = -EINVAL; + goto err_kfree; + } md->disk = alloc_disk(1 << MMC_SHIFT); if (md->disk == NULL) { @@ -362,6 +409,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) */ sprintf(md->disk->disk_name, "mmcblk%d", devidx); + sprintf(md->disk->devfs_name, "mmc/blk%d", devidx); blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); @@ -507,6 +555,7 @@ static int __init mmc_blk_init(void) if (major == 0) major = res; + devfs_mk_dir("mmc"); return mmc_register_driver(&mmc_driver); out: @@ -516,6 +565,7 @@ static int __init mmc_blk_init(void) static void __exit mmc_blk_exit(void) { mmc_unregister_driver(&mmc_driver); + devfs_remove("mmc"); unregister_blkdev(major, "mmc"); }