diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-09-25 12:12:39 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-09-25 12:12:39 -0400 |
commit | 956e944c7690ea994757a8cbedbb6241e1d9138f (patch) | |
tree | c2c4c3eead457d963583925bbf517f840d40db69 /drivers/mtd/nand | |
parent | 4bf63fcb83dc761853f69a77b15e47712689020b (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.c | 44 |
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, | |||
1323 | static int nand_read_oob(struct mtd_info *mtd, loff_t from, | 1326 | static 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 | */ |
1489 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 1483 | static 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, | |||
1769 | static int nand_write_oob(struct mtd_info *mtd, loff_t to, | 1767 | static 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); |