From: Rafał Miłecki Date: Sat, 2 Jan 2016 00:33:48 +0000 (+0000) Subject: kernel: make bcm47xxpart work with TRX flashed at bad block(s) X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=7bede46e587da51765a9d0a435f8cc14d3082d7c;p=openwrt%2Fstaging%2Fansuel.git kernel: make bcm47xxpart work with TRX flashed at bad block(s) Signed-off-by: Rafał Miłecki SVN-Revision: 48061 --- diff --git a/target/linux/bcm53xx/patches-4.1/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch b/target/linux/bcm53xx/patches-4.1/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch index aa68415d68..d9537d594b 100644 --- a/target/linux/bcm53xx/patches-4.1/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch +++ b/target/linux/bcm53xx/patches-4.1/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch @@ -22,7 +22,7 @@ Signed-off-by: Rafał Miłecki #include -@@ -131,6 +132,17 @@ static int bcm47xxpart_parse(struct mtd_ +@@ -159,6 +160,17 @@ static int bcm47xxpart_parse(struct mtd_ break; } diff --git a/target/linux/bcm53xx/patches-4.1/902-mtd-bcm47xxpart-print-buffer-used-for-determining-pa.patch b/target/linux/bcm53xx/patches-4.1/902-mtd-bcm47xxpart-print-buffer-used-for-determining-pa.patch index 1ebc75a4df..3b99443146 100644 --- a/target/linux/bcm53xx/patches-4.1/902-mtd-bcm47xxpart-print-buffer-used-for-determining-pa.patch +++ b/target/linux/bcm53xx/patches-4.1/902-mtd-bcm47xxpart-print-buffer-used-for-determining-pa.patch @@ -12,7 +12,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c -@@ -66,19 +66,22 @@ static void bcm47xxpart_add_part(struct +@@ -94,19 +94,22 @@ static size_t bcm47xxpart_real_offset(st static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, size_t offset) { diff --git a/target/linux/bcm53xx/patches-4.4/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch b/target/linux/bcm53xx/patches-4.4/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch index aa68415d68..d9537d594b 100644 --- a/target/linux/bcm53xx/patches-4.4/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch +++ b/target/linux/bcm53xx/patches-4.4/901-mtd-bcm47xxpart-workaround-for-Asus-RT-AC87U-asus-pa.patch @@ -22,7 +22,7 @@ Signed-off-by: Rafał Miłecki #include -@@ -131,6 +132,17 @@ static int bcm47xxpart_parse(struct mtd_ +@@ -159,6 +160,17 @@ static int bcm47xxpart_parse(struct mtd_ break; } diff --git a/target/linux/generic/patches-3.18/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/patches-3.18/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch new file mode 100644 index 0000000000..6adac77669 --- /dev/null +++ b/target/linux/generic/patches-3.18/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch @@ -0,0 +1,100 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +--- + drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 40 insertions(+), 10 deletions(-) + +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -61,6 +61,34 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name, + 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) + { +@@ -182,6 +210,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, + + /* TRX */ + if (buf[0x000 / 4] == TRX_MAGIC) { ++ uint32_t tmp; ++ + if (BCM47XXPART_MAX_PARTS - curr_part < 4) { + pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); + break; +@@ -196,18 +226,18 @@ static int bcm47xxpart_parse(struct mtd_info *master, + i = 0; + /* We have LZMA loader if offset[2] points to sth */ + if (trx->offset[2]) { ++ tmp = bcm47xxpart_real_offset(master, offset, ++ trx->offset[i]); + bcm47xxpart_add_part(&parts[curr_part++], +- "loader", +- offset + trx->offset[i], +- 0); ++ "loader", tmp, 0); + i++; + } + + if (trx->offset[i]) { ++ tmp = bcm47xxpart_real_offset(master, offset, ++ trx->offset[i]); + bcm47xxpart_add_part(&parts[curr_part++], +- "linux", +- offset + trx->offset[i], +- 0); ++ "linux", tmp, 0); + i++; + } + +@@ -219,11 +249,11 @@ static int bcm47xxpart_parse(struct mtd_info *master, + if (trx->offset[i]) { + const char *name; + +- name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); ++ tmp = bcm47xxpart_real_offset(master, offset, ++ trx->offset[i]); ++ name = bcm47xxpart_trx_data_part_name(master, tmp); + bcm47xxpart_add_part(&parts[curr_part++], +- name, +- offset + trx->offset[i], +- 0); ++ name, tmp, 0); + i++; + } + diff --git a/target/linux/generic/patches-3.18/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/patches-3.18/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch index a3b7c1f71f..9e5ca91e55 100644 --- a/target/linux/generic/patches-3.18/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch +++ b/target/linux/generic/patches-3.18/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch @@ -24,7 +24,7 @@ Signed-off-by: Rafał Miłecki #define ML_MAGIC1 0x39685a42 #define ML_MAGIC2 0x26594131 #define TRX_MAGIC 0x30524448 -@@ -179,6 +180,15 @@ static int bcm47xxpart_parse(struct mtd_ +@@ -207,6 +208,15 @@ static int bcm47xxpart_parse(struct mtd_ MTD_WRITEABLE); continue; } diff --git a/target/linux/generic/patches-4.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/patches-4.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch new file mode 100644 index 0000000000..6adac77669 --- /dev/null +++ b/target/linux/generic/patches-4.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch @@ -0,0 +1,100 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +--- + drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 40 insertions(+), 10 deletions(-) + +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -61,6 +61,34 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name, + 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) + { +@@ -182,6 +210,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, + + /* TRX */ + if (buf[0x000 / 4] == TRX_MAGIC) { ++ uint32_t tmp; ++ + if (BCM47XXPART_MAX_PARTS - curr_part < 4) { + pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); + break; +@@ -196,18 +226,18 @@ static int bcm47xxpart_parse(struct mtd_info *master, + i = 0; + /* We have LZMA loader if offset[2] points to sth */ + if (trx->offset[2]) { ++ tmp = bcm47xxpart_real_offset(master, offset, ++ trx->offset[i]); + bcm47xxpart_add_part(&parts[curr_part++], +- "loader", +- offset + trx->offset[i], +- 0); ++ "loader", tmp, 0); + i++; + } + + if (trx->offset[i]) { ++ tmp = bcm47xxpart_real_offset(master, offset, ++ trx->offset[i]); + bcm47xxpart_add_part(&parts[curr_part++], +- "linux", +- offset + trx->offset[i], +- 0); ++ "linux", tmp, 0); + i++; + } + +@@ -219,11 +249,11 @@ static int bcm47xxpart_parse(struct mtd_info *master, + if (trx->offset[i]) { + const char *name; + +- name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); ++ tmp = bcm47xxpart_real_offset(master, offset, ++ trx->offset[i]); ++ name = bcm47xxpart_trx_data_part_name(master, tmp); + bcm47xxpart_add_part(&parts[curr_part++], +- name, +- offset + trx->offset[i], +- 0); ++ name, tmp, 0); + i++; + } + diff --git a/target/linux/generic/patches-4.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/patches-4.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch index a3b7c1f71f..9e5ca91e55 100644 --- a/target/linux/generic/patches-4.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch +++ b/target/linux/generic/patches-4.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch @@ -24,7 +24,7 @@ Signed-off-by: Rafał Miłecki #define ML_MAGIC1 0x39685a42 #define ML_MAGIC2 0x26594131 #define TRX_MAGIC 0x30524448 -@@ -179,6 +180,15 @@ static int bcm47xxpart_parse(struct mtd_ +@@ -207,6 +208,15 @@ static int bcm47xxpart_parse(struct mtd_ MTD_WRITEABLE); continue; } diff --git a/target/linux/generic/patches-4.4/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/patches-4.4/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch new file mode 100644 index 0000000000..6adac77669 --- /dev/null +++ b/target/linux/generic/patches-4.4/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch @@ -0,0 +1,100 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +--- + drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 40 insertions(+), 10 deletions(-) + +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -61,6 +61,34 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name, + 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) + { +@@ -182,6 +210,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, + + /* TRX */ + if (buf[0x000 / 4] == TRX_MAGIC) { ++ uint32_t tmp; ++ + if (BCM47XXPART_MAX_PARTS - curr_part < 4) { + pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); + break; +@@ -196,18 +226,18 @@ static int bcm47xxpart_parse(struct mtd_info *master, + i = 0; + /* We have LZMA loader if offset[2] points to sth */ + if (trx->offset[2]) { ++ tmp = bcm47xxpart_real_offset(master, offset, ++ trx->offset[i]); + bcm47xxpart_add_part(&parts[curr_part++], +- "loader", +- offset + trx->offset[i], +- 0); ++ "loader", tmp, 0); + i++; + } + + if (trx->offset[i]) { ++ tmp = bcm47xxpart_real_offset(master, offset, ++ trx->offset[i]); + bcm47xxpart_add_part(&parts[curr_part++], +- "linux", +- offset + trx->offset[i], +- 0); ++ "linux", tmp, 0); + i++; + } + +@@ -219,11 +249,11 @@ static int bcm47xxpart_parse(struct mtd_info *master, + if (trx->offset[i]) { + const char *name; + +- name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); ++ tmp = bcm47xxpart_real_offset(master, offset, ++ trx->offset[i]); ++ name = bcm47xxpart_trx_data_part_name(master, tmp); + bcm47xxpart_add_part(&parts[curr_part++], +- name, +- offset + trx->offset[i], +- 0); ++ name, tmp, 0); + i++; + } + diff --git a/target/linux/generic/patches-4.4/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/patches-4.4/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch index a3b7c1f71f..9e5ca91e55 100644 --- a/target/linux/generic/patches-4.4/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch +++ b/target/linux/generic/patches-4.4/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch @@ -24,7 +24,7 @@ Signed-off-by: Rafał Miłecki #define ML_MAGIC1 0x39685a42 #define ML_MAGIC2 0x26594131 #define TRX_MAGIC 0x30524448 -@@ -179,6 +180,15 @@ static int bcm47xxpart_parse(struct mtd_ +@@ -207,6 +208,15 @@ static int bcm47xxpart_parse(struct mtd_ MTD_WRITEABLE); continue; }