From 648bdbee5d2cc3ff27370d05e7577ade8496bfd0 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 6 Jan 2013 16:08:35 +0100 Subject: mtd: bcm47xxpart: simplify size calculation to one loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- drivers/mtd/bcm47xxpart.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/mtd/bcm47xxpart.c') diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index e06d782489a6..06125eb59f14 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -169,11 +169,12 @@ static int bcm47xxpart_parse(struct mtd_info *master, * Assume that partitions end at the beginning of the one they are * followed by. */ - for (i = 0; i < curr_part - 1; i++) - parts[i].size = parts[i + 1].offset - parts[i].offset; - if (curr_part > 0) - parts[curr_part - 1].size = - master->size - parts[curr_part - 1].offset; + for (i = 0; i < curr_part; i++) { + u64 next_part_offset = (i < curr_part - 1) ? + parts[i + 1].offset : master->size; + + parts[i].size = next_part_offset - parts[i].offset; + } *pparts = parts; return curr_part; -- cgit v1.2.3 From 396afe553bd607dca4d28b00b6cab2ea826acba2 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Sun, 6 Jan 2013 16:08:36 +0100 Subject: mtd: bcm47xxpart: register extra "firmware" partition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's required for accessing trx header (usually re-calculating a checksum) and for writing a new firmware. Signed-off-by: Rafał Miłecki --- drivers/mtd/bcm47xxpart.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/mtd/bcm47xxpart.c') diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 06125eb59f14..3411bc2a1482 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -61,6 +61,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, uint32_t offset; uint32_t blocksize = 0x10000; struct trx_header *trx; + int trx_part = -1; + int last_trx_part = -1; /* Alloc */ parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS, @@ -131,6 +133,10 @@ static int bcm47xxpart_parse(struct mtd_info *master, if (buf[0x000 / 4] == TRX_MAGIC) { trx = (struct trx_header *)buf; + trx_part = curr_part; + bcm47xxpart_add_part(&parts[curr_part++], "firmware", + offset, 0); + i = 0; /* We have LZMA loader if offset[2] points to sth */ if (trx->offset[2]) { @@ -154,6 +160,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, offset + trx->offset[i], 0); i++; + last_trx_part = curr_part - 1; + /* * We have whole TRX scanned, skip to the next part. Use * roundown (not roundup), as the loop will increase @@ -174,6 +182,9 @@ static int bcm47xxpart_parse(struct mtd_info *master, parts[i + 1].offset : master->size; parts[i].size = next_part_offset - parts[i].offset; + if (i == last_trx_part && trx_part >= 0) + parts[trx_part].size = next_part_offset - + parts[trx_part].offset; } *pparts = parts; -- cgit v1.2.3 From 25bad1d3c9f5616aaa50849300248d03141574a0 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 24 Jan 2013 17:39:58 +0100 Subject: mtd: bcm47xxpart: add support for other erase sizes To make the partitions writable they should aligned to erase sizes of the flash. If the erase size is small use 0x10000. Signed-off-by: Hauke Mehrtens Signed-off-by: Artem Bityutskiy --- drivers/mtd/bcm47xxpart.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/mtd/bcm47xxpart.c') diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 3411bc2a1482..986ab6ef3181 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -59,11 +59,14 @@ static int bcm47xxpart_parse(struct mtd_info *master, uint32_t *buf; size_t bytes_read; uint32_t offset; - uint32_t blocksize = 0x10000; + uint32_t blocksize = master->erasesize; struct trx_header *trx; int trx_part = -1; int last_trx_part = -1; + if (blocksize <= 0x10000) + blocksize = 0x10000; + /* Alloc */ parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS, GFP_KERNEL); -- cgit v1.2.3 From be3781b71ac03723b552dc156931620634ef1b22 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 24 Jan 2013 19:03:37 +0100 Subject: 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 Signed-off-by: Artem Bityutskiy --- drivers/mtd/bcm47xxpart.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers/mtd/bcm47xxpart.c') diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 986ab6ef3181..9bcec8f22bbb 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/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; } -- cgit v1.2.3