[PATCH] spl: mmc: Use correct MMC device when loading image

Quentin Schulz quentin.schulz at theobroma-systems.com
Mon Jul 11 12:18:01 CEST 2022


Hi Harald,

On 7/6/22 12:58, Harald Seiler wrote:
> When attempting to load images from multiple MMC devices in sequence,
> spl_mmc_load() chooses the wrong device from the second attempt onwards.
> 
> The reason is that MMC initialization is only done on its first call and
> spl_mmc_load() will then continue using this same device for all future
> calls.
> 
> Fix this by checking the devnum of the "cached" device struct against
> the one which is requested.  If they match, use the cached one but if
> they do not match, initialize the new device.
> 
> This fixes specifying multiple MMC devices in the SPL's boot order to
> fall back when U-Boot Proper is corrupted or missing on the first
> attempted MMC device.
> 
> Fixes: e1eb6ada4e38 ("spl: Make image loader infrastructure more universal")
> Signed-off-by: Harald Seiler <hws at denx.de>
> ---
>   common/spl/spl_mmc.c | 6 ++++--
>   1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
> index e1a7d25bd0..22c8a8097c 100644
> --- a/common/spl/spl_mmc.c
> +++ b/common/spl/spl_mmc.c
> @@ -371,9 +371,11 @@ int spl_mmc_load(struct spl_image_info *spl_image,
>   	u32 boot_mode;
>   	int err = 0;
>   	__maybe_unused int part = 0;
> +	int mmc_dev;
>   
> -	/* Perform peripheral init only once */
> -	if (!mmc) {
> +	/* Perform peripheral init only once for an mmc device */
> +	mmc_dev = spl_mmc_get_device_index(bootdev->boot_device);
> +	if (!mmc || mmc->block_dev.devnum != mmc_dev) {

block_dev field only exists when CONFIG_BLK is not defined, c.f. 
https://elixir.bootlin.com/u-boot/latest/source/include/mmc.h#L705

Considering the commit introducing this, c.f. 
https://source.denx.de/u-boot/u-boot/-/commit/33fb211dd2706e666db4008801dc0d5903fd82f6, 
I can suggest the following diff (which makes it compile with 
rk3399-puma_defconfig):

diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index e0e1a80536..c40b436a11 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -409,10 +409,17 @@ int spl_mmc_load(struct spl_image_info *spl_image,
         int err = 0;
         __maybe_unused int part = 0;
         int mmc_dev;
+       struct blk_desc *block_dev;

         /* Perform peripheral init only once for an mmc device */
         mmc_dev = spl_mmc_get_device_index(bootdev->boot_device);
-       if (!mmc || mmc->block_dev.devnum != mmc_dev) {
+#if !CONFIG_IS_ENABLED(BLK)
+       block_dev = &mmc->block_dev;
+#else
+       block_dev = dev_get_uclass_plat(mmc->dev);
+#endif
+
+       if (!mmc || block_dev->devnum != mmc_dev) {
                 err = spl_mmc_find_device(&mmc, bootdev->boot_device);
                 if (err)
                         return err;

Note: Only build tested.

Cheers,
Quentin


More information about the U-Boot mailing list