brcm47xx: add some more partition parser fixes by Rafał Miłecki
authorHauke Mehrtens <hauke@hauke-m.de>
Sat, 9 Mar 2013 19:48:03 +0000 (19:48 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 9 Mar 2013 19:48:03 +0000 (19:48 +0000)
SVN-Revision: 35912

target/linux/brcm47xx/patches-3.8/024-Revert-mtd-bcm47xxpart-improve-probing-of-nvram-part.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.8/024-mtd-bcm47xxpart-get-nvram.patch [deleted file]
target/linux/brcm47xx/patches-3.8/025-mtd-bcm47xxpart-look-for-NVRAM-at-the-end-of-device.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.8/026-mtd-bcm47xxpart-find-boot-partition-by-CFE-magic.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.8/027-mtd-bcm47xxpart-get-nvram.patch [new file with mode: 0644]

diff --git a/target/linux/brcm47xx/patches-3.8/024-Revert-mtd-bcm47xxpart-improve-probing-of-nvram-part.patch b/target/linux/brcm47xx/patches-3.8/024-Revert-mtd-bcm47xxpart-improve-probing-of-nvram-part.patch
new file mode 100644 (file)
index 0000000..0fc78c5
--- /dev/null
@@ -0,0 +1,61 @@
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -19,6 +19,12 @@
+ /* 10 parts were found on sflash on Netgear WNDR4500 */
+ #define BCM47XXPART_MAX_PARTS         12
++/*
++ * Amount of bytes we read when analyzing each block of flash memory.
++ * Set it big enough to allow detecting partition and reading important data.
++ */
++#define BCM47XXPART_BYTES_TO_READ     0x404
++
+ /* Magics */
+ #define BOARD_DATA_MAGIC              0x5246504D      /* MPFR */
+ #define POT_MAGIC1                    0x54544f50      /* POTT */
+@@ -57,17 +63,14 @@ static int bcm47xxpart_parse(struct mtd_
+       struct trx_header *trx;
+       int trx_part = -1;
+       int last_trx_part = -1;
+-      int max_bytes_to_read = 0x8004;
+       if (blocksize <= 0x10000)
+               blocksize = 0x10000;
+-      if (blocksize == 0x20000)
+-              max_bytes_to_read = 0x18004;
+       /* Alloc */
+       parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS,
+                       GFP_KERNEL);
+-      buf = kzalloc(max_bytes_to_read, GFP_KERNEL);
++      buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL);
+       /* Parse block by block looking for magics */
+       for (offset = 0; offset <= master->size - blocksize;
+@@ -82,7 +85,7 @@ static int bcm47xxpart_parse(struct mtd_
+               }
+               /* Read beginning of the block */
+-              if (mtd_read(master, offset, max_bytes_to_read,
++              if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
+                            &bytes_read, (uint8_t *)buf) < 0) {
+                       pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
+                              offset);
+@@ -97,16 +100,9 @@ static int bcm47xxpart_parse(struct mtd_
+               }
+               /* Standard NVRAM */
+-              if (buf[0x000 / 4] == NVRAM_HEADER ||
+-                  buf[0x1000 / 4] == NVRAM_HEADER ||
+-                  buf[0x8000 / 4] == NVRAM_HEADER ||
+-                  (blocksize == 0x20000 && (
+-                    buf[0x10000 / 4] == NVRAM_HEADER ||
+-                    buf[0x11000 / 4] == NVRAM_HEADER ||
+-                    buf[0x18000 / 4] == NVRAM_HEADER))) {
++              if (buf[0x000 / 4] == NVRAM_HEADER) {
+                       bcm47xxpart_add_part(&parts[curr_part++], "nvram",
+                                            offset, 0);
+-                      offset = rounddown(offset, blocksize);
+                       continue;
+               }
diff --git a/target/linux/brcm47xx/patches-3.8/024-mtd-bcm47xxpart-get-nvram.patch b/target/linux/brcm47xx/patches-3.8/024-mtd-bcm47xxpart-get-nvram.patch
deleted file mode 100644 (file)
index 9932665..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -58,6 +58,7 @@ static int bcm47xxpart_parse(struct mtd_
-       int trx_part = -1;
-       int last_trx_part = -1;
-       int max_bytes_to_read = 0x8004;
-+      bool found_nvram = false;
-       if (blocksize <= 0x10000)
-               blocksize = 0x10000;
-@@ -107,6 +108,7 @@ static int bcm47xxpart_parse(struct mtd_
-                       bcm47xxpart_add_part(&parts[curr_part++], "nvram",
-                                            offset, 0);
-                       offset = rounddown(offset, blocksize);
-+                      found_nvram = true;
-                       continue;
-               }
-@@ -194,6 +196,15 @@ static int bcm47xxpart_parse(struct mtd_
-                                              parts[trx_part].offset;
-       }
-+      if (!found_nvram) {
-+              pr_err("can not find a nvram partition reserve last block\n");
-+              bcm47xxpart_add_part(&parts[curr_part++], "nvram_guess",
-+                                   master->size - blocksize, MTD_WRITEABLE);
-+              for (i = 0; i < curr_part; i++) {
-+                      if (parts[i].size + parts[i].offset == master->size)
-+                              parts[i].offset -= blocksize;
-+              }
-+      }
-       *pparts = parts;
-       return curr_part;
- };
diff --git a/target/linux/brcm47xx/patches-3.8/025-mtd-bcm47xxpart-look-for-NVRAM-at-the-end-of-device.patch b/target/linux/brcm47xx/patches-3.8/025-mtd-bcm47xxpart-look-for-NVRAM-at-the-end-of-device.patch
new file mode 100644 (file)
index 0000000..1f82c92
--- /dev/null
@@ -0,0 +1,55 @@
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -63,6 +63,7 @@ static int bcm47xxpart_parse(struct mtd_
+       struct trx_header *trx;
+       int trx_part = -1;
+       int last_trx_part = -1;
++      int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
+       if (blocksize <= 0x10000)
+               blocksize = 0x10000;
+@@ -99,13 +100,6 @@ static int bcm47xxpart_parse(struct mtd_
+                       continue;
+               }
+-              /* Standard NVRAM */
+-              if (buf[0x000 / 4] == NVRAM_HEADER) {
+-                      bcm47xxpart_add_part(&parts[curr_part++], "nvram",
+-                                           offset, 0);
+-                      continue;
+-              }
+-
+               /*
+                * board_data starts with board_id which differs across boards,
+                * but we can use 'MPFR' (hopefully) magic at 0x100
+@@ -174,6 +168,30 @@ static int bcm47xxpart_parse(struct mtd_
+                       continue;
+               }
+       }
++
++      /* Look for NVRAM at the end of the last block. */
++      for (i = 0; i < ARRAY_SIZE(possible_nvram_sizes); i++) {
++              if (curr_part > BCM47XXPART_MAX_PARTS) {
++                      pr_warn("Reached maximum number of partitions, scanning stopped!\n");
++                      break;
++              }
++
++              offset = master->size - possible_nvram_sizes[i];
++              if (mtd_read(master, offset, 0x4, &bytes_read,
++                           (uint8_t *)buf) < 0) {
++                      pr_err("mtd_read error while reading at offset 0x%X!\n",
++                             offset);
++                      continue;
++              }
++
++              /* Standard NVRAM */
++              if (buf[0] == NVRAM_HEADER) {
++                      bcm47xxpart_add_part(&parts[curr_part++], "nvram",
++                                           master->size - blocksize, 0);
++                      break;
++              }
++      }
++
+       kfree(buf);
+       /*
diff --git a/target/linux/brcm47xx/patches-3.8/026-mtd-bcm47xxpart-find-boot-partition-by-CFE-magic.patch b/target/linux/brcm47xx/patches-3.8/026-mtd-bcm47xxpart-find-boot-partition-by-CFE-magic.patch
new file mode 100644 (file)
index 0000000..d3fb9d3
--- /dev/null
@@ -0,0 +1,26 @@
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -23,9 +23,10 @@
+  * Amount of bytes we read when analyzing each block of flash memory.
+  * Set it big enough to allow detecting partition and reading important data.
+  */
+-#define BCM47XXPART_BYTES_TO_READ     0x404
++#define BCM47XXPART_BYTES_TO_READ     0x4e8
+ /* Magics */
++#define CFE_MAGIC                     0x43464531      /* 1EFC */
+ #define BOARD_DATA_MAGIC              0x5246504D      /* MPFR */
+ #define POT_MAGIC1                    0x54544f50      /* POTT */
+ #define POT_MAGIC2                    0x504f          /* OP */
+@@ -93,8 +94,9 @@ static int bcm47xxpart_parse(struct mtd_
+                       continue;
+               }
+-              /* CFE has small NVRAM at 0x400 */
+-              if (buf[0x400 / 4] == NVRAM_HEADER) {
++              /* Magic or small NVRAM at 0x400 */
++              if (buf[0x4e0 / 4] == CFE_MAGIC ||
++                  buf[0x400 / 4] == NVRAM_HEADER) {
+                       bcm47xxpart_add_part(&parts[curr_part++], "boot",
+                                            offset, MTD_WRITEABLE);
+                       continue;
diff --git a/target/linux/brcm47xx/patches-3.8/027-mtd-bcm47xxpart-get-nvram.patch b/target/linux/brcm47xx/patches-3.8/027-mtd-bcm47xxpart-get-nvram.patch
new file mode 100644 (file)
index 0000000..4cd78c2
--- /dev/null
@@ -0,0 +1,34 @@
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -65,6 +65,7 @@ static int bcm47xxpart_parse(struct mtd_
+       int trx_part = -1;
+       int last_trx_part = -1;
+       int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
++      bool found_nvram = false;
+       if (blocksize <= 0x10000)
+               blocksize = 0x10000;
+@@ -190,12 +191,23 @@ static int bcm47xxpart_parse(struct mtd_
+               if (buf[0] == NVRAM_HEADER) {
+                       bcm47xxpart_add_part(&parts[curr_part++], "nvram",
+                                            master->size - blocksize, 0);
++                      found_nvram = true;
+                       break;
+               }
+       }
+       kfree(buf);
++      if (!found_nvram) {
++              pr_err("can not find a nvram partition reserve last block\n");
++              bcm47xxpart_add_part(&parts[curr_part++], "nvram_guess",
++                                   master->size - blocksize * 2, MTD_WRITEABLE);
++              for (i = 0; i < curr_part; i++) {
++                      if (parts[i].size + parts[i].offset == master->size)
++                              parts[i].offset -= blocksize * 2;
++              }
++      }
++
+       /*
+        * Assume that partitions end at the beginning of the one they are
+        * followed by.