diff options
author | Brian Norris <computersforpeace@gmail.com> | 2012-01-13 21:11:48 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-03-26 19:11:50 -0400 |
commit | cdbec0508699e3346052bf098c5c330a711a86a9 (patch) | |
tree | fa354f87911bf1929c7c04925900c8523eb6722f /drivers | |
parent | 009184296d957d864d6fa9ac2dd192d29e069878 (diff) |
mtd: nand: fix SCAN2NDPAGE check for BBM
nand_block_bad() doesn't check the correct pages when
NAND_BBT_SCAN2NDPAGE is enabled. It should scan both the OOB region of
both the 1st and 2nd page of each block.
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')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index cd827d5a8255..7855fd2d5c60 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -338,7 +338,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
338 | */ | 338 | */ |
339 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | 339 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) |
340 | { | 340 | { |
341 | int page, chipnr, res = 0; | 341 | int page, chipnr, res = 0, i = 0; |
342 | struct nand_chip *chip = mtd->priv; | 342 | struct nand_chip *chip = mtd->priv; |
343 | u16 bad; | 343 | u16 bad; |
344 | 344 | ||
@@ -356,23 +356,29 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |||
356 | chip->select_chip(mtd, chipnr); | 356 | chip->select_chip(mtd, chipnr); |
357 | } | 357 | } |
358 | 358 | ||
359 | if (chip->options & NAND_BUSWIDTH_16) { | 359 | do { |
360 | chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE, | 360 | if (chip->options & NAND_BUSWIDTH_16) { |
361 | page); | 361 | chip->cmdfunc(mtd, NAND_CMD_READOOB, |
362 | bad = cpu_to_le16(chip->read_word(mtd)); | 362 | chip->badblockpos & 0xFE, page); |
363 | if (chip->badblockpos & 0x1) | 363 | bad = cpu_to_le16(chip->read_word(mtd)); |
364 | bad >>= 8; | 364 | if (chip->badblockpos & 0x1) |
365 | else | 365 | bad >>= 8; |
366 | bad &= 0xFF; | 366 | else |
367 | } else { | 367 | bad &= 0xFF; |
368 | chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page); | 368 | } else { |
369 | bad = chip->read_byte(mtd); | 369 | chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, |
370 | } | 370 | page); |
371 | bad = chip->read_byte(mtd); | ||
372 | } | ||
371 | 373 | ||
372 | if (likely(chip->badblockbits == 8)) | 374 | if (likely(chip->badblockbits == 8)) |
373 | res = bad != 0xFF; | 375 | res = bad != 0xFF; |
374 | else | 376 | else |
375 | res = hweight8(bad) < chip->badblockbits; | 377 | res = hweight8(bad) < chip->badblockbits; |
378 | ofs += mtd->writesize; | ||
379 | page = (int)(ofs >> chip->page_shift) & chip->pagemask; | ||
380 | i++; | ||
381 | } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); | ||
376 | 382 | ||
377 | if (getchip) | 383 | if (getchip) |
378 | nand_release_device(mtd); | 384 | nand_release_device(mtd); |