aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Wool <vwool@ru.mvista.com>2006-11-03 10:20:38 -0500
committerDavid Woodhouse <dwmw2@infradead.org>2006-11-28 17:39:03 -0500
commit7014568bad55c20b7ee4f439d78c9e875912d51f (patch)
tree1b558ef8d77d31925cc396ed69d8f785615cf09f
parent191876729901d0c8dab8a331f9a1e4b73a56457b (diff)
[MTD] [NAND] remove len/ooblen confusion.
As was discussed between Ricard Wanderlöf, David Woodhouse, Artem Bityutskiy and me, the current API for reading/writing OOB is confusing. The thing that introduces confusion is the need to specify ops.len together with ops.ooblen for reads/writes that concern only OOB not data area. So, ops.len is overloaded: when ops.datbuf != NULL it serves to specify the length of the data read, and when ops.datbuf == NULL, it serves to specify the full OOB read length. The patch inlined below is the slightly updated version of the previous patch serving the same purpose, but with the new Artem's comments taken into account. Artem, BTW, thanks a lot for your valuable input! Signed-off-by: Vitaly Wool <vwool@ru.mvista.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r--drivers/mtd/inftlcore.c6
-rw-r--r--drivers/mtd/mtdchar.c12
-rw-r--r--drivers/mtd/mtdconcat.c39
-rw-r--r--drivers/mtd/mtdpart.c4
-rw-r--r--drivers/mtd/nand/nand_base.c51
-rw-r--r--drivers/mtd/nand/nand_bbt.c5
-rw-r--r--drivers/mtd/nftlcore.c6
-rw-r--r--drivers/mtd/ssfdc.c5
-rw-r--r--fs/jffs2/wbuf.c21
-rw-r--r--include/linux/mtd/mtd.h12
10 files changed, 88 insertions, 73 deletions
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index a1b2de605000..d2f54c037e0f 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -163,10 +163,9 @@ int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
163 ops.ooblen = len; 163 ops.ooblen = len;
164 ops.oobbuf = buf; 164 ops.oobbuf = buf;
165 ops.datbuf = NULL; 165 ops.datbuf = NULL;
166 ops.len = len;
167 166
168 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 167 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
169 *retlen = ops.retlen; 168 *retlen = ops.oobretlen;
170 return res; 169 return res;
171} 170}
172 171
@@ -184,10 +183,9 @@ int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
184 ops.ooblen = len; 183 ops.ooblen = len;
185 ops.oobbuf = buf; 184 ops.oobbuf = buf;
186 ops.datbuf = NULL; 185 ops.datbuf = NULL;
187 ops.len = len;
188 186
189 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 187 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
190 *retlen = ops.retlen; 188 *retlen = ops.oobretlen;
191 return res; 189 return res;
192} 190}
193 191
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 866c8e0d57e4..07618f51d969 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -499,13 +499,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
499 if (ret) 499 if (ret)
500 return ret; 500 return ret;
501 501
502 ops.len = buf.length;
503 ops.ooblen = buf.length; 502 ops.ooblen = buf.length;
504 ops.ooboffs = buf.start & (mtd->oobsize - 1); 503 ops.ooboffs = buf.start & (mtd->oobsize - 1);
505 ops.datbuf = NULL; 504 ops.datbuf = NULL;
506 ops.mode = MTD_OOB_PLACE; 505 ops.mode = MTD_OOB_PLACE;
507 506
508 if (ops.ooboffs && ops.len > (mtd->oobsize - ops.ooboffs)) 507 if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
509 return -EINVAL; 508 return -EINVAL;
510 509
511 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); 510 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);
@@ -520,7 +519,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
520 buf.start &= ~(mtd->oobsize - 1); 519 buf.start &= ~(mtd->oobsize - 1);
521 ret = mtd->write_oob(mtd, buf.start, &ops); 520 ret = mtd->write_oob(mtd, buf.start, &ops);
522 521
523 if (copy_to_user(argp + sizeof(uint32_t), &ops.retlen, 522 if (copy_to_user(argp + sizeof(uint32_t), &ops.oobretlen,
524 sizeof(uint32_t))) 523 sizeof(uint32_t)))
525 ret = -EFAULT; 524 ret = -EFAULT;
526 525
@@ -548,7 +547,6 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
548 if (ret) 547 if (ret)
549 return ret; 548 return ret;
550 549
551 ops.len = buf.length;
552 ops.ooblen = buf.length; 550 ops.ooblen = buf.length;
553 ops.ooboffs = buf.start & (mtd->oobsize - 1); 551 ops.ooboffs = buf.start & (mtd->oobsize - 1);
554 ops.datbuf = NULL; 552 ops.datbuf = NULL;
@@ -564,10 +562,10 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
564 buf.start &= ~(mtd->oobsize - 1); 562 buf.start &= ~(mtd->oobsize - 1);
565 ret = mtd->read_oob(mtd, buf.start, &ops); 563 ret = mtd->read_oob(mtd, buf.start, &ops);
566 564
567 if (put_user(ops.retlen, (uint32_t __user *)argp)) 565 if (put_user(ops.oobretlen, (uint32_t __user *)argp))
568 ret = -EFAULT; 566 ret = -EFAULT;
569 else if (ops.retlen && copy_to_user(buf.ptr, ops.oobbuf, 567 else if (ops.oobretlen && copy_to_user(buf.ptr, ops.oobbuf,
570 ops.retlen)) 568 ops.oobretlen))
571 ret = -EFAULT; 569 ret = -EFAULT;
572 570
573 kfree(ops.oobbuf); 571 kfree(ops.oobbuf);
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 1fea631b5852..cf927a8803e7 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -247,7 +247,7 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
247 struct mtd_oob_ops devops = *ops; 247 struct mtd_oob_ops devops = *ops;
248 int i, err, ret = 0; 248 int i, err, ret = 0;
249 249
250 ops->retlen = 0; 250 ops->retlen = ops->oobretlen = 0;
251 251
252 for (i = 0; i < concat->num_subdev; i++) { 252 for (i = 0; i < concat->num_subdev; i++) {
253 struct mtd_info *subdev = concat->subdev[i]; 253 struct mtd_info *subdev = concat->subdev[i];
@@ -263,6 +263,7 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
263 263
264 err = subdev->read_oob(subdev, from, &devops); 264 err = subdev->read_oob(subdev, from, &devops);
265 ops->retlen += devops.retlen; 265 ops->retlen += devops.retlen;
266 ops->oobretlen += devops.oobretlen;
266 267
267 /* Save information about bitflips! */ 268 /* Save information about bitflips! */
268 if (unlikely(err)) { 269 if (unlikely(err)) {
@@ -278,14 +279,18 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
278 return err; 279 return err;
279 } 280 }
280 281
281 devops.len = ops->len - ops->retlen; 282 if (devops.datbuf) {
282 if (!devops.len) 283 devops.len = ops->len - ops->retlen;
283 return ret; 284 if (!devops.len)
284 285 return ret;
285 if (devops.datbuf)
286 devops.datbuf += devops.retlen; 286 devops.datbuf += devops.retlen;
287 if (devops.oobbuf) 287 }
288 devops.oobbuf += devops.ooblen; 288 if (devops.oobbuf) {
289 devops.ooblen = ops->ooblen - ops->oobretlen;
290 if (!devops.ooblen)
291 return ret;
292 devops.oobbuf += ops->oobretlen;
293 }
289 294
290 from = 0; 295 from = 0;
291 } 296 }
@@ -321,14 +326,18 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
321 if (err) 326 if (err)
322 return err; 327 return err;
323 328
324 devops.len = ops->len - ops->retlen; 329 if (devops.datbuf) {
325 if (!devops.len) 330 devops.len = ops->len - ops->retlen;
326 return 0; 331 if (!devops.len)
327 332 return 0;
328 if (devops.datbuf)
329 devops.datbuf += devops.retlen; 333 devops.datbuf += devops.retlen;
330 if (devops.oobbuf) 334 }
331 devops.oobbuf += devops.ooblen; 335 if (devops.oobbuf) {
336 devops.ooblen = ops->ooblen - ops->oobretlen;
337 if (!devops.ooblen)
338 return 0;
339 devops.oobbuf += devops.oobretlen;
340 }
332 to = 0; 341 to = 0;
333 } 342 }
334 return -EINVAL; 343 return -EINVAL;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 06a930372b7a..a20f75fd8d61 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -94,7 +94,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
94 94
95 if (from >= mtd->size) 95 if (from >= mtd->size)
96 return -EINVAL; 96 return -EINVAL;
97 if (from + ops->len > mtd->size) 97 if (ops->datbuf && from + ops->len > mtd->size)
98 return -EINVAL; 98 return -EINVAL;
99 res = part->master->read_oob(part->master, from + part->offset, ops); 99 res = part->master->read_oob(part->master, from + part->offset, ops);
100 100
@@ -161,7 +161,7 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
161 161
162 if (to >= mtd->size) 162 if (to >= mtd->size)
163 return -EINVAL; 163 return -EINVAL;
164 if (to + ops->len > mtd->size) 164 if (ops->datbuf && to + ops->len > mtd->size)
165 return -EINVAL; 165 return -EINVAL;
166 return part->master->write_oob(part->master, to + part->offset, ops); 166 return part->master->write_oob(part->master, to + part->offset, ops);
167} 167}
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 8df36e2c9a53..5dcb2e066ce7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -897,12 +897,11 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
897 * @chip: nand chip structure 897 * @chip: nand chip structure
898 * @oob: oob destination address 898 * @oob: oob destination address
899 * @ops: oob ops structure 899 * @ops: oob ops structure
900 * @len: size of oob to transfer
900 */ 901 */
901static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, 902static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
902 struct mtd_oob_ops *ops) 903 struct mtd_oob_ops *ops, size_t len)
903{ 904{
904 size_t len = ops->ooblen;
905
906 switch(ops->mode) { 905 switch(ops->mode) {
907 906
908 case MTD_OOB_PLACE: 907 case MTD_OOB_PLACE:
@@ -960,6 +959,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
960 int sndcmd = 1; 959 int sndcmd = 1;
961 int ret = 0; 960 int ret = 0;
962 uint32_t readlen = ops->len; 961 uint32_t readlen = ops->len;
962 uint32_t oobreadlen = ops->ooblen;
963 uint8_t *bufpoi, *oob, *buf; 963 uint8_t *bufpoi, *oob, *buf;
964 964
965 stats = mtd->ecc_stats; 965 stats = mtd->ecc_stats;
@@ -1006,10 +1006,17 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1006 1006
1007 if (unlikely(oob)) { 1007 if (unlikely(oob)) {
1008 /* Raw mode does data:oob:data:oob */ 1008 /* Raw mode does data:oob:data:oob */
1009 if (ops->mode != MTD_OOB_RAW) 1009 if (ops->mode != MTD_OOB_RAW) {
1010 oob = nand_transfer_oob(chip, oob, ops); 1010 int toread = min(oobreadlen,
1011 else 1011 chip->ecc.layout->oobavail);
1012 buf = nand_transfer_oob(chip, buf, ops); 1012 if (toread) {
1013 oob = nand_transfer_oob(chip,
1014 oob, ops, toread);
1015 oobreadlen -= toread;
1016 }
1017 } else
1018 buf = nand_transfer_oob(chip,
1019 buf, ops, mtd->oobsize);
1013 } 1020 }
1014 1021
1015 if (!(chip->options & NAND_NO_READRDY)) { 1022 if (!(chip->options & NAND_NO_READRDY)) {
@@ -1056,6 +1063,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1056 } 1063 }
1057 1064
1058 ops->retlen = ops->len - (size_t) readlen; 1065 ops->retlen = ops->len - (size_t) readlen;
1066 if (oob)
1067 ops->oobretlen = ops->ooblen - oobreadlen;
1059 1068
1060 if (ret) 1069 if (ret)
1061 return ret; 1070 return ret;
@@ -1256,12 +1265,18 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1256 int page, realpage, chipnr, sndcmd = 1; 1265 int page, realpage, chipnr, sndcmd = 1;
1257 struct nand_chip *chip = mtd->priv; 1266 struct nand_chip *chip = mtd->priv;
1258 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; 1267 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
1259 int readlen = ops->len; 1268 int readlen = ops->ooblen;
1269 int len;
1260 uint8_t *buf = ops->oobbuf; 1270 uint8_t *buf = ops->oobbuf;
1261 1271
1262 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n", 1272 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n",
1263 (unsigned long long)from, readlen); 1273 (unsigned long long)from, readlen);
1264 1274
1275 if (ops->mode == MTD_OOB_RAW)
1276 len = mtd->oobsize;
1277 else
1278 len = chip->ecc.layout->oobavail;
1279
1265 chipnr = (int)(from >> chip->chip_shift); 1280 chipnr = (int)(from >> chip->chip_shift);
1266 chip->select_chip(mtd, chipnr); 1281 chip->select_chip(mtd, chipnr);
1267 1282
@@ -1271,7 +1286,9 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1271 1286
1272 while(1) { 1287 while(1) {
1273 sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); 1288 sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
1274 buf = nand_transfer_oob(chip, buf, ops); 1289
1290 len = min(len, readlen);
1291 buf = nand_transfer_oob(chip, buf, ops, len);
1275 1292
1276 if (!(chip->options & NAND_NO_READRDY)) { 1293 if (!(chip->options & NAND_NO_READRDY)) {
1277 /* 1294 /*
@@ -1286,7 +1303,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1286 nand_wait_ready(mtd); 1303 nand_wait_ready(mtd);
1287 } 1304 }
1288 1305
1289 readlen -= ops->ooblen; 1306 readlen -= len;
1290 if (!readlen) 1307 if (!readlen)
1291 break; 1308 break;
1292 1309
@@ -1308,7 +1325,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1308 sndcmd = 1; 1325 sndcmd = 1;
1309 } 1326 }
1310 1327
1311 ops->retlen = ops->len; 1328 ops->oobretlen = ops->ooblen;
1312 return 0; 1329 return 0;
1313} 1330}
1314 1331
@@ -1329,7 +1346,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1329 ops->retlen = 0; 1346 ops->retlen = 0;
1330 1347
1331 /* Do not allow reads past end of device */ 1348 /* Do not allow reads past end of device */
1332 if ((from + ops->len) > mtd->size) { 1349 if (ops->datbuf && (from + ops->len) > mtd->size) {
1333 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " 1350 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1334 "Attempt read beyond end of device\n"); 1351 "Attempt read beyond end of device\n");
1335 return -EINVAL; 1352 return -EINVAL;
@@ -1654,6 +1671,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
1654 } 1671 }
1655 1672
1656 ops->retlen = ops->len - writelen; 1673 ops->retlen = ops->len - writelen;
1674 if (unlikely(oob))
1675 ops->oobretlen = ops->ooblen;
1657 return ret; 1676 return ret;
1658} 1677}
1659 1678
@@ -1709,10 +1728,10 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1709 struct nand_chip *chip = mtd->priv; 1728 struct nand_chip *chip = mtd->priv;
1710 1729
1711 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", 1730 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
1712 (unsigned int)to, (int)ops->len); 1731 (unsigned int)to, (int)ops->ooblen);
1713 1732
1714 /* Do not allow write past end of page */ 1733 /* Do not allow write past end of page */
1715 if ((ops->ooboffs + ops->len) > mtd->oobsize) { 1734 if ((ops->ooboffs + ops->ooblen) > mtd->oobsize) {
1716 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " 1735 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1717 "Attempt to write past end of page\n"); 1736 "Attempt to write past end of page\n");
1718 return -EINVAL; 1737 return -EINVAL;
@@ -1748,7 +1767,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1748 if (status) 1767 if (status)
1749 return status; 1768 return status;
1750 1769
1751 ops->retlen = ops->len; 1770 ops->oobretlen = ops->ooblen;
1752 1771
1753 return 0; 1772 return 0;
1754} 1773}
@@ -1768,7 +1787,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1768 ops->retlen = 0; 1787 ops->retlen = 0;
1769 1788
1770 /* Do not allow writes past end of device */ 1789 /* Do not allow writes past end of device */
1771 if ((to + ops->len) > mtd->size) { 1790 if (ops->datbuf && (to + ops->len) > mtd->size) {
1772 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " 1791 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1773 "Attempt read beyond end of device\n"); 1792 "Attempt read beyond end of device\n");
1774 return -EINVAL; 1793 return -EINVAL;
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 9402653eb09b..4e74fe9af29e 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -333,7 +333,6 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
333 struct mtd_oob_ops ops; 333 struct mtd_oob_ops ops;
334 int j, ret; 334 int j, ret;
335 335
336 ops.len = mtd->oobsize;
337 ops.ooblen = mtd->oobsize; 336 ops.ooblen = mtd->oobsize;
338 ops.oobbuf = buf; 337 ops.oobbuf = buf;
339 ops.ooboffs = 0; 338 ops.ooboffs = 0;
@@ -676,10 +675,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
676 "bad block table\n"); 675 "bad block table\n");
677 } 676 }
678 /* Read oob data */ 677 /* Read oob data */
679 ops.len = (len >> this->page_shift) * mtd->oobsize; 678 ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
680 ops.oobbuf = &buf[len]; 679 ops.oobbuf = &buf[len];
681 res = mtd->read_oob(mtd, to + mtd->writesize, &ops); 680 res = mtd->read_oob(mtd, to + mtd->writesize, &ops);
682 if (res < 0 || ops.retlen != ops.len) 681 if (res < 0 || ops.oobretlen != ops.ooblen)
683 goto outerr; 682 goto outerr;
684 683
685 /* Calc the byte offset in the buffer */ 684 /* Calc the byte offset in the buffer */
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index d974adab3492..f4d38546068f 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -147,10 +147,9 @@ int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
147 ops.ooblen = len; 147 ops.ooblen = len;
148 ops.oobbuf = buf; 148 ops.oobbuf = buf;
149 ops.datbuf = NULL; 149 ops.datbuf = NULL;
150 ops.len = len;
151 150
152 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 151 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
153 *retlen = ops.retlen; 152 *retlen = ops.oobretlen;
154 return res; 153 return res;
155} 154}
156 155
@@ -168,10 +167,9 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
168 ops.ooblen = len; 167 ops.ooblen = len;
169 ops.oobbuf = buf; 168 ops.oobbuf = buf;
170 ops.datbuf = NULL; 169 ops.datbuf = NULL;
171 ops.len = len;
172 170
173 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 171 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
174 *retlen = ops.retlen; 172 *retlen = ops.oobretlen;
175 return res; 173 return res;
176} 174}
177 175
diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c
index 79d3bb659bfe..e834cc16c9f9 100644
--- a/drivers/mtd/ssfdc.c
+++ b/drivers/mtd/ssfdc.c
@@ -172,13 +172,12 @@ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
172 172
173 ops.mode = MTD_OOB_RAW; 173 ops.mode = MTD_OOB_RAW;
174 ops.ooboffs = 0; 174 ops.ooboffs = 0;
175 ops.ooblen = mtd->oobsize; 175 ops.ooblen = OOB_SIZE;
176 ops.len = OOB_SIZE;
177 ops.oobbuf = buf; 176 ops.oobbuf = buf;
178 ops.datbuf = NULL; 177 ops.datbuf = NULL;
179 178
180 ret = mtd->read_oob(mtd, offs, &ops); 179 ret = mtd->read_oob(mtd, offs, &ops);
181 if (ret < 0 || ops.retlen != OOB_SIZE) 180 if (ret < 0 || ops.oobretlen != OOB_SIZE)
182 return -1; 181 return -1;
183 182
184 return 0; 183 return 0;
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index b9b700730dfe..dcb18e9a646e 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -968,8 +968,7 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
968 int oobsize = c->mtd->oobsize; 968 int oobsize = c->mtd->oobsize;
969 struct mtd_oob_ops ops; 969 struct mtd_oob_ops ops;
970 970
971 ops.len = NR_OOB_SCAN_PAGES * oobsize; 971 ops.ooblen = NR_OOB_SCAN_PAGES * oobsize;
972 ops.ooblen = oobsize;
973 ops.oobbuf = c->oobbuf; 972 ops.oobbuf = c->oobbuf;
974 ops.ooboffs = 0; 973 ops.ooboffs = 0;
975 ops.datbuf = NULL; 974 ops.datbuf = NULL;
@@ -982,10 +981,10 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
982 return ret; 981 return ret;
983 } 982 }
984 983
985 if (ops.retlen < ops.len) { 984 if (ops.oobretlen < ops.ooblen) {
986 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB " 985 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB "
987 "returned short read (%zd bytes not %d) for block " 986 "returned short read (%zd bytes not %d) for block "
988 "at %08x\n", ops.retlen, ops.len, jeb->offset)); 987 "at %08x\n", ops.oobretlen, ops.ooblen, jeb->offset));
989 return -EIO; 988 return -EIO;
990 } 989 }
991 990
@@ -1004,7 +1003,7 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
1004 } 1003 }
1005 1004
1006 /* we know, we are aligned :) */ 1005 /* we know, we are aligned :) */
1007 for (page = oobsize; page < ops.len; page += sizeof(long)) { 1006 for (page = oobsize; page < ops.ooblen; page += sizeof(long)) {
1008 long dat = *(long *)(&ops.oobbuf[page]); 1007 long dat = *(long *)(&ops.oobbuf[page]);
1009 if(dat != -1) 1008 if(dat != -1)
1010 return 1; 1009 return 1;
@@ -1032,7 +1031,6 @@ int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c,
1032 return 2; 1031 return 2;
1033 } 1032 }
1034 1033
1035 ops.len = oobsize;
1036 ops.ooblen = oobsize; 1034 ops.ooblen = oobsize;
1037 ops.oobbuf = c->oobbuf; 1035 ops.oobbuf = c->oobbuf;
1038 ops.ooboffs = 0; 1036 ops.ooboffs = 0;
@@ -1047,10 +1045,10 @@ int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c,
1047 return ret; 1045 return ret;
1048 } 1046 }
1049 1047
1050 if (ops.retlen < ops.len) { 1048 if (ops.oobretlen < ops.ooblen) {
1051 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): " 1049 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): "
1052 "Read OOB return short read (%zd bytes not %d) " 1050 "Read OOB return short read (%zd bytes not %d) "
1053 "for block at %08x\n", ops.retlen, ops.len, 1051 "for block at %08x\n", ops.oobretlen, ops.ooblen,
1054 jeb->offset)); 1052 jeb->offset));
1055 return -EIO; 1053 return -EIO;
1056 } 1054 }
@@ -1089,8 +1087,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
1089 n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); 1087 n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
1090 n.totlen = cpu_to_je32(8); 1088 n.totlen = cpu_to_je32(8);
1091 1089
1092 ops.len = c->fsdata_len; 1090 ops.ooblen = c->fsdata_len;
1093 ops.ooblen = c->fsdata_len;;
1094 ops.oobbuf = (uint8_t *)&n; 1091 ops.oobbuf = (uint8_t *)&n;
1095 ops.ooboffs = c->fsdata_pos; 1092 ops.ooboffs = c->fsdata_pos;
1096 ops.datbuf = NULL; 1093 ops.datbuf = NULL;
@@ -1104,10 +1101,10 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
1104 jeb->offset, ret)); 1101 jeb->offset, ret));
1105 return ret; 1102 return ret;
1106 } 1103 }
1107 if (ops.retlen != ops.len) { 1104 if (ops.oobretlen != ops.ooblen) {
1108 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): " 1105 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): "
1109 "Short write for block at %08x: %zd not %d\n", 1106 "Short write for block at %08x: %zd not %d\n",
1110 jeb->offset, ops.retlen, ops.len)); 1107 jeb->offset, ops.oobretlen, ops.ooblen));
1111 return -EIO; 1108 return -EIO;
1112 } 1109 }
1113 return 0; 1110 return 0;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 94a443d45258..4fc391ec9d01 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -75,15 +75,12 @@ typedef enum {
75 * struct mtd_oob_ops - oob operation operands 75 * struct mtd_oob_ops - oob operation operands
76 * @mode: operation mode 76 * @mode: operation mode
77 * 77 *
78 * @len: number of bytes to write/read. When a data buffer is given 78 * @len: number of data bytes to write/read
79 * (datbuf != NULL) this is the number of data bytes. When
80 * no data buffer is available this is the number of oob bytes.
81 * 79 *
82 * @retlen: number of bytes written/read. When a data buffer is given 80 * @retlen: number of data bytes written/read
83 * (datbuf != NULL) this is the number of data bytes. When
84 * no data buffer is available this is the number of oob bytes.
85 * 81 *
86 * @ooblen: number of oob bytes per page 82 * @ooblen: number of oob bytes to write/read
83 * @oobretlen: number of oob bytes written/read
87 * @ooboffs: offset of oob data in the oob area (only relevant when 84 * @ooboffs: offset of oob data in the oob area (only relevant when
88 * mode = MTD_OOB_PLACE) 85 * mode = MTD_OOB_PLACE)
89 * @datbuf: data buffer - if NULL only oob data are read/written 86 * @datbuf: data buffer - if NULL only oob data are read/written
@@ -94,6 +91,7 @@ struct mtd_oob_ops {
94 size_t len; 91 size_t len;
95 size_t retlen; 92 size_t retlen;
96 size_t ooblen; 93 size_t ooblen;
94 size_t oobretlen;
97 uint32_t ooboffs; 95 uint32_t ooboffs;
98 uint8_t *datbuf; 96 uint8_t *datbuf;
99 uint8_t *oobbuf; 97 uint8_t *oobbuf;