[PATCH 3/5] backport mtd api change to nand, onenand infrastructure

Mike Dunn mikedunn at newsguy.com
Mon Nov 28 20:02:49 EST 2011


Backport of the mtd api change to nand and onenand infrastructure code.

Signed-off-by: Mike Dunn <mikedunn at newsguy.com>
---
 drivers/mtd/nand/nand_base.c       |   19 ++++++++++++++++---
 drivers/mtd/nand/nand_bbt.c        |   11 ++++++++---
 drivers/mtd/onenand/onenand_base.c |    5 ++++-
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 35b4565..49598c7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1458,6 +1458,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 	oob = ops->oobbuf;
 
 	while (1) {
+		__u32 prior_corrected = mtd->ecc_stats.corrected;
+
 		bytes = min(mtd->writesize - col, readlen);
 		aligned = (bytes == mtd->writesize);
 
@@ -1530,8 +1532,11 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 			buf += bytes;
 		}
 
-		readlen -= bytes;
+		ops->max_bitflips =
+			max(ops->max_bitflips,
+			    mtd->ecc_stats.corrected - prior_corrected);
 
+		readlen -= bytes;
 		if (!readlen)
 			break;
 
@@ -1580,7 +1585,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
  * Get hold of the chip and call nand_do_read.
  */
 static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
-		     size_t *retlen, uint8_t *buf)
+		     size_t *retlen, uint8_t *buf, unsigned int *max_bitflips)
 {
 	struct nand_chip *chip = mtd->priv;
 	struct mtd_oob_ops ops;
@@ -1598,10 +1603,12 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
 	ops.datbuf = buf;
 	ops.oobbuf = NULL;
 	ops.mode = 0;
+	ops.max_bitflips = 0;
 
 	ret = nand_do_read_ops(mtd, from, &ops);
 
 	*retlen = ops.retlen;
+	*max_bitflips = ops.max_bitflips;
 
 	nand_release_device(mtd);
 
@@ -1799,6 +1806,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 	page = realpage & chip->pagemask;
 
 	while (1) {
+		__u32 prior_corrected = mtd->ecc_stats.corrected;
+
 		if (ops->mode == MTD_OPS_RAW)
 			sndcmd = chip->ecc.read_oob_raw(mtd, chip, page, sndcmd);
 		else
@@ -1820,6 +1829,10 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 				nand_wait_ready(mtd);
 		}
 
+		ops->max_bitflips =
+			max(ops->max_bitflips,
+			    mtd->ecc_stats.corrected - prior_corrected);
+
 		readlen -= len;
 		if (!readlen)
 			break;
@@ -1865,7 +1878,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
 	struct nand_chip *chip = mtd->priv;
 	int ret = -ENOTSUPP;
 
-	ops->retlen = 0;
+	ops->retlen = ops->max_bitflips = 0;
 
 	/* Do not allow reads past end of device */
 	if (ops->datbuf && (from + ops->len) > mtd->size) {
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 69148ae..4b1b707 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -191,6 +191,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
 	from = ((loff_t)page) << this->page_shift;
 
 	while (totlen) {
+		unsigned int max_bitflips;
 		len = min(totlen, (size_t)(1 << this->bbt_erase_shift));
 		if (marker_len) {
 			/*
@@ -201,7 +202,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
 			from += marker_len;
 			marker_len = 0;
 		}
-		res = mtd->read(mtd, from, len, &retlen, buf);
+		res = mtd->read(mtd, from, len, &retlen, buf, &max_bitflips);
 		if (res < 0) {
 			if (mtd_is_eccerr(res)) {
 				pr_info("nand_bbt: ECC error in BBT at "
@@ -293,12 +294,13 @@ static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
 {
 	size_t retlen;
 	size_t len;
+	unsigned int max_bitflips;
 
 	len = td->len;
 	if (td->options & NAND_BBT_VERSION)
 		len++;
 
-	return mtd->read(mtd, offs, len, &retlen, buf);
+	return mtd->read(mtd, offs, len, &retlen, buf, &max_bitflips);
 }
 
 /* Scan read raw data from flash */
@@ -753,10 +755,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 
 		/* Must we save the block contents? */
 		if (td->options & NAND_BBT_SAVECONTENT) {
+			unsigned int max_bitflips;
+
 			/* Make it block aligned */
 			to &= ~((loff_t)((1 << this->bbt_erase_shift) - 1));
 			len = 1 << this->bbt_erase_shift;
-			res = mtd->read(mtd, to, len, &retlen, buf);
+			res = mtd->read(mtd, to, len, &retlen, buf,
+					&max_bitflips);
 			if (res < 0) {
 				if (retlen != len) {
 					pr_info("nand_bbt: error reading block "
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index a839473..27a140a 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1451,7 +1451,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
  * Read with ecc
 */
 static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
-	size_t *retlen, u_char *buf)
+			size_t *retlen, u_char *buf, unsigned int *max_bitflips)
 {
 	struct onenand_chip *this = mtd->priv;
 	struct mtd_oob_ops ops = {
@@ -1469,6 +1469,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
 	onenand_release_device(mtd);
 
 	*retlen = ops.retlen;
+	*max_bitflips = mtd_is_bitflip(ret) ? 1 : 0;
 	return ret;
 }
 
@@ -1505,6 +1506,8 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
 		ret = onenand_read_oob_nolock(mtd, from, ops);
 	onenand_release_device(mtd);
 
+	ops->max_bitflips = mtd_is_bitflip(ret) ? 1 : 0;
+
 	return ret;
 }
 
-- 
1.7.3.4




More information about the linux-mtd mailing list