aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2011-09-07 16:13:40 -0400
committerArtem Bityutskiy <artem.bityutskiy@intel.com>2011-09-21 02:19:08 -0400
commit6d77b9d0af57409c918ab9501866233082546ba6 (patch)
tree7229784e41ddbc35861bed96c3203e9d90e50e54 /drivers
parent752ed6c5f8c0ee182219ff8682f5a98e47ee866f (diff)
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@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/nand_base.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index c9767b511dfe..51653d9e1438 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,
1479 else 1479 else
1480 ret = chip->ecc.read_page(mtd, chip, bufpoi, 1480 ret = chip->ecc.read_page(mtd, chip, bufpoi,
1481 page); 1481 page);
1482 if (ret < 0) 1482 if (ret < 0) {
1483 if (!aligned)
1484 /* Invalidate page cache */
1485 chip->pagebuf = -1;
1483 break; 1486 break;
1487 }
1484 1488
1485 /* Transfer not aligned data */ 1489 /* Transfer not aligned data */
1486 if (!aligned) { 1490 if (!aligned) {
1487 if (!NAND_SUBPAGE_READ(chip) && !oob && 1491 if (!NAND_SUBPAGE_READ(chip) && !oob &&
1488 !(mtd->ecc_stats.failed - stats.failed)) 1492 !(mtd->ecc_stats.failed - stats.failed) &&
1493 (ops->mode != MTD_OPS_RAW))
1489 chip->pagebuf = realpage; 1494 chip->pagebuf = realpage;
1495 else
1496 /* Invalidate page cache */
1497 chip->pagebuf = -1;
1490 memcpy(buf, chip->buffers->databuf + col, bytes); 1498 memcpy(buf, chip->buffers->databuf + col, bytes);
1491 } 1499 }
1492 1500