diff -Nru prev/drivers/mtd/redboot.c linux/drivers/mtd/redboot.c --- prev/drivers/mtd/redboot.c Fri Mar 14 16:30:08 2003 +++ linux/drivers/mtd/redboot.c Mon Oct 27 14:53:17 2003 @@ -44,6 +44,7 @@ size_t retlen; char *names; int namelen = 0; + unsigned flash_base = 0; buf = kmalloc(PAGE_SIZE, GFP_KERNEL); @@ -64,8 +65,12 @@ /* RedBoot image could appear in any of the first three slots */ for (i = 0; i < 3; i++) { - if (!memcmp(buf[i].name, "RedBoot", 8)) + if (!memcmp(buf[i].name, "RedBoot", 8)) { + /* Legacy way of detecting flash base */ + /* Use RedBoot to be sure that we are using valid entry */ + flash_base = buf[i].flash_base & (master->size - 1); break; + } } if (i == 3) { /* Didn't find it */ @@ -75,6 +80,22 @@ goto out; } + /* + * Legacy way of detecting flash base does not work in two cases: + * 1) When map size (number of chips) is not equal power of 2 + * 2) When flash base is not aligned to map size + */ + /* Look for FIS directory in entire read area */ + for (i = 0; i < PAGE_SIZE / sizeof(struct fis_image_desc); i++) { + if (!memcmp(buf[i].name, "FIS directory", sizeof("FIS directory"))) { + flash_base = buf[i].flash_base - (master->size - master->erasesize); + break; + } + } + printk(KERN_DEBUG "RedBoot partition base 0x%08X\n", + flash_base); + + for (i = 0; i < PAGE_SIZE / sizeof(struct fis_image_desc); i++) { struct fis_list *new_fl, **prev; @@ -90,7 +111,7 @@ goto out; } new_fl->img = &buf[i]; - buf[i].flash_base &= master->size-1; + buf[i].flash_base -= flash_base; /* I'm sure the JFFS2 code has done me permanent damage. * I now think the following is _normal_