[U-Boot] [PATCH] mtd: nand: fix the written length when nand_write_skip_bad failed

Tao Hou hotforest at gmail.com
Sat Mar 2 10:01:10 CET 2013


When the data has been partially written into the NAND Flash,
returning the written length instead of 0. The written length
may be useful when the upper level decides to continue the writing
after skipping the block causing the write failure.

Signed-off-by: Tao Hou <hotforest at gmail.com>
Cc: Scott Wood <scottwood at freescale.com>
Cc: Ben Gardiner <bengardiner at nanometrics.ca>
Cc: Lei Wen <leiwen at marvell.com>
---
 drivers/mtd/nand/nand_util.c |   22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index de1d13e..f57d723 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -496,8 +496,10 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 
 #ifdef CONFIG_CMD_NAND_YAFFS
 	if (flags & WITH_YAFFS_OOB) {
-		if (flags & ~WITH_YAFFS_OOB)
+		if (flags & ~WITH_YAFFS_OOB) {
+			*length = 0;
 			return -EINVAL;
+		}
 
 		int pages;
 		pages = nand->erasesize / nand->writesize;
@@ -505,6 +507,7 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 		if (*length % (nand->writesize + nand->oobsize)) {
 			printf("Attempt to write incomplete page"
 				" in yaffs mode\n");
+			*length = 0;
 			return -EINVAL;
 		}
 	} else
@@ -542,7 +545,6 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 		if (rval == 0)
 			return 0;
 
-		*length = 0;
 		printf("NAND write to offset %llx failed %d\n",
 			offset, rval);
 		return rval;
@@ -550,7 +552,7 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 
 	while (left_to_write > 0) {
 		size_t block_offset = offset & (nand->erasesize - 1);
-		size_t write_size, truncated_write_size;
+		size_t write_size, truncated_write_size, written_size;
 
 		WATCHDOG_RESET();
 
@@ -586,8 +588,10 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 				ops.oobbuf = ops.datbuf + pagesize;
 
 				rval = nand->write_oob(nand, offset, &ops);
-				if (rval != 0)
+				if (rval != 0) {
+					written_size = pagesize_oob * page;
 					break;
+				}
 
 				offset += pagesize;
 				p_buffer += pagesize_oob;
@@ -605,14 +609,18 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
 
 			rval = nand_write(nand, offset, &truncated_write_size,
 					p_buffer);
-			offset += write_size;
-			p_buffer += write_size;
+			if (rval == 0) {
+				offset += write_size;
+				p_buffer += write_size;
+			} else {
+				written_size = truncated_write_size;
+			}
 		}
 
 		if (rval != 0) {
 			printf("NAND write to offset %llx failed %d\n",
 				offset, rval);
-			*length -= left_to_write;
+			*length -= left_to_write - written_size;
 			return rval;
 		}
 
-- 
1.7.9.5



More information about the U-Boot mailing list