[PATCH] spl: mmc: Use correct MMC device when loading image
Harald Seiler
hws at denx.de
Mon Jul 11 14:31:23 CEST 2022
Hi,
On Mon, 2022-07-11 at 12:18 +0200, Quentin Schulz wrote:
> 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.
Thanks for reporting. It's not quite that simple because `mmc` is NULL
on first call to spl_mmc_load(). I'll send a v2 to fix this.
--
Harald
More information about the U-Boot
mailing list