--- a/drivers/mtd/parsers/redboot.c +++ b/drivers/mtd/parsers/redboot.c @@ -71,6 +71,22 @@ static void parse_redboot_of(struct mtd_ directory = dirblock; } +static uint32_t mtd_get_offset_erasesize(struct mtd_info *mtd, uint64_t offset) +{ + struct mtd_erase_region_info *regions = mtd->eraseregions; + int i; + + for (i = 0; i < mtd->numeraseregions; i++) { + if (regions[i].offset + + regions[i].numblocks * regions[i].erasesize <= offset) + continue; + + return regions[i].erasesize; + } + + return mtd->erasesize; +} + static int parse_redboot_partitions(struct mtd_info *master, const struct mtd_partition **pparts, struct mtd_part_parser_data *data) @@ -87,6 +103,7 @@ static int parse_redboot_partitions(stru int namelen = 0; int nulllen = 0; int numslots; + int first_slot; unsigned long offset; #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED static char nullstring[] = "unallocated"; @@ -134,7 +151,9 @@ nogood: } numslots = (master->erasesize / sizeof(struct fis_image_desc)); - for (i = 0; i < numslots; i++) { + first_slot = (buf[i].flash_base & (master->erasesize - 1)) / + sizeof(struct fis_image_desc); + for (i = first_slot; i < first_slot + numslots; i++) { if (!memcmp(buf[i].name, "FIS directory", 14)) { /* This is apparently the FIS directory entry for the * FIS directory itself. The FIS directory size is @@ -200,7 +219,10 @@ nogood: goto out; } - for (i = 0; i < numslots; i++) { + first_slot = (buf[i].flash_base & (master->erasesize - 1)) / + sizeof(struct fis_image_desc); + + for (i = first_slot; i < first_slot + numslots; i++) { struct fis_list *new_fl, **prev; if (buf[i].name[0] == 0xff) { @@ -275,12 +297,13 @@ nogood: } #endif for ( ; i < nrparts; i++) { - if (max_offset < buf[i].flash_base + buf[i].size) - max_offset = buf[i].flash_base + buf[i].size; parts[i].size = fl->img->size; parts[i].offset = fl->img->flash_base; parts[i].name = names; + if (max_offset < parts[i].offset + parts[i].size) + max_offset = parts[i].offset + parts[i].size; + strcpy(names, fl->img->name); #ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY if (!memcmp(names, "RedBoot", 8) || @@ -310,7 +333,9 @@ nogood: fl = fl->next; kfree(tmp_fl); } - if (master->size - max_offset >= master->erasesize) { + + if (master->size - max_offset >= + mtd_get_offset_erasesize(master, max_offset)) { parts[nrparts].size = master->size - max_offset; parts[nrparts].offset = max_offset; parts[nrparts].name = names;