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

Commit 67a9ad9b authored by Ezequiel Garcia's avatar Ezequiel Garcia Committed by Brian Norris
Browse files

mtd: nand: Warn the user if the selected ECC strength is too weak



This commit makes use of the chip->ecc_strength_ds and chip->ecc_step_ds which
contain the datasheet minimum requested ECC strength to produce a noisy warning
if the configured ECC strength is weaker.

Signed-off-by: default avatarEzequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent edf02fb2
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -3794,6 +3794,39 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
}
EXPORT_SYMBOL(nand_scan_ident);

/*
 * Check if the chip configuration meet the datasheet requirements.

 * If our configuration corrects A bits per B bytes and the minimum
 * required correction level is X bits per Y bytes, then we must ensure
 * both of the following are true:
 *
 * (1) A / B >= X / Y
 * (2) A >= X
 *
 * Requirement (1) ensures we can correct for the required bitflip density.
 * Requirement (2) ensures we can correct even when all bitflips are clumped
 * in the same sector.
 */
static bool nand_ecc_strength_good(struct mtd_info *mtd)
{
	struct nand_chip *chip = mtd->priv;
	struct nand_ecc_ctrl *ecc = &chip->ecc;
	int corr, ds_corr;

	if (ecc->size == 0 || chip->ecc_step_ds == 0)
		/* Not enough information */
		return true;

	/*
	 * We get the number of corrected bits per page to compare
	 * the correction density.
	 */
	corr = (mtd->writesize * ecc->strength) / ecc->size;
	ds_corr = (mtd->writesize * chip->ecc_strength_ds) / chip->ecc_step_ds;

	return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
}

/**
 * nand_scan_tail - [NAND Interface] Scan for the NAND device
@@ -4014,6 +4047,9 @@ int nand_scan_tail(struct mtd_info *mtd)
		ecc->layout->oobavail += ecc->layout->oobfree[i].length;
	mtd->oobavail = ecc->layout->oobavail;

	/* ECC sanity check: warn noisily if it's too weak */
	WARN_ON(!nand_ecc_strength_good(mtd));

	/*
	 * Set the number of read / write steps for one page depending on ECC
	 * mode.