--- zzzz-none-000/linux-5.4.213/drivers/mtd/parsers/parser_trx.c 2022-09-15 10:04:56.000000000 +0000 +++ alder-5690pro-762/linux-5.4.213/drivers/mtd/parsers/parser_trx.c 2024-08-14 09:02:07.000000000 +0000 @@ -25,6 +25,33 @@ 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) { @@ -79,21 +106,21 @@ 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++; }