|
|
|
From 3282055a7d0a304d541dbdbe2e32167e1a2f117c Mon Sep 17 00:00:00 2001
|
|
|
|
From: Boris BREZILLON <boris.brezillon@free-electrons.com>
|
|
|
|
Date: Mon, 28 Jul 2014 14:20:54 +0200
|
|
|
|
Subject: [PATCH] mtd: nand: Take nand_ecc_ctrl initialization out of
|
|
|
|
nand_scan_tail
|
|
|
|
|
|
|
|
Take ECC initialization code portion out of nand_scan_tail so that we can
|
|
|
|
re-use this implementation.
|
|
|
|
|
|
|
|
This commit only moves some code around and makes no functional changes.
|
|
|
|
|
|
|
|
Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
|
|
|
|
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
|
---
|
|
|
|
drivers/mtd/nand/nand_base.c | 91 +++++++++++++++++++++++++++-----------------
|
|
|
|
1 file changed, 56 insertions(+), 35 deletions(-)
|
|
|
|
|
|
|
|
--- a/drivers/mtd/nand/nand_base.c
|
|
|
|
+++ b/drivers/mtd/nand/nand_base.c
|
|
|
|
@@ -3892,42 +3892,15 @@ static bool nand_ecc_strength_good(struc
|
|
|
|
return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
|
|
|
|
}
|
|
|
|
|
|
|
|
-/**
|
|
|
|
- * nand_scan_tail - [NAND Interface] Scan for the NAND device
|
|
|
|
- * @mtd: MTD device structure
|
|
|
|
- *
|
|
|
|
- * This is the second phase of the normal nand_scan() function. It fills out
|
|
|
|
- * all the uninitialized function pointers with the defaults and scans for a
|
|
|
|
- * bad block table if appropriate.
|
|
|
|
+/*
|
|
|
|
+ * Initialize ECC struct:
|
|
|
|
+ * - fill ECC struct with default function/values when these ones are undefined
|
|
|
|
+ * - fill ECC infos based on MTD device
|
|
|
|
*/
|
|
|
|
-int nand_scan_tail(struct mtd_info *mtd)
|
|
|
|
+static int nand_ecc_ctrl_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
- struct nand_chip *chip = mtd->priv;
|
|
|
|
- struct nand_ecc_ctrl *ecc = &chip->ecc;
|
|
|
|
- struct nand_buffers *nbuf;
|
|
|
|
|
|
|
|
- /* New bad blocks should be marked in OOB, flash-based BBT, or both */
|
|
|
|
- BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
|
|
|
|
- !(chip->bbt_options & NAND_BBT_USE_FLASH));
|
|
|
|
-
|
|
|
|
- if (!(chip->options & NAND_OWN_BUFFERS)) {
|
|
|
|
- nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
|
|
|
|
- + mtd->oobsize * 3, GFP_KERNEL);
|
|
|
|
- if (!nbuf)
|
|
|
|
- return -ENOMEM;
|
|
|
|
- nbuf->ecccalc = (uint8_t *)(nbuf + 1);
|
|
|
|
- nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
|
|
|
|
- nbuf->databuf = nbuf->ecccode + mtd->oobsize;
|
|
|
|
-
|
|
|
|
- chip->buffers = nbuf;
|
|
|
|
- } else {
|
|
|
|
- if (!chip->buffers)
|
|
|
|
- return -ENOMEM;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Set the internal oob buffer location, just after the page data */
|
|
|
|
- chip->oob_poi = chip->buffers->databuf + mtd->writesize;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If no default placement scheme is given, select an appropriate one.
|
|
|
|
@@ -3953,9 +3926,6 @@ int nand_scan_tail(struct mtd_info *mtd)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- if (!chip->write_page)
|
|
|
|
- chip->write_page = nand_write_page;
|
|
|
|
-
|
|
|
|
/*
|
|
|
|
* Check ECC mode, default to software if 3byte/512byte hardware ECC is
|
|
|
|
* selected and we have 256 byte pagesize fallback to software ECC
|
|
|
|
@@ -4125,6 +4095,57 @@ int nand_scan_tail(struct mtd_info *mtd)
|
|
|
|
}
|
|
|
|
ecc->total = ecc->steps * ecc->bytes;
|
|
|
|
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * nand_scan_tail - [NAND Interface] Scan for the NAND device
|
|
|
|
+ * @mtd: MTD device structure
|
|
|
|
+ *
|
|
|
|
+ * This is the second phase of the normal nand_scan() function. It fills out
|
|
|
|
+ * all the uninitialized function pointers with the defaults and scans for a
|
|
|
|
+ * bad block table if appropriate.
|
|
|
|
+ */
|
|
|
|
+int nand_scan_tail(struct mtd_info *mtd)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+ struct nand_chip *chip = mtd->priv;
|
|
|
|
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
|
|
|
|
+ struct nand_buffers *nbuf;
|
|
|
|
+
|
|
|
|
+ /* New bad blocks should be marked in OOB, flash-based BBT, or both */
|
|
|
|
+ BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
|
|
|
|
+ !(chip->bbt_options & NAND_BBT_USE_FLASH));
|
|
|
|
+
|
|
|
|
+ if (!(chip->options & NAND_OWN_BUFFERS)) {
|
|
|
|
+ nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
|
|
|
|
+ + mtd->oobsize * 3, GFP_KERNEL);
|
|
|
|
+ if (!nbuf)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ nbuf->ecccalc = (uint8_t *)(nbuf + 1);
|
|
|
|
+ nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
|
|
|
|
+ nbuf->databuf = nbuf->ecccode + mtd->oobsize;
|
|
|
|
+ chip->buffers = nbuf;
|
|
|
|
+ } else {
|
|
|
|
+ if (!chip->buffers)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Set the internal oob buffer location, just after the page data */
|
|
|
|
+ chip->oob_poi = chip->buffers->databuf + mtd->writesize;
|
|
|
|
+
|
|
|
|
+ if (!chip->write_page)
|
|
|
|
+ chip->write_page = nand_write_page;
|
|
|
|
+
|
|
|
|
+ /* Initialize ECC struct */
|
|
|
|
+ ret = nand_ecc_ctrl_init(mtd, ecc);
|
|
|
|
+ if (ret) {
|
|
|
|
+ if (!(chip->options & NAND_OWN_BUFFERS))
|
|
|
|
+ kfree(chip->buffers);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
/* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
|
|
|
|
if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
|
|
|
|
switch (ecc->steps) {
|