Re: [Yaffs] Problem with Yaffs on Routerboard RB112 and kern…

Top Page
Attachments:
Message as email
+ (text/plain)
+ 550-rb_oob_layout.patch (text/plain)
Delete this message
Reply to this message
Author: Andrea Conti
Date:  
To: yaffs
Subject: Re: [Yaffs] Problem with Yaffs on Routerboard RB112 and kernel 2.6.19

It looks like we're getting there :)

This patch (against the stock openwrt-svn) combines the ideas from David
and Claudio (with some fixes in the byte ordering) into something that
can write a bootable kernel image to the flash.

However, the resulting kernel cannot read the pre-2.6.17 yaffs format
because of the different blockStatus encoding.

While I can get two-way compatibility by also including the block status
byte in an oob_free range and handling it at the yaffs level, I don't
know if it doing that is a good idea.

What do you think?

Andrea
diff -Nur linux-2.6.19.2-base/drivers/mtd/nand/rbmipsnand.c linux-2.6.19.2/drivers/mtd/nand/rbmipsnand.c
--- linux-2.6.19.2-base/drivers/mtd/nand/rbmipsnand.c    2007-05-14 22:02:21.000000000 +0200
+++ linux-2.6.19.2/drivers/mtd/nand/rbmipsnand.c    2007-05-15 00:04:46.000000000 +0200
@@ -67,6 +67,12 @@
 static struct mtd_info rmtd;
 static struct nand_chip rnand;


+static struct nand_ecclayout rb_ecclayout = {
+        .eccbytes = 6,
+        .eccpos = { 8, 9, 10, 13, 14, 15 },
+        .oobfree = { { 0, 5 } , { 6, 2 }, { 11, 2 } }
+};
+
 static unsigned init_ok = 0;


 unsigned get_rbnand_block_size(void) {
@@ -93,6 +99,7 @@
         return -ENXIO;
     }
     rnand.ecc.mode = NAND_ECC_SOFT;
+    rnand.ecc.layout = &rb_ecclayout;
     rnand.chip_delay = 25;
     rnand.options |= NAND_NO_AUTOINCR;
     rmtd.priv = &rnand;
diff -Nur linux-2.6.19.2-base/fs/yaffs2/yaffs_mtdif.c linux-2.6.19.2/fs/yaffs2/yaffs_mtdif.c
--- linux-2.6.19.2-base/fs/yaffs2/yaffs_mtdif.c    2007-05-14 21:51:13.000000000 +0200
+++ linux-2.6.19.2/fs/yaffs2/yaffs_mtdif.c    2007-05-15 01:49:20.000000000 +0200
@@ -45,12 +45,12 @@
     oob[1] = spare->tagByte1;
     oob[2] = spare->tagByte2;
     oob[3] = spare->tagByte3;
-    oob[4] = spare->tagByte4;
-    oob[5] = spare->tagByte5 & 0x3f;
-    oob[5] |= spare->blockStatus == 'Y' ? 0: 0x80;
-    oob[5] |= spare->pageStatus == 0 ? 0: 0x40;
-    oob[6] = spare->tagByte6;
-    oob[7] = spare->tagByte7;
+    oob[4] = spare->pageStatus;
+    oob[5] = spare->tagByte4;
+    oob[6] = spare->tagByte5 & 0x3f;
+    oob[6] |= spare->blockStatus == 'Y' ? 0: 0x80;
+    oob[7] = spare->tagByte6;
+    oob[8] = spare->tagByte7;
 }


 static inline void translate_oob2spare(yaffs_Spare *spare, __u8 *oob)
@@ -60,13 +60,13 @@
     spare->tagByte1 = oob[1];
     spare->tagByte2 = oob[2];
     spare->tagByte3 = oob[3];
-    spare->tagByte4 = oob[4];
-    spare->tagByte5 = oob[5] == 0xff ? 0xff : oob[5] & 0x3f;
-    spare->blockStatus = oob[5] & 0x80 ? 0xff : 'Y';
-    spare->pageStatus = oob[5] & 0x40 ? 0xff : 0;
+    spare->pageStatus = oob[4];
+    spare->tagByte4 = oob[5];
+    spare->tagByte5 = oob[6] == 0xff ? 0xff : oob[6] & 0x3f;
+    spare->blockStatus = oob[6] & 0x80 ? 0xff : 'Y';
     spare->ecc1[0] = spare->ecc1[1] = spare->ecc1[2] = 0xff;
-    spare->tagByte6 = oob[6];
-    spare->tagByte7 = oob[7];
+    spare->tagByte6 = oob[7];
+    spare->tagByte7 = oob[8];
     spare->ecc2[0] = spare->ecc2[1] = spare->ecc2[2] = 0xff;


     nspare->eccres1 = nspare->eccres2 = 0; /* FIXME */
@@ -85,7 +85,7 @@


     loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-    __u8 spareAsBytes[8]; /* OOB */
+    __u8 spareAsBytes[9]; /* OOB */


     if (data && !spare)
         retval = mtd->write(mtd, addr, dev->nDataBytesPerChunk,
@@ -94,7 +94,7 @@
         if (dev->useNANDECC) {
             translate_spare2oob(spare, spareAsBytes);
             ops.mode = MTD_OOB_AUTO;
-            ops.ooblen = 8; /* temp hack */
+            ops.ooblen = 9; /* temp hack */
         } else {
             ops.mode = MTD_OOB_RAW;
             ops.ooblen = YAFFS_BYTES_PER_SPARE;
@@ -149,7 +149,7 @@


     loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-    __u8 spareAsBytes[8]; /* OOB */
+    __u8 spareAsBytes[9]; /* OOB */


     if (data && !spare)
         retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
@@ -157,7 +157,7 @@
     else if (spare) {
         if (dev->useNANDECC) {
             ops.mode = MTD_OOB_AUTO;
-            ops.ooblen = 8; /* temp hack */
+            ops.ooblen = 9; /* temp hack */
         } else {
             ops.mode = MTD_OOB_RAW;
             ops.ooblen = YAFFS_BYTES_PER_SPARE;