aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_base.c
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2013-07-30 20:52:59 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2013-08-30 11:48:17 -0400
commitb32843b772db6024336e36c39359d8edc3b416ab (patch)
tree9e4cd381d3abfa5075dceb1ff544908645431a4b /drivers/mtd/nand/nand_base.c
parent5a0edb251ae91c6f9b1f28dc165becd955666118 (diff)
mtd: nand: hide in-memory BBT implementation details
nand_base.c shouldn't have to know the implementation details of nand_bbt's in-memory BBT. Specifically, nand_base shouldn't perform the bit masking and shifting to isolate a BBT entry. Instead, just move some of the BBT code into a new nand_markbad_bbt() interface. This interface allows external users (i.e., nand_base) to mark a single block as bad in the BBT. Then nand_bbt will take care of modifying the in-memory BBT and updating the flash-based BBT (if applicable). Signed-off-by: Brian Norris <computersforpeace@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r--drivers/mtd/nand/nand_base.c32
1 files changed, 11 insertions, 21 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5a7467c33757..9a487580e370 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -374,22 +374,20 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
374 * block table(s) and/or marker(s)). We only allow the hardware driver to 374 * block table(s) and/or marker(s)). We only allow the hardware driver to
375 * specify how to write bad block markers to OOB (chip->block_markbad). 375 * specify how to write bad block markers to OOB (chip->block_markbad).
376 * 376 *
377 * We try operations in the following order, according to our bbt_options 377 * We try operations in the following order:
378 * (NAND_BBT_NO_OOB_BBM and NAND_BBT_USE_FLASH):
379 * (1) erase the affected block, to allow OOB marker to be written cleanly 378 * (1) erase the affected block, to allow OOB marker to be written cleanly
380 * (2) update in-memory BBT 379 * (2) write bad block marker to OOB area of affected block (unless flag
381 * (3) write bad block marker to OOB area of affected block 380 * NAND_BBT_NO_OOB_BBM is present)
382 * (4) update flash-based BBT 381 * (3) update the BBT
383 * Note that we retain the first error encountered in (3) or (4), finish the 382 * Note that we retain the first error encountered in (2) or (3), finish the
384 * procedures, and dump the error in the end. 383 * procedures, and dump the error in the end.
385*/ 384*/
386static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) 385static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
387{ 386{
388 struct nand_chip *chip = mtd->priv; 387 struct nand_chip *chip = mtd->priv;
389 int block, res, ret = 0; 388 int res, ret = 0;
390 int write_oob = !(chip->bbt_options & NAND_BBT_NO_OOB_BBM);
391 389
392 if (write_oob) { 390 if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) {
393 struct erase_info einfo; 391 struct erase_info einfo;
394 392
395 /* Attempt erase before marking OOB */ 393 /* Attempt erase before marking OOB */
@@ -398,24 +396,16 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
398 einfo.addr = ofs; 396 einfo.addr = ofs;
399 einfo.len = 1 << chip->phys_erase_shift; 397 einfo.len = 1 << chip->phys_erase_shift;
400 nand_erase_nand(mtd, &einfo, 0); 398 nand_erase_nand(mtd, &einfo, 0);
401 }
402
403 /* Get block number */
404 block = (int)(ofs >> chip->bbt_erase_shift);
405 /* Mark block bad in memory-based BBT */
406 if (chip->bbt)
407 chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
408 399
409 /* Write bad block marker to OOB */ 400 /* Write bad block marker to OOB */
410 if (write_oob) {
411 nand_get_device(mtd, FL_WRITING); 401 nand_get_device(mtd, FL_WRITING);
412 ret = chip->block_markbad(mtd, ofs); 402 ret = chip->block_markbad(mtd, ofs);
413 nand_release_device(mtd); 403 nand_release_device(mtd);
414 } 404 }
415 405
416 /* Update flash-based bad block table */ 406 /* Mark block bad in BBT */
417 if (chip->bbt_options & NAND_BBT_USE_FLASH) { 407 if (chip->bbt) {
418 res = nand_update_bbt(mtd, ofs); 408 res = nand_markbad_bbt(mtd, ofs);
419 if (!ret) 409 if (!ret)
420 ret = res; 410 ret = res;
421 } 411 }