From: Peng Fan <[email protected]> mmc_bwrite() uses mmc->cfg->b_max directly to limit per-transfer block count. The read path (mmc_bread()) correctly calls mmc_get_b_max() which dispatches to the host driver get_b_max() callback. This callback allows host drivers to enforce DMA boundary constraints based on the buffer address.
Fix mmc_bwrite() to use mmc_get_b_max() to match the read path. This requires removing the static qualifier from the non-DM mmc_get_b_max() and adding its declaration to mmc_private.h. Signed-off-by: Peng Fan <[email protected]> --- drivers/mmc/mmc.c | 2 +- drivers/mmc/mmc_private.h | 4 ++++ drivers/mmc/mmc_write.c | 6 ++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ef7defcde71..5fd12d21f92 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -490,7 +490,7 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, } #if !CONFIG_IS_ENABLED(DM_MMC) -static int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt) +int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt) { if (mmc->cfg->ops->get_b_max) return mmc->cfg->ops->get_b_max(mmc, dst, blkcnt); diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h index fc45f017e5d..24e68ceb5e6 100644 --- a/drivers/mmc/mmc_private.h +++ b/drivers/mmc/mmc_private.h @@ -17,6 +17,10 @@ int mmc_poll_for_busy(struct mmc *mmc, int timeout); int mmc_set_blocklen(struct mmc *mmc, int len); +#if !CONFIG_IS_ENABLED(DM_MMC) +int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt); +#endif + #if CONFIG_IS_ENABLED(BLK) ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst); diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index 928c05872ca..9cf07b4ad1f 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -228,6 +228,7 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, int dev_num = block_dev->devnum; lbaint_t cur, blocks_todo = blkcnt; int err; + uint b_max; struct mmc *mmc = find_mmc_device(dev_num); if (!mmc) @@ -240,9 +241,10 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, if (mmc_set_blocklen(mmc, mmc->write_bl_len)) return 0; + b_max = mmc_get_b_max(mmc, (void *)src, blkcnt); + do { - cur = (blocks_todo > mmc->cfg->b_max) ? - mmc->cfg->b_max : blocks_todo; + cur = (blocks_todo > b_max) ? b_max : blocks_todo; if (mmc_write_blocks(mmc, start, cur, src) != cur) return 0; blocks_todo -= cur; -- 2.51.0

