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;
}