aboutsummaryrefslogtreecommitdiff
path: root/drivers/dfu/dfu_mtd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dfu/dfu_mtd.c')
-rw-r--r--drivers/dfu/dfu_mtd.c34
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;
}
}