diff options
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 407 |
1 files changed, 299 insertions, 108 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d551ddd9537a..a46e9bb847bd 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -42,14 +42,12 @@ | |||
42 | #include <linux/mtd/mtd.h> | 42 | #include <linux/mtd/mtd.h> |
43 | #include <linux/mtd/nand.h> | 43 | #include <linux/mtd/nand.h> |
44 | #include <linux/mtd/nand_ecc.h> | 44 | #include <linux/mtd/nand_ecc.h> |
45 | #include <linux/mtd/nand_bch.h> | ||
45 | #include <linux/interrupt.h> | 46 | #include <linux/interrupt.h> |
46 | #include <linux/bitops.h> | 47 | #include <linux/bitops.h> |
47 | #include <linux/leds.h> | 48 | #include <linux/leds.h> |
48 | #include <asm/io.h> | 49 | #include <linux/io.h> |
49 | |||
50 | #ifdef CONFIG_MTD_PARTITIONS | ||
51 | #include <linux/mtd/partitions.h> | 50 | #include <linux/mtd/partitions.h> |
52 | #endif | ||
53 | 51 | ||
54 | /* Define default oob placement schemes for large and small page devices */ | 52 | /* Define default oob placement schemes for large and small page devices */ |
55 | static struct nand_ecclayout nand_oob_8 = { | 53 | static struct nand_ecclayout nand_oob_8 = { |
@@ -59,7 +57,7 @@ static struct nand_ecclayout nand_oob_8 = { | |||
59 | {.offset = 3, | 57 | {.offset = 3, |
60 | .length = 2}, | 58 | .length = 2}, |
61 | {.offset = 6, | 59 | {.offset = 6, |
62 | .length = 2}} | 60 | .length = 2} } |
63 | }; | 61 | }; |
64 | 62 | ||
65 | static struct nand_ecclayout nand_oob_16 = { | 63 | static struct nand_ecclayout nand_oob_16 = { |
@@ -67,7 +65,7 @@ static struct nand_ecclayout nand_oob_16 = { | |||
67 | .eccpos = {0, 1, 2, 3, 6, 7}, | 65 | .eccpos = {0, 1, 2, 3, 6, 7}, |
68 | .oobfree = { | 66 | .oobfree = { |
69 | {.offset = 8, | 67 | {.offset = 8, |
70 | . length = 8}} | 68 | . length = 8} } |
71 | }; | 69 | }; |
72 | 70 | ||
73 | static struct nand_ecclayout nand_oob_64 = { | 71 | static struct nand_ecclayout nand_oob_64 = { |
@@ -78,7 +76,7 @@ static struct nand_ecclayout nand_oob_64 = { | |||
78 | 56, 57, 58, 59, 60, 61, 62, 63}, | 76 | 56, 57, 58, 59, 60, 61, 62, 63}, |
79 | .oobfree = { | 77 | .oobfree = { |
80 | {.offset = 2, | 78 | {.offset = 2, |
81 | .length = 38}} | 79 | .length = 38} } |
82 | }; | 80 | }; |
83 | 81 | ||
84 | static struct nand_ecclayout nand_oob_128 = { | 82 | static struct nand_ecclayout nand_oob_128 = { |
@@ -92,7 +90,7 @@ static struct nand_ecclayout nand_oob_128 = { | |||
92 | 120, 121, 122, 123, 124, 125, 126, 127}, | 90 | 120, 121, 122, 123, 124, 125, 126, 127}, |
93 | .oobfree = { | 91 | .oobfree = { |
94 | {.offset = 2, | 92 | {.offset = 2, |
95 | .length = 78}} | 93 | .length = 78} } |
96 | }; | 94 | }; |
97 | 95 | ||
98 | static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, | 96 | static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, |
@@ -612,7 +610,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, | |||
612 | NAND_CTRL_CLE | NAND_CTRL_CHANGE); | 610 | NAND_CTRL_CLE | NAND_CTRL_CHANGE); |
613 | chip->cmd_ctrl(mtd, | 611 | chip->cmd_ctrl(mtd, |
614 | NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); | 612 | NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); |
615 | while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ; | 613 | while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) |
614 | ; | ||
616 | return; | 615 | return; |
617 | 616 | ||
618 | /* This applies to read commands */ | 617 | /* This applies to read commands */ |
@@ -718,7 +717,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
718 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); | 717 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); |
719 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, | 718 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, |
720 | NAND_NCE | NAND_CTRL_CHANGE); | 719 | NAND_NCE | NAND_CTRL_CHANGE); |
721 | while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ; | 720 | while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) |
721 | ; | ||
722 | return; | 722 | return; |
723 | 723 | ||
724 | case NAND_CMD_RNDOUT: | 724 | case NAND_CMD_RNDOUT: |
@@ -784,7 +784,7 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) | |||
784 | spinlock_t *lock = &chip->controller->lock; | 784 | spinlock_t *lock = &chip->controller->lock; |
785 | wait_queue_head_t *wq = &chip->controller->wq; | 785 | wait_queue_head_t *wq = &chip->controller->wq; |
786 | DECLARE_WAITQUEUE(wait, current); | 786 | DECLARE_WAITQUEUE(wait, current); |
787 | retry: | 787 | retry: |
788 | spin_lock(lock); | 788 | spin_lock(lock); |
789 | 789 | ||
790 | /* Hardware controller shared among independent devices */ | 790 | /* Hardware controller shared among independent devices */ |
@@ -819,7 +819,7 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) | |||
819 | * | 819 | * |
820 | * Wait for command done. This is a helper function for nand_wait used when | 820 | * Wait for command done. This is a helper function for nand_wait used when |
821 | * we are in interrupt context. May happen when in panic and trying to write | 821 | * we are in interrupt context. May happen when in panic and trying to write |
822 | * an oops trough mtdoops. | 822 | * an oops through mtdoops. |
823 | */ | 823 | */ |
824 | static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip, | 824 | static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip, |
825 | unsigned long timeo) | 825 | unsigned long timeo) |
@@ -834,7 +834,7 @@ static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip, | |||
834 | break; | 834 | break; |
835 | } | 835 | } |
836 | mdelay(1); | 836 | mdelay(1); |
837 | } | 837 | } |
838 | } | 838 | } |
839 | 839 | ||
840 | /** | 840 | /** |
@@ -973,13 +973,11 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
973 | ret = __nand_unlock(mtd, ofs, len, 0); | 973 | ret = __nand_unlock(mtd, ofs, len, 0); |
974 | 974 | ||
975 | out: | 975 | out: |
976 | /* de-select the NAND device */ | ||
977 | chip->select_chip(mtd, -1); | ||
978 | |||
979 | nand_release_device(mtd); | 976 | nand_release_device(mtd); |
980 | 977 | ||
981 | return ret; | 978 | return ret; |
982 | } | 979 | } |
980 | EXPORT_SYMBOL(nand_unlock); | ||
983 | 981 | ||
984 | /** | 982 | /** |
985 | * nand_lock - [REPLACEABLE] locks all blocks present in the device | 983 | * nand_lock - [REPLACEABLE] locks all blocks present in the device |
@@ -1042,13 +1040,11 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
1042 | ret = __nand_unlock(mtd, ofs, len, 0x1); | 1040 | ret = __nand_unlock(mtd, ofs, len, 0x1); |
1043 | 1041 | ||
1044 | out: | 1042 | out: |
1045 | /* de-select the NAND device */ | ||
1046 | chip->select_chip(mtd, -1); | ||
1047 | |||
1048 | nand_release_device(mtd); | 1043 | nand_release_device(mtd); |
1049 | 1044 | ||
1050 | return ret; | 1045 | return ret; |
1051 | } | 1046 | } |
1047 | EXPORT_SYMBOL(nand_lock); | ||
1052 | 1048 | ||
1053 | /** | 1049 | /** |
1054 | * nand_read_page_raw - [Intern] read raw page data without ecc | 1050 | * nand_read_page_raw - [Intern] read raw page data without ecc |
@@ -1076,8 +1072,9 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1076 | * | 1072 | * |
1077 | * We need a special oob layout and handling even when OOB isn't used. | 1073 | * We need a special oob layout and handling even when OOB isn't used. |
1078 | */ | 1074 | */ |
1079 | static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | 1075 | static int nand_read_page_raw_syndrome(struct mtd_info *mtd, |
1080 | uint8_t *buf, int page) | 1076 | struct nand_chip *chip, |
1077 | uint8_t *buf, int page) | ||
1081 | { | 1078 | { |
1082 | int eccsize = chip->ecc.size; | 1079 | int eccsize = chip->ecc.size; |
1083 | int eccbytes = chip->ecc.bytes; | 1080 | int eccbytes = chip->ecc.bytes; |
@@ -1158,7 +1155,8 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1158 | * @readlen: data length | 1155 | * @readlen: data length |
1159 | * @bufpoi: buffer to store read data | 1156 | * @bufpoi: buffer to store read data |
1160 | */ | 1157 | */ |
1161 | static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi) | 1158 | static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, |
1159 | uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi) | ||
1162 | { | 1160 | { |
1163 | int start_step, end_step, num_steps; | 1161 | int start_step, end_step, num_steps; |
1164 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 1162 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
@@ -1166,6 +1164,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3 | |||
1166 | int data_col_addr, i, gaps = 0; | 1164 | int data_col_addr, i, gaps = 0; |
1167 | int datafrag_len, eccfrag_len, aligned_len, aligned_pos; | 1165 | int datafrag_len, eccfrag_len, aligned_len, aligned_pos; |
1168 | int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; | 1166 | int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; |
1167 | int index = 0; | ||
1169 | 1168 | ||
1170 | /* Column address wihin the page aligned to ECC size (256bytes). */ | 1169 | /* Column address wihin the page aligned to ECC size (256bytes). */ |
1171 | start_step = data_offs / chip->ecc.size; | 1170 | start_step = data_offs / chip->ecc.size; |
@@ -1204,26 +1203,30 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3 | |||
1204 | } else { | 1203 | } else { |
1205 | /* send the command to read the particular ecc bytes */ | 1204 | /* send the command to read the particular ecc bytes */ |
1206 | /* take care about buswidth alignment in read_buf */ | 1205 | /* take care about buswidth alignment in read_buf */ |
1207 | aligned_pos = eccpos[start_step * chip->ecc.bytes] & ~(busw - 1); | 1206 | index = start_step * chip->ecc.bytes; |
1207 | |||
1208 | aligned_pos = eccpos[index] & ~(busw - 1); | ||
1208 | aligned_len = eccfrag_len; | 1209 | aligned_len = eccfrag_len; |
1209 | if (eccpos[start_step * chip->ecc.bytes] & (busw - 1)) | 1210 | if (eccpos[index] & (busw - 1)) |
1210 | aligned_len++; | 1211 | aligned_len++; |
1211 | if (eccpos[(start_step + num_steps) * chip->ecc.bytes] & (busw - 1)) | 1212 | if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1)) |
1212 | aligned_len++; | 1213 | aligned_len++; |
1213 | 1214 | ||
1214 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize + aligned_pos, -1); | 1215 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, |
1216 | mtd->writesize + aligned_pos, -1); | ||
1215 | chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len); | 1217 | chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len); |
1216 | } | 1218 | } |
1217 | 1219 | ||
1218 | for (i = 0; i < eccfrag_len; i++) | 1220 | for (i = 0; i < eccfrag_len; i++) |
1219 | chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + start_step * chip->ecc.bytes]]; | 1221 | chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]]; |
1220 | 1222 | ||
1221 | p = bufpoi + data_col_addr; | 1223 | p = bufpoi + data_col_addr; |
1222 | for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) { | 1224 | for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) { |
1223 | int stat; | 1225 | int stat; |
1224 | 1226 | ||
1225 | stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); | 1227 | stat = chip->ecc.correct(mtd, p, |
1226 | if (stat == -1) | 1228 | &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); |
1229 | if (stat < 0) | ||
1227 | mtd->ecc_stats.failed++; | 1230 | mtd->ecc_stats.failed++; |
1228 | else | 1231 | else |
1229 | mtd->ecc_stats.corrected += stat; | 1232 | mtd->ecc_stats.corrected += stat; |
@@ -1390,7 +1393,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | |||
1390 | static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, | 1393 | static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, |
1391 | struct mtd_oob_ops *ops, size_t len) | 1394 | struct mtd_oob_ops *ops, size_t len) |
1392 | { | 1395 | { |
1393 | switch(ops->mode) { | 1396 | switch (ops->mode) { |
1394 | 1397 | ||
1395 | case MTD_OOB_PLACE: | 1398 | case MTD_OOB_PLACE: |
1396 | case MTD_OOB_RAW: | 1399 | case MTD_OOB_RAW: |
@@ -1402,7 +1405,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, | |||
1402 | uint32_t boffs = 0, roffs = ops->ooboffs; | 1405 | uint32_t boffs = 0, roffs = ops->ooboffs; |
1403 | size_t bytes = 0; | 1406 | size_t bytes = 0; |
1404 | 1407 | ||
1405 | for(; free->length && len; free++, len -= bytes) { | 1408 | for (; free->length && len; free++, len -= bytes) { |
1406 | /* Read request not from offset 0 ? */ | 1409 | /* Read request not from offset 0 ? */ |
1407 | if (unlikely(roffs)) { | 1410 | if (unlikely(roffs)) { |
1408 | if (roffs >= free->length) { | 1411 | if (roffs >= free->length) { |
@@ -1466,7 +1469,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1466 | buf = ops->datbuf; | 1469 | buf = ops->datbuf; |
1467 | oob = ops->oobbuf; | 1470 | oob = ops->oobbuf; |
1468 | 1471 | ||
1469 | while(1) { | 1472 | while (1) { |
1470 | bytes = min(mtd->writesize - col, readlen); | 1473 | bytes = min(mtd->writesize - col, readlen); |
1471 | aligned = (bytes == mtd->writesize); | 1474 | aligned = (bytes == mtd->writesize); |
1472 | 1475 | ||
@@ -1484,7 +1487,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1484 | ret = chip->ecc.read_page_raw(mtd, chip, | 1487 | ret = chip->ecc.read_page_raw(mtd, chip, |
1485 | bufpoi, page); | 1488 | bufpoi, page); |
1486 | else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob) | 1489 | else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob) |
1487 | ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi); | 1490 | ret = chip->ecc.read_subpage(mtd, chip, |
1491 | col, bytes, bufpoi); | ||
1488 | else | 1492 | else |
1489 | ret = chip->ecc.read_page(mtd, chip, bufpoi, | 1493 | ret = chip->ecc.read_page(mtd, chip, bufpoi, |
1490 | page); | 1494 | page); |
@@ -1493,7 +1497,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1493 | 1497 | ||
1494 | /* Transfer not aligned data */ | 1498 | /* Transfer not aligned data */ |
1495 | if (!aligned) { | 1499 | if (!aligned) { |
1496 | if (!NAND_SUBPAGE_READ(chip) && !oob) | 1500 | if (!NAND_SUBPAGE_READ(chip) && !oob && |
1501 | !(mtd->ecc_stats.failed - stats.failed)) | ||
1497 | chip->pagebuf = realpage; | 1502 | chip->pagebuf = realpage; |
1498 | memcpy(buf, chip->buffers->databuf + col, bytes); | 1503 | memcpy(buf, chip->buffers->databuf + col, bytes); |
1499 | } | 1504 | } |
@@ -1568,7 +1573,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1568 | } | 1573 | } |
1569 | 1574 | ||
1570 | /** | 1575 | /** |
1571 | * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc | 1576 | * nand_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc |
1572 | * @mtd: MTD device structure | 1577 | * @mtd: MTD device structure |
1573 | * @from: offset to read from | 1578 | * @from: offset to read from |
1574 | * @len: number of bytes to read | 1579 | * @len: number of bytes to read |
@@ -1791,7 +1796,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
1791 | realpage = (int)(from >> chip->page_shift); | 1796 | realpage = (int)(from >> chip->page_shift); |
1792 | page = realpage & chip->pagemask; | 1797 | page = realpage & chip->pagemask; |
1793 | 1798 | ||
1794 | while(1) { | 1799 | while (1) { |
1795 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); | 1800 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); |
1796 | 1801 | ||
1797 | len = min(len, readlen); | 1802 | len = min(len, readlen); |
@@ -1861,7 +1866,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, | |||
1861 | 1866 | ||
1862 | nand_get_device(chip, mtd, FL_READING); | 1867 | nand_get_device(chip, mtd, FL_READING); |
1863 | 1868 | ||
1864 | switch(ops->mode) { | 1869 | switch (ops->mode) { |
1865 | case MTD_OOB_PLACE: | 1870 | case MTD_OOB_PLACE: |
1866 | case MTD_OOB_AUTO: | 1871 | case MTD_OOB_AUTO: |
1867 | case MTD_OOB_RAW: | 1872 | case MTD_OOB_RAW: |
@@ -1876,7 +1881,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, | |||
1876 | else | 1881 | else |
1877 | ret = nand_do_read_ops(mtd, from, ops); | 1882 | ret = nand_do_read_ops(mtd, from, ops); |
1878 | 1883 | ||
1879 | out: | 1884 | out: |
1880 | nand_release_device(mtd); | 1885 | nand_release_device(mtd); |
1881 | return ret; | 1886 | return ret; |
1882 | } | 1887 | } |
@@ -1905,8 +1910,9 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1905 | * | 1910 | * |
1906 | * We need a special oob layout and handling even when ECC isn't checked. | 1911 | * We need a special oob layout and handling even when ECC isn't checked. |
1907 | */ | 1912 | */ |
1908 | static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | 1913 | static void nand_write_page_raw_syndrome(struct mtd_info *mtd, |
1909 | const uint8_t *buf) | 1914 | struct nand_chip *chip, |
1915 | const uint8_t *buf) | ||
1910 | { | 1916 | { |
1911 | int eccsize = chip->ecc.size; | 1917 | int eccsize = chip->ecc.size; |
1912 | int eccbytes = chip->ecc.bytes; | 1918 | int eccbytes = chip->ecc.bytes; |
@@ -2099,7 +2105,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
2099 | static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, | 2105 | static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, |
2100 | struct mtd_oob_ops *ops) | 2106 | struct mtd_oob_ops *ops) |
2101 | { | 2107 | { |
2102 | switch(ops->mode) { | 2108 | switch (ops->mode) { |
2103 | 2109 | ||
2104 | case MTD_OOB_PLACE: | 2110 | case MTD_OOB_PLACE: |
2105 | case MTD_OOB_RAW: | 2111 | case MTD_OOB_RAW: |
@@ -2111,7 +2117,7 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, | |||
2111 | uint32_t boffs = 0, woffs = ops->ooboffs; | 2117 | uint32_t boffs = 0, woffs = ops->ooboffs; |
2112 | size_t bytes = 0; | 2118 | size_t bytes = 0; |
2113 | 2119 | ||
2114 | for(; free->length && len; free++, len -= bytes) { | 2120 | for (; free->length && len; free++, len -= bytes) { |
2115 | /* Write request not from offset 0 ? */ | 2121 | /* Write request not from offset 0 ? */ |
2116 | if (unlikely(woffs)) { | 2122 | if (unlikely(woffs)) { |
2117 | if (woffs >= free->length) { | 2123 | if (woffs >= free->length) { |
@@ -2137,7 +2143,7 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, | |||
2137 | return NULL; | 2143 | return NULL; |
2138 | } | 2144 | } |
2139 | 2145 | ||
2140 | #define NOTALIGNED(x) (x & (chip->subpagesize - 1)) != 0 | 2146 | #define NOTALIGNED(x) ((x & (chip->subpagesize - 1)) != 0) |
2141 | 2147 | ||
2142 | /** | 2148 | /** |
2143 | * nand_do_write_ops - [Internal] NAND write with ECC | 2149 | * nand_do_write_ops - [Internal] NAND write with ECC |
@@ -2200,10 +2206,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
2200 | memset(chip->oob_poi, 0xff, mtd->oobsize); | 2206 | memset(chip->oob_poi, 0xff, mtd->oobsize); |
2201 | 2207 | ||
2202 | /* Don't allow multipage oob writes with offset */ | 2208 | /* Don't allow multipage oob writes with offset */ |
2203 | if (ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) | 2209 | if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) |
2204 | return -EINVAL; | 2210 | return -EINVAL; |
2205 | 2211 | ||
2206 | while(1) { | 2212 | while (1) { |
2207 | int bytes = mtd->writesize; | 2213 | int bytes = mtd->writesize; |
2208 | int cached = writelen > bytes && page != blockmask; | 2214 | int cached = writelen > bytes && page != blockmask; |
2209 | uint8_t *wbuf = buf; | 2215 | uint8_t *wbuf = buf; |
@@ -2363,7 +2369,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
2363 | return -EINVAL; | 2369 | return -EINVAL; |
2364 | } | 2370 | } |
2365 | 2371 | ||
2366 | /* Do not allow reads past end of device */ | 2372 | /* Do not allow write past end of device */ |
2367 | if (unlikely(to >= mtd->size || | 2373 | if (unlikely(to >= mtd->size || |
2368 | ops->ooboffs + ops->ooblen > | 2374 | ops->ooboffs + ops->ooblen > |
2369 | ((mtd->size >> chip->page_shift) - | 2375 | ((mtd->size >> chip->page_shift) - |
@@ -2431,7 +2437,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, | |||
2431 | 2437 | ||
2432 | nand_get_device(chip, mtd, FL_WRITING); | 2438 | nand_get_device(chip, mtd, FL_WRITING); |
2433 | 2439 | ||
2434 | switch(ops->mode) { | 2440 | switch (ops->mode) { |
2435 | case MTD_OOB_PLACE: | 2441 | case MTD_OOB_PLACE: |
2436 | case MTD_OOB_AUTO: | 2442 | case MTD_OOB_AUTO: |
2437 | case MTD_OOB_RAW: | 2443 | case MTD_OOB_RAW: |
@@ -2446,7 +2452,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, | |||
2446 | else | 2452 | else |
2447 | ret = nand_do_write_ops(mtd, to, ops); | 2453 | ret = nand_do_write_ops(mtd, to, ops); |
2448 | 2454 | ||
2449 | out: | 2455 | out: |
2450 | nand_release_device(mtd); | 2456 | nand_release_device(mtd); |
2451 | return ret; | 2457 | return ret; |
2452 | } | 2458 | } |
@@ -2511,7 +2517,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, | |||
2511 | { | 2517 | { |
2512 | int page, status, pages_per_block, ret, chipnr; | 2518 | int page, status, pages_per_block, ret, chipnr; |
2513 | struct nand_chip *chip = mtd->priv; | 2519 | struct nand_chip *chip = mtd->priv; |
2514 | loff_t rewrite_bbt[NAND_MAX_CHIPS]={0}; | 2520 | loff_t rewrite_bbt[NAND_MAX_CHIPS] = {0}; |
2515 | unsigned int bbt_masked_page = 0xffffffff; | 2521 | unsigned int bbt_masked_page = 0xffffffff; |
2516 | loff_t len; | 2522 | loff_t len; |
2517 | 2523 | ||
@@ -2632,7 +2638,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, | |||
2632 | } | 2638 | } |
2633 | instr->state = MTD_ERASE_DONE; | 2639 | instr->state = MTD_ERASE_DONE; |
2634 | 2640 | ||
2635 | erase_exit: | 2641 | erase_exit: |
2636 | 2642 | ||
2637 | ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; | 2643 | ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; |
2638 | 2644 | ||
@@ -2706,7 +2712,8 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
2706 | struct nand_chip *chip = mtd->priv; | 2712 | struct nand_chip *chip = mtd->priv; |
2707 | int ret; | 2713 | int ret; |
2708 | 2714 | ||
2709 | if ((ret = nand_block_isbad(mtd, ofs))) { | 2715 | ret = nand_block_isbad(mtd, ofs); |
2716 | if (ret) { | ||
2710 | /* If it was bad already, return success and do nothing. */ | 2717 | /* If it was bad already, return success and do nothing. */ |
2711 | if (ret > 0) | 2718 | if (ret > 0) |
2712 | return 0; | 2719 | return 0; |
@@ -2787,15 +2794,119 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) | |||
2787 | } | 2794 | } |
2788 | 2795 | ||
2789 | /* | 2796 | /* |
2797 | * sanitize ONFI strings so we can safely print them | ||
2798 | */ | ||
2799 | static void sanitize_string(uint8_t *s, size_t len) | ||
2800 | { | ||
2801 | ssize_t i; | ||
2802 | |||
2803 | /* null terminate */ | ||
2804 | s[len - 1] = 0; | ||
2805 | |||
2806 | /* remove non printable chars */ | ||
2807 | for (i = 0; i < len - 1; i++) { | ||
2808 | if (s[i] < ' ' || s[i] > 127) | ||
2809 | s[i] = '?'; | ||
2810 | } | ||
2811 | |||
2812 | /* remove trailing spaces */ | ||
2813 | strim(s); | ||
2814 | } | ||
2815 | |||
2816 | static u16 onfi_crc16(u16 crc, u8 const *p, size_t len) | ||
2817 | { | ||
2818 | int i; | ||
2819 | while (len--) { | ||
2820 | crc ^= *p++ << 8; | ||
2821 | for (i = 0; i < 8; i++) | ||
2822 | crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0); | ||
2823 | } | ||
2824 | |||
2825 | return crc; | ||
2826 | } | ||
2827 | |||
2828 | /* | ||
2829 | * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise | ||
2830 | */ | ||
2831 | static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | ||
2832 | int busw) | ||
2833 | { | ||
2834 | struct nand_onfi_params *p = &chip->onfi_params; | ||
2835 | int i; | ||
2836 | int val; | ||
2837 | |||
2838 | /* try ONFI for unknow chip or LP */ | ||
2839 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); | ||
2840 | if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || | ||
2841 | chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') | ||
2842 | return 0; | ||
2843 | |||
2844 | printk(KERN_INFO "ONFI flash detected\n"); | ||
2845 | chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); | ||
2846 | for (i = 0; i < 3; i++) { | ||
2847 | chip->read_buf(mtd, (uint8_t *)p, sizeof(*p)); | ||
2848 | if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) == | ||
2849 | le16_to_cpu(p->crc)) { | ||
2850 | printk(KERN_INFO "ONFI param page %d valid\n", i); | ||
2851 | break; | ||
2852 | } | ||
2853 | } | ||
2854 | |||
2855 | if (i == 3) | ||
2856 | return 0; | ||
2857 | |||
2858 | /* check version */ | ||
2859 | val = le16_to_cpu(p->revision); | ||
2860 | if (val & (1 << 5)) | ||
2861 | chip->onfi_version = 23; | ||
2862 | else if (val & (1 << 4)) | ||
2863 | chip->onfi_version = 22; | ||
2864 | else if (val & (1 << 3)) | ||
2865 | chip->onfi_version = 21; | ||
2866 | else if (val & (1 << 2)) | ||
2867 | chip->onfi_version = 20; | ||
2868 | else if (val & (1 << 1)) | ||
2869 | chip->onfi_version = 10; | ||
2870 | else | ||
2871 | chip->onfi_version = 0; | ||
2872 | |||
2873 | if (!chip->onfi_version) { | ||
2874 | printk(KERN_INFO "%s: unsupported ONFI version: %d\n", | ||
2875 | __func__, val); | ||
2876 | return 0; | ||
2877 | } | ||
2878 | |||
2879 | sanitize_string(p->manufacturer, sizeof(p->manufacturer)); | ||
2880 | sanitize_string(p->model, sizeof(p->model)); | ||
2881 | if (!mtd->name) | ||
2882 | mtd->name = p->model; | ||
2883 | mtd->writesize = le32_to_cpu(p->byte_per_page); | ||
2884 | mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; | ||
2885 | mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); | ||
2886 | chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; | ||
2887 | busw = 0; | ||
2888 | if (le16_to_cpu(p->features) & 1) | ||
2889 | busw = NAND_BUSWIDTH_16; | ||
2890 | |||
2891 | chip->options &= ~NAND_CHIPOPTIONS_MSK; | ||
2892 | chip->options |= (NAND_NO_READRDY | | ||
2893 | NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK; | ||
2894 | |||
2895 | return 1; | ||
2896 | } | ||
2897 | |||
2898 | /* | ||
2790 | * Get the flash and manufacturer id and lookup if the type is supported | 2899 | * Get the flash and manufacturer id and lookup if the type is supported |
2791 | */ | 2900 | */ |
2792 | static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | 2901 | static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, |
2793 | struct nand_chip *chip, | 2902 | struct nand_chip *chip, |
2794 | int busw, int *maf_id, | 2903 | int busw, |
2904 | int *maf_id, int *dev_id, | ||
2795 | struct nand_flash_dev *type) | 2905 | struct nand_flash_dev *type) |
2796 | { | 2906 | { |
2797 | int i, dev_id, maf_idx; | 2907 | int i, maf_idx; |
2798 | u8 id_data[8]; | 2908 | u8 id_data[8]; |
2909 | int ret; | ||
2799 | 2910 | ||
2800 | /* Select the device */ | 2911 | /* Select the device */ |
2801 | chip->select_chip(mtd, 0); | 2912 | chip->select_chip(mtd, 0); |
@@ -2811,7 +2922,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2811 | 2922 | ||
2812 | /* Read manufacturer and device IDs */ | 2923 | /* Read manufacturer and device IDs */ |
2813 | *maf_id = chip->read_byte(mtd); | 2924 | *maf_id = chip->read_byte(mtd); |
2814 | dev_id = chip->read_byte(mtd); | 2925 | *dev_id = chip->read_byte(mtd); |
2815 | 2926 | ||
2816 | /* Try again to make sure, as some systems the bus-hold or other | 2927 | /* Try again to make sure, as some systems the bus-hold or other |
2817 | * interface concerns can cause random data which looks like a | 2928 | * interface concerns can cause random data which looks like a |
@@ -2821,15 +2932,13 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2821 | 2932 | ||
2822 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | 2933 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
2823 | 2934 | ||
2824 | /* Read entire ID string */ | 2935 | for (i = 0; i < 2; i++) |
2825 | |||
2826 | for (i = 0; i < 8; i++) | ||
2827 | id_data[i] = chip->read_byte(mtd); | 2936 | id_data[i] = chip->read_byte(mtd); |
2828 | 2937 | ||
2829 | if (id_data[0] != *maf_id || id_data[1] != dev_id) { | 2938 | if (id_data[0] != *maf_id || id_data[1] != *dev_id) { |
2830 | printk(KERN_INFO "%s: second ID read did not match " | 2939 | printk(KERN_INFO "%s: second ID read did not match " |
2831 | "%02x,%02x against %02x,%02x\n", __func__, | 2940 | "%02x,%02x against %02x,%02x\n", __func__, |
2832 | *maf_id, dev_id, id_data[0], id_data[1]); | 2941 | *maf_id, *dev_id, id_data[0], id_data[1]); |
2833 | return ERR_PTR(-ENODEV); | 2942 | return ERR_PTR(-ENODEV); |
2834 | } | 2943 | } |
2835 | 2944 | ||
@@ -2837,8 +2946,23 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2837 | type = nand_flash_ids; | 2946 | type = nand_flash_ids; |
2838 | 2947 | ||
2839 | for (; type->name != NULL; type++) | 2948 | for (; type->name != NULL; type++) |
2840 | if (dev_id == type->id) | 2949 | if (*dev_id == type->id) |
2841 | break; | 2950 | break; |
2951 | |||
2952 | chip->onfi_version = 0; | ||
2953 | if (!type->name || !type->pagesize) { | ||
2954 | /* Check is chip is ONFI compliant */ | ||
2955 | ret = nand_flash_detect_onfi(mtd, chip, busw); | ||
2956 | if (ret) | ||
2957 | goto ident_done; | ||
2958 | } | ||
2959 | |||
2960 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | ||
2961 | |||
2962 | /* Read entire ID string */ | ||
2963 | |||
2964 | for (i = 0; i < 8; i++) | ||
2965 | id_data[i] = chip->read_byte(mtd); | ||
2842 | 2966 | ||
2843 | if (!type->name) | 2967 | if (!type->name) |
2844 | return ERR_PTR(-ENODEV); | 2968 | return ERR_PTR(-ENODEV); |
@@ -2848,8 +2972,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2848 | 2972 | ||
2849 | chip->chipsize = (uint64_t)type->chipsize << 20; | 2973 | chip->chipsize = (uint64_t)type->chipsize << 20; |
2850 | 2974 | ||
2851 | /* Newer devices have all the information in additional id bytes */ | 2975 | if (!type->pagesize && chip->init_size) { |
2852 | if (!type->pagesize) { | 2976 | /* set the pagesize, oobsize, erasesize by the driver*/ |
2977 | busw = chip->init_size(mtd, chip, id_data); | ||
2978 | } else if (!type->pagesize) { | ||
2853 | int extid; | 2979 | int extid; |
2854 | /* The 3rd id byte holds MLC / multichip data */ | 2980 | /* The 3rd id byte holds MLC / multichip data */ |
2855 | chip->cellinfo = id_data[2]; | 2981 | chip->cellinfo = id_data[2]; |
@@ -2859,7 +2985,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2859 | /* | 2985 | /* |
2860 | * Field definitions are in the following datasheets: | 2986 | * Field definitions are in the following datasheets: |
2861 | * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) | 2987 | * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) |
2862 | * New style (6 byte ID): Samsung K9GAG08U0D (p.40) | 2988 | * New style (6 byte ID): Samsung K9GBG08U0M (p.40) |
2863 | * | 2989 | * |
2864 | * Check for wraparound + Samsung ID + nonzero 6th byte | 2990 | * Check for wraparound + Samsung ID + nonzero 6th byte |
2865 | * to decide what to do. | 2991 | * to decide what to do. |
@@ -2872,7 +2998,20 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2872 | mtd->writesize = 2048 << (extid & 0x03); | 2998 | mtd->writesize = 2048 << (extid & 0x03); |
2873 | extid >>= 2; | 2999 | extid >>= 2; |
2874 | /* Calc oobsize */ | 3000 | /* Calc oobsize */ |
2875 | mtd->oobsize = (extid & 0x03) == 0x01 ? 128 : 218; | 3001 | switch (extid & 0x03) { |
3002 | case 1: | ||
3003 | mtd->oobsize = 128; | ||
3004 | break; | ||
3005 | case 2: | ||
3006 | mtd->oobsize = 218; | ||
3007 | break; | ||
3008 | case 3: | ||
3009 | mtd->oobsize = 400; | ||
3010 | break; | ||
3011 | default: | ||
3012 | mtd->oobsize = 436; | ||
3013 | break; | ||
3014 | } | ||
2876 | extid >>= 2; | 3015 | extid >>= 2; |
2877 | /* Calc blocksize */ | 3016 | /* Calc blocksize */ |
2878 | mtd->erasesize = (128 * 1024) << | 3017 | mtd->erasesize = (128 * 1024) << |
@@ -2900,7 +3039,35 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2900 | mtd->writesize = type->pagesize; | 3039 | mtd->writesize = type->pagesize; |
2901 | mtd->oobsize = mtd->writesize / 32; | 3040 | mtd->oobsize = mtd->writesize / 32; |
2902 | busw = type->options & NAND_BUSWIDTH_16; | 3041 | busw = type->options & NAND_BUSWIDTH_16; |
3042 | |||
3043 | /* | ||
3044 | * Check for Spansion/AMD ID + repeating 5th, 6th byte since | ||
3045 | * some Spansion chips have erasesize that conflicts with size | ||
3046 | * listed in nand_ids table | ||
3047 | * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39) | ||
3048 | */ | ||
3049 | if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 && | ||
3050 | id_data[5] == 0x00 && id_data[6] == 0x00 && | ||
3051 | id_data[7] == 0x00 && mtd->writesize == 512) { | ||
3052 | mtd->erasesize = 128 * 1024; | ||
3053 | mtd->erasesize <<= ((id_data[3] & 0x03) << 1); | ||
3054 | } | ||
2903 | } | 3055 | } |
3056 | /* Get chip options, preserve non chip based options */ | ||
3057 | chip->options &= ~NAND_CHIPOPTIONS_MSK; | ||
3058 | chip->options |= type->options & NAND_CHIPOPTIONS_MSK; | ||
3059 | |||
3060 | /* Check if chip is a not a samsung device. Do not clear the | ||
3061 | * options for chips which are not having an extended id. | ||
3062 | */ | ||
3063 | if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) | ||
3064 | chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; | ||
3065 | ident_done: | ||
3066 | |||
3067 | /* | ||
3068 | * Set chip as a default. Board drivers can override it, if necessary | ||
3069 | */ | ||
3070 | chip->options |= NAND_NO_AUTOINCR; | ||
2904 | 3071 | ||
2905 | /* Try to identify manufacturer */ | 3072 | /* Try to identify manufacturer */ |
2906 | for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) { | 3073 | for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) { |
@@ -2915,7 +3082,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2915 | if (busw != (chip->options & NAND_BUSWIDTH_16)) { | 3082 | if (busw != (chip->options & NAND_BUSWIDTH_16)) { |
2916 | printk(KERN_INFO "NAND device: Manufacturer ID:" | 3083 | printk(KERN_INFO "NAND device: Manufacturer ID:" |
2917 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, | 3084 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, |
2918 | dev_id, nand_manuf_ids[maf_idx].name, mtd->name); | 3085 | *dev_id, nand_manuf_ids[maf_idx].name, mtd->name); |
2919 | printk(KERN_WARNING "NAND bus width %d instead %d bit\n", | 3086 | printk(KERN_WARNING "NAND bus width %d instead %d bit\n", |
2920 | (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, | 3087 | (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, |
2921 | busw ? 16 : 8); | 3088 | busw ? 16 : 8); |
@@ -2931,8 +3098,12 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2931 | ffs(mtd->erasesize) - 1; | 3098 | ffs(mtd->erasesize) - 1; |
2932 | if (chip->chipsize & 0xffffffff) | 3099 | if (chip->chipsize & 0xffffffff) |
2933 | chip->chip_shift = ffs((unsigned)chip->chipsize) - 1; | 3100 | chip->chip_shift = ffs((unsigned)chip->chipsize) - 1; |
2934 | else | 3101 | else { |
2935 | chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1; | 3102 | chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)); |
3103 | chip->chip_shift += 32 - 1; | ||
3104 | } | ||
3105 | |||
3106 | chip->badblockbits = 8; | ||
2936 | 3107 | ||
2937 | /* Set the bad block position */ | 3108 | /* Set the bad block position */ |
2938 | if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16)) | 3109 | if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16)) |
@@ -2940,27 +3111,12 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2940 | else | 3111 | else |
2941 | chip->badblockpos = NAND_SMALL_BADBLOCK_POS; | 3112 | chip->badblockpos = NAND_SMALL_BADBLOCK_POS; |
2942 | 3113 | ||
2943 | /* Get chip options, preserve non chip based options */ | ||
2944 | chip->options &= ~NAND_CHIPOPTIONS_MSK; | ||
2945 | chip->options |= type->options & NAND_CHIPOPTIONS_MSK; | ||
2946 | |||
2947 | /* | ||
2948 | * Set chip as a default. Board drivers can override it, if necessary | ||
2949 | */ | ||
2950 | chip->options |= NAND_NO_AUTOINCR; | ||
2951 | |||
2952 | /* Check if chip is a not a samsung device. Do not clear the | ||
2953 | * options for chips which are not having an extended id. | ||
2954 | */ | ||
2955 | if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) | ||
2956 | chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; | ||
2957 | |||
2958 | /* | 3114 | /* |
2959 | * Bad block marker is stored in the last page of each block | 3115 | * Bad block marker is stored in the last page of each block |
2960 | * on Samsung and Hynix MLC devices; stored in first two pages | 3116 | * on Samsung and Hynix MLC devices; stored in first two pages |
2961 | * of each block on Micron devices with 2KiB pages and on | 3117 | * of each block on Micron devices with 2KiB pages and on |
2962 | * SLC Samsung, Hynix, and AMD/Spansion. All others scan only | 3118 | * SLC Samsung, Hynix, Toshiba and AMD/Spansion. All others scan |
2963 | * the first page. | 3119 | * only the first page. |
2964 | */ | 3120 | */ |
2965 | if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) && | 3121 | if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) && |
2966 | (*maf_id == NAND_MFR_SAMSUNG || | 3122 | (*maf_id == NAND_MFR_SAMSUNG || |
@@ -2969,6 +3125,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2969 | else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) && | 3125 | else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) && |
2970 | (*maf_id == NAND_MFR_SAMSUNG || | 3126 | (*maf_id == NAND_MFR_SAMSUNG || |
2971 | *maf_id == NAND_MFR_HYNIX || | 3127 | *maf_id == NAND_MFR_HYNIX || |
3128 | *maf_id == NAND_MFR_TOSHIBA || | ||
2972 | *maf_id == NAND_MFR_AMD)) || | 3129 | *maf_id == NAND_MFR_AMD)) || |
2973 | (mtd->writesize == 2048 && | 3130 | (mtd->writesize == 2048 && |
2974 | *maf_id == NAND_MFR_MICRON)) | 3131 | *maf_id == NAND_MFR_MICRON)) |
@@ -2994,9 +3151,11 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2994 | if (mtd->writesize > 512 && chip->cmdfunc == nand_command) | 3151 | if (mtd->writesize > 512 && chip->cmdfunc == nand_command) |
2995 | chip->cmdfunc = nand_command_lp; | 3152 | chip->cmdfunc = nand_command_lp; |
2996 | 3153 | ||
3154 | /* TODO onfi flash name */ | ||
2997 | printk(KERN_INFO "NAND device: Manufacturer ID:" | 3155 | printk(KERN_INFO "NAND device: Manufacturer ID:" |
2998 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, | 3156 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id, |
2999 | nand_manuf_ids[maf_idx].name, type->name); | 3157 | nand_manuf_ids[maf_idx].name, |
3158 | chip->onfi_version ? chip->onfi_params.model : type->name); | ||
3000 | 3159 | ||
3001 | return type; | 3160 | return type; |
3002 | } | 3161 | } |
@@ -3015,7 +3174,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
3015 | int nand_scan_ident(struct mtd_info *mtd, int maxchips, | 3174 | int nand_scan_ident(struct mtd_info *mtd, int maxchips, |
3016 | struct nand_flash_dev *table) | 3175 | struct nand_flash_dev *table) |
3017 | { | 3176 | { |
3018 | int i, busw, nand_maf_id; | 3177 | int i, busw, nand_maf_id, nand_dev_id; |
3019 | struct nand_chip *chip = mtd->priv; | 3178 | struct nand_chip *chip = mtd->priv; |
3020 | struct nand_flash_dev *type; | 3179 | struct nand_flash_dev *type; |
3021 | 3180 | ||
@@ -3025,7 +3184,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
3025 | nand_set_defaults(chip, busw); | 3184 | nand_set_defaults(chip, busw); |
3026 | 3185 | ||
3027 | /* Read the flash type */ | 3186 | /* Read the flash type */ |
3028 | type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, table); | 3187 | type = nand_get_flash_type(mtd, chip, busw, |
3188 | &nand_maf_id, &nand_dev_id, table); | ||
3029 | 3189 | ||
3030 | if (IS_ERR(type)) { | 3190 | if (IS_ERR(type)) { |
3031 | if (!(chip->options & NAND_SCAN_SILENT_NODEV)) | 3191 | if (!(chip->options & NAND_SCAN_SILENT_NODEV)) |
@@ -3043,7 +3203,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
3043 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | 3203 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
3044 | /* Read manufacturer and device IDs */ | 3204 | /* Read manufacturer and device IDs */ |
3045 | if (nand_maf_id != chip->read_byte(mtd) || | 3205 | if (nand_maf_id != chip->read_byte(mtd) || |
3046 | type->id != chip->read_byte(mtd)) | 3206 | nand_dev_id != chip->read_byte(mtd)) |
3047 | break; | 3207 | break; |
3048 | } | 3208 | } |
3049 | if (i > 1) | 3209 | if (i > 1) |
@@ -3055,6 +3215,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
3055 | 3215 | ||
3056 | return 0; | 3216 | return 0; |
3057 | } | 3217 | } |
3218 | EXPORT_SYMBOL(nand_scan_ident); | ||
3058 | 3219 | ||
3059 | 3220 | ||
3060 | /** | 3221 | /** |
@@ -3081,7 +3242,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3081 | /* | 3242 | /* |
3082 | * If no default placement scheme is given, select an appropriate one | 3243 | * If no default placement scheme is given, select an appropriate one |
3083 | */ | 3244 | */ |
3084 | if (!chip->ecc.layout) { | 3245 | if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) { |
3085 | switch (mtd->oobsize) { | 3246 | switch (mtd->oobsize) { |
3086 | case 8: | 3247 | case 8: |
3087 | chip->ecc.layout = &nand_oob_8; | 3248 | chip->ecc.layout = &nand_oob_8; |
@@ -3184,6 +3345,40 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3184 | chip->ecc.bytes = 3; | 3345 | chip->ecc.bytes = 3; |
3185 | break; | 3346 | break; |
3186 | 3347 | ||
3348 | case NAND_ECC_SOFT_BCH: | ||
3349 | if (!mtd_nand_has_bch()) { | ||
3350 | printk(KERN_WARNING "CONFIG_MTD_ECC_BCH not enabled\n"); | ||
3351 | BUG(); | ||
3352 | } | ||
3353 | chip->ecc.calculate = nand_bch_calculate_ecc; | ||
3354 | chip->ecc.correct = nand_bch_correct_data; | ||
3355 | chip->ecc.read_page = nand_read_page_swecc; | ||
3356 | chip->ecc.read_subpage = nand_read_subpage; | ||
3357 | chip->ecc.write_page = nand_write_page_swecc; | ||
3358 | chip->ecc.read_page_raw = nand_read_page_raw; | ||
3359 | chip->ecc.write_page_raw = nand_write_page_raw; | ||
3360 | chip->ecc.read_oob = nand_read_oob_std; | ||
3361 | chip->ecc.write_oob = nand_write_oob_std; | ||
3362 | /* | ||
3363 | * Board driver should supply ecc.size and ecc.bytes values to | ||
3364 | * select how many bits are correctable; see nand_bch_init() | ||
3365 | * for details. | ||
3366 | * Otherwise, default to 4 bits for large page devices | ||
3367 | */ | ||
3368 | if (!chip->ecc.size && (mtd->oobsize >= 64)) { | ||
3369 | chip->ecc.size = 512; | ||
3370 | chip->ecc.bytes = 7; | ||
3371 | } | ||
3372 | chip->ecc.priv = nand_bch_init(mtd, | ||
3373 | chip->ecc.size, | ||
3374 | chip->ecc.bytes, | ||
3375 | &chip->ecc.layout); | ||
3376 | if (!chip->ecc.priv) { | ||
3377 | printk(KERN_WARNING "BCH ECC initialization failed!\n"); | ||
3378 | BUG(); | ||
3379 | } | ||
3380 | break; | ||
3381 | |||
3187 | case NAND_ECC_NONE: | 3382 | case NAND_ECC_NONE: |
3188 | printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " | 3383 | printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " |
3189 | "This is not recommended !!\n"); | 3384 | "This is not recommended !!\n"); |
@@ -3219,7 +3414,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3219 | * mode | 3414 | * mode |
3220 | */ | 3415 | */ |
3221 | chip->ecc.steps = mtd->writesize / chip->ecc.size; | 3416 | chip->ecc.steps = mtd->writesize / chip->ecc.size; |
3222 | if(chip->ecc.steps * chip->ecc.size != mtd->writesize) { | 3417 | if (chip->ecc.steps * chip->ecc.size != mtd->writesize) { |
3223 | printk(KERN_WARNING "Invalid ecc parameters\n"); | 3418 | printk(KERN_WARNING "Invalid ecc parameters\n"); |
3224 | BUG(); | 3419 | BUG(); |
3225 | } | 3420 | } |
@@ -3231,7 +3426,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3231 | */ | 3426 | */ |
3232 | if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && | 3427 | if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && |
3233 | !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) { | 3428 | !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) { |
3234 | switch(chip->ecc.steps) { | 3429 | switch (chip->ecc.steps) { |
3235 | case 2: | 3430 | case 2: |
3236 | mtd->subpage_sft = 1; | 3431 | mtd->subpage_sft = 1; |
3237 | break; | 3432 | break; |
@@ -3272,6 +3467,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3272 | mtd->resume = nand_resume; | 3467 | mtd->resume = nand_resume; |
3273 | mtd->block_isbad = nand_block_isbad; | 3468 | mtd->block_isbad = nand_block_isbad; |
3274 | mtd->block_markbad = nand_block_markbad; | 3469 | mtd->block_markbad = nand_block_markbad; |
3470 | mtd->writebufsize = mtd->writesize; | ||
3275 | 3471 | ||
3276 | /* propagate ecc.layout to mtd_info */ | 3472 | /* propagate ecc.layout to mtd_info */ |
3277 | mtd->ecclayout = chip->ecc.layout; | 3473 | mtd->ecclayout = chip->ecc.layout; |
@@ -3283,10 +3479,11 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3283 | /* Build bad block table */ | 3479 | /* Build bad block table */ |
3284 | return chip->scan_bbt(mtd); | 3480 | return chip->scan_bbt(mtd); |
3285 | } | 3481 | } |
3482 | EXPORT_SYMBOL(nand_scan_tail); | ||
3286 | 3483 | ||
3287 | /* is_module_text_address() isn't exported, and it's mostly a pointless | 3484 | /* is_module_text_address() isn't exported, and it's mostly a pointless |
3288 | test if this is a module _anyway_ -- they'd have to try _really_ hard | 3485 | * test if this is a module _anyway_ -- they'd have to try _really_ hard |
3289 | to call us from in-kernel code if the core NAND support is modular. */ | 3486 | * to call us from in-kernel code if the core NAND support is modular. */ |
3290 | #ifdef MODULE | 3487 | #ifdef MODULE |
3291 | #define caller_is_module() (1) | 3488 | #define caller_is_module() (1) |
3292 | #else | 3489 | #else |
@@ -3322,6 +3519,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
3322 | ret = nand_scan_tail(mtd); | 3519 | ret = nand_scan_tail(mtd); |
3323 | return ret; | 3520 | return ret; |
3324 | } | 3521 | } |
3522 | EXPORT_SYMBOL(nand_scan); | ||
3325 | 3523 | ||
3326 | /** | 3524 | /** |
3327 | * nand_release - [NAND Interface] Free resources held by the NAND device | 3525 | * nand_release - [NAND Interface] Free resources held by the NAND device |
@@ -3331,12 +3529,10 @@ void nand_release(struct mtd_info *mtd) | |||
3331 | { | 3529 | { |
3332 | struct nand_chip *chip = mtd->priv; | 3530 | struct nand_chip *chip = mtd->priv; |
3333 | 3531 | ||
3334 | #ifdef CONFIG_MTD_PARTITIONS | 3532 | if (chip->ecc.mode == NAND_ECC_SOFT_BCH) |
3335 | /* Deregister partitions */ | 3533 | nand_bch_free((struct nand_bch_control *)chip->ecc.priv); |
3336 | del_mtd_partitions(mtd); | 3534 | |
3337 | #endif | 3535 | mtd_device_unregister(mtd); |
3338 | /* Deregister the device */ | ||
3339 | del_mtd_device(mtd); | ||
3340 | 3536 | ||
3341 | /* Free bad block table memory */ | 3537 | /* Free bad block table memory */ |
3342 | kfree(chip->bbt); | 3538 | kfree(chip->bbt); |
@@ -3348,12 +3544,6 @@ void nand_release(struct mtd_info *mtd) | |||
3348 | & NAND_BBT_DYNAMICSTRUCT) | 3544 | & NAND_BBT_DYNAMICSTRUCT) |
3349 | kfree(chip->badblock_pattern); | 3545 | kfree(chip->badblock_pattern); |
3350 | } | 3546 | } |
3351 | |||
3352 | EXPORT_SYMBOL_GPL(nand_lock); | ||
3353 | EXPORT_SYMBOL_GPL(nand_unlock); | ||
3354 | EXPORT_SYMBOL_GPL(nand_scan); | ||
3355 | EXPORT_SYMBOL_GPL(nand_scan_ident); | ||
3356 | EXPORT_SYMBOL_GPL(nand_scan_tail); | ||
3357 | EXPORT_SYMBOL_GPL(nand_release); | 3547 | EXPORT_SYMBOL_GPL(nand_release); |
3358 | 3548 | ||
3359 | static int __init nand_base_init(void) | 3549 | static int __init nand_base_init(void) |
@@ -3371,5 +3561,6 @@ module_init(nand_base_init); | |||
3371 | module_exit(nand_base_exit); | 3561 | module_exit(nand_base_exit); |
3372 | 3562 | ||
3373 | MODULE_LICENSE("GPL"); | 3563 | MODULE_LICENSE("GPL"); |
3374 | MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); | 3564 | MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>"); |
3565 | MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>"); | ||
3375 | MODULE_DESCRIPTION("Generic NAND flash driver code"); | 3566 | MODULE_DESCRIPTION("Generic NAND flash driver code"); |