[U-Boot] [RESEND 2/2] mmc:fix Call mmc_init() when executing mmc_get_dev()

Lei Wen adrian.wenl at gmail.com
Thu Apr 19 16:23:18 CEST 2012


Hi Lukasz,

On Thu, Apr 19, 2012 at 8:39 PM, Lukasz Majewski <l.majewski at samsung.com> wrote:
> This code adds call to mmc_init(), for partition related commands (e.g.
> fatls, fatinfo etc.).
>
> It is safe to call mmc_init() multiple times since mmc->has_init flag
> prevents from multiple initialization.
>
> The FAT related code calls get_dev high level method and then uses
> elements from mmc->block_dev, which is uninitialized until the mmc_init
> (and thereof mmc_startup) is called.
>
> This problem appears on boards, which don't use mmc as the default
> place for envs
>
> Signed-off-by: Lukasz Majewski <l.majewski at samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
> Cc: Andy Fleming <afleming at gmail.com>
> ---
>  drivers/mmc/mmc.c |    5 ++++-
>  1 files changed, 4 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 618960e..84eb4e0 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -1305,8 +1305,11 @@ int mmc_register(struct mmc *mmc)
>  block_dev_desc_t *mmc_get_dev(int dev)
>  {
>        struct mmc *mmc = find_mmc_device(dev);
> +       if (!mmc)
> +               return NULL;
>
> -       return mmc ? &mmc->block_dev : NULL;
> +       mmc_init(mmc);

I'm concerning with this adding init here.
Since not every platform mount with emmc as boot device, and what they
need is booting fast. If you order them to initialize all mmc/sd at mmc register
stage, this adding booting time may not be the one they want to see.

For FAT command, I think you could abstract a init method, in which mmc
could call its mmc_init(). I previously make a patch for this, don't whether it
could fit your need:

diff --git a/disk/part.c b/disk/part.c
index e4e7997..3d00670 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -77,7 +77,7 @@ DECLARE_GLOBAL_DATA_PTR;
 block_dev_desc_t *get_dev(char* ifname, int dev)
 {
 	const struct block_drvr *drvr = block_drvr;
-	block_dev_desc_t* (*reloc_get_dev)(int dev);
+	block_dev_desc_t* (*reloc_get_dev)(int dev), *dev_desc;
 	char *name;

 	name = drvr->name;
@@ -91,8 +91,13 @@ block_dev_desc_t *get_dev(char* ifname, int dev)
 		name += gd->reloc_off;
 		reloc_get_dev += gd->reloc_off;
 #endif
-		if (strncmp(ifname, name, strlen(name)) == 0)
-			return reloc_get_dev(dev);
+		if (strncmp(ifname, name, strlen(name)) == 0) {
+			dev_desc = reloc_get_dev(dev);
+			if (dev_desc && dev_desc->dev_init(dev_desc->dev))
+				dev_desc = NULL;
+
+			return dev_desc;
+		}
 		drvr++;
 	}
 	return NULL;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 1622417..c4c48e7 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1150,6 +1150,7 @@ int mmc_send_if_cond(struct mmc *mmc)
 	return 0;
 }

+static int mmc_dev_init(int dev_num);
 int mmc_register(struct mmc *mmc)
 {
 	/* Setup the universal parts of the block interface just once */
@@ -1159,6 +1160,7 @@ int mmc_register(struct mmc *mmc)
 	mmc->block_dev.block_read = mmc_bread;
 	mmc->block_dev.block_write = mmc_bwrite;
 	mmc->block_dev.block_erase = mmc_berase;
+	mmc->block_dev.dev_init = mmc_dev_init;
 	if (!mmc->b_max)
 		mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;

@@ -1226,6 +1228,15 @@ int mmc_init(struct mmc *mmc)
 	return err;
 }

+static int mmc_dev_init(int dev_num)
+{
+	struct mmc *mmc = find_mmc_device(dev_num);
+	if (!mmc)
+		return -1;
+
+	return mmc_init(mmc);
+}
+
 /*
  * CPU and board-specific MMC initializations.  Aliased function
  * signals caller to move on
diff --git a/include/part.h b/include/part.h
index 2864adb..dac2bdd 100644
--- a/include/part.h
+++ b/include/part.h
@@ -41,6 +41,7 @@ typedef struct block_dev_desc {
 	char		vendor [40+1];	/* IDE model, SCSI Vendor */
 	char		product[20+1];	/* IDE Serial no, SCSI product */
 	char		revision[8+1];	/* firmware revision */
+	int		(*dev_init)(int dev);
 	unsigned long	(*block_read)(int dev,
 				      unsigned long start,
 				      lbaint_t blkcnt,


Thanks,
Lei

Thanks,
Lei


More information about the U-Boot mailing list