X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmtd%2Fredboot.c;h=a61351f88ec046d894bf07bc042907e2a22bb364;hb=91fe7d7cdd7ebb0b6c01f201a23824ab5b466ada;hp=035cd9b0cc08b327f83d8f12958eacdcab7f6c94;hpb=b22364c8eec89e6b0c081a237f3b6348df87796f;p=linux-2.6 diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 035cd9b0cc..a61351f88e 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -94,8 +94,19 @@ 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); for (j = 0; j < numslots; ++j) { /* A single 0xff denotes a deleted entry. @@ -120,11 +131,11 @@ static int parse_redboot_partitions(struct mtd_info *master, swab32s(&buf[j].desc_cksum); swab32s(&buf[j].file_cksum); } + } else if (buf[i].size < master->erasesize) { + /* Update numslots based on actual FIS directory size */ + numslots = buf[i].size / sizeof(struct fis_image_desc); } break; - } else { - /* re-calculate of real numslots */ - numslots = buf[i].size / sizeof(struct fis_image_desc); } } if (i == numslots) {