X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fmtd%2Fredboot.c;h=c5030f94f04e180adeea6eda0af5f0b8994e83cb;hb=f6dc8ccaab6d8f63cbae1e6c73fe972b26f5376c;hp=a459ffa1e6766a1a1f414255573d8422c911e814;hpb=11192146e57bc8e58865e7d9c2497f66a4f7e6e7;p=linux-2.6-omap-h63xx.git diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index a459ffa1e67..c5030f94f04 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -59,16 +59,31 @@ static int parse_redboot_partitions(struct mtd_info *master, static char nullstring[] = "unallocated"; #endif + if ( directory < 0 ) { + offset = master->size + directory * master->erasesize; + while (master->block_isbad && + master->block_isbad(master, offset)) { + if (!offset) { + nogood: + printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n"); + return -EIO; + } + offset -= master->erasesize; + } + } else { + offset = directory * master->erasesize; + while (master->block_isbad && + master->block_isbad(master, offset)) { + offset += master->erasesize; + if (offset == master->size) + goto nogood; + } + } buf = vmalloc(master->erasesize); if (!buf) return -ENOMEM; - if ( directory < 0 ) - offset = master->size + directory*master->erasesize; - else - offset = directory*master->erasesize; - printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n", master->name, offset); @@ -94,7 +109,16 @@ static int parse_redboot_partitions(struct mtd_info *master, * (NOTE: this is 'size' not 'data_length'; size is * the full size of the entry.) */ - if (swab32(buf[i].size) == master->erasesize) { + + /* RedBoot can combine the FIS directory and + config partitions into a single eraseblock; + we assume wrong-endian if either the swapped + 'size' matches the eraseblock size precisely, + or if the swapped size actually fits in an + eraseblock while the unswapped size doesn't. */ + if (swab32(buf[i].size) == master->erasesize || + (buf[i].size > master->erasesize + && swab32(buf[i].size) < master->erasesize)) { int j; /* Update numslots based on actual FIS directory size */ numslots = swab32(buf[i].size) / sizeof (struct fis_image_desc); @@ -122,7 +146,7 @@ static int parse_redboot_partitions(struct mtd_info *master, swab32s(&buf[j].desc_cksum); swab32s(&buf[j].file_cksum); } - } else { + } else if (buf[i].size < master->erasesize) { /* Update numslots based on actual FIS directory size */ numslots = buf[i].size / sizeof(struct fis_image_desc); } @@ -271,5 +295,5 @@ module_init(redboot_parser_init); module_exit(redboot_parser_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse "); +MODULE_AUTHOR("David Woodhouse "); MODULE_DESCRIPTION("Parsing code for RedBoot Flash Image System (FIS) tables");