summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cramfs/cramfs.c38
-rw-r--r--fs/jffs2/jffs2_1pass.c132
-rw-r--r--fs/jffs2/jffs2_private.h1
3 files changed, 117 insertions, 54 deletions
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c
index 98ff567..f02bf3c 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 c3553cb..5180107 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 d53e576..65ca6eb 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;