aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2011-08-23 20:17:32 -0400
committerArtem Bityutskiy <artem.bityutskiy@intel.com>2011-09-11 08:02:17 -0400
commit305b93f180b221789a6213bf3d298c6735102da1 (patch)
tree5d5b71a27538e78453c7f4227aca8c94552e51ed /drivers/mtd
parentc97926dd8d7cc094830b253afc817cbf406c0de7 (diff)
mtd: do not assume oobsize is power of 2
Previous generations of MTDs all used OOB sizes that were powers of 2, (e.g., 64, 128). However, newer generations of flash, especially NAND, use irregular OOB sizes that are not powers of 2 (e.g., 218, 224, 448). This means we cannot use masks like "mtd->oobsize - 1" to assume that we will get a proper bitmask for OOB operations. These masks are really only intended to hide the "page" portion of the offset, leaving any OOB offset intact, so a masking with the writesize (which *is* always a power of 2) is valid and makes more sense. This has been tested for read/write of NAND devices (nanddump/nandwrite) using nandsim and actual NAND flash. Signed-off-by: Brian Norris <computersforpeace@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/mtdchar.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index a75d55577e49..b20625475132 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -410,7 +410,7 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
410 return ret; 410 return ret;
411 411
412 ops.ooblen = length; 412 ops.ooblen = length;
413 ops.ooboffs = start & (mtd->oobsize - 1); 413 ops.ooboffs = start & (mtd->writesize - 1);
414 ops.datbuf = NULL; 414 ops.datbuf = NULL;
415 ops.mode = MTD_OOB_PLACE; 415 ops.mode = MTD_OOB_PLACE;
416 416
@@ -421,7 +421,7 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
421 if (IS_ERR(ops.oobbuf)) 421 if (IS_ERR(ops.oobbuf))
422 return PTR_ERR(ops.oobbuf); 422 return PTR_ERR(ops.oobbuf);
423 423
424 start &= ~((uint64_t)mtd->oobsize - 1); 424 start &= ~((uint64_t)mtd->writesize - 1);
425 ret = mtd->write_oob(mtd, start, &ops); 425 ret = mtd->write_oob(mtd, start, &ops);
426 426
427 if (ops.oobretlen > 0xFFFFFFFFU) 427 if (ops.oobretlen > 0xFFFFFFFFU)
@@ -452,7 +452,7 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
452 return ret; 452 return ret;
453 453
454 ops.ooblen = length; 454 ops.ooblen = length;
455 ops.ooboffs = start & (mtd->oobsize - 1); 455 ops.ooboffs = start & (mtd->writesize - 1);
456 ops.datbuf = NULL; 456 ops.datbuf = NULL;
457 ops.mode = MTD_OOB_PLACE; 457 ops.mode = MTD_OOB_PLACE;
458 458
@@ -463,7 +463,7 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
463 if (!ops.oobbuf) 463 if (!ops.oobbuf)
464 return -ENOMEM; 464 return -ENOMEM;
465 465
466 start &= ~((uint64_t)mtd->oobsize - 1); 466 start &= ~((uint64_t)mtd->writesize - 1);
467 ret = mtd->read_oob(mtd, start, &ops); 467 ret = mtd->read_oob(mtd, start, &ops);
468 468
469 if (put_user(ops.oobretlen, retp)) 469 if (put_user(ops.oobretlen, retp))