diff options
-rw-r--r-- | drivers/mtd/mtdchar.c | 26 | ||||
-rw-r--r-- | drivers/mtd/mtdconcat.c | 2 | ||||
-rw-r--r-- | drivers/mtd/mtdpart.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/diskonchip.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 52 | ||||
-rw-r--r-- | drivers/mtd/nand/ndfc.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/rtc_from4.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/s3c2410.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/sharpsl.c | 5 | ||||
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 14 | ||||
-rw-r--r-- | fs/jffs2/jffs2_fs_sb.h | 2 | ||||
-rw-r--r-- | fs/jffs2/wbuf.c | 51 | ||||
-rw-r--r-- | include/linux/mtd/inftl.h | 2 | ||||
-rw-r--r-- | include/linux/mtd/mtd.h | 4 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 9 | ||||
-rw-r--r-- | include/linux/mtd/nftl.h | 2 | ||||
-rw-r--r-- | include/linux/mtd/onenand.h | 6 | ||||
-rw-r--r-- | include/linux/mtd/partitions.h | 2 | ||||
-rw-r--r-- | include/mtd/mtd-abi.h | 36 | ||||
-rw-r--r-- | include/mtd/mtd-user.h | 1 |
20 files changed, 134 insertions, 99 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 608f7af679cb..e75ec5fe7760 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -512,14 +512,36 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
512 | break; | 512 | break; |
513 | } | 513 | } |
514 | 514 | ||
515 | /* Legacy interface */ | ||
515 | case MEMGETOOBSEL: | 516 | case MEMGETOOBSEL: |
516 | { | 517 | { |
517 | if (copy_to_user(argp, mtd->oobinfo, | 518 | struct nand_oobinfo oi; |
518 | sizeof(struct nand_oobinfo))) | 519 | |
520 | if (!mtd->ecclayout) | ||
521 | return -EOPNOTSUPP; | ||
522 | if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos)) | ||
523 | return -EINVAL; | ||
524 | |||
525 | oi.useecc = MTD_NANDECC_AUTOPLACE; | ||
526 | memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos)); | ||
527 | memcpy(&oi.oobfree, mtd->ecclayout->oobfree, | ||
528 | sizeof(oi.oobfree)); | ||
529 | |||
530 | if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo))) | ||
519 | return -EFAULT; | 531 | return -EFAULT; |
520 | break; | 532 | break; |
521 | } | 533 | } |
522 | 534 | ||
535 | case ECCGETLAYOUT: | ||
536 | |||
537 | if (!mtd->ecclayout) | ||
538 | return -EOPNOTSUPP; | ||
539 | |||
540 | if (copy_to_user(argp, &mtd->ecclayout, | ||
541 | sizeof(struct nand_ecclayout))) | ||
542 | return -EFAULT; | ||
543 | break; | ||
544 | |||
523 | case MEMGETBADBLOCK: | 545 | case MEMGETBADBLOCK: |
524 | { | 546 | { |
525 | loff_t offs; | 547 | loff_t offs; |
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 699fce7770de..ec15abcdbdfa 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c | |||
@@ -766,7 +766,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c | |||
766 | 766 | ||
767 | } | 767 | } |
768 | 768 | ||
769 | concat->mtd.oobinfo = subdev[0]->oobinfo; | 769 | concat->mtd.ecclayout = subdev[0]->ecclayout; |
770 | 770 | ||
771 | concat->num_subdev = num_devs; | 771 | concat->num_subdev = num_devs; |
772 | concat->mtd.name = name; | 772 | concat->mtd.name = name; |
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index b6b218952d49..6d7639b98eab 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -434,7 +434,7 @@ int add_mtd_partitions(struct mtd_info *master, | |||
434 | parts[i].name); | 434 | parts[i].name); |
435 | } | 435 | } |
436 | 436 | ||
437 | slave->mtd.oobinfo = master->oobinfo; | 437 | slave->mtd.ecclayout = master->ecclayout; |
438 | 438 | ||
439 | if(parts[i].mtdp) | 439 | if(parts[i].mtdp) |
440 | { /* store the object pointer (caller may or may not register it */ | 440 | { /* store the object pointer (caller may or may not register it */ |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 82262a4a4208..463e12ced1b3 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -1058,8 +1058,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, | |||
1058 | * safer. The only problem with it is that any code that parses oobfree must | 1058 | * safer. The only problem with it is that any code that parses oobfree must |
1059 | * be able to handle out-of-order segments. | 1059 | * be able to handle out-of-order segments. |
1060 | */ | 1060 | */ |
1061 | static struct nand_oobinfo doc200x_oobinfo = { | 1061 | static struct nand_ecclayout doc200x_oobinfo = { |
1062 | .useecc = MTD_NANDECC_AUTOPLACE, | ||
1063 | .eccbytes = 6, | 1062 | .eccbytes = 6, |
1064 | .eccpos = {0, 1, 2, 3, 4, 5}, | 1063 | .eccpos = {0, 1, 2, 3, 4, 5}, |
1065 | .oobfree = {{8, 8}, {6, 2}} | 1064 | .oobfree = {{8, 8}, {6, 2}} |
@@ -1662,7 +1661,7 @@ static int __init doc_probe(unsigned long physadr) | |||
1662 | nand->ecc.calculate = doc200x_calculate_ecc; | 1661 | nand->ecc.calculate = doc200x_calculate_ecc; |
1663 | nand->ecc.correct = doc200x_correct_data; | 1662 | nand->ecc.correct = doc200x_correct_data; |
1664 | 1663 | ||
1665 | nand->autooob = &doc200x_oobinfo; | 1664 | nand->ecc.layout = &doc200x_oobinfo; |
1666 | nand->ecc.mode = NAND_ECC_HW_SYNDROME; | 1665 | nand->ecc.mode = NAND_ECC_HW_SYNDROME; |
1667 | nand->ecc.size = 512; | 1666 | nand->ecc.size = 512; |
1668 | nand->ecc.bytes = 6; | 1667 | nand->ecc.bytes = 6; |
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) |
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 5790d630faed..551702ddcacb 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c | |||
@@ -168,7 +168,7 @@ static void ndfc_chip_init(struct ndfc_nand_mtd *mtd) | |||
168 | chip->ecc.mode = NAND_ECC_HW; | 168 | chip->ecc.mode = NAND_ECC_HW; |
169 | chip->ecc.size = 256; | 169 | chip->ecc.size = 256; |
170 | chip->ecc.bytes = 3; | 170 | chip->ecc.bytes = 3; |
171 | chip->autooob = mtd->pl_chip->oobinfo; | 171 | chip->ecclayout = mtd->pl_chip->ecclayout; |
172 | mtd->mtd.priv = chip; | 172 | mtd->mtd.priv = chip; |
173 | mtd->mtd.owner = THIS_MODULE; | 173 | mtd->mtd.owner = THIS_MODULE; |
174 | } | 174 | } |
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index de6de91fbad9..f8c49645324d 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c | |||
@@ -142,8 +142,7 @@ static struct rs_control *rs_decoder; | |||
142 | /* | 142 | /* |
143 | * hardware specific Out Of Band information | 143 | * hardware specific Out Of Band information |
144 | */ | 144 | */ |
145 | static struct nand_oobinfo rtc_from4_nand_oobinfo = { | 145 | static struct nand_ecclayout rtc_from4_nand_oobinfo = { |
146 | .useecc = MTD_NANDECC_AUTOPLACE, | ||
147 | .eccbytes = 32, | 146 | .eccbytes = 32, |
148 | .eccpos = { | 147 | .eccpos = { |
149 | 0, 1, 2, 3, 4, 5, 6, 7, | 148 | 0, 1, 2, 3, 4, 5, 6, 7, |
@@ -574,7 +573,7 @@ static int __init rtc_from4_init(void) | |||
574 | /* return the status of extra status and ECC checks */ | 573 | /* return the status of extra status and ECC checks */ |
575 | this->errstat = rtc_from4_errstat; | 574 | this->errstat = rtc_from4_errstat; |
576 | /* set the nand_oobinfo to support FPGA H/W error detection */ | 575 | /* set the nand_oobinfo to support FPGA H/W error detection */ |
577 | this->autooob = &rtc_from4_nand_oobinfo; | 576 | this->ecc.layout = &rtc_from4_nand_oobinfo; |
578 | this->ecc.hwctl = rtc_from4_enable_hwecc; | 577 | this->ecc.hwctl = rtc_from4_enable_hwecc; |
579 | this->ecc.calculate = rtc_from4_calculate_ecc; | 578 | this->ecc.calculate = rtc_from4_calculate_ecc; |
580 | this->ecc.correct = rtc_from4_correct_data; | 579 | this->ecc.correct = rtc_from4_correct_data; |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 215227d1a65c..8429793a6288 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -76,8 +76,7 @@ static int hardware_ecc = 0; | |||
76 | /* new oob placement block for use with hardware ecc generation | 76 | /* new oob placement block for use with hardware ecc generation |
77 | */ | 77 | */ |
78 | 78 | ||
79 | static struct nand_oobinfo nand_hw_eccoob = { | 79 | static struct nand_ecclayout nand_hw_eccoob = { |
80 | .useecc = MTD_NANDECC_AUTOPLACE, | ||
81 | .eccbytes = 3, | 80 | .eccbytes = 3, |
82 | .eccpos = {0, 1, 2}, | 81 | .eccpos = {0, 1, 2}, |
83 | .oobfree = {{8, 8}} | 82 | .oobfree = {{8, 8}} |
@@ -502,7 +501,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
502 | chip->ecc.mode = NAND_ECC_HW; | 501 | chip->ecc.mode = NAND_ECC_HW; |
503 | chip->ecc.size = 512; | 502 | chip->ecc.size = 512; |
504 | chip->ecc.bytes = 3; | 503 | chip->ecc.bytes = 3; |
505 | chip->autooob = &nand_hw_eccoob; | 504 | chip->ecc.layout = &nand_hw_eccoob; |
506 | 505 | ||
507 | if (info->is_s3c2440) { | 506 | if (info->is_s3c2440) { |
508 | chip->ecc.hwctl = s3c2440_nand_enable_hwecc; | 507 | chip->ecc.hwctl = s3c2440_nand_enable_hwecc; |
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 45a1da724bff..21743658d150 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
@@ -115,8 +115,7 @@ static struct nand_bbt_descr sharpsl_akita_bbt = { | |||
115 | .pattern = scan_ff_pattern | 115 | .pattern = scan_ff_pattern |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static struct nand_oobinfo akita_oobinfo = { | 118 | static struct nand_ecclayout akita_oobinfo = { |
119 | .useecc = MTD_NANDECC_AUTOPLACE, | ||
120 | .eccbytes = 24, | 119 | .eccbytes = 24, |
121 | .eccpos = { | 120 | .eccpos = { |
122 | 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11, | 121 | 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11, |
@@ -202,7 +201,7 @@ static int __init sharpsl_nand_init(void) | |||
202 | this->badblock_pattern = &sharpsl_bbt; | 201 | this->badblock_pattern = &sharpsl_bbt; |
203 | if (machine_is_akita() || machine_is_borzoi()) { | 202 | if (machine_is_akita() || machine_is_borzoi()) { |
204 | this->badblock_pattern = &sharpsl_akita_bbt; | 203 | this->badblock_pattern = &sharpsl_akita_bbt; |
205 | this->autooob = &akita_oobinfo; | 204 | this->ecc.layout = &akita_oobinfo; |
206 | } | 205 | } |
207 | this->ecc.hwctl = sharpsl_nand_enable_hwecc; | 206 | this->ecc.hwctl = sharpsl_nand_enable_hwecc; |
208 | this->ecc.calculate = sharpsl_nand_calculate_ecc; | 207 | this->ecc.calculate = sharpsl_nand_calculate_ecc; |
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index b24bfa6e202c..a0d3f011c0f2 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -23,8 +23,7 @@ | |||
23 | /** | 23 | /** |
24 | * onenand_oob_64 - oob info for large (2KB) page | 24 | * onenand_oob_64 - oob info for large (2KB) page |
25 | */ | 25 | */ |
26 | static struct nand_oobinfo onenand_oob_64 = { | 26 | static struct nand_ecclayout onenand_oob_64 = { |
27 | .useecc = MTD_NANDECC_AUTOPLACE, | ||
28 | .eccbytes = 20, | 27 | .eccbytes = 20, |
29 | .eccpos = { | 28 | .eccpos = { |
30 | 8, 9, 10, 11, 12, | 29 | 8, 9, 10, 11, 12, |
@@ -41,8 +40,7 @@ static struct nand_oobinfo onenand_oob_64 = { | |||
41 | /** | 40 | /** |
42 | * onenand_oob_32 - oob info for middle (1KB) page | 41 | * onenand_oob_32 - oob info for middle (1KB) page |
43 | */ | 42 | */ |
44 | static struct nand_oobinfo onenand_oob_32 = { | 43 | static struct nand_ecclayout onenand_oob_32 = { |
45 | .useecc = MTD_NANDECC_AUTOPLACE, | ||
46 | .eccbytes = 10, | 44 | .eccbytes = 10, |
47 | .eccpos = { | 45 | .eccpos = { |
48 | 8, 9, 10, 11, 12, | 46 | 8, 9, 10, 11, 12, |
@@ -1747,22 +1745,22 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
1747 | 1745 | ||
1748 | switch (mtd->oobsize) { | 1746 | switch (mtd->oobsize) { |
1749 | case 64: | 1747 | case 64: |
1750 | this->autooob = &onenand_oob_64; | 1748 | this->ecclayout = &onenand_oob_64; |
1751 | break; | 1749 | break; |
1752 | 1750 | ||
1753 | case 32: | 1751 | case 32: |
1754 | this->autooob = &onenand_oob_32; | 1752 | this->ecclayout = &onenand_oob_32; |
1755 | break; | 1753 | break; |
1756 | 1754 | ||
1757 | default: | 1755 | default: |
1758 | printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n", | 1756 | printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n", |
1759 | mtd->oobsize); | 1757 | mtd->oobsize); |
1760 | /* To prevent kernel oops */ | 1758 | /* To prevent kernel oops */ |
1761 | this->autooob = &onenand_oob_32; | 1759 | this->ecclayout = &onenand_oob_32; |
1762 | break; | 1760 | break; |
1763 | } | 1761 | } |
1764 | 1762 | ||
1765 | mtd->oobinfo = this->autooob; | 1763 | mtd->ecclayout = this->ecclayout; |
1766 | 1764 | ||
1767 | /* Fill in remaining MTD driver data */ | 1765 | /* Fill in remaining MTD driver data */ |
1768 | mtd->type = MTD_NANDFLASH; | 1766 | mtd->type = MTD_NANDFLASH; |
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h index 272fbea55192..506690cc9a78 100644 --- a/fs/jffs2/jffs2_fs_sb.h +++ b/fs/jffs2/jffs2_fs_sb.h | |||
@@ -107,7 +107,7 @@ struct jffs2_sb_info { | |||
107 | struct rw_semaphore wbuf_sem; /* Protects the write buffer */ | 107 | struct rw_semaphore wbuf_sem; /* Protects the write buffer */ |
108 | 108 | ||
109 | /* Information about out-of-band area usage... */ | 109 | /* Information about out-of-band area usage... */ |
110 | struct nand_oobinfo *oobinfo; | 110 | struct nand_ecclayout *ecclayout; |
111 | uint32_t badblock_pos; | 111 | uint32_t badblock_pos; |
112 | uint32_t fsdata_pos; | 112 | uint32_t fsdata_pos; |
113 | uint32_t fsdata_len; | 113 | uint32_t fsdata_len; |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index dc275cedfe4a..c6a62e162963 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -1140,18 +1140,9 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock * | |||
1140 | return 1; | 1140 | return 1; |
1141 | } | 1141 | } |
1142 | 1142 | ||
1143 | #define NAND_JFFS2_OOB16_FSDALEN 8 | ||
1144 | |||
1145 | static struct nand_oobinfo jffs2_oobinfo_docecc = { | ||
1146 | .useecc = MTD_NANDECC_PLACE, | ||
1147 | .eccbytes = 6, | ||
1148 | .eccpos = {0,1,2,3,4,5} | ||
1149 | }; | ||
1150 | |||
1151 | |||
1152 | static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c) | 1143 | static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c) |
1153 | { | 1144 | { |
1154 | struct nand_oobinfo *oinfo = c->mtd->oobinfo; | 1145 | struct nand_ecclayout *oinfo = c->mtd->ecclayout; |
1155 | 1146 | ||
1156 | /* Do this only, if we have an oob buffer */ | 1147 | /* Do this only, if we have an oob buffer */ |
1157 | if (!c->mtd->oobsize) | 1148 | if (!c->mtd->oobsize) |
@@ -1161,33 +1152,23 @@ static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c) | |||
1161 | c->cleanmarker_size = 0; | 1152 | c->cleanmarker_size = 0; |
1162 | 1153 | ||
1163 | /* Should we use autoplacement ? */ | 1154 | /* Should we use autoplacement ? */ |
1164 | if (oinfo && oinfo->useecc == MTD_NANDECC_AUTOPLACE) { | 1155 | if (!oinfo) { |
1165 | D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n")); | 1156 | D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n")); |
1166 | /* Get the position of the free bytes */ | 1157 | return -EINVAL; |
1167 | if (!oinfo->oobfree[0][1]) { | 1158 | } |
1168 | printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep. Autoplacement selected and no empty space in oob\n"); | ||
1169 | return -ENOSPC; | ||
1170 | } | ||
1171 | c->fsdata_pos = oinfo->oobfree[0][0]; | ||
1172 | c->fsdata_len = oinfo->oobfree[0][1]; | ||
1173 | if (c->fsdata_len > 8) | ||
1174 | c->fsdata_len = 8; | ||
1175 | } else { | ||
1176 | /* This is just a legacy fallback and should go away soon */ | ||
1177 | switch(c->mtd->ecctype) { | ||
1178 | case MTD_ECC_RS_DiskOnChip: | ||
1179 | printk(KERN_WARNING "JFFS2 using DiskOnChip hardware ECC without autoplacement. Fix it!\n"); | ||
1180 | c->oobinfo = &jffs2_oobinfo_docecc; | ||
1181 | c->fsdata_pos = 6; | ||
1182 | c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN; | ||
1183 | c->badblock_pos = 15; | ||
1184 | break; | ||
1185 | 1159 | ||
1186 | default: | 1160 | D1(printk(KERN_DEBUG "JFFS2 using autoplace on NAND\n")); |
1187 | D1(printk(KERN_DEBUG "JFFS2 on NAND. No autoplacment info found\n")); | 1161 | /* Get the position of the free bytes */ |
1188 | return -EINVAL; | 1162 | if (!oinfo->oobfree[0].length) { |
1189 | } | 1163 | printk (KERN_WARNING "jffs2_nand_set_oobinfo(): Eeep." |
1164 | " Autoplacement selected and no empty space in oob\n"); | ||
1165 | return -ENOSPC; | ||
1190 | } | 1166 | } |
1167 | c->fsdata_pos = oinfo->oobfree[0].offset; | ||
1168 | c->fsdata_len = oinfo->oobfree[0].length; | ||
1169 | if (c->fsdata_len > 8) | ||
1170 | c->fsdata_len = 8; | ||
1171 | |||
1191 | return 0; | 1172 | return 0; |
1192 | } | 1173 | } |
1193 | 1174 | ||
diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h index d7eaa40e5ab0..6977780e548f 100644 --- a/include/linux/mtd/inftl.h +++ b/include/linux/mtd/inftl.h | |||
@@ -46,7 +46,7 @@ struct INFTLrecord { | |||
46 | unsigned int nb_blocks; /* number of physical blocks */ | 46 | unsigned int nb_blocks; /* number of physical blocks */ |
47 | unsigned int nb_boot_blocks; /* number of blocks used by the bios */ | 47 | unsigned int nb_boot_blocks; /* number of blocks used by the bios */ |
48 | struct erase_info instr; | 48 | struct erase_info instr; |
49 | struct nand_oobinfo oobinfo; | 49 | struct nand_ecclayout oobinfo; |
50 | }; | 50 | }; |
51 | 51 | ||
52 | int INFTL_mount(struct INFTLrecord *s); | 52 | int INFTL_mount(struct INFTLrecord *s); |
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 8429da51bb09..48a9df21ab11 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h | |||
@@ -101,8 +101,8 @@ struct mtd_info { | |||
101 | char *name; | 101 | char *name; |
102 | int index; | 102 | int index; |
103 | 103 | ||
104 | /* oobinfo structure pointer - read only ! */ | 104 | /* ecc layout structure pointer - read only ! */ |
105 | struct nand_oobinfo *oobinfo; | 105 | struct nand_ecclayout *ecclayout; |
106 | 106 | ||
107 | /* Data for variable erase regions. If numeraseregions is zero, | 107 | /* Data for variable erase regions. If numeraseregions is zero, |
108 | * it means that the whole device has erasesize as given above. | 108 | * it means that the whole device has erasesize as given above. |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index fd46bcf52281..dc2bf1bcf42b 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -244,6 +244,7 @@ struct nand_ecc_ctrl { | |||
244 | int total; | 244 | int total; |
245 | int prepad; | 245 | int prepad; |
246 | int postpad; | 246 | int postpad; |
247 | struct nand_ecclayout *layout; | ||
247 | void (*hwctl)(struct mtd_info *mtd, int mode); | 248 | void (*hwctl)(struct mtd_info *mtd, int mode); |
248 | int (*calculate)(struct mtd_info *mtd, | 249 | int (*calculate)(struct mtd_info *mtd, |
249 | const uint8_t *dat, | 250 | const uint8_t *dat, |
@@ -318,7 +319,7 @@ struct nand_buffers { | |||
318 | * @chipsize: [INTERN] the size of one chip for multichip arrays | 319 | * @chipsize: [INTERN] the size of one chip for multichip arrays |
319 | * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 | 320 | * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 |
320 | * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf | 321 | * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf |
321 | * @autooob: [REPLACEABLE] the default (auto)placement scheme | 322 | * @ecclayout: [REPLACEABLE] the default ecc placement scheme |
322 | * @bbt: [INTERN] bad block table pointer | 323 | * @bbt: [INTERN] bad block table pointer |
323 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup | 324 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup |
324 | * @bbt_md: [REPLACEABLE] bad block table mirror descriptor | 325 | * @bbt_md: [REPLACEABLE] bad block table mirror descriptor |
@@ -368,7 +369,7 @@ struct nand_chip { | |||
368 | 369 | ||
369 | uint8_t *oob_poi; | 370 | uint8_t *oob_poi; |
370 | struct nand_hw_control *controller; | 371 | struct nand_hw_control *controller; |
371 | struct nand_oobinfo *autooob; | 372 | struct nand_ecclayout *ecclayout; |
372 | 373 | ||
373 | struct nand_ecc_ctrl ecc; | 374 | struct nand_ecc_ctrl ecc; |
374 | struct nand_buffers buffers; | 375 | struct nand_buffers buffers; |
@@ -522,7 +523,7 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
522 | * @partitions: mtd partition list | 523 | * @partitions: mtd partition list |
523 | * @chip_delay: R/B delay value in us | 524 | * @chip_delay: R/B delay value in us |
524 | * @options: Option flags, e.g. 16bit buswidth | 525 | * @options: Option flags, e.g. 16bit buswidth |
525 | * @oobinfo: oob info structure (ecc placement) | 526 | * @ecclayout: ecc layout info structure |
526 | * @priv: hardware controller specific settings | 527 | * @priv: hardware controller specific settings |
527 | */ | 528 | */ |
528 | struct platform_nand_chip { | 529 | struct platform_nand_chip { |
@@ -530,7 +531,7 @@ struct platform_nand_chip { | |||
530 | int chip_offset; | 531 | int chip_offset; |
531 | int nr_partitions; | 532 | int nr_partitions; |
532 | struct mtd_partition *partitions; | 533 | struct mtd_partition *partitions; |
533 | struct nand_oobinfo *oobinfo; | 534 | struct nand_ecclayout *ecclayout; |
534 | int chip_delay; | 535 | int chip_delay; |
535 | unsigned int options; | 536 | unsigned int options; |
536 | void *priv; | 537 | void *priv; |
diff --git a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h index d35d2c21ff3e..bcf2fb3fa4a7 100644 --- a/include/linux/mtd/nftl.h +++ b/include/linux/mtd/nftl.h | |||
@@ -37,7 +37,7 @@ struct NFTLrecord { | |||
37 | unsigned int nb_blocks; /* number of physical blocks */ | 37 | unsigned int nb_blocks; /* number of physical blocks */ |
38 | unsigned int nb_boot_blocks; /* number of blocks used by the bios */ | 38 | unsigned int nb_boot_blocks; /* number of blocks used by the bios */ |
39 | struct erase_info instr; | 39 | struct erase_info instr; |
40 | struct nand_oobinfo oobinfo; | 40 | struct nand_ecclayout oobinfo; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | int NFTL_mount(struct NFTLrecord *s); | 43 | int NFTL_mount(struct NFTLrecord *s); |
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 3f5919f2e9da..9ce9a48db444 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h | |||
@@ -77,7 +77,7 @@ struct onenand_bufferram { | |||
77 | * @param chip_lock [INTERN] spinlock used to protect access to this structure and the chip | 77 | * @param chip_lock [INTERN] spinlock used to protect access to this structure and the chip |
78 | * @param wq [INTERN] wait queue to sleep on if a OneNAND operation is in progress | 78 | * @param wq [INTERN] wait queue to sleep on if a OneNAND operation is in progress |
79 | * @param state [INTERN] the current state of the OneNAND device | 79 | * @param state [INTERN] the current state of the OneNAND device |
80 | * @param autooob [REPLACEABLE] the default (auto)placement scheme | 80 | * @param ecclayout [REPLACEABLE] the default ecc placement scheme |
81 | * @param bbm [REPLACEABLE] pointer to Bad Block Management | 81 | * @param bbm [REPLACEABLE] pointer to Bad Block Management |
82 | * @param priv [OPTIONAL] pointer to private chip date | 82 | * @param priv [OPTIONAL] pointer to private chip date |
83 | */ | 83 | */ |
@@ -113,9 +113,9 @@ struct onenand_chip { | |||
113 | onenand_state_t state; | 113 | onenand_state_t state; |
114 | unsigned char *page_buf; | 114 | unsigned char *page_buf; |
115 | 115 | ||
116 | struct nand_oobinfo *autooob; | 116 | struct nand_ecclayout *ecclayout; |
117 | 117 | ||
118 | void *bbm; | 118 | void *bbm; |
119 | 119 | ||
120 | void *priv; | 120 | void *priv; |
121 | }; | 121 | }; |
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index b03f512d51b9..da6b3d6f12a7 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h | |||
@@ -41,7 +41,7 @@ struct mtd_partition { | |||
41 | u_int32_t size; /* partition size */ | 41 | u_int32_t size; /* partition size */ |
42 | u_int32_t offset; /* offset within the master MTD space */ | 42 | u_int32_t offset; /* offset within the master MTD space */ |
43 | u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ | 43 | u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ |
44 | struct nand_oobinfo *oobsel; /* out of band layout for this partition (NAND only)*/ | 44 | struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ |
45 | struct mtd_info **mtdp; /* pointer to store the MTD object */ | 45 | struct mtd_info **mtdp; /* pointer to store the MTD object */ |
46 | }; | 46 | }; |
47 | 47 | ||
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h index 1e09e4c8f485..54c673f9648d 100644 --- a/include/mtd/mtd-abi.h +++ b/include/mtd/mtd-abi.h | |||
@@ -82,12 +82,12 @@ struct otp_info { | |||
82 | uint32_t locked; | 82 | uint32_t locked; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | #define MEMGETINFO _IOR('M', 1, struct mtd_info_user) | 85 | #define MEMGETINFO _IOR('M', 1, struct mtd_info_user) |
86 | #define MEMERASE _IOW('M', 2, struct erase_info_user) | 86 | #define MEMERASE _IOW('M', 2, struct erase_info_user) |
87 | #define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) | 87 | #define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) |
88 | #define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) | 88 | #define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) |
89 | #define MEMLOCK _IOW('M', 5, struct erase_info_user) | 89 | #define MEMLOCK _IOW('M', 5, struct erase_info_user) |
90 | #define MEMUNLOCK _IOW('M', 6, struct erase_info_user) | 90 | #define MEMUNLOCK _IOW('M', 6, struct erase_info_user) |
91 | #define MEMGETREGIONCOUNT _IOR('M', 7, int) | 91 | #define MEMGETREGIONCOUNT _IOR('M', 7, int) |
92 | #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) | 92 | #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) |
93 | #define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) | 93 | #define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) |
@@ -97,8 +97,13 @@ struct otp_info { | |||
97 | #define OTPSELECT _IOR('M', 13, int) | 97 | #define OTPSELECT _IOR('M', 13, int) |
98 | #define OTPGETREGIONCOUNT _IOW('M', 14, int) | 98 | #define OTPGETREGIONCOUNT _IOW('M', 14, int) |
99 | #define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) | 99 | #define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) |
100 | #define OTPLOCK _IOR('M', 16, struct otp_info) | 100 | #define OTPLOCK _IOR('M', 16, struct otp_info) |
101 | #define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout) | ||
101 | 102 | ||
103 | /* | ||
104 | * Obsolete legacy interface. Keep it in order not to break userspace | ||
105 | * interfaces | ||
106 | */ | ||
102 | struct nand_oobinfo { | 107 | struct nand_oobinfo { |
103 | uint32_t useecc; | 108 | uint32_t useecc; |
104 | uint32_t eccbytes; | 109 | uint32_t eccbytes; |
@@ -106,4 +111,21 @@ struct nand_oobinfo { | |||
106 | uint32_t eccpos[32]; | 111 | uint32_t eccpos[32]; |
107 | }; | 112 | }; |
108 | 113 | ||
114 | struct nand_oobfree { | ||
115 | uint32_t offset; | ||
116 | uint32_t length; | ||
117 | }; | ||
118 | |||
119 | #define MTD_MAX_OOBFREE_ENTRIES 8 | ||
120 | /* | ||
121 | * ECC layout control structure. Exported to userspace for | ||
122 | * diagnosis and to allow creation of raw images | ||
123 | */ | ||
124 | struct nand_ecclayout { | ||
125 | uint32_t eccbytes; | ||
126 | uint32_t eccpos[64]; | ||
127 | uint32_t oobavail; | ||
128 | struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; | ||
129 | }; | ||
130 | |||
109 | #endif /* __MTD_ABI_H__ */ | 131 | #endif /* __MTD_ABI_H__ */ |
diff --git a/include/mtd/mtd-user.h b/include/mtd/mtd-user.h index 1c13fc7161fe..713f34d3e62e 100644 --- a/include/mtd/mtd-user.h +++ b/include/mtd/mtd-user.h | |||
@@ -16,5 +16,6 @@ typedef struct mtd_info_user mtd_info_t; | |||
16 | typedef struct erase_info_user erase_info_t; | 16 | typedef struct erase_info_user erase_info_t; |
17 | typedef struct region_info_user region_info_t; | 17 | typedef struct region_info_user region_info_t; |
18 | typedef struct nand_oobinfo nand_oobinfo_t; | 18 | typedef struct nand_oobinfo nand_oobinfo_t; |
19 | typedef struct nand_ecclayout nand_ecclayout_t; | ||
19 | 20 | ||
20 | #endif /* __MTD_USER_H__ */ | 21 | #endif /* __MTD_USER_H__ */ |