Hi,

This patch fix the bad block skipping code.

Regards Michael

--- nand_read.c.orig	2008-04-10 12:29:30.000000000 +0200
+++ nand_read.c	2008-04-10 12:32:40.000000000 +0200
@@ -41,6 +41,27 @@
 #define NAND_BLOCK_MASK		(NAND_SECTOR_SIZE - 1)
 #define NAND_PAGE_SIZE		0x4000
 
+static inline int block_is_bad(int addr) {
+	unsigned char data;
+	int i;
+
+	NFCMD = 0x50;
+	wait_idle();
+
+	NFADDR = addr & 0xf;
+	NFADDR = (addr >> 9) & 0xff;
+	NFADDR = (addr >> 17) & 0xff;
+	NFADDR = (addr >> 25) & 0xff;
+
+	wait_idle();
+	data = (NFDATA & 0xff);
+
+	if (data != 0xff)
+		return 1;
+	
+	return 0;
+}
+
 /* low level nand read function */
 int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
 {
@@ -55,16 +76,10 @@
 
 	for (i=start_addr; i < (start_addr + size);) {
 #ifdef CONFIG_S3C2410_NAND_SKIP_BAD
-		if (start_addr % NAND_PAGE_SIZE == 0) {
-			unsigned char data;
-			NFCMD = 0x50;
-			NFADDR = 517&0xf;
-			NFADDR = (i >> 9) & 0xff;
-			NFADDR = (i >> 17) & 0xff;
-			NFADDR = (i >> 25) & 0xff;
-			wait_idle();
-			data = (NFDATA & 0xff);
-			if (data != 0xff) {
+		if (i % NAND_PAGE_SIZE == 0) {
+			/* We must check the first and second page */
+			if (block_is_bad(i + 5) || 
+			    block_is_bad((i + NAND_SECTOR_SIZE + 5))) {
 				/* Bad block */
 				i += NAND_PAGE_SIZE;
 				size += NAND_PAGE_SIZE;
@@ -74,6 +89,7 @@
 #endif
 		/* READ0 */
 		NFCMD = 0;
+		wait_idle();
 
 		/* Write Address */
 		NFADDR = i & 0xff;
@@ -90,7 +106,7 @@
 	}
 
 	/* chip Disable */
-	NFCONF |= 0x800;	/* chip disable */
+	NFCONF |= 0x800;
 
 	return 0;
 }

Reply via email to