aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/mtdchar.c26
-rw-r--r--drivers/mtd/mtdconcat.c2
-rw-r--r--drivers/mtd/mtdpart.c2
-rw-r--r--drivers/mtd/nand/diskonchip.c5
-rw-r--r--drivers/mtd/nand/nand_base.c52
-rw-r--r--drivers/mtd/nand/ndfc.c2
-rw-r--r--drivers/mtd/nand/rtc_from4.c5
-rw-r--r--drivers/mtd/nand/s3c2410.c5
-rw-r--r--drivers/mtd/nand/sharpsl.c5
-rw-r--r--drivers/mtd/onenand/onenand_base.c14
-rw-r--r--fs/jffs2/jffs2_fs_sb.h2
-rw-r--r--fs/jffs2/wbuf.c51
-rw-r--r--include/linux/mtd/inftl.h2
-rw-r--r--include/linux/mtd/mtd.h4
-rw-r--r--include/linux/mtd/nand.h9
-rw-r--r--include/linux/mtd/nftl.h2
-rw-r--r--include/linux/mtd/onenand.h6
-rw-r--r--include/linux/mtd/partitions.h2
-rw-r--r--include/mtd/mtd-abi.h36
-rw-r--r--include/mtd/mtd-user.h1
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 */
1061static struct nand_oobinfo doc200x_oobinfo = { 1061static 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 */
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)
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 */
145static struct nand_oobinfo rtc_from4_nand_oobinfo = { 145static 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
79static struct nand_oobinfo nand_hw_eccoob = { 79static 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
118static struct nand_oobinfo akita_oobinfo = { 118static 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 */
26static struct nand_oobinfo onenand_oob_64 = { 26static 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 */
44static struct nand_oobinfo onenand_oob_32 = { 43static 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
1145static 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
1152static int jffs2_nand_set_oobinfo(struct jffs2_sb_info *c) 1143static 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
52int INFTL_mount(struct INFTLrecord *s); 52int 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 */
528struct platform_nand_chip { 529struct 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
43int NFTL_mount(struct NFTLrecord *s); 43int 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 */
102struct nand_oobinfo { 107struct 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
114struct 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 */
124struct 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;
16typedef struct erase_info_user erase_info_t; 16typedef struct erase_info_user erase_info_t;
17typedef struct region_info_user region_info_t; 17typedef struct region_info_user region_info_t;
18typedef struct nand_oobinfo nand_oobinfo_t; 18typedef struct nand_oobinfo nand_oobinfo_t;
19typedef struct nand_ecclayout nand_ecclayout_t;
19 20
20#endif /* __MTD_USER_H__ */ 21#endif /* __MTD_USER_H__ */