Commit 23b1a99b87f3fc9e4242b98b2af3c9bed210f048

Authored by Brian Norris
Committed by Artem Bityutskiy
1 parent d5de1907d0

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>

Showing 1 changed file with 4 additions and 0 deletions Side-by-side Diff

drivers/mtd/nand/nand_base.c
... ... @@ -420,6 +420,7 @@
420 420 ops.datbuf = NULL;
421 421 ops.oobbuf = buf;
422 422 ops.ooboffs = chip->badblockpos & ~0x01;
  423 + ops.mode = MTD_OPS_PLACE_OOB;
423 424 do {
424 425 ret = nand_do_write_oob(mtd, ofs, &ops);
425 426  
... ... @@ -1596,6 +1597,7 @@
1596 1597 ops.len = len;
1597 1598 ops.datbuf = buf;
1598 1599 ops.oobbuf = NULL;
  1600 + ops.mode = 0;
1599 1601  
1600 1602 ret = nand_do_read_ops(mtd, from, &ops);
1601 1603  
... ... @@ -2306,6 +2308,7 @@
2306 2308 ops.len = len;
2307 2309 ops.datbuf = (uint8_t *)buf;
2308 2310 ops.oobbuf = NULL;
  2311 + ops.mode = 0;
2309 2312  
2310 2313 ret = nand_do_write_ops(mtd, to, &ops);
2311 2314  
... ... @@ -2341,6 +2344,7 @@
2341 2344 ops.len = len;
2342 2345 ops.datbuf = (uint8_t *)buf;
2343 2346 ops.oobbuf = NULL;
  2347 + ops.mode = 0;
2344 2348  
2345 2349 ret = nand_do_write_ops(mtd, to, &ops);
2346 2350