diff options
author | Wolfgang Denk <wd@pollux.denx.de> | 2005-08-08 01:03:24 +0200 |
---|---|---|
committer | Wolfgang Denk <wd@pollux.denx.de> | 2005-08-08 01:03:24 +0200 |
commit | 700a0c648df72f2c8e0589c0d0470b5ffd7cab7b (patch) | |
tree | 819928504de4b8fc80e632fa5c485204fd7542a7 /fs | |
parent | 452e8e72ada5141f58008a902e1d4be42ce15abb (diff) | |
download | u-boot-700a0c648df72f2c8e0589c0d0470b5ffd7cab7b.tar.gz u-boot-700a0c648df72f2c8e0589c0d0470b5ffd7cab7b.tar.xz u-boot-700a0c648df72f2c8e0589c0d0470b5ffd7cab7b.zip |
Add common (with Linux) MTD partition scheme and "mtdparts" command
Old, obsolete and duplicated code was cleaned up and replace by the
new partitioning method. There are two possible approaches now:
* define a single, static partition
* use mtdparts command line option and dynamic partitioning
Default is static partitioning.
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cramfs/cramfs.c | 38 | ||||
-rw-r--r-- | fs/jffs2/jffs2_1pass.c | 132 | ||||
-rw-r--r-- | fs/jffs2/jffs2_private.h | 1 |
3 files changed, 117 insertions, 54 deletions
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c index 98ff567269..f02bf3c744 100644 --- a/fs/cramfs/cramfs.c +++ b/fs/cramfs/cramfs.c @@ -42,17 +42,22 @@ struct cramfs_super super; +/* CPU address space offset calculation macro, struct part_info offset is + * device address space offset, so we need to shift it by a device start address. */ +extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; +#define PART_OFFSET(x) (x->offset + flash_info[x->dev->id->num].start[0]) + static int cramfs_read_super (struct part_info *info) { unsigned long root_offset; /* Read the first block and get the superblock from it */ - memcpy (&super, (void *) info->offset, sizeof (super)); + memcpy (&super, (void *) PART_OFFSET(info), sizeof (super)); /* Do sanity checks on the superblock */ if (super.magic != CRAMFS_32 (CRAMFS_MAGIC)) { /* check at 512 byte offset */ - memcpy (&super, (void *) info->offset + 512, sizeof (super)); + memcpy (&super, (void *) PART_OFFSET(info) + 512, sizeof (super)); if (super.magic != CRAMFS_32 (CRAMFS_MAGIC)) { printf ("cramfs: wrong magic\n"); return -1; @@ -87,7 +92,7 @@ static int cramfs_read_super (struct part_info *info) return 0; } -static unsigned long cramfs_resolve (char *begin, unsigned long offset, +static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset, unsigned long size, int raw, char *filename) { @@ -150,7 +155,7 @@ static unsigned long cramfs_resolve (char *begin, unsigned long offset, return 0; } -static int cramfs_uncompress (char *begin, unsigned long offset, +static int cramfs_uncompress (unsigned long begin, unsigned long offset, unsigned long loadoffset) { struct cramfs_inode *inode = (struct cramfs_inode *) (begin + offset); @@ -187,7 +192,7 @@ int cramfs_load (char *loadoffset, struct part_info *info, char *filename) if (cramfs_read_super (info)) return -1; - offset = cramfs_resolve (info->offset, + offset = cramfs_resolve (PART_OFFSET(info), CRAMFS_GET_OFFSET (&(super.root)) << 2, CRAMFS_24 (super.root.size), 0, strtok (filename, "/")); @@ -195,14 +200,14 @@ int cramfs_load (char *loadoffset, struct part_info *info, char *filename) if (offset <= 0) return offset; - return cramfs_uncompress (info->offset, offset, + return cramfs_uncompress (PART_OFFSET(info), offset, (unsigned long) loadoffset); } static int cramfs_list_inode (struct part_info *info, unsigned long offset) { struct cramfs_inode *inode = (struct cramfs_inode *) - (info->offset + offset); + (PART_OFFSET(info) + offset); char *name, str[20]; int namelen, nextoff; @@ -233,7 +238,7 @@ static int cramfs_list_inode (struct part_info *info, unsigned long offset) unsigned long size = CRAMFS_24 (inode->size); char *link = malloc (size); - if (link != NULL && cramfs_uncompress (info->offset, offset, + if (link != NULL && cramfs_uncompress (PART_OFFSET(info), offset, (unsigned long) link) == size) printf (" -> %*.*s\n", (int) size, (int) size, link); @@ -262,7 +267,7 @@ int cramfs_ls (struct part_info *info, char *filename) size = CRAMFS_24 (super.root.size); } else { /* Resolve the path */ - offset = cramfs_resolve (info->offset, + offset = cramfs_resolve (PART_OFFSET(info), CRAMFS_GET_OFFSET (&(super.root)) << 2, CRAMFS_24 (super.root.size), 1, strtok (filename, "/")); @@ -271,7 +276,7 @@ int cramfs_ls (struct part_info *info, char *filename) return offset; /* Resolving was successful. Examine the inode */ - inode = (struct cramfs_inode *) (info->offset + offset); + inode = (struct cramfs_inode *) (PART_OFFSET(info) + offset); if (!S_ISDIR (CRAMFS_16 (inode->mode))) { /* It's not a directory - list it, and that's that */ return (cramfs_list_inode (info, offset) > 0); @@ -284,7 +289,7 @@ int cramfs_ls (struct part_info *info, char *filename) /* List the given directory */ while (inodeoffset < size) { - inode = (struct cramfs_inode *) (info->offset + offset + + inode = (struct cramfs_inode *) (PART_OFFSET(info) + offset + inodeoffset); nextoffset = cramfs_list_inode (info, offset + inodeoffset); @@ -324,14 +329,17 @@ int cramfs_info (struct part_info *info) int cramfs_check (struct part_info *info) { - struct cramfs_super *sb = (struct cramfs_super *) info->offset; + struct cramfs_super *sb; + + if (info->dev->id->type != MTD_DEV_TYPE_NOR) + return 0; + sb = (struct cramfs_super *) PART_OFFSET(info); if (sb->magic != CRAMFS_32 (CRAMFS_MAGIC)) { /* check at 512 byte offset */ - sb = (struct cramfs_super *) (info->offset + 512); - if (sb->magic != CRAMFS_32 (CRAMFS_MAGIC)) { + sb = (struct cramfs_super *) (PART_OFFSET(info) + 512); + if (sb->magic != CRAMFS_32 (CRAMFS_MAGIC)) return 0; - } } return 1; } diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index c3553cb4ae..5180107f48 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -140,8 +140,10 @@ # define DEBUGF(fmt,args...) #endif -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) +/* keeps pointer to currentlu processed partition */ +static struct part_info *current_part; +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) /* * Support for jffs2 on top of NAND-flash * @@ -167,10 +169,10 @@ int read_jffs2_nand(size_t start, size_t len, static u8* nand_cache = NULL; static u32 nand_cache_off = (u32)-1; -static int nanddev = 0; /* nand device of current partition */ static int read_nand_cached(u32 off, u32 size, u_char *buf) { + struct mtdids *id = current_part->dev->id; u32 bytes_read = 0; size_t retlen; int cpy_bytes; @@ -190,10 +192,10 @@ static int read_nand_cached(u32 off, u32 size, u_char *buf) } } if (read_jffs2_nand(nand_cache_off, NAND_CACHE_SIZE, - &retlen, nand_cache, nanddev) < 0 || - retlen != NAND_CACHE_SIZE) { + &retlen, nand_cache, id->num) < 0 || + retlen != NAND_CACHE_SIZE) { printf("read_nand_cached: error reading nand off %#x size %d bytes\n", - nand_cache_off, NAND_CACHE_SIZE); + nand_cache_off, NAND_CACHE_SIZE); return -1; } } @@ -208,12 +210,12 @@ static int read_nand_cached(u32 off, u32 size, u_char *buf) return bytes_read; } -static void *get_fl_mem(u32 off, u32 size, void *ext_buf) +static void *get_fl_mem_nand(u32 off, u32 size, void *ext_buf) { u_char *buf = ext_buf ? (u_char*)ext_buf : (u_char*)malloc(size); if (NULL == buf) { - printf("get_fl_mem: can't alloc %d bytes\n", size); + printf("get_fl_mem_nand: can't alloc %d bytes\n", size); return NULL; } if (read_nand_cached(off, size, buf) < 0) { @@ -225,15 +227,15 @@ static void *get_fl_mem(u32 off, u32 size, void *ext_buf) return buf; } -static void *get_node_mem(u32 off) +static void *get_node_mem_nand(u32 off) { struct jffs2_unknown_node node; void *ret = NULL; - if (NULL == get_fl_mem(off, sizeof(node), &node)) + if (NULL == get_fl_mem_nand(off, sizeof(node), &node)) return NULL; - if (!(ret = get_fl_mem(off, node.magic == + if (!(ret = get_fl_mem_nand(off, node.magic == JFFS2_MAGIC_BITMASK ? node.totlen : sizeof(node), NULL))) { printf("off = %#x magic %#x type %#x node.totlen = %d\n", @@ -242,29 +244,88 @@ static void *get_node_mem(u32 off) return ret; } -static void put_fl_mem(void *buf) +static void put_fl_mem_nand(void *buf) { free(buf); } +#endif /* #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ + + +#if (CONFIG_COMMANDS & CFG_CMD_FLASH) +/* + * Support for jffs2 on top of NOR-flash + * + * NOR flash memory is mapped in processor's address space, + * just return address. + */ +static inline void *get_fl_mem_nor(u32 off) +{ + u32 addr = off; + struct mtdids *id = current_part->dev->id; + + extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + flash_info_t *flash = &flash_info[id->num]; + + addr += flash->start[0]; + return (void*)addr; +} + +static inline void *get_node_mem_nor(u32 off) +{ + return (void*)get_fl_mem_nor(off); +} +#endif /* #if (CONFIG_COMMANDS & CFG_CMD_FLASH) */ -#else /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ +/* + * Generic jffs2 raw memory and node read routines. + * + */ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) { + struct mtdids *id = current_part->dev->id; + +#if (CONFIG_COMMANDS & CFG_CMD_FLASH) + if (id->type == MTD_DEV_TYPE_NOR) + return get_fl_mem_nor(off); +#endif + +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) + if (id->type == MTD_DEV_TYPE_NAND) + return get_fl_mem_nand(off, size, ext_buf); +#endif + + printf("get_fl_mem: unknown device type, using raw offset!\n"); return (void*)off; } static inline void *get_node_mem(u32 off) { + struct mtdids *id = current_part->dev->id; + +#if (CONFIG_COMMANDS & CFG_CMD_FLASH) + if (id->type == MTD_DEV_TYPE_NOR) + return get_node_mem_nor(off); +#endif + +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) + if (id->type == MTD_DEV_TYPE_NAND) + return get_node_mem_nand(off); +#endif + + printf("get_node_mem: unknown device type, using raw offset!\n"); return (void*)off; } static inline void put_fl_mem(void *buf) { -} - -#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ +#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) + struct mtdids *id = current_part->dev->id; + if (id->type == MTD_DEV_TYPE_NAND) + return put_fl_mem_nand(buf); +#endif +} /* Compression names */ static char *compr_names[] = { @@ -457,8 +518,8 @@ static int compare_dirents(struct b_node *new, struct b_node *old) static u32 jffs2_scan_empty(u32 start_offset, struct part_info *part) { - char *max = part->offset + part->size - sizeof(struct jffs2_raw_inode); - char *offset = part->offset + start_offset; + char *max = (char *)(part->offset + part->size - sizeof(struct jffs2_raw_inode)); + char *offset = (char *)(part->offset + start_offset); u32 off; while (offset < max && @@ -468,11 +529,11 @@ jffs2_scan_empty(u32 start_offset, struct part_info *part) if (((u32)offset & ((1 << SPIN_BLKSIZE)-1)) == 0) break; } - return offset - part->offset; + return (u32)offset - part->offset; } -static u32 -jffs_init_1pass_list(struct part_info *part) +void +jffs2_free_cache(struct part_info *part) { struct b_lists *pL; @@ -482,6 +543,15 @@ jffs_init_1pass_list(struct part_info *part) free_nodes(&pL->dir); free(pL); } +} + +static u32 +jffs_init_1pass_list(struct part_info *part) +{ + struct b_lists *pL; + + jffs2_free_cache(part); + if (NULL != (part->jffs2_priv = malloc(sizeof(struct b_lists)))) { pL = (struct b_lists *)part->jffs2_priv; @@ -979,25 +1049,13 @@ jffs2_1pass_rescan_needed(struct part_info *part) DEBUGF ("rescan: First time in use\n"); return 1; } + /* if we have no list, we need to rescan */ if (pL->frag.listCount == 0) { DEBUGF ("rescan: fraglist zero\n"); return 1; } - /* or if we are scanning a new partition */ - if (pL->partOffset != part->offset) { - DEBUGF ("rescan: different partition\n"); - return 1; - } - -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) - if (nanddev != (int)part->usr_priv - 1) { - DEBUGF ("rescan: nand device changed\n"); - return -1; - } -#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ - /* but suppose someone reflashed a partition at the same offset... */ b = pL->dir.listHead; while (b) { @@ -1087,10 +1145,6 @@ jffs2_1pass_build_lists(struct part_info * part) u32 counterF = 0; u32 counterN = 0; -#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) - nanddev = (int)part->usr_priv - 1; -#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */ - /* turn off the lcd. Refreshing the lcd adds 50% overhead to the */ /* jffs2 list building enterprise nope. in newer versions the overhead is */ /* only about 5 %. not enough to inconvenience people for. */ @@ -1099,7 +1153,6 @@ jffs2_1pass_build_lists(struct part_info * part) /* if we are building a list we need to refresh the cache. */ jffs_init_1pass_list(part); pL = (struct b_lists *)part->jffs2_priv; - pL->partOffset = part->offset; offset = 0; puts ("Scanning JFFS2 FS: "); @@ -1217,6 +1270,9 @@ jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL) static struct b_lists * jffs2_get_list(struct part_info * part, const char *who) { + /* copy requested part_info struct pointer to global location */ + current_part = part; + if (jffs2_1pass_rescan_needed(part)) { if (!jffs2_1pass_build_lists(part)) { printf("%s: Failed to scan JFFSv2 file structure\n", who); diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h index d53e5764b8..65ca6eb98f 100644 --- a/fs/jffs2/jffs2_private.h +++ b/fs/jffs2/jffs2_private.h @@ -22,7 +22,6 @@ struct b_list { }; struct b_lists { - char *partOffset; struct b_list dir; struct b_list frag; |