| From stable-bounces@linux.kernel.org Mon Feb 12 15:27:53 2007 |
| From: David Woodhouse <dwmw2@infradead.org> |
| Date: Tue, 13 Feb 2007 09:56:22 +1030 |
| Subject: MTD: Fatal regression in drivers/mtd/redboot.c in 2.6.20 |
| To: stable@kernel.org |
| Cc: Andrew Morton <akpm@osdl.org>, David Woodhouse <dwmw2@infradead.org>, Martin Michlmayr <tbm@cyrius.com>, Yoshinori Sato <ysato@users.sourceforge.jp> |
| Message-ID: <45D0F79E.7010104@whitby.id.au> |
| |
| From: David Woodhouse <dwmw2@infradead.org> |
| |
| [MTD] Fix regression in RedBoot partition scanning |
| |
| This fixes a regression introduced by the attempt to handle RedBoot FIS |
| tables which are smaller than an eraseblock, in commit |
| 0b47d654089c5ce3f2ea26a4485db9bcead1e515 |
| |
| It moves the recalculation of the number of slots in the table to the |
| correct place, and improves the heuristic for when we think we need to |
| byte-swap what we read from the flash. |
| |
| Signed-off-by: David Woodhouse <dwmw2@infradead.org> |
| Cc: Rod Whitby <rod@whitby.id.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/mtd/redboot.c | 19 +++++++++++++++---- |
| 1 file changed, 15 insertions(+), 4 deletions(-) |
| |
| --- linux-2.6.20.1.orig/drivers/mtd/redboot.c |
| +++ linux-2.6.20.1/drivers/mtd/redboot.c |
| @@ -94,8 +94,19 @@ static int parse_redboot_partitions(stru |
| * (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(stru |
| 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) { |