00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #if 0
00077 #include <linux/delay.h>
00078 #endif
00079 #include <linux/errno.h>
00080 #if 0
00081 #include <linux/sched.h>
00082 #include <linux/slab.h>
00083 #endif
00084 #include <linux/types.h>
00085 #if 0
00086 #include <linux/mtd/mtd.h>
00087 #include <linux/mtd/nand.h>
00088 #include <linux/mtd/nand_ecc.h>
00089 #include <linux/mtd/compatmac.h>
00090 #include <linux/interrupt.h>
00091 #endif
00092 #include <linux/bitops.h>
00093 #if 0
00094 #include <asm/io.h>
00095 #endif
00096
00097 #include "mtd.h"
00098 #include "nand.h"
00099 #include "nand_ecc.h"
00100 #include "delay.h"
00101
00102 #ifdef CONFIG_MTD_PARTITIONS
00103 #include <linux/mtd/partitions.h>
00104 #endif
00105
00106
00107 static struct nand_oobinfo nand_oob_8 = {
00108 .useecc = MTD_NANDECC_AUTOPLACE,
00109 .eccbytes = 3,
00110 .eccpos = {0, 1, 2},
00111 .oobfree = { {3, 2}, {6, 2} }
00112 };
00113
00114 static struct nand_oobinfo nand_oob_16 = {
00115 .useecc = MTD_NANDECC_AUTOPLACE,
00116 .eccbytes = 6,
00117 .eccpos = {0, 1, 2, 3, 6, 7},
00118 .oobfree = { {8, 8} }
00119 };
00120
00121 static struct nand_oobinfo nand_oob_64 = {
00122 .useecc = MTD_NANDECC_AUTOPLACE,
00123 .eccbytes = 24,
00124 .eccpos = {
00125 40, 41, 42, 43, 44, 45, 46, 47,
00126 48, 49, 50, 51, 52, 53, 54, 55,
00127 56, 57, 58, 59, 60, 61, 62, 63},
00128 .oobfree = { {2, 38} }
00129 };
00130
00131
00132 #if NAND_WRITE_SUPPORT
00133 static u_char ffchars[] = {
00134 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00135 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00136 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00137 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00138 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00139 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00140 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00141 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00142 };
00143 #endif
00144
00145
00146
00147
00148 static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
00149 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
00150 static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
00151
00152 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
00153 static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
00154 size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
00155 static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
00156 #if NAND_WRITE_SUPPORT
00157 static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
00158 static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
00159 size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
00160 static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
00161 #endif
00162 #if NAND_KVEC_SUPPORT && NAND_WRITE_SUPPORT
00163 static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
00164 unsigned long count, loff_t to, size_t * retlen);
00165 static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
00166 unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
00167 #endif
00168 #if NAND_ERASE_SUPPORT
00169 static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
00170 #endif
00171 static void nand_sync (struct mtd_info *mtd);
00172
00173
00174 #if NAND_WRITE_SUPPORT
00175 static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
00176 struct nand_oobinfo *oobsel, int mode);
00177 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
00178 static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
00179 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
00180 #else
00181 #define nand_verify_pages(...) (0)
00182 #endif
00183 #endif
00184
00185 static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
00186
00193 static void nand_release_device (struct mtd_info *mtd)
00194 {
00195 struct nand_chip *this = mtd->priv;
00196
00197
00198 this->select_chip(mtd, -1);
00199
00200 if (this->controller) {
00201
00202 spin_lock(&this->controller->lock);
00203 this->controller->active = NULL;
00204 this->state = FL_READY;
00205 wake_up(&this->controller->wq);
00206 spin_unlock(&this->controller->lock);
00207 } else {
00208
00209 spin_lock(&this->chip_lock);
00210 this->state = FL_READY;
00211 wake_up(&this->wq);
00212 spin_unlock(&this->chip_lock);
00213 }
00214 }
00215
00222 static u_char nand_read_byte(struct mtd_info *mtd)
00223 {
00224 struct nand_chip *this = mtd->priv;
00225 return readb(this->IO_ADDR_R);
00226 }
00227
00235 static void nand_write_byte(struct mtd_info *mtd, u_char byte)
00236 {
00237 struct nand_chip *this = mtd->priv;
00238 writeb(byte, this->IO_ADDR_W);
00239 }
00240
00248 static u_char nand_read_byte16(struct mtd_info *mtd)
00249 {
00250 struct nand_chip *this = mtd->priv;
00251 return (u_char) cpu_to_le16(readw(this->IO_ADDR_R));
00252 }
00253
00262 static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
00263 {
00264 struct nand_chip *this = mtd->priv;
00265 writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
00266 }
00267
00275 static u16 nand_read_word(struct mtd_info *mtd)
00276 {
00277 struct nand_chip *this = mtd->priv;
00278 return readw(this->IO_ADDR_R);
00279 }
00280
00289 static void nand_write_word(struct mtd_info *mtd, u16 word)
00290 {
00291 struct nand_chip *this = mtd->priv;
00292 writew(word, this->IO_ADDR_W);
00293 }
00294
00302 static void nand_select_chip(struct mtd_info *mtd, int chip)
00303 {
00304 struct nand_chip *this = mtd->priv;
00305 switch(chip) {
00306 case -1:
00307 this->hwcontrol(mtd, NAND_CTL_CLRNCE);
00308 break;
00309 case 0:
00310 this->hwcontrol(mtd, NAND_CTL_SETNCE);
00311 break;
00312
00313 default:
00314 BUG();
00315 }
00316 }
00317
00326 static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
00327 {
00328 int i;
00329 struct nand_chip *this = mtd->priv;
00330
00331 for (i=0; i<len; i++)
00332 writeb(buf[i], this->IO_ADDR_W);
00333 }
00334
00343 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
00344 {
00345 int i;
00346 struct nand_chip *this = mtd->priv;
00347
00348 for (i=0; i<len; i++)
00349 buf[i] = readb(this->IO_ADDR_R);
00350 }
00351
00360 static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
00361 {
00362 int i;
00363 struct nand_chip *this = mtd->priv;
00364
00365 for (i=0; i<len; i++)
00366 if (buf[i] != readb(this->IO_ADDR_R))
00367 return -EFAULT;
00368
00369 return 0;
00370 }
00371
00380 static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
00381 {
00382 int i;
00383 struct nand_chip *this = mtd->priv;
00384 u16 *p = (u16 *) buf;
00385 len >>= 1;
00386
00387 for (i=0; i<len; i++)
00388 writew(p[i], this->IO_ADDR_W);
00389
00390 }
00391
00400 static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
00401 {
00402 int i;
00403 struct nand_chip *this = mtd->priv;
00404 u16 *p = (u16 *) buf;
00405 len >>= 1;
00406
00407 for (i=0; i<len; i++)
00408 p[i] = readw(this->IO_ADDR_R);
00409 }
00410
00419 static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
00420 {
00421 int i;
00422 struct nand_chip *this = mtd->priv;
00423 u16 *p = (u16 *) buf;
00424 len >>= 1;
00425
00426 for (i=0; i<len; i++)
00427 if (p[i] != readw(this->IO_ADDR_R))
00428 return -EFAULT;
00429
00430 return 0;
00431 }
00432
00441 static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
00442 {
00443 int page, chipnr, res = 0;
00444 struct nand_chip *this = mtd->priv;
00445 u16 bad;
00446
00447 if (getchip) {
00448 page = (int)(ofs >> this->page_shift);
00449 chipnr = (int)(ofs >> this->chip_shift);
00450
00451
00452 nand_get_device (this, mtd, FL_READING);
00453
00454
00455 this->select_chip(mtd, chipnr);
00456 } else
00457 page = (int) ofs;
00458
00459 if (this->options & NAND_BUSWIDTH_16) {
00460 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
00461 bad = cpu_to_le16(this->read_word(mtd));
00462 if (this->badblockpos & 0x1)
00463 bad >>= 8;
00464 if ((bad & 0xFF) != 0xff)
00465 res = 1;
00466 } else {
00467 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask);
00468 if (this->read_byte(mtd) != 0xff)
00469 res = 1;
00470 }
00471
00472 if (getchip) {
00473
00474 nand_release_device(mtd);
00475 }
00476
00477 return res;
00478 }
00479
00488 #if NAND_WRITE_SUPPORT
00489 static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
00490 {
00491 struct nand_chip *this = mtd->priv;
00492 u_char buf[2] = {0, 0};
00493 size_t retlen;
00494 int block;
00495
00496
00497 block = ((int) ofs) >> this->bbt_erase_shift;
00498 if (this->bbt)
00499 this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
00500
00501
00502 if (this->options & NAND_USE_FLASH_BBT)
00503 return nand_update_bbt (mtd, ofs);
00504
00505
00506 ofs += mtd->oobsize + (this->badblockpos & ~0x01);
00507 return nand_write_oob (mtd, ofs , 2, &retlen, buf);
00508 }
00509 #endif
00510
00518 #if NAND_WRITE_SUPPORT
00519 static int nand_check_wp (struct mtd_info *mtd)
00520 {
00521 struct nand_chip *this = mtd->priv;
00522
00523 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
00524 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
00525 }
00526 #endif
00527
00538 static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
00539 {
00540 struct nand_chip *this = mtd->priv;
00541
00542 if (!this->bbt)
00543 return this->block_bad(mtd, ofs, getchip);
00544
00545
00546 return nand_isbad_bbt (mtd, ofs, allowbbt);
00547 }
00548
00549
00550
00551
00552
00553 static void nand_wait_ready(struct mtd_info *mtd)
00554 {
00555 struct nand_chip *this = mtd->priv;
00556 unsigned long timeo = jiffies + 2;
00557
00558
00559 do {
00560 if (this->dev_ready(mtd))
00561 return;
00562 touch_softlockup_watchdog();
00563 } while (time_before(jiffies, timeo));
00564 }
00565
00576 static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
00577 {
00578 register struct nand_chip *this = mtd->priv;
00579
00580
00581 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00582
00583
00584
00585 if (command == NAND_CMD_SEQIN) {
00586 int readcmd;
00587
00588 if (column >= mtd->oobblock) {
00589
00590 column -= mtd->oobblock;
00591 readcmd = NAND_CMD_READOOB;
00592 } else if (column < 256) {
00593
00594 readcmd = NAND_CMD_READ0;
00595 } else {
00596 column -= 256;
00597 readcmd = NAND_CMD_READ1;
00598 }
00599 this->write_byte(mtd, readcmd);
00600 }
00601 this->write_byte(mtd, command);
00602
00603
00604 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00605
00606 if (column != -1 || page_addr != -1) {
00607 this->hwcontrol(mtd, NAND_CTL_SETALE);
00608
00609
00610 if (column != -1) {
00611
00612 if (this->options & NAND_BUSWIDTH_16)
00613 column >>= 1;
00614 this->write_byte(mtd, column);
00615 }
00616 if (page_addr != -1) {
00617 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
00618 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
00619
00620 if (this->chipsize > (32 << 20))
00621 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
00622 }
00623
00624 this->hwcontrol(mtd, NAND_CTL_CLRALE);
00625 }
00626
00627
00628
00629
00630
00631 switch (command) {
00632
00633 case NAND_CMD_PAGEPROG:
00634 case NAND_CMD_ERASE1:
00635 case NAND_CMD_ERASE2:
00636 case NAND_CMD_SEQIN:
00637 case NAND_CMD_STATUS:
00638 return;
00639
00640 case NAND_CMD_RESET:
00641 if (this->dev_ready)
00642 break;
00643 udelay(this->chip_delay);
00644 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00645 this->write_byte(mtd, NAND_CMD_STATUS);
00646 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00647 while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
00648 return;
00649
00650
00651 default:
00652
00653
00654
00655
00656 if (!this->dev_ready) {
00657 udelay (this->chip_delay);
00658 return;
00659 }
00660 }
00661
00662
00663 ndelay (100);
00664
00665 nand_wait_ready(mtd);
00666 }
00667
00680 static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr)
00681 {
00682 register struct nand_chip *this = mtd->priv;
00683
00684
00685 if (command == NAND_CMD_READOOB) {
00686 column += mtd->oobblock;
00687 command = NAND_CMD_READ0;
00688 }
00689
00690
00691
00692 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00693
00694 this->write_byte(mtd, (command & 0xff));
00695
00696 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00697
00698 if (column != -1 || page_addr != -1) {
00699 this->hwcontrol(mtd, NAND_CTL_SETALE);
00700
00701
00702 if (column != -1) {
00703
00704 if (this->options & NAND_BUSWIDTH_16)
00705 column >>= 1;
00706 this->write_byte(mtd, column & 0xff);
00707 this->write_byte(mtd, column >> 8);
00708 }
00709 if (page_addr != -1) {
00710 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
00711 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
00712
00713 if (this->chipsize > (128 << 20))
00714 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff));
00715 }
00716
00717 this->hwcontrol(mtd, NAND_CTL_CLRALE);
00718 }
00719
00720
00721
00722
00723
00724 switch (command) {
00725
00726 case NAND_CMD_CACHEDPROG:
00727 case NAND_CMD_PAGEPROG:
00728 case NAND_CMD_ERASE1:
00729 case NAND_CMD_ERASE2:
00730 case NAND_CMD_SEQIN:
00731 case NAND_CMD_STATUS:
00732 case NAND_CMD_DEPLETE1:
00733 return;
00734
00735
00736
00737
00738 case NAND_CMD_STATUS_ERROR:
00739 case NAND_CMD_STATUS_ERROR0:
00740 case NAND_CMD_STATUS_ERROR1:
00741 case NAND_CMD_STATUS_ERROR2:
00742 case NAND_CMD_STATUS_ERROR3:
00743 udelay(this->chip_delay);
00744 return;
00745
00746 case NAND_CMD_RESET:
00747 if (this->dev_ready)
00748 break;
00749 udelay(this->chip_delay);
00750 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00751 this->write_byte(mtd, NAND_CMD_STATUS);
00752 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00753 while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
00754 return;
00755
00756 case NAND_CMD_READ0:
00757
00758 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00759
00760 this->write_byte(mtd, NAND_CMD_READSTART);
00761
00762 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00763
00764
00765
00766 default:
00767
00768
00769
00770
00771 if (!this->dev_ready) {
00772 udelay (this->chip_delay);
00773 return;
00774 }
00775 }
00776
00777
00778
00779 ndelay (100);
00780
00781 nand_wait_ready(mtd);
00782 }
00783
00792 static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
00793 {
00794 struct nand_chip *active;
00795 spinlock_t *lock;
00796 wait_queue_head_t *wq;
00797 DECLARE_WAITQUEUE (wait, current);
00798
00799 lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
00800 wq = (this->controller) ? &this->controller->wq : &this->wq;
00801 retry:
00802 active = this;
00803 spin_lock(lock);
00804
00805
00806 if (this->controller) {
00807 if (this->controller->active)
00808 active = this->controller->active;
00809 else
00810 this->controller->active = this;
00811 }
00812 if (active == this && this->state == FL_READY) {
00813 this->state = new_state;
00814 spin_unlock(lock);
00815 return 0;
00816 }
00817 if (new_state == FL_PM_SUSPENDED) {
00818 spin_unlock(lock);
00819 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
00820 }
00821 set_current_state(TASK_UNINTERRUPTIBLE);
00822 add_wait_queue(wq, &wait);
00823 spin_unlock(lock);
00824 schedule();
00825 remove_wait_queue(wq, &wait);
00826 goto retry;
00827 }
00828
00840 static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
00841 {
00842
00843 unsigned long timeo = jiffies;
00844 int status;
00845
00846 if (state == FL_ERASING)
00847 timeo += (HZ * 400) / 1000;
00848 else
00849 timeo += (HZ * 20) / 1000;
00850
00851
00852
00853 ndelay (100);
00854
00855 if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
00856 this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
00857 else
00858 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
00859
00860 while (time_before(jiffies, timeo)) {
00861
00862 if (this->state != state)
00863 return 0;
00864
00865 if (this->dev_ready) {
00866 if (this->dev_ready(mtd))
00867 break;
00868 } else {
00869 if (this->read_byte(mtd) & NAND_STATUS_READY)
00870 break;
00871 }
00872 cond_resched();
00873 }
00874 status = (int) this->read_byte(mtd);
00875 return status;
00876 }
00877
00893 #if NAND_WRITE_SUPPORT
00894 static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
00895 u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
00896 {
00897 int i, status;
00898 u_char ecc_code[32];
00899 int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
00900 int *oob_config = oobsel->eccpos;
00901 int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
00902 int eccbytes = 0;
00903
00904
00905 cached = 0;
00906
00907
00908 this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
00909
00910
00911 switch (eccmode) {
00912
00913 case NAND_ECC_NONE:
00914 printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
00915 this->write_buf(mtd, this->data_poi, mtd->oobblock);
00916 break;
00917
00918
00919 case NAND_ECC_SOFT:
00920 for (; eccsteps; eccsteps--) {
00921 this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
00922 for (i = 0; i < 3; i++, eccidx++)
00923 oob_buf[oob_config[eccidx]] = ecc_code[i];
00924 datidx += this->eccsize;
00925 }
00926 this->write_buf(mtd, this->data_poi, mtd->oobblock);
00927 break;
00928 default:
00929 eccbytes = this->eccbytes;
00930 for (; eccsteps; eccsteps--) {
00931
00932 this->enable_hwecc(mtd, NAND_ECC_WRITE);
00933 this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
00934 this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
00935 for (i = 0; i < eccbytes; i++, eccidx++)
00936 oob_buf[oob_config[eccidx]] = ecc_code[i];
00937
00938
00939
00940 if (this->options & NAND_HWECC_SYNDROME)
00941 this->write_buf(mtd, ecc_code, eccbytes);
00942 datidx += this->eccsize;
00943 }
00944 break;
00945 }
00946
00947
00948 if (this->options & NAND_HWECC_SYNDROME)
00949 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
00950 else
00951 this->write_buf(mtd, oob_buf, mtd->oobsize);
00952
00953
00954 this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
00955
00956 if (!cached) {
00957
00958 status = this->waitfunc (mtd, this, FL_WRITING);
00959
00960
00961 if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
00962 status = this->errstat(mtd, this, FL_WRITING, status, page);
00963 }
00964
00965
00966 if (status & NAND_STATUS_FAIL) {
00967 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
00968 return -EIO;
00969 }
00970 } else {
00971
00972
00973
00974 }
00975 return 0;
00976 }
00977 #endif
00978
00979 #if NAND_WRITE_SUPPORT
00980 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
00981
01000 static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
01001 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
01002 {
01003 int i, j, datidx = 0, oobofs = 0, res = -EIO;
01004 int eccsteps = this->eccsteps;
01005 int hweccbytes;
01006 u_char oobdata[64];
01007
01008 hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
01009
01010
01011 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
01012
01013 for(;;) {
01014 for (j = 0; j < eccsteps; j++) {
01015
01016 if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) {
01017 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
01018 goto out;
01019 }
01020 datidx += mtd->eccsize;
01021
01022 if (!hweccbytes)
01023 continue;
01024 if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
01025 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
01026 goto out;
01027 }
01028 oobofs += hweccbytes;
01029 }
01030
01031
01032
01033
01034 if (oobmode) {
01035 if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) {
01036 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
01037 goto out;
01038 }
01039 } else {
01040
01041 this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);
01042
01043 if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
01044 int ecccnt = oobsel->eccbytes;
01045
01046 for (i = 0; i < ecccnt; i++) {
01047 int idx = oobsel->eccpos[i];
01048 if (oobdata[idx] != oob_buf[oobofs + idx] ) {
01049 DEBUG (MTD_DEBUG_LEVEL0,
01050 "%s: Failed ECC write "
01051 "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
01052 goto out;
01053 }
01054 }
01055 }
01056 }
01057 oobofs += mtd->oobsize - hweccbytes * eccsteps;
01058 page++;
01059 numpages--;
01060
01061
01062
01063
01064
01065
01066
01067
01068 if (!this->dev_ready)
01069 udelay (this->chip_delay);
01070 else
01071 nand_wait_ready(mtd);
01072
01073
01074 if (!numpages)
01075 return 0;
01076
01077
01078
01079 if (!NAND_CANAUTOINCR(this))
01080 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
01081 }
01082
01083
01084
01085
01086 out:
01087 this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
01088 return res;
01089 }
01090 #endif
01091 #endif
01092
01104 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
01105 {
01106 return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
01107 }
01108
01109
01122 static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
01123 size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
01124 {
01125
01126 if (oobsel == NULL)
01127 oobsel = &mtd->oobinfo;
01128 return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff);
01129 }
01130
01131
01148 int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
01149 size_t * retlen, u_char * buf, u_char * oob_buf,
01150 struct nand_oobinfo *oobsel, int flags)
01151 {
01152
01153 int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
01154 int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
01155 struct nand_chip *this = mtd->priv;
01156 u_char *data_poi, *oob_data = oob_buf;
01157 u_char ecc_calc[32];
01158 u_char ecc_code[32];
01159 int eccmode, eccsteps;
01160 int *oob_config, datidx;
01161 int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
01162 int eccbytes;
01163 int compareecc = 1;
01164 int oobreadlen;
01165
01166
01167 DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
01168
01169
01170 if ((from + len) > mtd->size) {
01171 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
01172 *retlen = 0;
01173 return -EINVAL;
01174 }
01175
01176
01177 if (flags & NAND_GET_DEVICE)
01178 nand_get_device (this, mtd, FL_READING);
01179
01180
01181 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
01182 oobsel = this->autooob;
01183
01184 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
01185 oob_config = oobsel->eccpos;
01186
01187
01188 chipnr = (int)(from >> this->chip_shift);
01189 this->select_chip(mtd, chipnr);
01190
01191
01192 realpage = (int) (from >> this->page_shift);
01193 page = realpage & this->pagemask;
01194
01195
01196 col = from & (mtd->oobblock - 1);
01197
01198 end = mtd->oobblock;
01199 ecc = this->eccsize;
01200 eccbytes = this->eccbytes;
01201
01202 if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
01203 compareecc = 0;
01204
01205 oobreadlen = mtd->oobsize;
01206 if (this->options & NAND_HWECC_SYNDROME)
01207 oobreadlen -= oobsel->eccbytes;
01208
01209
01210 while (read < len) {
01211
01212 int aligned = (!col && (len - read) >= end);
01213
01214
01215
01216
01217 if (aligned)
01218 data_poi = &buf[read];
01219 else
01220 data_poi = this->data_buf;
01221
01222
01223
01224
01225
01226
01227 if (realpage == this->pagebuf && !oob_buf) {
01228
01229 if (aligned)
01230 memcpy (data_poi, this->data_buf, end);
01231 goto readdata;
01232 }
01233
01234
01235 if (sndcmd) {
01236 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
01237 sndcmd = 0;
01238 }
01239
01240
01241 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
01242 oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
01243 oob_data = &this->data_buf[end];
01244
01245 eccsteps = this->eccsteps;
01246
01247 switch (eccmode) {
01248 case NAND_ECC_NONE: {
01249 static unsigned long lastwhinge = 0;
01250 if ((lastwhinge / HZ) != (jiffies / HZ)) {
01251 printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n");
01252 lastwhinge = jiffies;
01253 }
01254 this->read_buf(mtd, data_poi, end);
01255 break;
01256 }
01257
01258 case NAND_ECC_SOFT:
01259 this->read_buf(mtd, data_poi, end);
01260 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
01261 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
01262 break;
01263
01264 default:
01265 #if NAND_HWECC_SUPPORT
01266 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
01267 this->enable_hwecc(mtd, NAND_ECC_READ);
01268 this->read_buf(mtd, &data_poi[datidx], ecc);
01269
01270
01271
01272 if (!compareecc) {
01273
01274
01275 this->enable_hwecc(mtd, NAND_ECC_READSYN);
01276 this->read_buf(mtd, &oob_data[i], eccbytes);
01277
01278
01279
01280 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
01281 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
01282 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
01283 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
01284 ecc_failed++;
01285 }
01286 } else {
01287 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
01288 }
01289 }
01290 #endif
01291 break;
01292 }
01293
01294
01295 this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
01296
01297
01298 if (!compareecc)
01299 goto readoob;
01300
01301
01302 for (j = 0; j < oobsel->eccbytes; j++)
01303 ecc_code[j] = oob_data[oob_config[j]];
01304
01305
01306 for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
01307 ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
01308
01309
01310 j += eccbytes;
01311
01312
01313
01314
01315
01316 if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
01317 int *p = (int *)(&oob_data[mtd->oobsize]);
01318 p[i] = ecc_status;
01319 }
01320
01321 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
01322 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
01323 ecc_failed++;
01324 }
01325 }
01326
01327 readoob:
01328
01329 if (oob_buf) {
01330
01331 switch(oobsel->useecc) {
01332 case MTD_NANDECC_AUTOPLACE:
01333 case MTD_NANDECC_AUTOPL_USR:
01334
01335 for (i = 0; oobsel->oobfree[i][1]; i++) {
01336 int from = oobsel->oobfree[i][0];
01337 int num = oobsel->oobfree[i][1];
01338 memcpy(&oob_buf[oob], &oob_data[from], num);
01339 oob += num;
01340 }
01341 break;
01342 case MTD_NANDECC_PLACE:
01343
01344 oob_data += this->eccsteps * sizeof (int);
01345 default:
01346 oob_data += mtd->oobsize;
01347 }
01348 }
01349 readdata:
01350
01351 if (!aligned) {
01352 for (j = col; j < end && read < len; j++)
01353 buf[read++] = data_poi[j];
01354 this->pagebuf = realpage;
01355 } else
01356 read += mtd->oobblock;
01357
01358
01359
01360
01361
01362
01363 if (!this->dev_ready)
01364 udelay (this->chip_delay);
01365 else
01366 nand_wait_ready(mtd);
01367
01368 if (read == len)
01369 break;
01370
01371
01372 col = 0;
01373
01374 realpage++;
01375
01376 page = realpage & this->pagemask;
01377
01378 if (!page) {
01379 chipnr++;
01380 this->select_chip(mtd, -1);
01381 this->select_chip(mtd, chipnr);
01382 }
01383
01384
01385
01386 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
01387 sndcmd = 1;
01388 }
01389
01390
01391 if (flags & NAND_GET_DEVICE)
01392 nand_release_device(mtd);
01393
01394
01395
01396
01397
01398
01399 *retlen = read;
01400 return ecc_failed ? -EBADMSG : 0;
01401 }
01402
01413 static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
01414 {
01415 int i, col, page, chipnr;
01416 struct nand_chip *this = mtd->priv;
01417 int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
01418
01419 DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
01420
01421
01422 page = (int)(from >> this->page_shift);
01423 chipnr = (int)(from >> this->chip_shift);
01424
01425
01426 col = from & (mtd->oobsize - 1);
01427
01428
01429 *retlen = 0;
01430
01431
01432 if ((from + len) > mtd->size) {
01433 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
01434 *retlen = 0;
01435 return -EINVAL;
01436 }
01437
01438
01439 nand_get_device (this, mtd , FL_READING);
01440
01441
01442 this->select_chip(mtd, chipnr);
01443
01444
01445 this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
01446
01447
01448
01449
01450 i = 0;
01451 while (i < len) {
01452 int thislen = mtd->oobsize - col;
01453 thislen = min_t(int, thislen, len);
01454 this->read_buf(mtd, &buf[i], thislen);
01455 i += thislen;
01456
01457
01458 if (i < len) {
01459 page++;
01460 col = 0;
01461
01462
01463 if (!(page & this->pagemask)) {
01464 chipnr++;
01465 this->select_chip(mtd, -1);
01466 this->select_chip(mtd, chipnr);
01467 }
01468
01469
01470
01471
01472
01473
01474 if (!this->dev_ready)
01475 udelay (this->chip_delay);
01476 else
01477 nand_wait_ready(mtd);
01478
01479
01480
01481
01482 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
01483
01484 this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
01485 }
01486 }
01487 }
01488
01489
01490 nand_release_device(mtd);
01491
01492
01493 *retlen = len;
01494 return 0;
01495 }
01496
01507 int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
01508 {
01509 struct nand_chip *this = mtd->priv;
01510 int page = (int) (from >> this->page_shift);
01511 int chip = (int) (from >> this->chip_shift);
01512 int sndcmd = 1;
01513 int cnt = 0;
01514 int pagesize = mtd->oobblock + mtd->oobsize;
01515 int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
01516
01517
01518 if ((from + len) > mtd->size) {
01519 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
01520 return -EINVAL;
01521 }
01522
01523
01524 nand_get_device (this, mtd , FL_READING);
01525
01526 this->select_chip (mtd, chip);
01527
01528
01529 len += ooblen;
01530
01531 while (len) {
01532 if (sndcmd)
01533 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
01534 sndcmd = 0;
01535
01536 this->read_buf (mtd, &buf[cnt], pagesize);
01537
01538 len -= pagesize;
01539 cnt += pagesize;
01540 page++;
01541
01542 if (!this->dev_ready)
01543 udelay (this->chip_delay);
01544 else
01545 nand_wait_ready(mtd);
01546
01547
01548 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
01549 sndcmd = 1;
01550 }
01551
01552
01553 nand_release_device(mtd);
01554 return 0;
01555 }
01556
01557
01581 #if NAND_WRITE_SUPPORT
01582 static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel,
01583 int autoplace, int numpages)
01584 {
01585 struct nand_chip *this = mtd->priv;
01586 int i, len, ofs;
01587
01588
01589 if (fsbuf && !autoplace)
01590 return fsbuf;
01591
01592
01593 if (this->oobdirty) {
01594 memset (this->oob_buf, 0xff,
01595 mtd->oobsize << (this->phys_erase_shift - this->page_shift));
01596 this->oobdirty = 0;
01597 }
01598
01599
01600 if (!autoplace || !fsbuf)
01601 return this->oob_buf;
01602
01603
01604 this->oobdirty = 1;
01605 ofs = 0;
01606 while (numpages--) {
01607 for (i = 0, len = 0; len < mtd->oobavail; i++) {
01608 int to = ofs + oobsel->oobfree[i][0];
01609 int num = oobsel->oobfree[i][1];
01610 memcpy (&this->oob_buf[to], fsbuf, num);
01611 len += num;
01612 fsbuf += num;
01613 }
01614 ofs += mtd->oobavail;
01615 }
01616 return this->oob_buf;
01617 }
01618 #endif
01619
01620 #define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
01621
01633 #if NAND_WRITE_SUPPORT
01634 static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
01635 {
01636 return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
01637 }
01638 #endif
01639
01652 #if NAND_WRITE_SUPPORT
01653 static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
01654 size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
01655 {
01656 int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr;
01657 int autoplace = 0, numpages, totalpages;
01658 struct nand_chip *this = mtd->priv;
01659 u_char *oobbuf, *bufstart;
01660 int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
01661
01662 DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
01663
01664
01665 *retlen = 0;
01666
01667
01668 if ((to + len) > mtd->size) {
01669 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
01670 return -EINVAL;
01671 }
01672
01673
01674 if (NOTALIGNED (to) || NOTALIGNED(len)) {
01675 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
01676 return -EINVAL;
01677 }
01678
01679
01680 nand_get_device (this, mtd, FL_WRITING);
01681
01682
01683 chipnr = (int)(to >> this->chip_shift);
01684
01685 this->select_chip(mtd, chipnr);
01686
01687
01688 if (nand_check_wp(mtd))
01689 goto out;
01690
01691
01692 if (oobsel == NULL)
01693 oobsel = &mtd->oobinfo;
01694
01695
01696 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
01697 oobsel = this->autooob;
01698 autoplace = 1;
01699 }
01700 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
01701 autoplace = 1;
01702
01703
01704 totalpages = len >> this->page_shift;
01705 page = (int) (to >> this->page_shift);
01706
01707 if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
01708 this->pagebuf = -1;
01709
01710
01711 page &= this->pagemask;
01712 startpage = page;
01713
01714 numpages = min (ppblock - (startpage & (ppblock - 1)), totalpages);
01715 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
01716 bufstart = (u_char *)buf;
01717
01718
01719 while (written < len) {
01720
01721 this->data_poi = (u_char*) &buf[written];
01722
01723
01724
01725
01726
01727 ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
01728 if (ret) {
01729 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
01730 goto out;
01731 }
01732
01733 oob += mtd->oobsize;
01734
01735 written += mtd->oobblock;
01736 if (written == len)
01737 goto cmp;
01738
01739
01740 page++;
01741
01742
01743
01744
01745
01746 if (!(page & (ppblock - 1))){
01747 int ofs;
01748 this->data_poi = bufstart;
01749 ret = nand_verify_pages (mtd, this, startpage,
01750 page - startpage,
01751 oobbuf, oobsel, chipnr, (eccbuf != NULL));
01752 if (ret) {
01753 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
01754 goto out;
01755 }
01756 *retlen = written;
01757
01758 ofs = autoplace ? mtd->oobavail : mtd->oobsize;
01759 if (eccbuf)
01760 eccbuf += (page - startpage) * ofs;
01761 totalpages -= page - startpage;
01762 numpages = min (totalpages, ppblock);
01763 page &= this->pagemask;
01764 startpage = page;
01765 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
01766 autoplace, numpages);
01767 oob = 0;
01768
01769 if (!page) {
01770 chipnr++;
01771 this->select_chip(mtd, -1);
01772 this->select_chip(mtd, chipnr);
01773 }
01774 }
01775 }
01776
01777 cmp:
01778 this->data_poi = bufstart;
01779 ret = nand_verify_pages (mtd, this, startpage, totalpages,
01780 oobbuf, oobsel, chipnr, (eccbuf != NULL));
01781 if (!ret)
01782 *retlen = written;
01783 else
01784 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
01785
01786 out:
01787
01788 nand_release_device(mtd);
01789
01790 return ret;
01791 }
01792 #endif
01793
01794
01805 #if NAND_WRITE_SUPPORT
01806 static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
01807 {
01808 int column, page, status, ret = -EIO, chipnr;
01809 struct nand_chip *this = mtd->priv;
01810
01811 DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
01812
01813
01814 page = (int) (to >> this->page_shift);
01815 chipnr = (int) (to >> this->chip_shift);
01816
01817
01818 column = to & (mtd->oobsize - 1);
01819
01820
01821 *retlen = 0;
01822
01823
01824 if ((column + len) > mtd->oobsize) {
01825 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
01826 return -EINVAL;
01827 }
01828
01829
01830 nand_get_device (this, mtd, FL_WRITING);
01831
01832
01833 this->select_chip(mtd, chipnr);
01834
01835
01836
01837
01838
01839
01840 this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
01841
01842
01843 if (nand_check_wp(mtd))
01844 goto out;
01845
01846
01847 if (page == this->pagebuf)
01848 this->pagebuf = -1;
01849
01850 if (NAND_MUST_PAD(this)) {
01851
01852 this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
01853
01854 this->write_buf(mtd, ffchars, column);
01855
01856 this->write_buf(mtd, buf, len);
01857
01858 this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
01859 } else {
01860
01861 this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
01862
01863 this->write_buf(mtd, buf, len);
01864 }
01865
01866 this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
01867
01868 status = this->waitfunc (mtd, this, FL_WRITING);
01869
01870
01871 if (status & NAND_STATUS_FAIL) {
01872 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
01873 ret = -EIO;
01874 goto out;
01875 }
01876
01877 *retlen = len;
01878
01879 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
01880
01881 this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
01882
01883 if (this->verify_buf(mtd, buf, len)) {
01884 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
01885 ret = -EIO;
01886 goto out;
01887 }
01888 #endif
01889 ret = 0;
01890 out:
01891
01892 nand_release_device(mtd);
01893
01894 return ret;
01895 }
01896 #endif
01897
01898
01909 #if NAND_KVEC_SUPPORT
01910 #if NAND_WRITE_SUPPORT
01911 static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
01912 loff_t to, size_t * retlen)
01913 {
01914 return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
01915 }
01916 #endif
01917 #endif
01918
01931 #if NAND_KVEC_SUPPORT
01932 #if NAND_WRITE_SUPPORT
01933 static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
01934 loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
01935 {
01936 int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
01937 int oob, numpages, autoplace = 0, startpage;
01938 struct nand_chip *this = mtd->priv;
01939 int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
01940 u_char *oobbuf, *bufstart;
01941
01942
01943 *retlen = 0;
01944
01945
01946 total_len = 0;
01947 for (i = 0; i < count; i++)
01948 total_len += (int) vecs[i].iov_len;
01949
01950 DEBUG (MTD_DEBUG_LEVEL3,
01951 "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
01952
01953
01954 if ((to + total_len) > mtd->size) {
01955 DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
01956 return -EINVAL;
01957 }
01958
01959
01960 if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
01961 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
01962 return -EINVAL;
01963 }
01964
01965
01966 nand_get_device (this, mtd, FL_WRITING);
01967
01968
01969 chipnr = (int) (to >> this->chip_shift);
01970
01971 this->select_chip(mtd, chipnr);
01972
01973
01974 if (nand_check_wp(mtd))
01975 goto out;
01976
01977
01978 if (oobsel == NULL)
01979 oobsel = &mtd->oobinfo;
01980
01981
01982 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
01983 oobsel = this->autooob;
01984 autoplace = 1;
01985 }
01986 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
01987 autoplace = 1;
01988
01989
01990 page = (int) (to >> this->page_shift);
01991
01992 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
01993 this->pagebuf = -1;
01994
01995 startpage = page & this->pagemask;
01996
01997
01998 len = 0;
01999 while (count) {
02000
02001
02002
02003 if ((vecs->iov_len - len) >= mtd->oobblock) {
02004
02005
02006 numpages = (vecs->iov_len - len) >> this->page_shift;
02007
02008 numpages = min (ppblock - (startpage & (ppblock - 1)), numpages);
02009 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
02010 bufstart = (u_char *)vecs->iov_base;
02011 bufstart += len;
02012 this->data_poi = bufstart;
02013 oob = 0;
02014 for (i = 1; i <= numpages; i++) {
02015
02016
02017
02018
02019 ret = nand_write_page (mtd, this, page & this->pagemask,
02020 &oobbuf[oob], oobsel, i != numpages);
02021 if (ret)
02022 goto out;
02023 this->data_poi += mtd->oobblock;
02024 len += mtd->oobblock;
02025 oob += mtd->oobsize;
02026 page++;
02027 }
02028
02029 if (len >= (int) vecs->iov_len) {
02030 vecs++;
02031 len = 0;
02032 count--;
02033 }
02034 } else {
02035
02036
02037
02038 int cnt = 0;
02039 while (cnt < mtd->oobblock) {
02040 if (vecs->iov_base != NULL && vecs->iov_len)
02041 this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
02042
02043 if (len >= (int) vecs->iov_len) {
02044 vecs++;
02045 len = 0;
02046 count--;
02047 }
02048 }
02049 this->pagebuf = page;
02050 this->data_poi = this->data_buf;
02051 bufstart = this->data_poi;
02052 numpages = 1;
02053 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
02054 ret = nand_write_page (mtd, this, page & this->pagemask,
02055 oobbuf, oobsel, 0);
02056 if (ret)
02057 goto out;
02058 page++;
02059 }
02060
02061 this->data_poi = bufstart;
02062 ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
02063 if (ret)
02064 goto out;
02065
02066 written += mtd->oobblock * numpages;
02067
02068 if (!count)
02069 break;
02070
02071 startpage = page & this->pagemask;
02072
02073 if (!startpage) {
02074 chipnr++;
02075 this->select_chip(mtd, -1);
02076 this->select_chip(mtd, chipnr);
02077 }
02078 }
02079 ret = 0;
02080 out:
02081
02082 nand_release_device(mtd);
02083
02084 *retlen = written;
02085 return ret;
02086 }
02087 #endif
02088 #endif
02089
02097 #if NAND_ERASE_SUPPORT
02098 static void single_erase_cmd (struct mtd_info *mtd, int page)
02099 {
02100 struct nand_chip *this = mtd->priv;
02101
02102 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
02103 this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
02104 }
02105 #endif
02106
02115 #if NAND_ERASE_SUPPORT
02116 static void multi_erase_cmd (struct mtd_info *mtd, int page)
02117 {
02118 struct nand_chip *this = mtd->priv;
02119
02120 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
02121 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
02122 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
02123 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
02124 this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
02125 }
02126 #endif
02127
02135 #if NAND_ERASE_SUPPORT
02136 static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
02137 {
02138 return nand_erase_nand (mtd, instr, 0);
02139 }
02140 #endif
02141
02142 #define BBT_PAGE_MASK 0xffffff3f
02143
02151 #if NAND_ERASE_SUPPORT
02152 int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
02153 {
02154 int page, len, status, pages_per_block, ret, chipnr;
02155 struct nand_chip *this = mtd->priv;
02156 int rewrite_bbt[NAND_MAX_CHIPS]={0};
02157 unsigned int bbt_masked_page;
02158
02159
02160
02161 DEBUG (MTD_DEBUG_LEVEL3,
02162 "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
02163
02164
02165 if (instr->addr & ((1 << this->phys_erase_shift) - 1)) {
02166 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n");
02167 return -EINVAL;
02168 }
02169
02170
02171 if (instr->len & ((1 << this->phys_erase_shift) - 1)) {
02172 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n");
02173 return -EINVAL;
02174 }
02175
02176
02177 if ((instr->len + instr->addr) > mtd->size) {
02178 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n");
02179 return -EINVAL;
02180 }
02181
02182 instr->fail_addr = 0xffffffff;
02183
02184
02185 nand_get_device (this, mtd, FL_ERASING);
02186
02187
02188 page = (int) (instr->addr >> this->page_shift);
02189 chipnr = (int) (instr->addr >> this->chip_shift);
02190
02191
02192 pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
02193
02194
02195 this->select_chip(mtd, chipnr);
02196
02197
02198
02199 if (nand_check_wp(mtd)) {
02200 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
02201 instr->state = MTD_ERASE_FAILED;
02202 goto erase_exit;
02203 }
02204
02205
02206 if (this->options & BBT_AUTO_REFRESH) {
02207 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
02208 } else {
02209 bbt_masked_page = 0xffffffff;
02210 }
02211
02212
02213 len = instr->len;
02214
02215 instr->state = MTD_ERASING;
02216
02217 while (len) {
02218
02219 if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
02220 printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
02221 instr->state = MTD_ERASE_FAILED;
02222 goto erase_exit;
02223 }
02224
02225
02226
02227 if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
02228 this->pagebuf = -1;
02229
02230 this->erase_cmd (mtd, page & this->pagemask);
02231
02232 status = this->waitfunc (mtd, this, FL_ERASING);
02233
02234
02235 if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
02236 status = this->errstat(mtd, this, FL_ERASING, status, page);
02237 }
02238
02239
02240 if (status & NAND_STATUS_FAIL) {
02241 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
02242 instr->state = MTD_ERASE_FAILED;
02243 instr->fail_addr = (page << this->page_shift);
02244 goto erase_exit;
02245 }
02246
02247
02248 if (this->options & BBT_AUTO_REFRESH) {
02249 if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
02250 (page != this->bbt_td->pages[chipnr])) {
02251 rewrite_bbt[chipnr] = (page << this->page_shift);
02252 }
02253 }
02254
02255
02256 len -= (1 << this->phys_erase_shift);
02257 page += pages_per_block;
02258
02259
02260 if (len && !(page & this->pagemask)) {
02261 chipnr++;
02262 this->select_chip(mtd, -1);
02263 this->select_chip(mtd, chipnr);
02264
02265
02266
02267 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
02268 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
02269 }
02270
02271 }
02272 }
02273 instr->state = MTD_ERASE_DONE;
02274
02275 erase_exit:
02276
02277 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
02278
02279 if (!ret)
02280 mtd_erase_callback(instr);
02281
02282
02283 nand_release_device(mtd);
02284
02285
02286 if ((this->options & BBT_AUTO_REFRESH) && (!ret)) {
02287 for (chipnr = 0; chipnr < this->numchips; chipnr++) {
02288 if (rewrite_bbt[chipnr]) {
02289
02290 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
02291 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
02292 nand_update_bbt (mtd, rewrite_bbt[chipnr]);
02293 }
02294 }
02295 }
02296
02297
02298 return ret;
02299 }
02300 #endif
02301
02308 static void nand_sync (struct mtd_info *mtd)
02309 {
02310 struct nand_chip *this = mtd->priv;
02311
02312 DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
02313
02314
02315 nand_get_device (this, mtd, FL_SYNCING);
02316
02317 nand_release_device (mtd);
02318 }
02319
02320
02326 static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
02327 {
02328
02329 if (ofs > mtd->size)
02330 return -EINVAL;
02331
02332 return nand_block_checkbad (mtd, ofs, 1, 0);
02333 }
02334
02340 #if NAND_WRITE_SUPPORT
02341 static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
02342 {
02343 struct nand_chip *this = mtd->priv;
02344 int ret;
02345
02346 if ((ret = nand_block_isbad(mtd, ofs))) {
02347
02348 if (ret > 0)
02349 return 0;
02350 return ret;
02351 }
02352
02353 return this->block_markbad(mtd, ofs);
02354 }
02355 #endif
02356
02361 static int nand_suspend(struct mtd_info *mtd)
02362 {
02363 struct nand_chip *this = mtd->priv;
02364
02365 return nand_get_device (this, mtd, FL_PM_SUSPENDED);
02366 }
02367
02372 static void nand_resume(struct mtd_info *mtd)
02373 {
02374 struct nand_chip *this = mtd->priv;
02375
02376 if (this->state == FL_PM_SUSPENDED)
02377 nand_release_device(mtd);
02378 else
02379 printk(KERN_ERR "resume() called for the chip which is not "
02380 "in suspended state\n");
02381
02382 }
02383
02384
02397 int nand_scan (struct mtd_info *mtd, int maxchips)
02398 {
02399 int i, nand_maf_id, nand_dev_id, busw, maf_id;
02400 struct nand_chip *this = mtd->priv;
02401
02402
02403 busw = this->options & NAND_BUSWIDTH_16;
02404
02405
02406 if (!this->chip_delay)
02407 this->chip_delay = 20;
02408
02409
02410 if (this->cmdfunc == NULL)
02411 this->cmdfunc = nand_command;
02412
02413
02414 if (this->waitfunc == NULL)
02415 this->waitfunc = nand_wait;
02416
02417 if (!this->select_chip)
02418 this->select_chip = nand_select_chip;
02419 if (!this->write_byte)
02420 this->write_byte = busw ? nand_write_byte16 : nand_write_byte;
02421 if (!this->read_byte)
02422 this->read_byte = busw ? nand_read_byte16 : nand_read_byte;
02423 if (!this->write_word)
02424 this->write_word = nand_write_word;
02425 if (!this->read_word)
02426 this->read_word = nand_read_word;
02427 if (!this->block_bad)
02428 this->block_bad = nand_block_bad;
02429 if (!this->block_markbad)
02430 this->block_markbad = nand_default_block_markbad;
02431 if (!this->write_buf)
02432 this->write_buf = busw ? nand_write_buf16 : nand_write_buf;
02433 if (!this->read_buf)
02434 this->read_buf = busw ? nand_read_buf16 : nand_read_buf;
02435 if (!this->verify_buf)
02436 this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
02437 if (!this->scan_bbt)
02438 this->scan_bbt = nand_default_bbt;
02439
02440
02441 this->select_chip(mtd, 0);
02442
02443
02444 this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
02445
02446
02447 nand_maf_id = this->read_byte(mtd);
02448 nand_dev_id = this->read_byte(mtd);
02449
02450 this->select_chip(mtd, 0);
02451 this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
02452 nand_maf_id = this->read_byte(mtd);
02453 nand_dev_id = this->read_byte(mtd);
02454 puts("maf_id: ");
02455 putx(nand_maf_id);
02456 puts("; dev_id: ");
02457 putx(nand_dev_id);
02458 putnl();
02459
02460 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
02461
02462 if (nand_dev_id != nand_flash_ids[i].id)
02463 continue;
02464
02465 if (!mtd->name) mtd->name = nand_flash_ids[i].name;
02466 this->chipsize = nand_flash_ids[i].chipsize << 20;
02467
02468
02469 if (!nand_flash_ids[i].pagesize) {
02470 int extid;
02471
02472 extid = this->read_byte(mtd);
02473
02474 extid = this->read_byte(mtd);
02475
02476 mtd->oobblock = 1024 << (extid & 0x3);
02477 extid >>= 2;
02478
02479 mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
02480 extid >>= 2;
02481
02482 mtd->erasesize = (64 * 1024) << (extid & 0x03);
02483 extid >>= 2;
02484
02485 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
02486
02487 } else {
02488
02489
02490 mtd->erasesize = nand_flash_ids[i].erasesize;
02491 mtd->oobblock = nand_flash_ids[i].pagesize;
02492 mtd->oobsize = mtd->oobblock / 32;
02493 busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
02494 }
02495
02496
02497 for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {
02498 if (nand_manuf_ids[maf_id].id == nand_maf_id)
02499 break;
02500 }
02501
02502
02503
02504 if (busw != (this->options & NAND_BUSWIDTH_16)) {
02505 printk (KERN_INFO "NAND device: Manufacturer ID:"
02506 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
02507 nand_manuf_ids[maf_id].name , mtd->name);
02508 printk (KERN_WARNING
02509 "NAND bus width %d instead %d bit\n",
02510 (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
02511 busw ? 16 : 8);
02512 this->select_chip(mtd, -1);
02513 return 1;
02514 }
02515
02516
02517 this->page_shift = ffs(mtd->oobblock) - 1;
02518 this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
02519 this->chip_shift = ffs(this->chipsize) - 1;
02520
02521
02522 this->badblockpos = mtd->oobblock > 512 ?
02523 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
02524
02525
02526 this->options &= ~NAND_CHIPOPTIONS_MSK;
02527 this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
02528
02529 this->options |= NAND_NO_AUTOINCR;
02530
02531
02532
02533 if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
02534 this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
02535
02536 #if NAND_ERASE_SUPPORT
02537
02538 if (this->options & NAND_4PAGE_ARRAY)
02539 this->erase_cmd = multi_erase_cmd;
02540 else
02541 this->erase_cmd = single_erase_cmd;
02542 #endif
02543
02544
02545 if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
02546 this->cmdfunc = nand_command_lp;
02547
02548 printk (KERN_INFO "NAND device: Manufacturer ID:"
02549 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
02550 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
02551 break;
02552 }
02553
02554 if (!nand_flash_ids[i].name) {
02555 printk (KERN_WARNING "No NAND device found!!!\n");
02556 this->select_chip(mtd, -1);
02557 return 1;
02558 }
02559
02560 for (i=1; i < maxchips; i++) {
02561 this->select_chip(mtd, i);
02562
02563
02564 this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
02565
02566
02567 if (nand_maf_id != this->read_byte(mtd) ||
02568 nand_dev_id != this->read_byte(mtd))
02569 break;
02570 }
02571 if (i > 1)
02572 printk(KERN_INFO "%d NAND chips detected\n", i);
02573
02574
02575 if (!this->oob_buf) {
02576 size_t len;
02577 len = mtd->oobsize << (this->phys_erase_shift - this->page_shift);
02578 this->oob_buf = kmalloc (len, GFP_KERNEL);
02579 if (!this->oob_buf) {
02580 printk (KERN_ERR "nand_scan(): Cannot allocate oob_buf\n");
02581 return -ENOMEM;
02582 }
02583 this->options |= NAND_OOBBUF_ALLOC;
02584 }
02585
02586 if (!this->data_buf) {
02587 size_t len;
02588 len = mtd->oobblock + mtd->oobsize;
02589 this->data_buf = kmalloc (len, GFP_KERNEL);
02590 if (!this->data_buf) {
02591 if (this->options & NAND_OOBBUF_ALLOC)
02592 kfree (this->oob_buf);
02593 printk (KERN_ERR "nand_scan(): Cannot allocate data_buf\n");
02594 return -ENOMEM;
02595 }
02596 this->options |= NAND_DATABUF_ALLOC;
02597 }
02598
02599
02600 this->numchips = i;
02601 mtd->size = i * this->chipsize;
02602
02603
02604 this->pagemask = (this->chipsize >> this->page_shift) - 1;
02605
02606 memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift));
02607
02608
02609
02610 if (!this->autooob) {
02611
02612
02613 switch (mtd->oobsize) {
02614 case 8:
02615 this->autooob = &nand_oob_8;
02616 break;
02617 case 16:
02618 this->autooob = &nand_oob_16;
02619 break;
02620 case 64:
02621 this->autooob = &nand_oob_64;
02622 break;
02623 default:
02624 printk (KERN_WARNING "No oob scheme defined for oobsize %d\n",
02625 mtd->oobsize);
02626 BUG();
02627 }
02628 }
02629
02630
02631
02632 mtd->oobavail = 0;
02633 for (i = 0; this->autooob->oobfree[i][1]; i++)
02634 mtd->oobavail += this->autooob->oobfree[i][1];
02635
02636
02637
02638
02639
02640
02641 this->eccsize = 256;
02642 this->eccbytes = 3;
02643
02644 switch (this->eccmode) {
02645 #if NAND_HWECC_SUPPORT
02646 case NAND_ECC_HW12_2048:
02647 if (mtd->oobblock < 2048) {
02648 printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
02649 mtd->oobblock);
02650 this->eccmode = NAND_ECC_SOFT;
02651 this->calculate_ecc = nand_calculate_ecc;
02652 this->correct_data = nand_correct_data;
02653 } else
02654 this->eccsize = 2048;
02655 break;
02656
02657 case NAND_ECC_HW3_512:
02658 case NAND_ECC_HW6_512:
02659 case NAND_ECC_HW8_512:
02660 if (mtd->oobblock == 256) {
02661 printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
02662 this->eccmode = NAND_ECC_SOFT;
02663 this->calculate_ecc = nand_calculate_ecc;
02664 this->correct_data = nand_correct_data;
02665 } else
02666 this->eccsize = 512;
02667 break;
02668
02669 case NAND_ECC_HW3_256:
02670 break;
02671 #endif
02672
02673 case NAND_ECC_NONE:
02674 printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
02675 this->eccmode = NAND_ECC_NONE;
02676 break;
02677
02678 case NAND_ECC_SOFT:
02679 this->calculate_ecc = nand_calculate_ecc;
02680 this->correct_data = nand_correct_data;
02681 break;
02682
02683 default:
02684 printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
02685 BUG();
02686 }
02687
02688
02689
02690
02691 switch (this->eccmode) {
02692 case NAND_ECC_HW12_2048:
02693 this->eccbytes += 4;
02694 case NAND_ECC_HW8_512:
02695 this->eccbytes += 2;
02696 case NAND_ECC_HW6_512:
02697 this->eccbytes += 3;
02698 case NAND_ECC_HW3_512:
02699 case NAND_ECC_HW3_256:
02700 if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
02701 break;
02702 printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
02703 BUG();
02704 }
02705
02706 mtd->eccsize = this->eccsize;
02707
02708
02709 switch (this->eccmode) {
02710 case NAND_ECC_HW12_2048:
02711 this->eccsteps = mtd->oobblock / 2048;
02712 break;
02713 case NAND_ECC_HW3_512:
02714 case NAND_ECC_HW6_512:
02715 case NAND_ECC_HW8_512:
02716 this->eccsteps = mtd->oobblock / 512;
02717 break;
02718 case NAND_ECC_HW3_256:
02719 case NAND_ECC_SOFT:
02720 this->eccsteps = mtd->oobblock / 256;
02721 break;
02722
02723 case NAND_ECC_NONE:
02724 this->eccsteps = 1;
02725 break;
02726 }
02727
02728
02729 this->state = FL_READY;
02730 init_waitqueue_head (&this->wq);
02731 spin_lock_init (&this->chip_lock);
02732
02733
02734 this->select_chip(mtd, -1);
02735
02736
02737 this->pagebuf = -1;
02738
02739
02740 mtd->type = MTD_NANDFLASH;
02741 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
02742 mtd->ecctype = MTD_ECC_SW;
02743 mtd->erase = nand_erase;
02744 mtd->point = NULL;
02745 mtd->unpoint = NULL;
02746 mtd->read = nand_read;
02747 mtd->write = nand_write;
02748 mtd->read_ecc = nand_read_ecc;
02749 mtd->write_ecc = nand_write_ecc;
02750 mtd->read_oob = nand_read_oob;
02751 mtd->write_oob = nand_write_oob;
02752 mtd->readv = NULL;
02753 mtd->writev = nand_writev;
02754 mtd->writev_ecc = nand_writev_ecc;
02755 mtd->sync = nand_sync;
02756 mtd->lock = NULL;
02757 mtd->unlock = NULL;
02758 mtd->suspend = nand_suspend;
02759 mtd->resume = nand_resume;
02760 mtd->block_isbad = nand_block_isbad;
02761 mtd->block_markbad = nand_block_markbad;
02762
02763
02764 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
02765
02766 mtd->owner = THIS_MODULE;
02767
02768
02769 if (this->options & NAND_SKIP_BBTSCAN)
02770 return 0;
02771
02772 puts("mtd->size == ");
02773 putx(mtd->size);
02774 putnl();
02775
02776 return this->scan_bbt (mtd);
02777 }
02778
02783 void nand_release (struct mtd_info *mtd)
02784 {
02785 struct nand_chip *this = mtd->priv;
02786
02787 #ifdef CONFIG_MTD_PARTITIONS
02788
02789 del_mtd_partitions (mtd);
02790 #endif
02791
02792 del_mtd_device (mtd);
02793
02794
02795 kfree (this->bbt);
02796
02797 if (this->options & NAND_OOBBUF_ALLOC)
02798 kfree (this->oob_buf);
02799
02800 if (this->options & NAND_DATABUF_ALLOC)
02801 kfree (this->data_buf);
02802 }
02803
02804 EXPORT_SYMBOL_GPL (nand_scan);
02805 EXPORT_SYMBOL_GPL (nand_release);
02806
02807 MODULE_LICENSE ("GPL");
02808 MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
02809 MODULE_DESCRIPTION ("Generic NAND flash driver code");