/branches/18.06.1/target/linux/generic/pending-4.14/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch |
@@ -0,0 +1,68 @@ |
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> |
Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets |
|
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> |
--- |
|
--- a/drivers/mtd/parsers/parser_trx.c |
+++ b/drivers/mtd/parsers/parser_trx.c |
@@ -29,6 +29,33 @@ struct trx_header { |
uint32_t offset[3]; |
} __packed; |
|
+/* |
+ * Calculate real end offset (address) for a given amount of data. It checks |
+ * all blocks skipping bad ones. |
+ */ |
+static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes) |
+{ |
+ size_t real_offset = 0; |
+ |
+ if (mtd_block_isbad(mtd, real_offset)) |
+ pr_warn("Base offset shouldn't be at bad block"); |
+ |
+ while (bytes >= mtd->erasesize) { |
+ bytes -= mtd->erasesize; |
+ real_offset += mtd->erasesize; |
+ while (mtd_block_isbad(mtd, real_offset)) { |
+ real_offset += mtd->erasesize; |
+ |
+ if (real_offset >= mtd->size) |
+ return real_offset - mtd->erasesize; |
+ } |
+ } |
+ |
+ real_offset += bytes; |
+ |
+ return real_offset; |
+} |
+ |
static const char *parser_trx_data_part_name(struct mtd_info *master, |
size_t offset) |
{ |
@@ -83,21 +110,21 @@ static int parser_trx_parse(struct mtd_i |
if (trx.offset[2]) { |
part = &parts[curr_part++]; |
part->name = "loader"; |
- part->offset = trx.offset[i]; |
+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); |
i++; |
} |
|
if (trx.offset[i]) { |
part = &parts[curr_part++]; |
part->name = "linux"; |
- part->offset = trx.offset[i]; |
+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); |
i++; |
} |
|
if (trx.offset[i]) { |
part = &parts[curr_part++]; |
- part->name = parser_trx_data_part_name(mtd, trx.offset[i]); |
- part->offset = trx.offset[i]; |
+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); |
+ part->name = parser_trx_data_part_name(mtd, part->offset); |
i++; |
} |
|