aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r--drivers/mtd/nand/nand_base.c52
1 files changed, 33 insertions, 19 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 20f79fec73b5..e922b829c4be 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -52,28 +52,33 @@
52#endif 52#endif
53 53
54/* Define default oob placement schemes for large and small page devices */ 54/* Define default oob placement schemes for large and small page devices */
55static struct nand_oobinfo nand_oob_8 = { 55static struct nand_ecclayout nand_oob_8 = {
56 .useecc = MTD_NANDECC_AUTOPLACE,
57 .eccbytes = 3, 56 .eccbytes = 3,
58 .eccpos = {0, 1, 2}, 57 .eccpos = {0, 1, 2},
59 .oobfree = {{3, 2}, {6, 2}} 58 .oobfree = {
59 {.offset = 3,
60 .length = 2},
61 {.offset = 6,
62 .length = 2}}
60}; 63};
61 64
62static struct nand_oobinfo nand_oob_16 = { 65static struct nand_ecclayout nand_oob_16 = {
63 .useecc = MTD_NANDECC_AUTOPLACE,
64 .eccbytes = 6, 66 .eccbytes = 6,
65 .eccpos = {0, 1, 2, 3, 6, 7}, 67 .eccpos = {0, 1, 2, 3, 6, 7},
66 .oobfree = {{8, 8}} 68 .oobfree = {
69 {.offset = 8,
70 . length = 8}}
67}; 71};
68 72
69static struct nand_oobinfo nand_oob_64 = { 73static struct nand_ecclayout nand_oob_64 = {
70 .useecc = MTD_NANDECC_AUTOPLACE,
71 .eccbytes = 24, 74 .eccbytes = 24,
72 .eccpos = { 75 .eccpos = {
73 40, 41, 42, 43, 44, 45, 46, 47, 76 40, 41, 42, 43, 44, 45, 46, 47,
74 48, 49, 50, 51, 52, 53, 54, 55, 77 48, 49, 50, 51, 52, 53, 54, 55,
75 56, 57, 58, 59, 60, 61, 62, 63}, 78 56, 57, 58, 59, 60, 61, 62, 63},
76 .oobfree = {{2, 38}} 79 .oobfree = {
80 {.offset = 2,
81 .length = 38}}
77}; 82};
78 83
79/* This is used for padding purposes in nand_write_oob */ 84/* This is used for padding purposes in nand_write_oob */
@@ -749,7 +754,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
749 uint8_t *p = buf; 754 uint8_t *p = buf;
750 uint8_t *ecc_calc = chip->buffers.ecccalc; 755 uint8_t *ecc_calc = chip->buffers.ecccalc;
751 uint8_t *ecc_code = chip->buffers.ecccode; 756 uint8_t *ecc_code = chip->buffers.ecccode;
752 int *eccpos = chip->autooob->eccpos; 757 int *eccpos = chip->ecc.layout->eccpos;
753 758
754 chip->read_buf(mtd, buf, mtd->writesize); 759 chip->read_buf(mtd, buf, mtd->writesize);
755 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); 760 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -795,7 +800,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
795 uint8_t *p = buf; 800 uint8_t *p = buf;
796 uint8_t *ecc_calc = chip->buffers.ecccalc; 801 uint8_t *ecc_calc = chip->buffers.ecccalc;
797 uint8_t *ecc_code = chip->buffers.ecccode; 802 uint8_t *ecc_code = chip->buffers.ecccode;
798 int *eccpos = chip->autooob->eccpos; 803 int *eccpos = chip->ecc.layout->eccpos;
799 804
800 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 805 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
801 chip->ecc.hwctl(mtd, NAND_ECC_READ); 806 chip->ecc.hwctl(mtd, NAND_ECC_READ);
@@ -1198,7 +1203,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
1198 int eccsteps = chip->ecc.steps; 1203 int eccsteps = chip->ecc.steps;
1199 uint8_t *ecc_calc = chip->buffers.ecccalc; 1204 uint8_t *ecc_calc = chip->buffers.ecccalc;
1200 const uint8_t *p = buf; 1205 const uint8_t *p = buf;
1201 int *eccpos = chip->autooob->eccpos; 1206 int *eccpos = chip->ecc.layout->eccpos;
1202 1207
1203 if (chip->ecc.mode != NAND_ECC_NONE) { 1208 if (chip->ecc.mode != NAND_ECC_NONE) {
1204 /* Software ecc calculation */ 1209 /* Software ecc calculation */
@@ -1227,7 +1232,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
1227 int eccsteps = chip->ecc.steps; 1232 int eccsteps = chip->ecc.steps;
1228 uint8_t *ecc_calc = chip->buffers.ecccalc; 1233 uint8_t *ecc_calc = chip->buffers.ecccalc;
1229 const uint8_t *p = buf; 1234 const uint8_t *p = buf;
1230 int *eccpos = chip->autooob->eccpos; 1235 int *eccpos = chip->ecc.layout->eccpos;
1231 1236
1232 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 1237 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1233 chip->ecc.hwctl(mtd, NAND_ECC_WRITE); 1238 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
@@ -2124,16 +2129,16 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2124 /* 2129 /*
2125 * If no default placement scheme is given, select an appropriate one 2130 * If no default placement scheme is given, select an appropriate one
2126 */ 2131 */
2127 if (!chip->autooob) { 2132 if (!chip->ecc.layout) {
2128 switch (mtd->oobsize) { 2133 switch (mtd->oobsize) {
2129 case 8: 2134 case 8:
2130 chip->autooob = &nand_oob_8; 2135 chip->ecc.layout = &nand_oob_8;
2131 break; 2136 break;
2132 case 16: 2137 case 16:
2133 chip->autooob = &nand_oob_16; 2138 chip->ecc.layout = &nand_oob_16;
2134 break; 2139 break;
2135 case 64: 2140 case 64:
2136 chip->autooob = &nand_oob_64; 2141 chip->ecc.layout = &nand_oob_64;
2137 break; 2142 break;
2138 default: 2143 default:
2139 printk(KERN_WARNING "No oob scheme defined for " 2144 printk(KERN_WARNING "No oob scheme defined for "
@@ -2198,6 +2203,15 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2198 } 2203 }
2199 2204
2200 /* 2205 /*
2206 * The number of bytes available for a client to place data into
2207 * the out of band area
2208 */
2209 chip->ecc.layout->oobavail = 0;
2210 for (i = 0; chip->ecc.layout->oobfree[i].length; i++)
2211 chip->ecc.layout->oobavail +=
2212 chip->ecc.layout->oobfree[i].length;
2213
2214 /*
2201 * Set the number of read / write steps for one page depending on ECC 2215 * Set the number of read / write steps for one page depending on ECC
2202 * mode 2216 * mode
2203 */ 2217 */
@@ -2236,8 +2250,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2236 mtd->block_isbad = nand_block_isbad; 2250 mtd->block_isbad = nand_block_isbad;
2237 mtd->block_markbad = nand_block_markbad; 2251 mtd->block_markbad = nand_block_markbad;
2238 2252
2239 /* and make the autooob the default one */ 2253 /* propagate ecc.layout to mtd_info */
2240 mtd->oobinfo = chip->autooob; 2254 mtd->ecclayout = chip->ecc.layout;
2241 2255
2242 /* Check, if we should skip the bad block table scan */ 2256 /* Check, if we should skip the bad block table scan */
2243 if (chip->options & NAND_SKIP_BBTSCAN) 2257 if (chip->options & NAND_SKIP_BBTSCAN)