diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-02-05 11:03:59 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-02-10 09:58:18 +0100 |
commit | eebfbe9116a46d504f0912a25cf5ff7eaff96884 (patch) | |
tree | 1177faebbd2c5403b8ba433099fa7aa39054de99 | |
parent | 3b71b23b46278de78f3db265ea90a28c8e4246a5 (diff) | |
download | barebox-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.c | 24 |
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 |