summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2015-02-05 11:03:59 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2015-02-10 09:58:18 +0100
commiteebfbe9116a46d504f0912a25cf5ff7eaff96884 (patch)
tree1177faebbd2c5403b8ba433099fa7aa39054de99
parent3b71b23b46278de78f3db265ea90a28c8e4246a5 (diff)
downloadbarebox-eebfbe9116a46d504f0912a25cf5ff7eaff96884.tar.gz
barebox-eebfbe9116a46d504f0912a25cf5ff7eaff96884.tar.xz
mtd: nand-bb: fix erasing bb devices with bad blocks
mtd_erase does not skip bad blocks, we must skip them in nand_bb_erase instead. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/mtd/nand/nand-bb.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/mtd/nand/nand-bb.c b/drivers/mtd/nand/nand-bb.c
index e38517d983..f134635f2a 100644
--- a/drivers/mtd/nand/nand-bb.c
+++ b/drivers/mtd/nand/nand-bb.c
@@ -159,16 +159,34 @@ static int nand_bb_erase(struct cdev *cdev, size_t count, loff_t offset)
{
struct nand_bb *bb = cdev->priv;
struct erase_info erase = {};
+ int ret;
if (offset != 0) {
printf("can only erase from beginning of device\n");
return -EINVAL;
}
- erase.addr = 0;
- erase.len = bb->mtd->size;
+ while (count) {
+ if (offset + bb->mtd->erasesize > bb->mtd->size)
+ return 0;
+
+ if (mtd_block_isbad(bb->mtd, offset)) {
+ offset += bb->mtd->erasesize;
+ continue;
+ }
- return mtd_erase(bb->mtd, &erase);
+ erase.addr = offset;
+ erase.len = bb->mtd->erasesize;
+
+ ret = mtd_erase(bb->mtd, &erase);
+ if (ret)
+ return ret;
+
+ offset += bb->mtd->erasesize;
+ count -= bb->mtd->erasesize;
+ }
+
+ return 0;
}
#endif