diff options
author | Brian Norris <computersforpeace@gmail.com> | 2011-10-14 23:09:33 -0400 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2011-10-16 08:04:00 -0400 |
commit | 23b1a99b87f3fc9e4242b98b2af3c9bed210f048 (patch) | |
tree | 7a33efa8e9d82f6893ed7363d689b1d6774a480d | |
parent | d5de1907d0af22e1a02de2b16a624148517a39c2 (diff) |
mtd: nand: initialize ops.mode
Our `ops' information was converted to a local variable recently, and
apparently, old code relied on the fact that the global version was
often left in a valid mode. We can't make this assumption on local
structs, and we shouldn't be relying on a previous state anyway.
Instead, we initialize mode to 0 for don't-care situations (i.e., the
operation does not use OOB anyway) and MTD_OPS_PLACE_OOB when we want to
place OOB data.
This fixes a bug with nand_default_block_markbad(), where we catch on
the BUG() call in nand_fill_oob():
Kernel bug detected[#1]:
...
Call Trace:
[<80307350>] nand_fill_oob.clone.5+0xa4/0x15c
[<803075d8>] nand_do_write_oob+0x1d0/0x260
[<803077c4>] nand_default_block_markbad+0x15c/0x1a8
[<802e8c2c>] part_block_markbad+0x80/0x98
[<802ebc74>] mtd_ioctl+0x6d8/0xbd0
[<802ec1a4>] mtd_unlocked_ioctl+0x38/0x5c
[<800d9c60>] do_vfs_ioctl+0xa4/0x6e4
[<800da2e4>] sys_ioctl+0x44/0xa0
[<8001381c>] stack_done+0x20/0x40
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
-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 51653d9e1438..3ed9c5e4d34e 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -420,6 +420,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
420 | ops.datbuf = NULL; | 420 | ops.datbuf = NULL; |
421 | ops.oobbuf = buf; | 421 | ops.oobbuf = buf; |
422 | ops.ooboffs = chip->badblockpos & ~0x01; | 422 | ops.ooboffs = chip->badblockpos & ~0x01; |
423 | ops.mode = MTD_OPS_PLACE_OOB; | ||
423 | do { | 424 | do { |
424 | ret = nand_do_write_oob(mtd, ofs, &ops); | 425 | ret = nand_do_write_oob(mtd, ofs, &ops); |
425 | 426 | ||
@@ -1596,6 +1597,7 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
1596 | ops.len = len; | 1597 | ops.len = len; |
1597 | ops.datbuf = buf; | 1598 | ops.datbuf = buf; |
1598 | ops.oobbuf = NULL; | 1599 | ops.oobbuf = NULL; |
1600 | ops.mode = 0; | ||
1599 | 1601 | ||
1600 | ret = nand_do_read_ops(mtd, from, &ops); | 1602 | ret = nand_do_read_ops(mtd, from, &ops); |
1601 | 1603 | ||
@@ -2306,6 +2308,7 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
2306 | ops.len = len; | 2308 | ops.len = len; |
2307 | ops.datbuf = (uint8_t *)buf; | 2309 | ops.datbuf = (uint8_t *)buf; |
2308 | ops.oobbuf = NULL; | 2310 | ops.oobbuf = NULL; |
2311 | ops.mode = 0; | ||
2309 | 2312 | ||
2310 | ret = nand_do_write_ops(mtd, to, &ops); | 2313 | ret = nand_do_write_ops(mtd, to, &ops); |
2311 | 2314 | ||
@@ -2341,6 +2344,7 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
2341 | ops.len = len; | 2344 | ops.len = len; |
2342 | ops.datbuf = (uint8_t *)buf; | 2345 | ops.datbuf = (uint8_t *)buf; |
2343 | ops.oobbuf = NULL; | 2346 | ops.oobbuf = NULL; |
2347 | ops.mode = 0; | ||
2344 | 2348 | ||
2345 | ret = nand_do_write_ops(mtd, to, &ops); | 2349 | ret = nand_do_write_ops(mtd, to, &ops); |
2346 | 2350 | ||