Index: linux-2.6.10/drivers/mtd/nand/nand_base.c =================================================================== --- linux-2.6.10.orig/drivers/mtd/nand/nand_base.c +++ linux-2.6.10/drivers/mtd/nand/nand_base.c @@ -904,11 +904,17 @@ static int nand_write_page (struct mtd_i } break; } - + /* Write out OOB data */ - if (this->options & NAND_HWECC_SYNDROME) - this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); - else + if (this->options & NAND_HWECC_SYNDROME) + if (mtd->ecctype != MTD_ECC_RS_DiskOnChip ) + for (i = 0; oobsel->oobfree[i][1]; i++ ) + this->write_buf (mtd, + oob_buf+oobsel->oobfree[i][0], + oobsel->oobfree[i][1] ); + else /* DiskOnChip legacy ECC */ + this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); + else this->write_buf(mtd, oob_buf, mtd->oobsize); /* Send command to actually program the data */ @@ -1247,8 +1253,15 @@ int nand_do_read_ecc (struct mtd_info *m break; } + /* read oobdata */ - this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen); + if (mtd->ecctype != MTD_ECC_RS_DiskOnChip ) + for (i = 0; oobsel->oobfree[i][1]; i++ ) + this->read_buf (mtd, + oob_data+oobsel->oobfree[i][0], + oobsel->oobfree[i][1] ); + else /* legacy DiskOnChip ECC */ + this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen); /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ if (!compareecc) @@ -2542,6 +2555,7 @@ int nand_scan (struct mtd_info *mtd, int this->eccsize = 2048; break; + case NAND_ECC_HW10_512: case NAND_ECC_HW3_512: case NAND_ECC_HW6_512: case NAND_ECC_HW8_512: @@ -2578,7 +2592,9 @@ int nand_scan (struct mtd_info *mtd, int switch (this->eccmode) { case NAND_ECC_HW12_2048: this->eccbytes += 4; - case NAND_ECC_HW8_512: + case NAND_ECC_HW10_512: + this->eccbytes += 2; + case NAND_ECC_HW8_512: this->eccbytes += 2; case NAND_ECC_HW6_512: this->eccbytes += 3; @@ -2600,6 +2616,7 @@ int nand_scan (struct mtd_info *mtd, int case NAND_ECC_HW3_512: case NAND_ECC_HW6_512: case NAND_ECC_HW8_512: + case NAND_ECC_HW10_512: this->eccsteps = mtd->oobblock / 512; break; case NAND_ECC_HW3_256: Index: linux-2.6.10/include/mtd/mtd-abi.h =================================================================== --- linux-2.6.10.orig/include/mtd/mtd-abi.h +++ linux-2.6.10/include/mtd/mtd-abi.h @@ -115,7 +115,7 @@ struct nand_oobinfo { uint32_t useecc; uint32_t eccbytes; uint32_t oobfree[8][2]; - uint32_t eccpos[32]; + uint32_t eccpos[40]; }; #endif /* __MTD_ABI_H__ */ Index: linux-2.6.10/include/linux/mtd/nand.h =================================================================== --- linux-2.6.10.orig/include/linux/mtd/nand.h +++ linux-2.6.10/include/linux/mtd/nand.h @@ -161,8 +161,10 @@ extern int nand_read_raw (struct mtd_inf #define NAND_ECC_HW6_512 4 /* Hardware ECC 8 byte ECC per 512 Byte data */ #define NAND_ECC_HW8_512 6 +/* SanDisk MLC: 10 bytes ECC per 512 Byte data */ +#define NAND_ECC_HW10_512 7 /* Hardware ECC 12 byte ECC per 2048 Byte data */ -#define NAND_ECC_HW12_2048 7 +#define NAND_ECC_HW12_2048 8 /* * Constants for Hardware ECC