[U-Boot] [PATCH 1/1] NAND Re: mtdparts fails with NAND >= 4GB
Aaron Williams
Aaron.Williams at caviumnetworks.com
Tue Feb 1 00:15:48 CET 2011
This patch seems to be working fine in my setup. Any comments?
-Aaron
On Thursday, January 27, 2011 05:43:10 pm Aaron Williams wrote:
> I have included my preliminary patch which seems to be working.
> It has not been extensively tested yet. All of the changes were basically
> making the sizes and offsets u64 instead of u32. When looking at the Linux
> kernel code it looks like they also use u64. I was mistaken and our NAND
> flash chip is 4GiB in size so I can't test with any larger chips.
>
> -Aaron
>
> diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
> index 5481c88..26d24b0 100644
> --- a/common/cmd_mtdparts.c
> +++ b/common/cmd_mtdparts.c
> @@ -21,6 +21,11 @@
> * $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $
> * Copyright 2002 SYSGO Real-Time Solutions GmbH
> *
> + * (C) Copyright 2011
> + * Aaron Williams, Cavium Networks, Inc.
> <aaron.williams at caviumnetworks.com> + *
> + * Added support for partitions and flash greater than or equal to 4GiB.
> + *
> * See file CREDITS for list of people who contributed to this
> * project.
> *
> @@ -174,7 +179,7 @@ static int device_del(struct mtd_device *dev);
> * @param retptr output pointer to next char after parse completes
> (output) * @return resulting unsigned int
> */
> -static unsigned long memsize_parse (const char *const ptr, const char
> **retptr) +static u64 memsize_parse (const char *const ptr, const char
> **retptr) {
> unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
>
> @@ -207,20 +212,20 @@ static unsigned long memsize_parse (const char *const
> ptr, const char **retptr) * @param buf output buffer
> * @param size size to be converted to string
> */
> -static void memsize_format(char *buf, u32 size)
> +static void memsize_format(char *buf, u64 size)
> {
> #define SIZE_GB ((u32)1024*1024*1024)
> #define SIZE_MB ((u32)1024*1024)
> #define SIZE_KB ((u32)1024)
>
> if ((size % SIZE_GB) == 0)
> - sprintf(buf, "%ug", size/SIZE_GB);
> + sprintf(buf, "%llug", size/SIZE_GB);
> else if ((size % SIZE_MB) == 0)
> - sprintf(buf, "%um", size/SIZE_MB);
> + sprintf(buf, "%llum", size/SIZE_MB);
> else if (size % SIZE_KB == 0)
> - sprintf(buf, "%uk", size/SIZE_KB);
> + sprintf(buf, "%lluk", size/SIZE_KB);
> else
> - sprintf(buf, "%u", size);
> + sprintf(buf, "%llu", size);
> }
>
> /**
> @@ -325,7 +330,7 @@ static int part_validate_eraseblock(struct mtdids *id,
> struct part_info *part) {
> struct mtd_info *mtd = NULL;
> int i, j;
> - ulong start;
> + u64 start;
>
> if (get_mtd_info(id->type, id->num, &mtd))
> return 1;
> @@ -337,7 +342,7 @@ static int part_validate_eraseblock(struct mtdids *id,
> struct part_info *part) * Only one eraseregion (NAND, OneNAND or uniform
> NOR), * checking for alignment is easy here
> */
> - if ((unsigned long)part->offset % mtd->erasesize) {
> + if ((u64)part->offset % mtd->erasesize) {
> printf("%s%d: partition (%s) start offset"
> "alignment incorrect\n",
> MTD_DEV_TYPE(id->type), id->num,
> part->name); @@ -412,7 +417,7 @@ static int part_validate(struct mtdids
> *id, struct part_info *part) part->size = id->size - part->offset;
>
> if (part->offset > id->size) {
> - printf("%s: offset %08x beyond flash size %08x\n",
> + printf("%s: offset %08llx beyond flash size %08llx\n",
> id->mtd_id, part->offset, id->size);
> return 1;
> }
> @@ -595,8 +600,8 @@ static int part_add(struct mtd_device *dev, struct
> part_info *part) static int part_parse(const char *const partdef, const
> char **ret, struct part_info **retpart) {
> struct part_info *part;
> - unsigned long size;
> - unsigned long offset;
> + u64 size;
> + u64 offset;
> const char *name;
> int name_len;
> unsigned int mask_flags;
> @@ -615,7 +620,7 @@ static int part_parse(const char *const partdef, const
> char **ret, struct part_i } else {
> size = memsize_parse(p, &p);
> if (size < MIN_PART_SIZE) {
> - printf("partition size too small (%lx)\n", size);
> + printf("partition size too small (%llx)\n", size);
> return 1;
> }
> }
> @@ -687,14 +692,14 @@ static int part_parse(const char *const partdef,
> const char **ret, struct part_i part->auto_name = 0;
> } else {
> /* auto generated name in form of size at offset */
> - sprintf(part->name, "0x%08lx at 0x%08lx", size, offset);
> + sprintf(part->name, "0x%08llx at 0x%08llx", size, offset);
> part->auto_name = 1;
> }
>
> part->name[name_len - 1] = '\0';
> INIT_LIST_HEAD(&part->link);
>
> - debug("+ partition: name %-22s size 0x%08x offset 0x%08x mask flags
> %d\n", + debug("+ partition: name %-22s size 0x%08llx offset
> 0x%08llx mask flags %d\n", part->name, part->size,
> part->offset, part->mask_flags);
>
> @@ -710,7 +715,7 @@ static int part_parse(const char *const partdef, const
> char **ret, struct part_i * @param size a pointer to the size of the mtd
> device (output)
> * @return 0 if device is valid, 1 otherwise
> */
> -int mtd_device_validate(u8 type, u8 num, u32 *size)
> +int mtd_device_validate(u8 type, u8 num, u64 *size)
> {
> struct mtd_info *mtd = NULL;
>
> @@ -842,7 +847,7 @@ static int device_parse(const char *const mtd_dev,
> const char **ret, struct mtd_ LIST_HEAD(tmp_list);
> struct list_head *entry, *n;
> u16 num_parts;
> - u32 offset;
> + u64 offset;
> int err = 1;
>
> debug("===device_parse===\n");
> @@ -1077,15 +1082,16 @@ int mtd_id_parse(const char *id, const char
> **ret_id, u8 *dev_type, u8 *dev_num) * @param buflen buffer size
> * @return 0 on success, 1 otherwise
> */
> -static int generate_mtdparts(char *buf, u32 buflen)
> +static int generate_mtdparts(char *buf, size_t buflen)
> {
> struct list_head *pentry, *dentry;
> struct mtd_device *dev;
> struct part_info *part, *prev_part;
> char *p = buf;
> char tmpbuf[32];
> - u32 size, offset, len, part_cnt;
> - u32 maxlen = buflen - 1;
> + u64 size, offset, len;
> + u32 part_cnt;
> + size_t maxlen = buflen - 1;
>
> debug("--- generate_mtdparts ---\n");
>
> @@ -1204,7 +1210,7 @@ cleanup:
> * @param buflen buffer size
> * @return 0 on success, 1 otherwise
> */
> -static int generate_mtdparts_save(char *buf, u32 buflen)
> +static int generate_mtdparts_save(char *buf, size_t buflen)
> {
> int ret;
>
> @@ -1265,13 +1271,13 @@ static void print_partition_table(void)
> printf(" #: name\t\tsize\t\tnet
> size\toffset\t\tmask_flags\n");
>
> list_for_each(pentry, &dev->parts) {
> - u32 net_size;
> + u64 net_size;
> char *size_note;
>
> part = list_entry(pentry, struct part_info, link);
> net_size = net_part_size(mtd, part);
> size_note = part->size == net_size ? " " : " (!)";
> - printf("%2d: %-20s0x%08x\t0x%08x%s\t0x%08x\t%d\n",
> + printf("%2d:
> %-20s0x%08llx\t0x%08llx%s\t0x%08llx\t%d\n", part_num, part->name,
> part->size, net_size, size_note, part->offset, part->mask_flags);
> @@ -1283,7 +1289,7 @@ static void print_partition_table(void)
>
> list_for_each(pentry, &dev->parts) {
> part = list_entry(pentry, struct part_info, link);
> - printf("%2d: %-20s0x%08x\t0x%08x\t%d\n",
> + printf("%2d: %-20s0x%08llx\t0x%08llx\t%d\n",
> part_num, part->name, part->size,
> part->offset, part->mask_flags);
> #endif /* defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) */
> @@ -1310,7 +1316,7 @@ static void list_partitions(void)
> if (current_mtd_dev) {
> part = mtd_part_info(current_mtd_dev, current_mtd_partnum);
> if (part) {
> - printf("\nactive partition: %s%d,%d - (%s) 0x%08x @
> 0x%08x\n", + printf("\nactive partition: %s%d,%d -
> (%s) 0x%08llx @ 0x%08llx\n", MTD_DEV_TYPE(current_mtd_dev->id->type),
> current_mtd_dev->id->num, current_mtd_partnum, part->name, part->size,
> part->offset); @@ -1410,7 +1416,7 @@ static int delete_partition(const
> char *id)
>
>
> if (find_dev_and_part(id, &dev, &pnum, &part) == 0) {
>
> - debug("delete_partition: device = %s%d, partition %d = (%s)
> 0x%08x at 0x%08x\n", + debug("delete_partition: device = %s%d,
> partition %d = (%s) 0x%08llx at 0x%08llx\n", MTD_DEV_TYPE(dev->id->type),
> dev->id->num, pnum, part->name, part->size, part->offset);
>
> @@ -1499,7 +1505,7 @@ static int spread_partitions(void)
> part = list_entry(pentry, struct part_info, link);
>
> debug("spread_partitions: device = %s%d, partition
> %d =" - " (%s) 0x%08x at 0x%08x\n",
> + " (%s) 0x%08llx at 0x%08llx\n",
> MTD_DEV_TYPE(dev->id->type), dev->id->num,
> part_num, part->name, part->size,
> part->offset);
> @@ -1596,7 +1602,7 @@ static int parse_mtdids(const char *const ids)
> struct list_head *entry, *n;
> struct mtdids *id_tmp;
> u8 type, num;
> - u32 size;
> + u64 size;
> int ret = 1;
>
> debug("\n---parse_mtdids---\nmtdids = %s\n\n", ids);
> @@ -1670,7 +1676,7 @@ static int parse_mtdids(const char *const ids)
> id->mtd_id[mtd_id_len - 1] = '\0';
> INIT_LIST_HEAD(&id->link);
>
> - debug("+ id %s%d\t%16d bytes\t%s\n",
> + debug("+ id %s%d\t%16llu bytes\t%s\n",
> MTD_DEV_TYPE(id->type), id->num,
> id->size, id->mtd_id);
>
> @@ -1999,7 +2005,7 @@ int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc,
> char * const argv[])
>
> if (!strcmp(&argv[1][3], ".spread")) {
> spread_partition(mtd, p, &next_offset);
> - debug("increased %s to %d bytes\n", p->name,
> p->size); + debug("increased %s to %llu bytes\n",
> p->name, p->size); }
> #endif
>
> diff --git a/include/jffs2/load_kernel.h b/include/jffs2/load_kernel.h
> index 906eb3d..dda096d 100644
> --- a/include/jffs2/load_kernel.h
> +++ b/include/jffs2/load_kernel.h
> @@ -46,8 +46,8 @@ struct part_info {
> struct list_head link;
> char *name; /* partition name */
> u8 auto_name; /* set to 1 for generated name */
> - u32 size; /* total size of the partition */
> - u32 offset; /* offset within device */
> + u64 size; /* total size of the partition */
> + u64 offset; /* offset within device */
> void *jffs2_priv; /* used internaly by jffs2 */
> u32 mask_flags; /* kernel MTD mask flags */
> u32 sector_size; /* size of sector */
> @@ -58,7 +58,7 @@ struct mtdids {
> struct list_head link;
> u8 type; /* device type */
> u8 num; /* device number */
> - u32 size; /* device size */
> + u64 size; /* device size */
> char *mtd_id; /* linux kernel device id */
> };
>
> On Thursday, January 27, 2011 05:14:15 pm Aaron Williams wrote:
> > I'll probably have something later today. I got it working with an
> > earlier version of u-boot though it hasn't been thoroughly tested.
> >
> > -Aaron
> >
> > On Thursday, January 27, 2011 05:06:09 pm Scott Wood wrote:
> > > On Thu, 27 Jan 2011 16:24:31 -0800
> > >
> > > Aaron Williams <Aaron.Williams at caviumnetworks.com> wrote:
> > > > Hi all,
> > > >
> > > > It looks like the mtd partitioning code fails if the flash size
> > > > exceeds a u32. I am working with an 8GB flash chip on our board and
> > > > was wondering if anyone else has any experience with MTD with a chip
> > > > this large?
> > >
> > > There's been some effort to make the U-Boot NAND code work with large
> > > devices, but it's not complete. Patches to take care of the rest of
> > > the problem spots are welcome, especially if you have hardware to
> > > test.
> > >
> > > -Scott
> >
> > _______________________________________________
> > U-Boot mailing list
> > U-Boot at lists.denx.de
> > http://lists.denx.de/mailman/listinfo/u-boot
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
More information about the U-Boot
mailing list