diff options
| -rw-r--r-- | common/cmd_mtdparts.c | 236 | 
1 files changed, 78 insertions, 158 deletions
| diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c index 6a0849f97..84108c244 100644 --- a/common/cmd_mtdparts.c +++ b/common/cmd_mtdparts.c @@ -90,7 +90,8 @@  #include <jffs2/load_kernel.h>  #include <linux/list.h>  #include <linux/ctype.h> -#include <cramfs/cramfs_fs.h> +#include <linux/err.h> +#include <linux/mtd/mtd.h>  #if defined(CONFIG_CMD_NAND)  #ifdef CONFIG_NAND_LEGACY @@ -102,7 +103,6 @@  #endif  #if defined(CONFIG_CMD_ONENAND) -#include <linux/mtd/mtd.h>  #include <linux/mtd/onenand.h>  #include <onenand_uboot.h>  #endif @@ -303,137 +303,91 @@ static void current_save(void)  }  /** - * Performs sanity check for supplied NOR flash partition. Table of existing - * NOR flash devices is searched and partition device is located. Alignment - * with the granularity of NOR flash sectors is verified. + * Performs sanity check for supplied flash partition. + * Table of existing MTD flash devices is searched and partition device + * is located. Alignment with the granularity of nand erasesize is verified.   *   * @param id of the parent device   * @param part partition to validate   * @return 0 if partition is valid, 1 otherwise   */ -static int part_validate_nor(struct mtdids *id, struct part_info *part) +static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)  { -#if defined(CONFIG_CMD_FLASH) -	/* info for FLASH chips */ -	extern flash_info_t flash_info[]; -	flash_info_t *flash; -	int offset_aligned; -	u32 end_offset, sector_size = 0; -	int i; - -	flash = &flash_info[id->num]; - -	/* size of last sector */ -	part->sector_size = flash->size - -		(flash->start[flash->sector_count-1] - flash->start[0]); +	struct mtd_info *mtd; +	char mtd_dev[16]; +	int i, j; +	ulong start; -	offset_aligned = 0; -	for (i = 0; i < flash->sector_count; i++) { -		if ((flash->start[i] - flash->start[0]) == part->offset) { -			offset_aligned = 1; -			break; -		} -	} -	if (offset_aligned == 0) { -		printf("%s%d: partition (%s) start offset alignment incorrect\n", -				MTD_DEV_TYPE(id->type), id->num, part->name); +	sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(id->type), id->num); +	mtd = get_mtd_device_nm(mtd_dev); +	if (IS_ERR(mtd)) { +		printf("Partition %s not found on device %s!\n", part->name, mtd_dev);  		return 1;  	} -	end_offset = part->offset + part->size; -	offset_aligned = 0; -	for (i = 0; i < flash->sector_count; i++) { -		if (i) { -			sector_size = flash->start[i] - flash->start[i-1]; -			if (part->sector_size < sector_size) -				part->sector_size = sector_size; -		} -		if ((flash->start[i] - flash->start[0]) == end_offset) -			offset_aligned = 1; -	} - -	if (offset_aligned || flash->size == end_offset) -		return 0; - -	printf("%s%d: partition (%s) size alignment incorrect\n", -			MTD_DEV_TYPE(id->type), id->num, part->name); -#endif -	return 1; -} +	part->sector_size = mtd->erasesize; -/** - * Performs sanity check for supplied NAND flash partition. Table of existing - * NAND flash devices is searched and partition device is located. Alignment - * with the granularity of nand erasesize is verified. - * - * @param id of the parent device - * @param part partition to validate - * @return 0 if partition is valid, 1 otherwise - */ -static int part_validate_nand(struct mtdids *id, struct part_info *part) -{ -#if defined(CONFIG_CMD_NAND) -	/* info for NAND chips */ -	nand_info_t *nand; +	if (!mtd->numeraseregions) { +		/* +		 * Only one eraseregion (NAND, OneNAND or uniform NOR), +		 * checking for alignment is easy here +		 */ +		if ((unsigned long)part->offset % mtd->erasesize) { +			printf("%s%d: partition (%s) start offset" +			       "alignment incorrect\n", +			       MTD_DEV_TYPE(id->type), id->num, part->name); +			return 1; +		} -	nand = &nand_info[id->num]; +		if (part->size % mtd->erasesize) { +			printf("%s%d: partition (%s) size alignment incorrect\n", +			       MTD_DEV_TYPE(id->type), id->num, part->name); +			return 1; +		} +	} else { +		/* +		 * Multiple eraseregions (non-uniform NOR), +		 * checking for alignment is more complex here +		 */ -	part->sector_size = nand->erasesize; +		/* Check start alignment */ +		for (i = 0; i < mtd->numeraseregions; i++) { +			start = mtd->eraseregions[i].offset; +			for (j = 0; j < mtd->eraseregions[i].numblocks; j++) { +				if (part->offset == start) +					goto start_ok; +				start += mtd->eraseregions[i].erasesize; +			} +		} -	if ((unsigned long)(part->offset) % nand->erasesize) {  		printf("%s%d: partition (%s) start offset alignment incorrect\n", -				MTD_DEV_TYPE(id->type), id->num, part->name); +		       MTD_DEV_TYPE(id->type), id->num, part->name);  		return 1; -	} - -	if (part->size % nand->erasesize) { -		printf("%s%d: partition (%s) size alignment incorrect\n", -				MTD_DEV_TYPE(id->type), id->num, part->name); -		return 1; -	} - -	return 0; -#else -	return 1; -#endif -} -/** - * Performs sanity check for supplied OneNAND flash partition. - * Table of existing OneNAND flash devices is searched and partition device - * is located. Alignment with the granularity of nand erasesize is verified. - * - * @param id of the parent device - * @param part partition to validate - * @return 0 if partition is valid, 1 otherwise - */ -static int part_validate_onenand(struct mtdids *id, struct part_info *part) -{ -#if defined(CONFIG_CMD_ONENAND) -	/* info for OneNAND chips */ -	struct mtd_info *mtd; - -	mtd = &onenand_mtd; - -	part->sector_size = mtd->erasesize; +	start_ok: -	if ((unsigned long)(part->offset) % mtd->erasesize) { -		printf("%s%d: partition (%s) start offset" -			"alignment incorrect\n", -				MTD_DEV_TYPE(id->type), id->num, part->name); -		return 1; -	} +		/* Check end/size alignment */ +		for (i = 0; i < mtd->numeraseregions; i++) { +			start = mtd->eraseregions[i].offset; +			for (j = 0; j < mtd->eraseregions[i].numblocks; j++) { +				if ((part->offset + part->size) == start) +					goto end_ok; +				start += mtd->eraseregions[i].erasesize; +			} +		} +		/* Check last sector alignment */ +		if ((part->offset + part->size) == start) +			goto end_ok; -	if (part->size % mtd->erasesize) {  		printf("%s%d: partition (%s) size alignment incorrect\n", -				MTD_DEV_TYPE(id->type), id->num, part->name); +		       MTD_DEV_TYPE(id->type), id->num, part->name);  		return 1; + +	end_ok: +		return 0;  	}  	return 0; -#else -	return 1; -#endif  } @@ -469,16 +423,11 @@ static int part_validate(struct mtdids *id, struct part_info *part)  		return 1;  	} -	if (id->type == MTD_DEV_TYPE_NAND) -		return part_validate_nand(id, part); -	else if (id->type == MTD_DEV_TYPE_NOR) -		return part_validate_nor(id, part); -	else if (id->type == MTD_DEV_TYPE_ONENAND) -		return part_validate_onenand(id, part); -	else -		DEBUGF("part_validate: invalid dev type\n"); - -	return 1; +	/* +	 * Now we need to check if the partition starts and ends on +	 * sector (eraseblock) regions +	 */ +	return part_validate_eraseblock(id, part);  }  /** @@ -762,48 +711,19 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i   */  int mtd_device_validate(u8 type, u8 num, u32 *size)  { -	if (type == MTD_DEV_TYPE_NOR) { -#if defined(CONFIG_CMD_FLASH) -		if (num < CONFIG_SYS_MAX_FLASH_BANKS) { -			extern flash_info_t flash_info[]; -			*size = flash_info[num].size; - -			return 0; -		} +	struct mtd_info *mtd; +	char mtd_dev[16]; -		printf("no such FLASH device: %s%d (valid range 0 ... %d\n", -				MTD_DEV_TYPE(type), num, CONFIG_SYS_MAX_FLASH_BANKS - 1); -#else -		printf("support for FLASH devices not present\n"); -#endif -	} else if (type == MTD_DEV_TYPE_NAND) { -#if defined(CONFIG_CMD_NAND) -		if (num < CONFIG_SYS_MAX_NAND_DEVICE) { -#ifndef CONFIG_NAND_LEGACY -			*size = nand_info[num].size; -#else -			extern struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE]; -			*size = nand_dev_desc[num].totlen; -#endif -			return 0; -		} +	sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(type), num); +	mtd = get_mtd_device_nm(mtd_dev); +	if (IS_ERR(mtd)) { +		printf("Device %s not found!\n", mtd_dev); +		return 1; +	} -		printf("no such NAND device: %s%d (valid range 0 ... %d)\n", -				MTD_DEV_TYPE(type), num, CONFIG_SYS_MAX_NAND_DEVICE - 1); -#else -		printf("support for NAND devices not present\n"); -#endif -	} else if (type == MTD_DEV_TYPE_ONENAND) { -#if defined(CONFIG_CMD_ONENAND) -		*size = onenand_mtd.size; -		return 0; -#else -		printf("support for OneNAND devices not present\n"); -#endif -	} else -		printf("Unknown defice type %d\n", type); +	*size = mtd->size; -	return 1; +	return 0;  }  /** |