diff options
Diffstat (limited to 'fs/jffs2')
| -rw-r--r-- | fs/jffs2/jffs2_1pass.c | 136 | ||||
| -rw-r--r-- | fs/jffs2/jffs2_private.h | 1 | 
2 files changed, 96 insertions, 41 deletions
| diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index c3553cb4a..e53aa31ef 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); @@ -1232,7 +1288,7 @@ u32  jffs2_1pass_ls(struct part_info * part, const char *fname)  {  	struct b_lists *pl; -	long ret = 0; +	long ret = 1;  	u32 inode;  	if (! (pl = jffs2_get_list(part, "ls"))) @@ -1259,7 +1315,7 @@ jffs2_1pass_load(char *dest, struct part_info * part, const char *fname)  {  	struct b_lists *pl; -	long ret = 0; +	long ret = 1;  	u32 inode;  	if (! (pl  = jffs2_get_list(part, "load"))) diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h index d53e5764b..65ca6eb98 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; |