| 1 | --- a/drivers/mtd/redboot.c |
| 2 | +++ b/drivers/mtd/redboot.c |
| 3 | @@ -39,6 +39,22 @@ static inline int redboot_checksum(struc |
| 4 | return 1; |
| 5 | } |
| 6 | |
| 7 | +static uint32_t mtd_get_offset_erasesize(struct mtd_info *mtd, uint64_t offset) |
| 8 | +{ |
| 9 | + struct mtd_erase_region_info *regions = mtd->eraseregions; |
| 10 | + int i; |
| 11 | + |
| 12 | + for (i = 0; i < mtd->numeraseregions; i++) { |
| 13 | + if (regions[i].offset + |
| 14 | + regions[i].numblocks * regions[i].erasesize <= offset) |
| 15 | + continue; |
| 16 | + |
| 17 | + return regions[i].erasesize; |
| 18 | + } |
| 19 | + |
| 20 | + return mtd->erasesize; |
| 21 | +} |
| 22 | + |
| 23 | static int parse_redboot_partitions(struct mtd_info *master, |
| 24 | struct mtd_partition **pparts, |
| 25 | unsigned long fis_origin) |
| 26 | @@ -55,6 +71,7 @@ static int parse_redboot_partitions(stru |
| 27 | int namelen = 0; |
| 28 | int nulllen = 0; |
| 29 | int numslots; |
| 30 | + int first_slot; |
| 31 | unsigned long offset; |
| 32 | #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED |
| 33 | static char nullstring[] = "unallocated"; |
| 34 | @@ -168,7 +185,10 @@ static int parse_redboot_partitions(stru |
| 35 | goto out; |
| 36 | } |
| 37 | |
| 38 | - for (i = 0; i < numslots; i++) { |
| 39 | + first_slot = (buf[i].flash_base & (master->erasesize - 1)) / |
| 40 | + sizeof(struct fis_image_desc); |
| 41 | + |
| 42 | + for (i = first_slot; i < first_slot + numslots; i++) { |
| 43 | struct fis_list *new_fl, **prev; |
| 44 | |
| 45 | if (buf[i].name[0] == 0xff) { |
| 46 | @@ -244,12 +264,13 @@ static int parse_redboot_partitions(stru |
| 47 | } |
| 48 | #endif |
| 49 | for ( ; i<nrparts; i++) { |
| 50 | - if(max_offset < buf[i].flash_base + buf[i].size) |
| 51 | - max_offset = buf[i].flash_base + buf[i].size; |
| 52 | parts[i].size = fl->img->size; |
| 53 | parts[i].offset = fl->img->flash_base; |
| 54 | parts[i].name = names; |
| 55 | |
| 56 | + if (max_offset < parts[i].offset + parts[i].size) |
| 57 | + max_offset = parts[i].offset + parts[i].size; |
| 58 | + |
| 59 | strcpy(names, fl->img->name); |
| 60 | #ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY |
| 61 | if (!memcmp(names, "RedBoot", 8) || |
| 62 | @@ -279,7 +300,9 @@ static int parse_redboot_partitions(stru |
| 63 | fl = fl->next; |
| 64 | kfree(tmp_fl); |
| 65 | } |
| 66 | - if(master->size - max_offset >= master->erasesize) |
| 67 | + |
| 68 | + if (master->size - max_offset >= |
| 69 | + mtd_get_offset_erasesize(master, max_offset)) |
| 70 | { |
| 71 | parts[nrparts].size = master->size - max_offset; |
| 72 | parts[nrparts].offset = max_offset; |
| 73 | |