Browse Source

mtd: bcm47xxpart: improve probing of nvram partition

The nvram in the nvram partition does not start at the beginning of the
partition on every device. Sometimes they are stating in the middle of
a partition or the first 0x1000 bytes are free.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Hauke Mehrtens 12 years ago
parent
commit
be3781b71a
1 changed files with 13 additions and 9 deletions
  1. 13 9
      drivers/mtd/bcm47xxpart.c

+ 13 - 9
drivers/mtd/bcm47xxpart.c

@@ -19,12 +19,6 @@
 /* 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 */
@@ -63,14 +57,17 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 	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(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL);
+	buf = kzalloc(max_bytes_to_read, GFP_KERNEL);
 
 	/* Parse block by block looking for magics */
 	for (offset = 0; offset <= master->size - blocksize;
@@ -85,7 +82,7 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 		}
 
 		/* Read beginning of the block */
-		if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
+		if (mtd_read(master, offset, max_bytes_to_read,
 			     &bytes_read, (uint8_t *)buf) < 0) {
 			pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
 			       offset);
@@ -100,9 +97,16 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 		}
 
 		/* Standard NVRAM */
-		if (buf[0x000 / 4] == NVRAM_HEADER) {
+		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))) {
 			bcm47xxpart_add_part(&parts[curr_part++], "nvram",
 					     offset, 0);
+			offset = rounddown(offset, blocksize);
 			continue;
 		}