Hello.

I have found the problem. The error was because we check if the
current block is bad or the next one is bad. And skip the current
block even if only the next one is bad. This way we skip good block
before a bad one.

Attached is a patch to fix it. Besides I have removed 4 bad block
count limit. Instead I check if we read till the end of nand. Or at
least this is what this code supposed to do:

if (start_block512 >> 2 > BAD_BLOCK_OFFSET)
    /* end of NAND */
    return -1;

I am not sure this is the best and/or correct way to do the stop check.

A similar check for bad block ahead the current one was added to
u-boot in commit 4ec60973cf2e028de905f6ea1f81ef99ca60d834 by Michael:

    Change the skip bad block. Avoid false positives by only checking
    the beginning of a block and check the second page

Qi code does the same thing. But it seems to be wrong at least in my case.

Regards,
  Dmitry
diff --git a/src/cpu/s3c2442/nand_read.c b/src/cpu/s3c2442/nand_read.c
index 06ec24d..8206717 100644
--- a/src/cpu/s3c2442/nand_read.c
+++ b/src/cpu/s3c2442/nand_read.c
@@ -119,7 +119,6 @@ int nand_read_ll(unsigned char *buf, unsigned long start_block512,
 								  int blocks512)
 {
 	int i, j;
-	int bad_count = 0;
 
 	/* chip Enable */
 	nand_select();
@@ -129,11 +128,10 @@ int nand_read_ll(unsigned char *buf, unsigned long start_block512,
 		;
 
 	while (blocks512 > 0) {
-		if (s3c2442_nand_is_bad_block(start_block512) ||
-				s3c2442_nand_is_bad_block(start_block512 + 4)) {
+		if (s3c2442_nand_is_bad_block(start_block512)) {
 			start_block512 += 4;
-			blocks512 += 4;
-			if (bad_count++ == 4)
+			if (start_block512 >> 2 > BAD_BLOCK_OFFSET)
+				/* end of NAND */
 				return -1;
 			continue;
 		}

Reply via email to