Problem with clean markers/partial writes on Micron 4-bit ECC NAND

Peter Barada peter.barada at gmail.com
Fri Jun 17 13:52:24 EDT 2011


I'm using a 2K page Micron NAND that has an internal 4-bit ECC engine.

The Micron NAND chip uses 8-bytes per 512 bytes of main data area + 4 
bytes of the OOB.  This allows the 32 bytes of ECC to correct 2048 bytes 
of the main data area and 16 bytes of the OOB area.

The problem I'm running into with JFFS2 is that empty flash is first 
marked with a clean marker into the OOB, and then a 2nd write to the 
main data area is done (w/o an intervening erase) to that page with data 
which corrupts the ECCs that were first modified by writing the cleanmarker.

The OOB layout I'm using (which allows ECC'ng 16 bytes of the OOB) is:

ecclayout = {
         eccbytes = 32,
         eccpos = { 8, 9, 10, 11, 12, 13, 14, 15,
                 24, 25, 26, 27, 28, 19, 30, 31,
                 40, 41, 42, 43, 44, 45, 46, 47,
                 56, 57, 58, 59, 60, 61, 62, 63},
         .oobfree = {
                 { .offset = 4,
                   .length = 4},
                 { .offset = 20,
                   .length = 4},
                 { .offset = 36,
                   .length = 4},
                 { .offset = 52,
                   .length = 4},
         },
};

After the cleanmarker is written into bytes 4-7 and 16-23 of the OOB, 
nanddump shows:

   OOB Data: ff ff ff ff 85 19 03 20 5a e3 da 69 01 40 f1 36
   OOB Data: ff ff ff ff 08 00 00 00 91 99 3c 05 01 d0 5d b3
   OOB Data: 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

Note the ECCs in bytes 8-15 and 25-31 are no longer 0xFF since the ECC 
at bytes 8-15 covers data area bytes 0-511 as well as OOB bytes 4-7 and 
the ECC at bytes 16-23 covers data area bytes 512-1023 as well as OOB 
bytes 16-23.

I believe I've figured out a workaround:

1) Modify the ecclayout to add the other 8 bytes of the OOB that are NOT 
ECCd *after* the 16 bytes that are ECCd (so the ecc layout looks like):

  ecclayout = {
         eccbytes = 32,
         eccpos = { 8, 9, 10, 11, 12, 13, 14, 15,
                 24, 25, 26, 27, 28, 19, 30, 31,
                 40, 41, 42, 43, 44, 45, 46, 47,
                 56, 57, 58, 59, 60, 61, 62, 63},
         .oobfree = {
                 { .offset = 4,
                   .length = 4},
                 { .offset = 20,
                   .length = 4},
                 { .offset = 36,
                   .length = 4},
                 { .offset = 52,
                   .length = 4},
                 { .offset = 2,
                   .length = 2},
                 { .offset = 18,
                   .length = 2},
                 { .offset = 24,
                   .length = 2},
                 { .offset = 42,
                   .length = 2},
         },
};

2) Then set ops.ooboffs to 16 in jffs2_write_nand_cleanmarker and 
jffs2_check_nand_cleanmarker.

This "offsets" the read/writes by 16 bytes to move the cleanmarker into 
OOB bytes that do not perturb the ECCs, and so far it looks to work.

However I feel this is a hack as our product will use two different NAND 
chips, the other being a more traditional SLC that can use 1-bit hamming 
for ECC (which does not ECC any bytes in the OOB).

How can I best code this into the MTD layer such that JFFS2 (and other 
NAND FSs that does partial writes including OOB bytes) can understand 
that some OOB bytes perturb the data area ECC?

I think adding a "non_ecc_oob_offset" variable to the ecclayout could 
capture this nuance of the OOB/ECC interaction for this chip and JFFS2 
could set ops.ooboffs to non_ecc_oob_offset in 
jffs2_write_nand_cleanmarker and jffs2_check_nand_cleanmarker.

Any comments are appreciated!

-- 
Peter Barada
peter.barada at gmail.com




More information about the linux-mtd mailing list