fa00dcd3b47aa5050639713230bac62549262eec
[openwrt.git] / target / linux / atheros / patches-3.10 / 142-redboot_various_erase_size_fix.patch
1 --- a/drivers/mtd/redboot.c
2 +++ b/drivers/mtd/redboot.c
3 @@ -58,6 +58,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                                     struct mtd_part_parser_data *data)
26 @@ -74,6 +90,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 @@ -186,7 +203,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 @@ -261,12 +281,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 @@ -296,7 +317,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;