Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c120e75e authored by Masahiro Yamada's avatar Masahiro Yamada Committed by Boris Brezillon
Browse files

mtd: nand: use read_oob() instead of cmdfunc() for bad block check



The nand_default_block_markbad() and scan_block_fast() use high
level APIs to get access to the BBM.

On the other hand, nand_block_bad (the default implementation of
->block_bad) calls the lower level ->cmdfunc hook.  This prevents
drivers from using ->ecc.read_oob() even if optimized read operation
is implemented.  Besides, some NAND controllers may protect the BBM
with ECC.

Signed-off-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent 9fe4b66e
Loading
Loading
Loading
Loading
+13 −21
Original line number Diff line number Diff line
@@ -354,42 +354,34 @@ static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 */
static int nand_block_bad(struct mtd_info *mtd, loff_t ofs)
{
	int page, res = 0, i = 0;
	int page, page_end, res;
	struct nand_chip *chip = mtd_to_nand(mtd);
	u16 bad;
	u8 bad;

	if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
		ofs += mtd->erasesize - mtd->writesize;

	page = (int)(ofs >> chip->page_shift) & chip->pagemask;
	page_end = page + (chip->bbt_options & NAND_BBT_SCAN2NDPAGE ? 2 : 1);

	do {
		if (chip->options & NAND_BUSWIDTH_16) {
			chip->cmdfunc(mtd, NAND_CMD_READOOB,
					chip->badblockpos & 0xFE, page);
			bad = cpu_to_le16(chip->read_word(mtd));
			if (chip->badblockpos & 0x1)
				bad >>= 8;
			else
				bad &= 0xFF;
		} else {
			chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos,
					page);
			bad = chip->read_byte(mtd);
		}
	for (; page < page_end; page++) {
		res = chip->ecc.read_oob(mtd, chip, page);
		if (res)
			return res;

		bad = chip->oob_poi[chip->badblockpos];

		if (likely(chip->badblockbits == 8))
			res = bad != 0xFF;
		else
			res = hweight8(bad) < chip->badblockbits;
		ofs += mtd->writesize;
		page = (int)(ofs >> chip->page_shift) & chip->pagemask;
		i++;
	} while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));

		if (res)
			return res;
	}

	return 0;
}

/**
 * nand_default_block_markbad - [DEFAULT] mark a block bad via bad block marker
 * @mtd: MTD device structure