
As mmc host limitation, the max number of block in one go should be limited to 65535, and the max buffer size should not excceed 512k bytes.
Signed-off-by: Lei Wen leiwen@marvell.com --- drivers/mmc/mmc.c | 56 +++++++++++++++++++++++++++++++++------------------- 1 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 94d1ac2..ea398a5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -77,29 +77,16 @@ struct mmc *find_mmc_device(int dev_num) return NULL; }
-static ulong -mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) +int mmc_write_block(struct mmc *mmc, ulong *src, ulong start, uint blocknum) { 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;
- err = mmc_set_blocklen(mmc, mmc->write_bl_len); - - if (err) { - printf("set write bl len failed\n\r"); - return err; - } - - if (blkcnt > 1) + BUG_ON(blklen * blocknum > 524288); + BUG_ON(blocknum > 65535); + if (blocknum > 1) cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; else cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK; @@ -113,7 +100,7 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) cmd.flags = 0;
data.src = src; - data.blocks = blkcnt; + data.blocks = blocknum; data.blocksize = blklen; data.flags = MMC_DATA_WRITE;
@@ -124,14 +111,41 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) return err; }
- if (blkcnt > 1) { + if (blocknum > 1) { cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_R1b; cmd.flags = 0; - stoperr = mmc_send_cmd(mmc, &cmd, NULL); + mmc_send_cmd(mmc, &cmd, NULL); }
+ return blocknum; +} + +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); + unsigned int max; + lbaint_t tmp = blkcnt, cur; + + 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; + } + + max = 524288 / mmc->write_bl_len; + do { + cur = (tmp > max) ? max : tmp; + tmp -= cur; + if(mmc_write_block(mmc, src, start, cur) != cur) + return -1; + } while (tmp > 0); return blkcnt; }