diff options
Diffstat (limited to 'drivers/dfu/dfu_mtd.c')
-rw-r--r-- | drivers/dfu/dfu_mtd.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c index 75e2f6a421..485586989c 100644 --- a/drivers/dfu/dfu_mtd.c +++ b/drivers/dfu/dfu_mtd.c @@ -85,27 +85,41 @@ static int mtd_block_op(enum dfu_op op, struct dfu_entity *dfu, while (remaining) { if (erase_op.addr + remaining > lim) { - printf("Limit reached 0x%llx while erasing at offset 0x%llx\n", - lim, off); + printf("Limit reached 0x%llx while erasing at offset 0x%llx, remaining 0x%llx\n", + lim, erase_op.addr, remaining); return -EIO; } + /* Skip the block if it is bad, don't erase it again */ + ret = mtd_block_isbad(mtd, erase_op.addr); + if (ret) { + printf("Skipping %s at 0x%08llx\n", + ret == 1 ? "bad block" : "bbt reserved", + erase_op.addr); + erase_op.addr += mtd->erasesize; + continue; + } + ret = mtd_erase(mtd, &erase_op); if (ret) { - /* Abort if its not a bad block error */ - if (ret != -EIO) { - printf("Failure while erasing at offset 0x%llx\n", - erase_op.fail_addr); - return 0; + /* If this is not -EIO, we have no idea what to do. */ + if (ret == -EIO) { + printf("Marking bad block at 0x%08llx (%d)\n", + erase_op.fail_addr, ret); + ret = mtd_block_markbad(mtd, erase_op.addr); + } + /* Abort if it is not -EIO or can't mark bad */ + if (ret) { + printf("Failure while erasing at offset 0x%llx (%d)\n", + erase_op.fail_addr, ret); + return ret; } - printf("Skipping bad block at 0x%08llx\n", - erase_op.addr); } else { remaining -= mtd->erasesize; } - /* Continue erase behind bad block */ + /* Continue erase behind the current block */ erase_op.addr += mtd->erasesize; } } |