r3859 - branches/src/target/kernel/2.6.24.x/patches

werner at sita.openmoko.org werner at sita.openmoko.org
Thu Jan 17 05:34:08 CET 2008


Author: werner
Date: 2008-01-17 05:34:04 +0100 (Thu, 17 Jan 2008)
New Revision: 3859

Added:
   branches/src/target/kernel/2.6.24.x/patches/fix-hwecc-2410.patch
Modified:
   branches/src/target/kernel/2.6.24.x/patches/series
Log:
NAND ECC error correction mis-calculated the bit position, thus turning a
correctable single-bit error into two errors. Fittingly, also reported
uncorrectable errors as success.

The NAND subsystem only does 512 byte reads even on large page NAND, so we can
use hardware ECC also on HXD8 and GTA02. Tests showed that this does indeed
work as expected.

series:
- added fix-hwecc-2410.patch
- commented out s3c2440-nand-disable-hwecc.patch, since this works, even
  without explicit large page support

fix-hwecc-2410.patch:
- drivers/mtd/nand/s3c2410.c (s3c2410_nand_correct_data): use Pn bits to
  calculate error position, not Pn'
- drivers/mtd/nand/s3c2410.c (s3c2410_nand_correct_data): don't report
  uncorrectable errors as "no error"



Added: branches/src/target/kernel/2.6.24.x/patches/fix-hwecc-2410.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/fix-hwecc-2410.patch	2008-01-16 16:14:28 UTC (rev 3858)
+++ branches/src/target/kernel/2.6.24.x/patches/fix-hwecc-2410.patch	2008-01-17 04:34:04 UTC (rev 3859)
@@ -0,0 +1,56 @@
+S3C24xx ECC mis-calculates the bit to flip:
+http://lists.infradead.org/pipermail/linux-mtd/2007-October/019586.html
+If the error couldn't be corrected, we returned "no problem" :-(
+http://lists.infradead.org/pipermail/linux-mtd/2007-October/019615.html
+
+Signed-off-by: Werner Almesberger <werner at openmoko.org>
+
+Index: linux-2.6.24-rc7/drivers/mtd/nand/s3c2410.c
+===================================================================
+--- linux-2.6.24-rc7.orig/drivers/mtd/nand/s3c2410.c
++++ linux-2.6.24-rc7/drivers/mtd/nand/s3c2410.c
+@@ -364,23 +364,21 @@
+ 	    ((diff2 ^ (diff2 >> 1)) & 0x55) == 0x55) {
+ 		/* calculate the bit position of the error */
+ 
+-		bit  = (diff2 >> 2) & 1;
+-		bit |= (diff2 >> 3) & 2;
+-		bit |= (diff2 >> 4) & 4;
++		bit  = ((diff2 >> 3) & 1) |
++		       ((diff2 >> 4) & 2) |
++		       ((diff2 >> 5) & 4);
+ 
+ 		/* calculate the byte position of the error */
+ 
+-		byte  = (diff1 << 1) & 0x80;
+-		byte |= (diff1 << 2) & 0x40;
+-		byte |= (diff1 << 3) & 0x20;
+-		byte |= (diff1 << 4) & 0x10;
+-
+-		byte |= (diff0 >> 3) & 0x08;
+-		byte |= (diff0 >> 2) & 0x04;
+-		byte |= (diff0 >> 1) & 0x02;
+-		byte |= (diff0 >> 0) & 0x01;
+-
+-		byte |= (diff2 << 8) & 0x100;
++		byte = ((diff2 << 7) & 0x100) |
++		       ((diff1 << 0) & 0x80)  |
++		       ((diff1 << 1) & 0x40)  |
++		       ((diff1 << 2) & 0x20)  |
++		       ((diff1 << 3) & 0x10)  |
++		       ((diff0 >> 4) & 0x08)  |
++		       ((diff0 >> 3) & 0x04)  |
++		       ((diff0 >> 2) & 0x02)  |
++		       ((diff0 >> 1) & 0x01);
+ 
+ 		dev_dbg(info->device, "correcting error bit %d, byte %d\n",
+ 			bit, byte);
+@@ -399,7 +397,7 @@
+ 	if ((diff0 & ~(1<<fls(diff0))) == 0)
+ 		return 1;
+ 
+-	return 0;
++	return -EBADMSG;
+ }
+ 
+ /* ECC functions

Modified: branches/src/target/kernel/2.6.24.x/patches/series
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/series	2008-01-16 16:14:28 UTC (rev 3858)
+++ branches/src/target/kernel/2.6.24.x/patches/series	2008-01-17 04:34:04 UTC (rev 3859)
@@ -58,7 +58,7 @@
 pm-debug_less_verbose.patch
 s3c2410_serial-nodebug.patch
 input-nots-mousedev.patch
-s3c2440-nand-disable-hwecc.patch
+#s3c2440-nand-disable-hwecc.patch
 
 # qt2410 local hacks
 qt2410-cs8900.patch
@@ -73,5 +73,8 @@
 atheros_2_0_hcd-patch
 atheros_2_0_sdio_stack.patch
 
+# bad bug
+fix-hwecc-2410.patch
+
 # Preliminary suspend/resume power saving improvements
 suspend-prelim1.patch





More information about the commitlog mailing list