mtd: nand: invalidate cache on unaligned reads

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Mon Nov 7 11:59:36 EST 2011


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=6d77b9d0af57409c918ab9501866233082546ba6
Commit:     6d77b9d0af57409c918ab9501866233082546ba6
Parent:     752ed6c5f8c0ee182219ff8682f5a98e47ee866f
Author:     Brian Norris <computersforpeace at gmail.com>
AuthorDate: Wed Sep 7 13:13:40 2011 -0700
Committer:  Artem Bityutskiy <artem.bityutskiy at intel.com>
CommitDate: Wed Sep 21 09:19:08 2011 +0300

    mtd: nand: invalidate cache on unaligned reads
    
    In rare cases, we are given an unaligned parameter `from' in
    `nand_do_read_ops()'. In such cases, we use the page cache
    (chip->buffers->databuf) as an intermediate buffer before dumping to the
    client buffer. However, there are also cases where this buffer is not
    cleanly reusable. In those cases, we need to make sure that we
    explicitly invalidate the cache.
    
    This patch prevents accidental reusage of the page cache, and for me,
    this solves some problems I come across when reading a corrupted BBT
    from flash (NAND_BBT_USE_FLASH and NAND_BBT_NO_OOB).
    
    Note: the rare "unaligned" case is a result of the extra BBT pattern +
    version located in the data area instead of OOB.
    
    Also, this patch disables caching on raw reads, since we are reading
    without error correction. This is, obviously, prone to errors and should
    not be cached.
    
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
    Signed-off-by: Artem Bityutskiy <artem.bityutskiy at intel.com>
---
 drivers/mtd/nand/nand_base.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index c9767b5..51653d9 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1479,14 +1479,22 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 			else
 				ret = chip->ecc.read_page(mtd, chip, bufpoi,
 							  page);
-			if (ret < 0)
+			if (ret < 0) {
+				if (!aligned)
+					/* Invalidate page cache */
+					chip->pagebuf = -1;
 				break;
+			}
 
 			/* Transfer not aligned data */
 			if (!aligned) {
 				if (!NAND_SUBPAGE_READ(chip) && !oob &&
-				    !(mtd->ecc_stats.failed - stats.failed))
+				    !(mtd->ecc_stats.failed - stats.failed) &&
+				    (ops->mode != MTD_OPS_RAW))
 					chip->pagebuf = realpage;
+				else
+					/* Invalidate page cache */
+					chip->pagebuf = -1;
 				memcpy(buf, chip->buffers->databuf + col, bytes);
 			}
 



More information about the linux-mtd-cvs mailing list