12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <[email protected]>
- Date: Sat, 2 Jan 2016 01:04:52 +0100
- Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating
- offsets
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- Signed-off-by: Rafał Miłecki <[email protected]>
- ---
- drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 40 insertions(+), 10 deletions(-)
- --- a/drivers/mtd/bcm47xxpart.c
- +++ b/drivers/mtd/bcm47xxpart.c
- @@ -62,6 +62,34 @@ static void bcm47xxpart_add_part(struct
- part->mask_flags = mask_flags;
- }
-
- +/*
- + * Calculate real end offset (address) for a given amount of data. It checks
- + * all blocks skipping bad ones.
- + */
- +static size_t bcm47xxpart_real_offset(struct mtd_info *master, size_t offset,
- + size_t bytes)
- +{
- + size_t real_offset = offset;
- +
- + if (mtd_block_isbad(master, real_offset))
- + pr_warn("Base offset shouldn't be at bad block");
- +
- + while (bytes >= master->erasesize) {
- + bytes -= master->erasesize;
- + real_offset += master->erasesize;
- + while (mtd_block_isbad(master, real_offset)) {
- + real_offset += master->erasesize;
- +
- + if (real_offset >= master->size)
- + return real_offset - master->erasesize;
- + }
- + }
- +
- + real_offset += bytes;
- +
- + return real_offset;
- +}
- +
- static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master,
- size_t offset)
- {
- @@ -113,19 +141,22 @@ static int bcm47xxpart_parse_trx(struct
- if (header.offset[2]) {
- part = &parts[curr_part++];
- part->name = "loader";
- - part->offset = trx->offset + header.offset[i];
- + part->offset = bcm47xxpart_real_offset(master, trx->offset,
- + header.offset[i]);
- i++;
- }
-
- if (header.offset[i]) {
- part = &parts[curr_part++];
- part->name = "linux";
- - part->offset = trx->offset + header.offset[i];
- + part->offset = bcm47xxpart_real_offset(master, trx->offset,
- + header.offset[i]);
- i++;
- }
-
- if (header.offset[i]) {
- - size_t offset = trx->offset + header.offset[i];
- + size_t offset = bcm47xxpart_real_offset(master, trx->offset,
- + header.offset[i]);
-
- part = &parts[curr_part++];
- part->name = bcm47xxpart_trx_data_part_name(master, offset);
|