diff options
| -rw-r--r-- | drivers/mmc/mmc.c | 54 | 
1 files changed, 39 insertions, 15 deletions
| diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index c543d837d..eb7bfb39e 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;  } |