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

Reply via email to