From patchwork Fri Jan 28 01:43:10 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Williams X-Patchwork-Id: 80759 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 41769B7114 for ; Fri, 28 Jan 2011 12:43:29 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 525412807E; Fri, 28 Jan 2011 02:43:26 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Q6weZuk76vbX; Fri, 28 Jan 2011 02:43:26 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8071B28086; Fri, 28 Jan 2011 02:43:23 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0FE3728086 for ; Fri, 28 Jan 2011 02:43:20 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6SCZBaVDNvwl for ; Fri, 28 Jan 2011 02:43:17 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail3.caviumnetworks.com (unknown [12.108.191.235]) by theia.denx.de (Postfix) with ESMTP id 0749B2807E for ; Fri, 28 Jan 2011 02:43:15 +0100 (CET) Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by mail3.caviumnetworks.com with MailMarshal (v6, 7, 2, 8378) id ; Thu, 27 Jan 2011 17:44:04 -0800 Received: from caexch01.caveonetworks.com ([192.168.16.9]) by caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.4675); Thu, 27 Jan 2011 17:43:14 -0800 Received: from awilliams-suse.localnet ([12.108.191.236]) by caexch01.caveonetworks.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Thu, 27 Jan 2011 17:43:14 -0800 From: Aaron Williams To: u-boot@lists.denx.de Date: Thu, 27 Jan 2011 17:43:10 -0800 User-Agent: KMail/1.13.5 (Linux/2.6.34.7-0.7-desktop; KDE/4.5.5; x86_64; ; ) References: <201101271624.31701.Aaron.Williams@caviumnetworks.com> <20110127190609.2e27e5bf@udp111988uds.am.freescale.net> <201101271714.16167.Aaron.Williams@caviumnetworks.com> In-Reply-To: <201101271714.16167.Aaron.Williams@caviumnetworks.com> MIME-Version: 1.0 Message-Id: <201101271743.10335.Aaron.Williams@caviumnetworks.com> X-OriginalArrivalTime: 28 Jan 2011 01:43:14.0217 (UTC) FILETIME=[BA668190:01CBBE8C] Cc: Scott Wood Subject: [U-Boot] [PATCH 1/1] NAND Re: mtdparts fails with NAND >= 4GB X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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 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 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@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot 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. + * + * 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@offset */ - sprintf(part->name, "0x%08lx@0x%08lx", size, offset); + sprintf(part->name, "0x%08llx@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@0x%08x\n", + debug("delete_partition: device = %s%d, partition %d = (%s) 0x%08llx@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@0x%08x\n", + " (%s) 0x%08llx@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 */ };