aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@cruncher.tec.linutronix.de>2006-06-20 14:05:05 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-06-20 15:31:24 -0400
commit7bc3312bef4d6f220812500c0de7868fb7625a41 (patch)
tree9ad49e850cdfe9868a19a37681bbf4d403e47ed3 /drivers
parent7e4178f90eec862affc97469118d5008bd1b5bda (diff)
[MTD] NAND: Fix breakage all over the place
Following problems are addressed: - wrong status caused early break out of nand_wait() - removed the bogus status check in nand_wait() which is a relict of the abandoned support for interrupted erase. - status check moved to the correct place in read_oob - oob support for syndrom based ecc with strange layouts - use given offset in the AUTOOOB based oob operations Partially based on a patch from Vitaly Vool <vwool@ru.mvista.com> Thanks to Savin Zlobec <savin@epico.si> for tracking down the status problem. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/mtdchar.c8
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/mtd/nand/nand_base.c297
3 files changed, 220 insertions, 87 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 5dd0b8d72c8b..aa18d45b264b 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -504,12 +504,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
504 return ret; 504 return ret;
505 505
506 ops.len = buf.length; 506 ops.len = buf.length;
507 ops.ooblen = mtd->oobsize; 507 ops.ooblen = buf.length;
508 ops.ooboffs = buf.start & (mtd->oobsize - 1); 508 ops.ooboffs = buf.start & (mtd->oobsize - 1);
509 ops.datbuf = NULL; 509 ops.datbuf = NULL;
510 ops.mode = MTD_OOB_PLACE; 510 ops.mode = MTD_OOB_PLACE;
511 511
512 if (ops.ooboffs && ops.len > (ops.ooblen - ops.ooboffs)) 512 if (ops.ooboffs && ops.len > (mtd->oobsize - ops.ooboffs))
513 return -EINVAL; 513 return -EINVAL;
514 514
515 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); 515 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);
@@ -553,12 +553,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
553 return ret; 553 return ret;
554 554
555 ops.len = buf.length; 555 ops.len = buf.length;
556 ops.ooblen = mtd->oobsize; 556 ops.ooblen = buf.length;
557 ops.ooboffs = buf.start & (mtd->oobsize - 1); 557 ops.ooboffs = buf.start & (mtd->oobsize - 1);
558 ops.datbuf = NULL; 558 ops.datbuf = NULL;
559 ops.mode = MTD_OOB_PLACE; 559 ops.mode = MTD_OOB_PLACE;
560 560
561 if (ops.ooboffs && ops.len > (ops.ooblen - ops.ooboffs)) 561 if (ops.ooboffs && ops.len > (mtd->oobsize - ops.ooboffs))
562 return -EINVAL; 562 return -EINVAL;
563 563
564 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); 564 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 463e12ced1b3..6107f532855b 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -464,7 +464,7 @@ static void __init doc2000_count_chips(struct mtd_info *mtd)
464 printk(KERN_DEBUG "Detected %d chips per floor.\n", i); 464 printk(KERN_DEBUG "Detected %d chips per floor.\n", i);
465} 465}
466 466
467static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state) 467static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this)
468{ 468{
469 struct doc_priv *doc = this->priv; 469 struct doc_priv *doc = this->priv;
470 470
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e74678e928cf..27083ed0a017 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -501,7 +501,6 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
501 case NAND_CMD_ERASE2: 501 case NAND_CMD_ERASE2:
502 case NAND_CMD_SEQIN: 502 case NAND_CMD_SEQIN:
503 case NAND_CMD_STATUS: 503 case NAND_CMD_STATUS:
504 chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE);
505 return; 504 return;
506 505
507 case NAND_CMD_RESET: 506 case NAND_CMD_RESET:
@@ -595,6 +594,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
595 case NAND_CMD_ERASE1: 594 case NAND_CMD_ERASE1:
596 case NAND_CMD_ERASE2: 595 case NAND_CMD_ERASE2:
597 case NAND_CMD_SEQIN: 596 case NAND_CMD_SEQIN:
597 case NAND_CMD_RNDIN:
598 case NAND_CMD_STATUS: 598 case NAND_CMD_STATUS:
599 case NAND_CMD_DEPLETE1: 599 case NAND_CMD_DEPLETE1:
600 return; 600 return;
@@ -621,6 +621,14 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
621 while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ; 621 while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ;
622 return; 622 return;
623 623
624 case NAND_CMD_RNDOUT:
625 /* No ready / busy check necessary */
626 chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART,
627 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
628 chip->cmd_ctrl(mtd, NAND_CMD_NONE,
629 NAND_NCE | NAND_CTRL_CHANGE);
630 return;
631
624 case NAND_CMD_READ0: 632 case NAND_CMD_READ0:
625 chip->cmd_ctrl(mtd, NAND_CMD_READSTART, 633 chip->cmd_ctrl(mtd, NAND_CMD_READSTART,
626 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); 634 NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
@@ -689,18 +697,17 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
689 * nand_wait - [DEFAULT] wait until the command is done 697 * nand_wait - [DEFAULT] wait until the command is done
690 * @mtd: MTD device structure 698 * @mtd: MTD device structure
691 * @this: NAND chip structure 699 * @this: NAND chip structure
692 * @state: state to select the max. timeout value
693 * 700 *
694 * Wait for command done. This applies to erase and program only 701 * Wait for command done. This applies to erase and program only
695 * Erase can take up to 400ms and program up to 20ms according to 702 * Erase can take up to 400ms and program up to 20ms according to
696 * general NAND and SmartMedia specs 703 * general NAND and SmartMedia specs
697 * 704 *
698*/ 705*/
699static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip, int state) 706static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
700{ 707{
701 708
702 unsigned long timeo = jiffies; 709 unsigned long timeo = jiffies;
703 int status; 710 int status, state = chip->state;
704 711
705 if (state == FL_ERASING) 712 if (state == FL_ERASING)
706 timeo += (HZ * 400) / 1000; 713 timeo += (HZ * 400) / 1000;
@@ -719,10 +726,6 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip, int state)
719 chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); 726 chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
720 727
721 while (time_before(jiffies, timeo)) { 728 while (time_before(jiffies, timeo)) {
722 /* Check, if we were interrupted */
723 if (chip->state != state)
724 return 0;
725
726 if (chip->dev_ready) { 729 if (chip->dev_ready) {
727 if (chip->dev_ready(mtd)) 730 if (chip->dev_ready(mtd))
728 break; 731 break;
@@ -909,12 +912,25 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
909 912
910 case MTD_OOB_AUTO: { 913 case MTD_OOB_AUTO: {
911 struct nand_oobfree *free = chip->ecc.layout->oobfree; 914 struct nand_oobfree *free = chip->ecc.layout->oobfree;
912 size_t bytes; 915 uint32_t boffs = 0, roffs = ops->ooboffs;
916 size_t bytes = 0;
913 917
914 for(; free->length && len; free++, len -= bytes) { 918 for(; free->length && len; free++, len -= bytes) {
915 bytes = min_t(size_t, len, free->length); 919 /* Read request not from offset 0 ? */
916 920 if (unlikely(roffs)) {
917 memcpy(oob, chip->oob_poi + free->offset, bytes); 921 if (roffs >= free->length) {
922 roffs -= free->length;
923 continue;
924 }
925 boffs = free->offset + roffs;
926 bytes = min_t(size_t, len,
927 (free->length - roffs));
928 roffs = 0;
929 } else {
930 bytes = min_t(size_t, len, free->length);
931 boffs = free->offset;
932 }
933 memcpy(oob, chip->oob_poi + boffs, bytes);
918 oob += bytes; 934 oob += bytes;
919 } 935 }
920 return oob; 936 return oob;
@@ -1084,6 +1100,145 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
1084} 1100}
1085 1101
1086/** 1102/**
1103 * nand_read_oob_std - [REPLACABLE] the most common OOB data read function
1104 * @mtd: mtd info structure
1105 * @chip: nand chip info structure
1106 * @page: page number to read
1107 * @sndcmd: flag whether to issue read command or not
1108 */
1109static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
1110 int page, int sndcmd)
1111{
1112 if (sndcmd) {
1113 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
1114 sndcmd = 0;
1115 }
1116 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
1117 return sndcmd;
1118}
1119
1120/**
1121 * nand_read_oob_syndrome - [REPLACABLE] OOB data read function for HW ECC
1122 * with syndromes
1123 * @mtd: mtd info structure
1124 * @chip: nand chip info structure
1125 * @page: page number to read
1126 * @sndcmd: flag whether to issue read command or not
1127 */
1128static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1129 int page, int sndcmd)
1130{
1131 uint8_t *buf = chip->oob_poi;
1132 int length = mtd->oobsize;
1133 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
1134 int eccsize = chip->ecc.size;
1135 uint8_t *bufpoi = buf;
1136 int i, toread, sndrnd = 0, pos;
1137
1138 chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page);
1139 for (i = 0; i < chip->ecc.steps; i++) {
1140 if (sndrnd) {
1141 pos = eccsize + i * (eccsize + chunk);
1142 if (mtd->writesize > 512)
1143 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, pos, -1);
1144 else
1145 chip->cmdfunc(mtd, NAND_CMD_READ0, pos, page);
1146 } else
1147 sndrnd = 1;
1148 toread = min_t(int, length, chunk);
1149 chip->read_buf(mtd, bufpoi, toread);
1150 bufpoi += toread;
1151 length -= toread;
1152 }
1153 if (length > 0)
1154 chip->read_buf(mtd, bufpoi, length);
1155
1156 return 1;
1157}
1158
1159/**
1160 * nand_write_oob_std - [REPLACABLE] the most common OOB data write function
1161 * @mtd: mtd info structure
1162 * @chip: nand chip info structure
1163 * @page: page number to write
1164 */
1165static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
1166 int page)
1167{
1168 int status = 0;
1169 const uint8_t *buf = chip->oob_poi;
1170 int length = mtd->oobsize;
1171
1172 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
1173 chip->write_buf(mtd, buf, length);
1174 /* Send command to program the OOB data */
1175 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1176
1177 status = chip->waitfunc(mtd, chip);
1178
1179 return status;
1180}
1181
1182/**
1183 * nand_write_oob_syndrome - [REPLACABLE] OOB data write function for HW ECC
1184 * with syndrome - only for large page flash !
1185 * @mtd: mtd info structure
1186 * @chip: nand chip info structure
1187 * @page: page number to write
1188 */
1189static int nand_write_oob_syndrome(struct mtd_info *mtd,
1190 struct nand_chip *chip, int page)
1191{
1192 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
1193 int eccsize = chip->ecc.size, length = mtd->oobsize;
1194 int i, len, pos, status = 0, sndcmd = 0, steps = chip->ecc.steps;
1195 const uint8_t *bufpoi = chip->oob_poi;
1196
1197 /*
1198 * data-ecc-data-ecc ... ecc-oob
1199 * or
1200 * data-pad-ecc-pad-data-pad .... ecc-pad-oob
1201 */
1202 if (!chip->ecc.prepad && !chip->ecc.postpad) {
1203 pos = steps * (eccsize + chunk);
1204 steps = 0;
1205 } else
1206 pos = eccsize + chunk;
1207
1208 chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page);
1209 for (i = 0; i < steps; i++) {
1210 if (sndcmd) {
1211 if (mtd->writesize <= 512) {
1212 uint32_t fill = 0xFFFFFFFF;
1213
1214 len = eccsize;
1215 while (len > 0) {
1216 int num = min_t(int, len, 4);
1217 chip->write_buf(mtd, (uint8_t *)&fill,
1218 num);
1219 len -= num;
1220 }
1221 } else {
1222 pos = eccsize + i * (eccsize + chunk);
1223 chip->cmdfunc(mtd, NAND_CMD_RNDIN, pos, -1);
1224 }
1225 } else
1226 sndcmd = 1;
1227 len = min_t(int, length, chunk);
1228 chip->write_buf(mtd, bufpoi, len);
1229 bufpoi += len;
1230 length -= len;
1231 }
1232 if (length > 0)
1233 chip->write_buf(mtd, bufpoi, length);
1234
1235 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1236 status = chip->waitfunc(mtd, chip);
1237
1238 return status & NAND_STATUS_FAIL ? -EIO : 0;
1239}
1240
1241/**
1087 * nand_do_read_oob - [Intern] NAND read out-of-band 1242 * nand_do_read_oob - [Intern] NAND read out-of-band
1088 * @mtd: MTD device structure 1243 * @mtd: MTD device structure
1089 * @from: offset to read from 1244 * @from: offset to read from
@@ -1094,11 +1249,11 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
1094static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, 1249static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1095 struct mtd_oob_ops *ops) 1250 struct mtd_oob_ops *ops)
1096{ 1251{
1097 int col, page, realpage, chipnr, sndcmd = 1; 1252 int page, realpage, chipnr, sndcmd = 1;
1098 struct nand_chip *chip = mtd->priv; 1253 struct nand_chip *chip = mtd->priv;
1099 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; 1254 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
1100 int direct, bytes, readlen = ops->len; 1255 int readlen = ops->len;
1101 uint8_t *bufpoi, *buf = ops->oobbuf; 1256 uint8_t *buf = ops->oobbuf;
1102 1257
1103 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n", 1258 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n",
1104 (unsigned long long)from, readlen); 1259 (unsigned long long)from, readlen);
@@ -1110,29 +1265,11 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1110 realpage = (int)(from >> chip->page_shift); 1265 realpage = (int)(from >> chip->page_shift);
1111 page = realpage & chip->pagemask; 1266 page = realpage & chip->pagemask;
1112 1267
1113 if (ops->mode != MTD_OOB_AUTO) { 1268 chip->oob_poi = chip->buffers.oobrbuf;
1114 col = ops->ooboffs;
1115 direct = 1;
1116 } else {
1117 col = 0;
1118 direct = 0;
1119 }
1120 1269
1121 while(1) { 1270 while(1) {
1122 bytes = direct ? ops->ooblen : mtd->oobsize; 1271 sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
1123 bufpoi = direct ? buf : chip->buffers.oobrbuf; 1272 buf = nand_transfer_oob(chip, buf, ops);
1124
1125 if (likely(sndcmd)) {
1126 chip->cmdfunc(mtd, NAND_CMD_READOOB, col, page);
1127 sndcmd = 0;
1128 }
1129
1130 chip->read_buf(mtd, bufpoi, bytes);
1131
1132 if (unlikely(!direct))
1133 buf = nand_transfer_oob(chip, buf, ops);
1134 else
1135 buf += ops->ooblen;
1136 1273
1137 readlen -= ops->ooblen; 1274 readlen -= ops->ooblen;
1138 if (!readlen) 1275 if (!readlen)
@@ -1365,7 +1502,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
1365 if (!cached || !(chip->options & NAND_CACHEPRG)) { 1502 if (!cached || !(chip->options & NAND_CACHEPRG)) {
1366 1503
1367 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); 1504 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1368 status = chip->waitfunc(mtd, chip, FL_WRITING); 1505 status = chip->waitfunc(mtd, chip);
1369 /* 1506 /*
1370 * See if operation failed and additional status checks are 1507 * See if operation failed and additional status checks are
1371 * available 1508 * available
@@ -1378,7 +1515,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
1378 return -EIO; 1515 return -EIO;
1379 } else { 1516 } else {
1380 chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1); 1517 chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1);
1381 status = chip->waitfunc(mtd, chip, FL_WRITING); 1518 status = chip->waitfunc(mtd, chip);
1382 } 1519 }
1383 1520
1384#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 1521#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
@@ -1411,11 +1548,25 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
1411 1548
1412 case MTD_OOB_AUTO: { 1549 case MTD_OOB_AUTO: {
1413 struct nand_oobfree *free = chip->ecc.layout->oobfree; 1550 struct nand_oobfree *free = chip->ecc.layout->oobfree;
1414 size_t bytes; 1551 uint32_t boffs = 0, woffs = ops->ooboffs;
1552 size_t bytes = 0;
1415 1553
1416 for(; free->length && len; free++, len -= bytes) { 1554 for(; free->length && len; free++, len -= bytes) {
1417 bytes = min_t(size_t, len, free->length); 1555 /* Write request not from offset 0 ? */
1418 memcpy(chip->oob_poi + free->offset, oob, bytes); 1556 if (unlikely(woffs)) {
1557 if (woffs >= free->length) {
1558 woffs -= free->length;
1559 continue;
1560 }
1561 boffs = free->offset + woffs;
1562 bytes = min_t(size_t, len,
1563 (free->length - woffs));
1564 woffs = 0;
1565 } else {
1566 bytes = min_t(size_t, len, free->length);
1567 boffs = free->offset;
1568 }
1569 memcpy(chip->oob_poi + woffs, oob, bytes);
1419 oob += bytes; 1570 oob += bytes;
1420 } 1571 }
1421 return oob; 1572 return oob;
@@ -1532,7 +1683,7 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
1532 if (!len) 1683 if (!len)
1533 return 0; 1684 return 0;
1534 1685
1535 nand_get_device(chip, mtd, FL_READING); 1686 nand_get_device(chip, mtd, FL_WRITING);
1536 1687
1537 chip->ops.len = len; 1688 chip->ops.len = len;
1538 chip->ops.datbuf = (uint8_t *)buf; 1689 chip->ops.datbuf = (uint8_t *)buf;
@@ -1592,48 +1743,18 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1592 if (page == chip->pagebuf) 1743 if (page == chip->pagebuf)
1593 chip->pagebuf = -1; 1744 chip->pagebuf = -1;
1594 1745
1595 if (ops->mode == MTD_OOB_AUTO || NAND_MUST_PAD(chip)) { 1746 chip->oob_poi = chip->buffers.oobwbuf;
1596 chip->oob_poi = chip->buffers.oobwbuf; 1747 memset(chip->oob_poi, 0xff, mtd->oobsize);
1597 memset(chip->oob_poi, 0xff, mtd->oobsize); 1748 nand_fill_oob(chip, ops->oobbuf, ops);
1598 nand_fill_oob(chip, ops->oobbuf, ops); 1749 status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
1599 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, 1750 memset(chip->oob_poi, 0xff, mtd->oobsize);
1600 page & chip->pagemask);
1601 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1602 memset(chip->oob_poi, 0xff, mtd->oobsize);
1603 } else {
1604 chip->cmdfunc(mtd, NAND_CMD_SEQIN,
1605 mtd->writesize + ops->ooboffs,
1606 page & chip->pagemask);
1607 chip->write_buf(mtd, ops->oobbuf, ops->len);
1608 }
1609
1610 /* Send command to program the OOB data */
1611 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1612 1751
1613 status = chip->waitfunc(mtd, chip, FL_WRITING); 1752 if (status)
1753 return status;
1614 1754
1615 /* See if device thinks it succeeded */
1616 if (status & NAND_STATUS_FAIL) {
1617 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1618 "Failed write, page 0x%08x\n", page);
1619 return -EIO;
1620 }
1621 ops->retlen = ops->len; 1755 ops->retlen = ops->len;
1622 1756
1623#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 1757 return 0;
1624 if (ops->mode != MTD_OOB_AUTO) {
1625 /* Send command to read back the data */
1626 chip->cmdfunc(mtd, NAND_CMD_READOOB, ops->ooboffs,
1627 page & chip->pagemask);
1628
1629 if (chip->verify_buf(mtd, ops->oobbuf, ops->len)) {
1630 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1631 "Failed write verify, page 0x%08x\n", page);
1632 return -EIO;
1633 }
1634 }
1635#endif
1636 return 0;
1637} 1758}
1638 1759
1639/** 1760/**
@@ -1659,7 +1780,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1659 return -EINVAL; 1780 return -EINVAL;
1660 } 1781 }
1661 1782
1662 nand_get_device(chip, mtd, FL_READING); 1783 nand_get_device(chip, mtd, FL_WRITING);
1663 1784
1664 switch(ops->mode) { 1785 switch(ops->mode) {
1665 case MTD_OOB_PLACE: 1786 case MTD_OOB_PLACE:
@@ -1833,7 +1954,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
1833 1954
1834 chip->erase_cmd(mtd, page & chip->pagemask); 1955 chip->erase_cmd(mtd, page & chip->pagemask);
1835 1956
1836 status = chip->waitfunc(mtd, chip, FL_ERASING); 1957 status = chip->waitfunc(mtd, chip);
1837 1958
1838 /* 1959 /*
1839 * See if operation failed and additional status checks are 1960 * See if operation failed and additional status checks are
@@ -2265,6 +2386,10 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2265 chip->ecc.read_page = nand_read_page_hwecc; 2386 chip->ecc.read_page = nand_read_page_hwecc;
2266 if (!chip->ecc.write_page) 2387 if (!chip->ecc.write_page)
2267 chip->ecc.write_page = nand_write_page_hwecc; 2388 chip->ecc.write_page = nand_write_page_hwecc;
2389 if (!chip->ecc.read_oob)
2390 chip->ecc.read_oob = nand_read_oob_std;
2391 if (!chip->ecc.write_oob)
2392 chip->ecc.write_oob = nand_write_oob_std;
2268 2393
2269 case NAND_ECC_HW_SYNDROME: 2394 case NAND_ECC_HW_SYNDROME:
2270 if (!chip->ecc.calculate || !chip->ecc.correct || 2395 if (!chip->ecc.calculate || !chip->ecc.correct ||
@@ -2278,6 +2403,10 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2278 chip->ecc.read_page = nand_read_page_syndrome; 2403 chip->ecc.read_page = nand_read_page_syndrome;
2279 if (!chip->ecc.write_page) 2404 if (!chip->ecc.write_page)
2280 chip->ecc.write_page = nand_write_page_syndrome; 2405 chip->ecc.write_page = nand_write_page_syndrome;
2406 if (!chip->ecc.read_oob)
2407 chip->ecc.read_oob = nand_read_oob_syndrome;
2408 if (!chip->ecc.write_oob)
2409 chip->ecc.write_oob = nand_write_oob_syndrome;
2281 2410
2282 if (mtd->writesize >= chip->ecc.size) 2411 if (mtd->writesize >= chip->ecc.size)
2283 break; 2412 break;
@@ -2291,6 +2420,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2291 chip->ecc.correct = nand_correct_data; 2420 chip->ecc.correct = nand_correct_data;
2292 chip->ecc.read_page = nand_read_page_swecc; 2421 chip->ecc.read_page = nand_read_page_swecc;
2293 chip->ecc.write_page = nand_write_page_swecc; 2422 chip->ecc.write_page = nand_write_page_swecc;
2423 chip->ecc.read_oob = nand_read_oob_std;
2424 chip->ecc.write_oob = nand_write_oob_std;
2294 chip->ecc.size = 256; 2425 chip->ecc.size = 256;
2295 chip->ecc.bytes = 3; 2426 chip->ecc.bytes = 3;
2296 break; 2427 break;
@@ -2300,6 +2431,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2300 "This is not recommended !!\n"); 2431 "This is not recommended !!\n");
2301 chip->ecc.read_page = nand_read_page_raw; 2432 chip->ecc.read_page = nand_read_page_raw;
2302 chip->ecc.write_page = nand_write_page_raw; 2433 chip->ecc.write_page = nand_write_page_raw;
2434 chip->ecc.read_oob = nand_read_oob_std;
2435 chip->ecc.write_oob = nand_write_oob_std;
2303 chip->ecc.size = mtd->writesize; 2436 chip->ecc.size = mtd->writesize;
2304 chip->ecc.bytes = 0; 2437 chip->ecc.bytes = 0;
2305 break; 2438 break;