diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-07-23 17:06:50 +0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-07-23 16:09:52 +0400 |
commit | c0b8ba7bfe7b4c1f11b3356b65520405b005bd33 (patch) | |
tree | 8a9a2ddccad561d21dc25ebd92b900a9bcc2d634 | |
parent | 0bf9733d0d65ebb413d62204ad8e328e0a0b9407 (diff) | |
download | linux-c0b8ba7bfe7b4c1f11b3356b65520405b005bd33.tar.xz |
[MTD] [NAND] fix race in nand_base.c
When we mark block bad we have to get chip because this involves
writing to the page's OOB. We hit this bug in UBI - we observed
random obscure crashes when it marks block bad from the background
thread and there is some parallel task which utilizes flash.
This patch also adds a TODO note about BBT table protection which
it seems does not exist.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 25673eacdd88..24ac6778b1a8 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -24,6 +24,7 @@ * if we have HW ecc support. * The AG-AND chips have nice features for speed improvement, * which are not supported yet. Read / program 4 pages in one go. + * BBT table is not serialized, has to be fixed * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -360,6 +361,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) /* We write two bytes, so we dont have to mess with 16 bit * access */ + nand_get_device(chip, mtd, FL_WRITING); ofs += mtd->oobsize; chip->ops.len = chip->ops.ooblen = 2; chip->ops.datbuf = NULL; @@ -367,9 +369,11 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) chip->ops.ooboffs = chip->badblockpos & ~0x01; ret = nand_do_write_oob(mtd, ofs, &chip->ops); + nand_release_device(mtd); } if (!ret) mtd->ecc_stats.badblocks++; + return ret; } |