diff options
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 52 |
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 */ |
55 | static struct nand_oobinfo nand_oob_8 = { | 55 | static 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 | ||
62 | static struct nand_oobinfo nand_oob_16 = { | 65 | static 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 | ||
69 | static struct nand_oobinfo nand_oob_64 = { | 73 | static 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) |