From 700a0c648df72f2c8e0589c0d0470b5ffd7cab7b Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Mon, 8 Aug 2005 01:03:24 +0200 Subject: 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. --- fs/jffs2/jffs2_1pass.c | 132 +++++++++++++++++++++++++++++++++-------------- fs/jffs2/jffs2_private.h | 1 - 2 files changed, 94 insertions(+), 39 deletions(-) (limited to 'fs/jffs2') 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; -- cgit