aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-09-25 12:12:39 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-09-25 12:12:39 -0400
commit956e944c7690ea994757a8cbedbb6241e1d9138f (patch)
treec2c4c3eead457d963583925bbf517f840d40db69 /drivers/mtd/nand
parent4bf63fcb83dc761853f69a77b15e47712689020b (diff)
[MTD NAND] Allow override of page read and write functions.
- allow high-level nand_write_page() function to be overridden - likewise low-level write_page_raw() and read_page_raw() functions - Clean up the abuse of chip->ecc.{write,read}_page() with MTD_OOB_RAW Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/nand_base.c44
1 files changed, 21 insertions, 23 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e1e81a9543e8..baece61169f4 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -990,7 +990,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
990 } 990 }
991 991
992 /* Now read the page into the buffer */ 992 /* Now read the page into the buffer */
993 ret = chip->ecc.read_page(mtd, chip, bufpoi); 993 if (unlikely(ops->mode == MTD_OOB_RAW))
994 ret = chip->ecc.read_page_raw(mtd, chip, bufpoi);
995 else
996 ret = chip->ecc.read_page(mtd, chip, bufpoi);
994 if (ret < 0) 997 if (ret < 0)
995 break; 998 break;
996 999
@@ -1323,8 +1326,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1323static int nand_read_oob(struct mtd_info *mtd, loff_t from, 1326static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1324 struct mtd_oob_ops *ops) 1327 struct mtd_oob_ops *ops)
1325{ 1328{
1326 int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
1327 uint8_t *buf) = NULL;
1328 struct nand_chip *chip = mtd->priv; 1329 struct nand_chip *chip = mtd->priv;
1329 int ret = -ENOTSUPP; 1330 int ret = -ENOTSUPP;
1330 1331
@@ -1342,12 +1343,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1342 switch(ops->mode) { 1343 switch(ops->mode) {
1343 case MTD_OOB_PLACE: 1344 case MTD_OOB_PLACE:
1344 case MTD_OOB_AUTO: 1345 case MTD_OOB_AUTO:
1345 break;
1346
1347 case MTD_OOB_RAW: 1346 case MTD_OOB_RAW:
1348 /* Replace the read_page algorithm temporary */
1349 read_page = chip->ecc.read_page;
1350 chip->ecc.read_page = nand_read_page_raw;
1351 break; 1347 break;
1352 1348
1353 default: 1349 default:
@@ -1359,8 +1355,6 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1359 else 1355 else
1360 ret = nand_do_read_ops(mtd, from, ops); 1356 ret = nand_do_read_ops(mtd, from, ops);
1361 1357
1362 if (unlikely(ops->mode == MTD_OOB_RAW))
1363 chip->ecc.read_page = read_page;
1364 out: 1358 out:
1365 nand_release_device(mtd); 1359 nand_release_device(mtd);
1366 return ret; 1360 return ret;
@@ -1479,7 +1473,7 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
1479} 1473}
1480 1474
1481/** 1475/**
1482 * nand_write_page - [INTERNAL] write one page 1476 * nand_write_page - [REPLACEABLE] write one page
1483 * @mtd: MTD device structure 1477 * @mtd: MTD device structure
1484 * @chip: NAND chip descriptor 1478 * @chip: NAND chip descriptor
1485 * @buf: the data to write 1479 * @buf: the data to write
@@ -1487,13 +1481,16 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
1487 * @cached: cached programming 1481 * @cached: cached programming
1488 */ 1482 */
1489static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, 1483static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
1490 const uint8_t *buf, int page, int cached) 1484 const uint8_t *buf, int page, int cached, int raw)
1491{ 1485{
1492 int status; 1486 int status;
1493 1487
1494 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); 1488 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
1495 1489
1496 chip->ecc.write_page(mtd, chip, buf); 1490 if (unlikely(raw))
1491 chip->ecc.write_page_raw(mtd, chip, buf);
1492 else
1493 chip->ecc.write_page(mtd, chip, buf);
1497 1494
1498 /* 1495 /*
1499 * Cached progamming disabled for now, Not sure if its worth the 1496 * Cached progamming disabled for now, Not sure if its worth the
@@ -1636,7 +1633,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
1636 if (unlikely(oob)) 1633 if (unlikely(oob))
1637 oob = nand_fill_oob(chip, oob, ops); 1634 oob = nand_fill_oob(chip, oob, ops);
1638 1635
1639 ret = nand_write_page(mtd, chip, buf, page, cached); 1636 ret = chip->write_page(mtd, chip, buf, page, cached,
1637 (ops->mode == MTD_OOB_RAW));
1640 if (ret) 1638 if (ret)
1641 break; 1639 break;
1642 1640
@@ -1769,8 +1767,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1769static int nand_write_oob(struct mtd_info *mtd, loff_t to, 1767static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1770 struct mtd_oob_ops *ops) 1768 struct mtd_oob_ops *ops)
1771{ 1769{
1772 void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
1773 const uint8_t *buf) = NULL;
1774 struct nand_chip *chip = mtd->priv; 1770 struct nand_chip *chip = mtd->priv;
1775 int ret = -ENOTSUPP; 1771 int ret = -ENOTSUPP;
1776 1772
@@ -1788,12 +1784,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1788 switch(ops->mode) { 1784 switch(ops->mode) {
1789 case MTD_OOB_PLACE: 1785 case MTD_OOB_PLACE:
1790 case MTD_OOB_AUTO: 1786 case MTD_OOB_AUTO:
1791 break;
1792
1793 case MTD_OOB_RAW: 1787 case MTD_OOB_RAW:
1794 /* Replace the write_page algorithm temporary */
1795 write_page = chip->ecc.write_page;
1796 chip->ecc.write_page = nand_write_page_raw;
1797 break; 1788 break;
1798 1789
1799 default: 1790 default:
@@ -1805,8 +1796,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1805 else 1796 else
1806 ret = nand_do_write_ops(mtd, to, ops); 1797 ret = nand_do_write_ops(mtd, to, ops);
1807 1798
1808 if (unlikely(ops->mode == MTD_OOB_RAW))
1809 chip->ecc.write_page = write_page;
1810 out: 1799 out:
1811 nand_release_device(mtd); 1800 nand_release_device(mtd);
1812 return ret; 1801 return ret;
@@ -2383,10 +2372,18 @@ int nand_scan_tail(struct mtd_info *mtd)
2383 } 2372 }
2384 } 2373 }
2385 2374
2375 if (!chip->write_page)
2376 chip->write_page = nand_write_page;
2377
2386 /* 2378 /*
2387 * check ECC mode, default to software if 3byte/512byte hardware ECC is 2379 * check ECC mode, default to software if 3byte/512byte hardware ECC is
2388 * selected and we have 256 byte pagesize fallback to software ECC 2380 * selected and we have 256 byte pagesize fallback to software ECC
2389 */ 2381 */
2382 if (!chip->ecc.read_page_raw)
2383 chip->ecc.read_page_raw = nand_read_page_raw;
2384 if (!chip->ecc.write_page_raw)
2385 chip->ecc.write_page_raw = nand_write_page_raw;
2386
2390 switch (chip->ecc.mode) { 2387 switch (chip->ecc.mode) {
2391 case NAND_ECC_HW: 2388 case NAND_ECC_HW:
2392 /* Use standard hwecc read page function ? */ 2389 /* Use standard hwecc read page function ? */
@@ -2444,6 +2441,7 @@ int nand_scan_tail(struct mtd_info *mtd)
2444 chip->ecc.size = mtd->writesize; 2441 chip->ecc.size = mtd->writesize;
2445 chip->ecc.bytes = 0; 2442 chip->ecc.bytes = 0;
2446 break; 2443 break;
2444
2447 default: 2445 default:
2448 printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", 2446 printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
2449 chip->ecc.mode); 2447 chip->ecc.mode);