Skip to contentSkip to conversation

JFFS2 on NAND, Magic bitmask 0x1985 not found

DISCUSSION Pathompong Puengrostham 2 participants 5 messages Jul 14, 2004

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hi all,

Could anybody help me on this please? I mounted a cleanly erased NAND flash , unmounted without writing anything into it and then mounted it again. I got the following errors.

nand_read_ecc: Failed ECC read, page 0x000000e0
mtd->read(0x400 bytes from 0x1c000) returned ECC error
jffs2_scan_eraseblock(): Node at 0x0001c008 {0x1985, 0x2003, 0x00000008) has invalid CRC 0xffff0000 (calculated 0x6b7c27e6) jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0001c00c: 0x0008 instead
nand_read_ecc: Failed ECC read, page 0x00000120
mtd->read(0x400 bytes from 0x24000) returned ECC error
jffs2_scan_eraseblock(): Node at 0x00024008 {0x1985, 0x2003, 0x00000008) has invalid CRC 0xffff0000 (calculated 0x6b7c27e6) jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0002400c: 0x0008 instead
...

This is the data that I dump out of the flash using "nanddump /dev/mtd3 dump.txt 114688 1024"

0x0001c000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0001c010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
...
0x0001c1f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
OOB Data: ff ff ff ff ff ff ff ff 85 19 03 20 08 00 00 00
0x0001c200: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0001c210: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
...
0x0001c3f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
OOB Data: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

I can see that the magic bitmask 0x1985 is there. Why did JFFS2 look at the wrong place and got 0x0008 instead?

I'm using mtd snapshot 20040707.

Thank you in advance.

Regards,
Jay

#1 lore raw

Hi,

I just found the problem. It is that my NAND flash CE pin is not driven by GPIO. It is driven by CS from the CPU. Here is the change that I made.

drivers/mtd/nand/nand_base.c +15 -1
@@ -990,8 +990,15 @@
 	 * by an GPIO pin ?
 	 */
 out:	
+#ifdef CONFIG_MTD_NAND_CE_NOT_GPIO
+	if (!this->dev_ready)
+		udelay (this->chip_delay);
+	else
+		while (!this->dev_ready(mtd));
+#else
 	this->select_chip(mtd, -1);
 	this->select_chip(mtd, chipnr);
+#endif
 	return res;
 }
 #endif
@@ -1248,8 +1255,15 @@
 		} else		
 			read += mtd->oobblock;
 
-		if (read == len)
+		if (read == len) {
+#ifdef CONFIG_MTD_NAND_CE_NOT_GPIO
+			if (!this->dev_ready)
+				udelay (this->chip_delay);
+			else
+				while (!this->dev_ready(mtd));
+#endif
 			break;	
+		}
 
 		/* For subsequent reads align to page boundary. */
 		col = 0;
@@ -1374,6 +1388,14 @@
 			        this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & 

this->pagemask);
}
}
+#ifdef CONFIG_MTD_NAND_CE_NOT_GPIO
+ else {
+ if (!this->dev_ready)
+ udelay (this->chip_delay);
+ else
+ while (!this->dev_ready(mtd));
+ }
+#endif
}

/* Deselect and wake up anyone waiting on the device */

I also had to add the following to my nand_init().

for (i = 0; nand_flash_ids[i].name != NULL; i++)

	nand_flash_ids[i].options |= NAND_NO_AUTOINCR;

Regards,
Jay

Quoted 41 lines · Pathompong Puengrostham

Hi all,

Could anybody help me on this please? I mounted a cleanly erased NAND flash , unmounted without writing anything into it and then mounted it again. I got the following errors.

nand_read_ecc: Failed ECC read, page 0x000000e0
mtd->read(0x400 bytes from 0x1c000) returned ECC error
jffs2_scan_eraseblock(): Node at 0x0001c008 {0x1985, 0x2003, 0x00000008) has invalid CRC 0xffff0000 (calculated 0x6b7c27e6) jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0001c00c: 0x0008 instead
nand_read_ecc: Failed ECC read, page 0x00000120
mtd->read(0x400 bytes from 0x24000) returned ECC error
jffs2_scan_eraseblock(): Node at 0x00024008 {0x1985, 0x2003, 0x00000008) has invalid CRC 0xffff0000 (calculated 0x6b7c27e6) jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0002400c: 0x0008 instead
...

This is the data that I dump out of the flash using "nanddump /dev/mtd3 dump.txt 114688 1024"

0x0001c000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0001c010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
...
0x0001c1f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
OOB Data: ff ff ff ff ff ff ff ff 85 19 03 20 08 00 00 00
0x0001c200: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0x0001c210: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
...
0x0001c3f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
OOB Data: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

I can see that the magic bitmask 0x1985 is there. Why did JFFS2 look at the wrong place and got 0x0008 instead?

I'm using mtd snapshot 20040707.

Thank you in advance.

Regards,
Jay

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

#2 lore raw
Quoted 4 lines · Pathompong Puengrostham

Hi,

I just found the problem. It is that my NAND flash CE pin is not driven by GPIO. It is driven by CS from the CPU. Here is the change that I made.

Ok, I accept the change in nand_verify_pages. I expected this to break, as it was stated in the comment. But for sure we will not invent a new CONFIG_ switch, we have an options field for such stuff already, also using a wait for ready there in any case will be enough.

Quoted 4 lines

I also had to add the following to my nand_init().

for (i = 0; nand_flash_ids[i].name != NULL; i++)

	nand_flash_ids[i].options |= NAND_NO_AUTOINCR;

Sorry, thats crap. The options are defined in nand_ids.c and are not a subject to be modified anywhere else. If you want to have the NO_AUTOINCR option set for your board, then set it in the options field before calling nand_scan. The bit is not overwritten by the option init in nand_scan.

Which chiptype are you using exactly?

The changes you made make not really sense as you put in delays which are neccecary for chips, which do autoincrement. Those chips which can not autoincrement do neither need a wait nor a deselect/select after a page is read.

tglx

#3 lore raw
Quoted 19 lines · Thomas Gleixner
Quoted 3 lines · Pathompong Puengrostham

Hi,

I just found the problem. It is that my NAND flash CE pin is not driven by GPIO. It is driven by CS from the CPU. Here is the change that I made.

Ok, I accept the change in nand_verify_pages. I expected this to break, as it was stated in the comment. But for sure we will not invent a new CONFIG_ switch, we have an options field for such stuff already, also using a wait for ready there in any case will be enough.

Quoted 4 lines

I also had to add the following to my nand_init().

for (i = 0; nand_flash_ids[i].name != NULL; i++)

	nand_flash_ids[i].options |= NAND_NO_AUTOINCR;
Quoted 6 lines

Sorry, thats crap. The options are defined in nand_ids.c and are not a subject to be modified anywhere else. If you want to have the NO_AUTOINCR option set for your board, then set it in the options field before calling nand_scan. The bit is not overwritten by the option init in nand_scan.

Thank you for pointing that out. I just read the nand_scan code. I didn't know I can do that. I copied the code from spia.c and changed only the low-level stuff.

Quoted 2 lines

Which chiptype are you using exactly?

I'm using Samsung K9F5608U0C.

Quoted 7 lines

The changes you made make not really sense as you put in delays which are neccecary for chips, which do autoincrement. Those chips which can not autoincrement do neither need a wait nor a deselect/select after a page is read.

tglx

The chip I'm using do autoincrement but I thought that after CE goes high I have to send the read command again which is not correct. Now I don't set NAND_NO_AUTOINCR and it works good. But I still need the delays.

Jay

#4 lore raw
Quoted 4 lines · Pathompong Puengrostham

The chip I'm using do autoincrement but I thought that after CE goes high I have to send the read command again which is not correct. Now I don't set NAND_NO_AUTOINCR and it works good. But I still need the delays.

Can you try this one ? It's against current CVS code.

tglx

? nand.diff
? nand_base.diff
Index: nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v retrieving revision 1.112

nand_base.c +30 -28
diff -u -r1.112 nand_base.c
@@ -964,34 +964,34 @@
 		oobofs += mtd->oobsize - hweccbytes * eccsteps;
 		page++;
 		numpages--;
-		if (!numpages)
-			break;
-		
+
 		/* Apply delay or wait for ready/busy pin 
 		 * Do this before the AUTOINCR check, so no problems
 		 * arise if a chip which does auto increment
 		 * is marked as NOAUTOINCR by the board driver.
+		 * Do this also before returning, so the chip is
+		 * ready for the next command.
 		*/
 		if (!this->dev_ready) 
 			udelay (this->chip_delay);
 		else
 			while (!this->dev_ready(mtd));	
+
+		/* All done, return happy */
+		if (!numpages)
+			return 0;
+		
 			
 		/* Check, if the chip supports auto page increment */ 
 		if (!NAND_CANAUTOINCR(this))
 			this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
 	}
-	res = 0;
 	/* 
-	 * Terminate the read command. This is faster than sending a reset command or 
-	 * applying a 20us delay before issuing the next programm sequence.
-	 * This is not a problem for all chips, but I have found a bunch of them.
-	 * FIXME, CHECKME: Does this work on systems, where CE is not driven
-	 * by an GPIO pin ?
+	 * Terminate the read command. We come here in case of an error
+	 * So we must issue a reset command.
 	 */
 out:	 
-	this->select_chip(mtd, -1);
-	this->select_chip(mtd, chipnr);
+	this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
 	return res;
 }
 #endif
@@ -1248,14 +1248,6 @@
 		} else		
 			read += mtd->oobblock;
 
-		if (read == len)
-			break;	
-
-		/* For subsequent reads align to page boundary. */
-		col = 0;
-		/* Increment page address */
-		realpage++;
-
 		/* Apply delay or wait for ready/busy pin 
 		 * Do this before the AUTOINCR check, so no problems
 		 * arise if a chip which does auto increment
@@ -1266,6 +1258,14 @@
 		else
 			while (!this->dev_ready(mtd));	
 			
+		if (read == len)
+			break;	
+
+		/* For subsequent reads align to page boundary. */
+		col = 0;
+		/* Increment page address */
+		realpage++;
+
 		page = realpage & this->pagemask;
 		/* Check, if we cross a chip boundary */
 		if (!page) {
@@ -1345,19 +1345,21 @@
 		thislen = min_t(int, thislen, len);
 		this->read_buf(mtd, &buf[i], thislen);
 		i += thislen;
+		
+		/* Apply delay or wait for ready/busy pin 
+		 * Do this before the AUTOINCR check, so no problems
+		 * arise if a chip which does auto increment
+		 * is marked as NOAUTOINCR by the board driver.
+		*/
+		if (!this->dev_ready) 
+			udelay (this->chip_delay);
+		else
+			while (!this->dev_ready(mtd));	
+
 		/* Read more ? */
 		if (i < len) {
 			page++;
 			col = 0;
-			/* Apply delay or wait for ready/busy pin 
-			 * Do this before the AUTOINCR check, so no problems
-			 * arise if a chip which does auto increment
-			 * is marked as NOAUTOINCR by the board driver.
-			*/
-			if (!this->dev_ready) 
-				udelay (this->chip_delay);
-			else
-				while (!this->dev_ready(mtd));	
 
 			/* Check, if we cross a chip boundary */
 			if (!(page & this->pagemask)) {