mtd: do not assume oobsize is power of 2
Linux-MTD Mailing List
linux-mtd at lists.infradead.org
Mon Nov 7 11:59:30 EST 2011
Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=305b93f180b221789a6213bf3d298c6735102da1
Commit: 305b93f180b221789a6213bf3d298c6735102da1
Parent: c97926dd8d7cc094830b253afc817cbf406c0de7
Author: Brian Norris <computersforpeace at gmail.com>
AuthorDate: Tue Aug 23 17:17:32 2011 -0700
Committer: Artem Bityutskiy <artem.bityutskiy at intel.com>
CommitDate: Sun Sep 11 15:02:17 2011 +0300
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 at gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy at intel.com>
---
drivers/mtd/mtdchar.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index a75d555..b206254 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,
return ret;
ops.ooblen = length;
- ops.ooboffs = start & (mtd->oobsize - 1);
+ ops.ooboffs = start & (mtd->writesize - 1);
ops.datbuf = NULL;
ops.mode = MTD_OOB_PLACE;
@@ -421,7 +421,7 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
if (IS_ERR(ops.oobbuf))
return PTR_ERR(ops.oobbuf);
- start &= ~((uint64_t)mtd->oobsize - 1);
+ start &= ~((uint64_t)mtd->writesize - 1);
ret = mtd->write_oob(mtd, start, &ops);
if (ops.oobretlen > 0xFFFFFFFFU)
@@ -452,7 +452,7 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
return ret;
ops.ooblen = length;
- ops.ooboffs = start & (mtd->oobsize - 1);
+ ops.ooboffs = start & (mtd->writesize - 1);
ops.datbuf = NULL;
ops.mode = MTD_OOB_PLACE;
@@ -463,7 +463,7 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
if (!ops.oobbuf)
return -ENOMEM;
- start &= ~((uint64_t)mtd->oobsize - 1);
+ start &= ~((uint64_t)mtd->writesize - 1);
ret = mtd->read_oob(mtd, start, &ops);
if (put_user(ops.oobretlen, retp))
More information about the linux-mtd-cvs
mailing list