X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fmmc%2Fmmc_write.c;h=54acbf73367b8acbb7d4597ef9c4c9815a05e7f4;hb=HEAD;hp=aa2fdefa75edeb39540954ae40cf73a841f5870a;hpb=3be2bdf5dc69b3142c1162a59bc67191c9077567;p=people%2Fms%2Fu-boot.git diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index aa2fdefa75..54acbf7336 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -9,7 +9,10 @@ #include #include +#include #include +#include +#include #include "mmc_private.h" static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) @@ -49,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) goto err_out; cmd.cmdidx = MMC_CMD_ERASE; - cmd.cmdarg = SECURE_ERASE; + cmd.cmdarg = MMC_ERASE_ARG; cmd.resp_type = MMC_RSP_R1b; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -63,9 +66,18 @@ err_out: return err; } -unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt) +#ifdef CONFIG_BLK +ulong mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt) +#else +ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) +#endif { +#ifdef CONFIG_BLK + struct blk_desc *block_dev = dev_get_uclass_platdata(dev); +#endif + int dev_num = block_dev->devnum; int err = 0; + u32 start_rem, blkcnt_rem; struct mmc *mmc = find_mmc_device(dev_num); lbaint_t blk = 0, blk_r = 0; int timeout = 1000; @@ -73,7 +85,19 @@ unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt) if (!mmc) return -1; - if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size)) + err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, + block_dev->hwpart); + if (err < 0) + return -1; + + /* + * We want to see if the requested start or total block count are + * unaligned. We discard the whole numbers and only care about the + * remainder. + */ + err = div_u64_rem(start, mmc->erase_grp_size, &start_rem); + err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem); + if (start_rem || blkcnt_rem) printf("\n\nCaution! Your devices Erase group is 0x%x\n" "The erase range would be change to " "0x" LBAF "~0x" LBAF "\n\n", @@ -82,8 +106,13 @@ unsigned long mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt) & ~(mmc->erase_grp_size - 1)) - 1); while (blk < blkcnt) { - blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? - mmc->erase_grp_size : (blkcnt - blk); + if (IS_SD(mmc) && mmc->ssr.au) { + blk_r = ((blkcnt - blk) > mmc->ssr.au) ? + mmc->ssr.au : (blkcnt - blk); + } else { + blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? + mmc->erase_grp_size : (blkcnt - blk); + } err = mmc_erase_t(mmc, start + blk, blk_r); if (err) break; @@ -105,9 +134,9 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start, struct mmc_data data; int timeout = 1000; - if ((start + blkcnt) > mmc->block_dev.lba) { + if ((start + blkcnt) > mmc_get_blk_desc(mmc)->lba) { printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n", - start + blkcnt, mmc->block_dev.lba); + start + blkcnt, mmc_get_blk_desc(mmc)->lba); return 0; } @@ -155,19 +184,35 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start, return blkcnt; } -ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void *src) +#ifdef CONFIG_BLK +ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, + const void *src) +#else +ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, + const void *src) +#endif { +#ifdef CONFIG_BLK + struct blk_desc *block_dev = dev_get_uclass_platdata(dev); +#endif + int dev_num = block_dev->devnum; lbaint_t cur, blocks_todo = blkcnt; + int err; struct mmc *mmc = find_mmc_device(dev_num); if (!mmc) return 0; + err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, block_dev->hwpart); + if (err < 0) + return 0; + if (mmc_set_blocklen(mmc, mmc->write_bl_len)) return 0; do { - cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo; + cur = (blocks_todo > mmc->cfg->b_max) ? + mmc->cfg->b_max : blocks_todo; if (mmc_write_blocks(mmc, start, cur, src) != cur) return 0; blocks_todo -= cur;