From 0158126e252b6860e7a7d8408d0872278a3483cf Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Thu, 14 Oct 2010 13:38:11 +0800 Subject: mmc: seperate block number into small parts for multi-write cmd Constraint the mmc framework to only send no more than 65535 blocks in one go during the multi-write command. This constraint comes due to the limitation of 16bit width block counter register at some hardware. Signed-off-by: Lei Wen Cc: Reinhard Meyer --- drivers/mmc/mmc.c | 54 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 15 deletions(-) (limited to 'drivers/mmc') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index c543d837dc..eb7bfb39e9 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -78,17 +78,11 @@ struct mmc *find_mmc_device(int dev_num) } static ulong -mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) +mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) { struct mmc_cmd cmd; struct mmc_data data; - int err; - int stoperr = 0; - struct mmc *mmc = find_mmc_device(dev_num); - int blklen; - - if (!mmc) - return -1; + int blklen, err; blklen = mmc->write_bl_len; @@ -97,12 +91,6 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) start + blkcnt, mmc->block_dev.lba); return 0; } - err = mmc_set_blocklen(mmc, mmc->write_bl_len); - - if (err) { - printf("set write bl len failed\n\r"); - return err; - } if (blkcnt > 1) cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; @@ -134,9 +122,45 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_R1b; cmd.flags = 0; - stoperr = mmc_send_cmd(mmc, &cmd, NULL); + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) { + printf("mmc fail to send stop cmd\n\r"); + return err; + } + } + + return blkcnt; +} + +static ulong +mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) +{ + int err; + struct mmc *mmc = find_mmc_device(dev_num); + lbaint_t cur, blocks_todo = blkcnt; + + if (!mmc) + return -1; + + err = mmc_set_blocklen(mmc, mmc->write_bl_len); + if (err) { + printf("set write bl len failed\n\r"); + return err; } + do { + /* + * The 65535 constraint comes from some hardware has + * only 16 bit width block number counter + */ + cur = (blocks_todo > 65535) ? 65535 : blocks_todo; + if(mmc_write_blocks(mmc, start, cur, src) != cur) + return -1; + blocks_todo -= cur; + start += cur; + src += cur * mmc->write_bl_len; + } while (blocks_todo > 0); + return blkcnt; } -- cgit v1.2.1