[U-Boot] [PATCH v5 2/5] mtd: add an mtd method for get_len_incl_bad()

Scott Wood scottwood at freescale.com
Mon Aug 30 22:57:24 CEST 2010


On Mon, 30 Aug 2010 13:38:57 -0400
Ben Gardiner <bengardiner at nanometrics.ca> wrote:

> The logic to 'spread' mtd partitions needs to calculate the length in
> the mtd device, including bad blocks.
> 
> This patch introduces a new function, mtd_get_len_incl_bad that can
> return both the length including bad blocks and whether that length
> was truncated on the device. This new function will be used by the
> mtdparts spread command later in this series. The definition of the
> function is #ifdef'd out in configurations that do not use the new
> 'mtdparts spread' command.
> 
> Signed-off-by: Ben Gardiner<bengardiner at nanometrics.ca>
> CC: Scott Wood <scottwood at freescale.com>
> 
> ---
> 
> Note: the mtd_get_len_incl_bad() function could also be used by the
> get_len_incl_bad() function in nand_util.c except for the fact that
> boards can enable NAND support without enabling MTD support. A note
> has been added to get_len_incl_bad() to remind us to refactor when/if
> MTD support is available whenever NAND support is enabled.
> 
> V5:
>  * introduced in v5 of this patchset
> ---
>  drivers/mtd/mtdcore.c        |   44 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/mtd/nand/nand_util.c |    6 +++++
>  include/linux/mtd/mtd.h      |    4 ++-
>  3 files changed, 53 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index 6eb52ed..cb86657 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -142,3 +142,47 @@ void put_mtd_device(struct mtd_info *mtd)
>  	c = --mtd->usecount;
>  	BUG_ON(c < 0);
>  }
> +
> +#if defined(CONFIG_CMD_MTDPARTS_SPREAD)
> +/**
> + * mtd_get_len_incl_bad
> + *
> + * Check if length including bad blocks fits into device.
> + *
> + * @param mtd an MTD device
> + * @param offset offset in flash
> + * @param length image length
> + * @return image length including bad blocks in *len_incl_bad and whether or not
> + *         the length returned was truncated in *truncated
> + */
> +void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
> +			  const uint64_t length, uint64_t *len_incl_bad,
> +			  int *truncated)
> +{
> +	*truncated = 0;
> +	*len_incl_bad = 0;
> +
> +	if (!mtd->block_isbad) {
> +		*len_incl_bad = length;
> +		return;
> +	}
> +
> +	uint64_t len_excl_bad = 0;
> +	uint64_t block_len;
> +
> +	while (len_excl_bad < length) {
> +		block_len = mtd->erasesize - (offset & (mtd->erasesize - 1));
> +
> +		if (!mtd->block_isbad(mtd, offset & ~(mtd->erasesize - 1)))
> +			len_excl_bad += block_len;
> +
> +		*len_incl_bad += block_len;
> +		offset       += block_len;
> +
> +		if (offset >= mtd->size) {
> +			*truncated = 1;
> +			break;
> +		}
> +	}

If this function is called with offset == mtd->size, you should return
length zero and truncated, without calling block_isbad().

-Scott



More information about the U-Boot mailing list