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 #define dprintf if(0)printf
00075
00076 #if 0
00077 #include <linux/delay.h>
00078 #include <linux/errno.h>
00079 #include <linux/sched.h>
00080 #include <linux/slab.h>
00081 #include <linux/types.h>
00082 #endif
00083
00084
00085 #include <axisrfl/mtd.h>
00086 #include <axisrfl/mtd_nand.h>
00087 #include <axisrfl/nand_ecc.h>
00088
00089 #include <axisrfl/funcs.h>
00090
00091
00092 #include <bitops.h>
00093
00094 #include <hal_intr.h>
00095 #include <string.h>
00096
00097 #if 0
00098 #include <linux/mtd/compatmac.h>
00099 #include <linux/interrupt.h>
00100 #include <linux/bitops.h>
00101 #include <asm/io.h>
00102
00103 #ifdef CONFIG_MTD_PARTITIONS
00104 #include <linux/mtd/partitions.h>
00105
00106 #endif
00107 #endif
00108
00109
00110
00111 #include <axisrfl/linuxerr.h>
00112
00113 #define udelay(x) HAL_DELAY_US(x)
00114 #undef nop
00115 #define nop() __asm__("nop")
00116
00117 #define ndelay(x) do { nop(); nop(); nop(); nop(); \
00118 nop(); nop(); nop(); nop(); } while (0)
00119
00120 #define GPIO_SYNC 0
00121
00122 #undef DEBUG
00123 #define DEBUG(n, args...) do { } while(0)
00124
00125 #define D(x) x
00126
00127
00128 static struct nand_oobinfo nand_oob_8 = {
00129 .useecc = MTD_NANDECC_AUTOPLACE,
00130 .eccbytes = 3,
00131 .eccpos = {0, 1, 2},
00132 .oobfree = { {3, 2}, {6, 2} }
00133 };
00134
00135 static struct nand_oobinfo nand_oob_16 = {
00136 .useecc = MTD_NANDECC_AUTOPLACE,
00137 .eccbytes = 6,
00138 .eccpos = {0, 1, 2, 3, 6, 7},
00139 .oobfree = { {8, 8} }
00140 };
00141
00142 static struct nand_oobinfo nand_oob_64 = {
00143 .useecc = MTD_NANDECC_AUTOPLACE,
00144 .eccbytes = 24,
00145 .eccpos = {
00146 40, 41, 42, 43, 44, 45, 46, 47,
00147 48, 49, 50, 51, 52, 53, 54, 55,
00148 56, 57, 58, 59, 60, 61, 62, 63},
00149 .oobfree = { {2, 38} }
00150 };
00151
00152
00153 #if NAND_WRITE_SUPPORT
00154 static u_char ffchars[] = {
00155 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00156 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00157 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00158 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00159 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00160 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00161 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00162 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00163 };
00164 #endif
00165
00166
00167
00168
00169
00170 static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
00171 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
00172 static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
00173
00174 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
00175 static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
00176 size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
00177 static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
00178 #if NAND_WRITE_SUPPORT
00179 static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
00180 static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
00181 size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
00182 static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
00183 #endif
00184 #if NAND_KVEC_SUPPORT
00185 static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
00186 unsigned long count, loff_t to, size_t * retlen);
00187 static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
00188 unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
00189 #endif
00190 #if NAND_ERASE_SUPPORT
00191 static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
00192 #endif
00193 #if 0
00194 static void nand_sync (struct mtd_info *mtd);
00195 #endif
00196
00197
00198 #if NAND_WRITE_SUPPORT
00199 static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
00200 struct nand_oobinfo *oobsel, int mode);
00201 #endif
00202 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
00203 #if NAND_WRITE_SUPPORT
00204 static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
00205 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
00206 #endif
00207 #else
00208 #define nand_verify_pages(...) (0)
00209 #endif
00210
00211 static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
00212
00219 static void nand_release_device (struct mtd_info *mtd)
00220 {
00221 struct nand_chip *this = mtd->priv;
00222
00223
00224 this->select_chip(mtd, -1);
00225 #if 0
00226
00227 if (this->controller) {
00228
00229 spin_lock(&this->controller->lock);
00230 this->controller->active = NULL;
00231 this->state = FL_READY;
00232 wake_up(&this->controller->wq);
00233 spin_unlock(&this->controller->lock);
00234 } else {
00235
00236 spin_lock(&this->chip_lock);
00237 this->state = FL_READY;
00238 wake_up(&this->wq);
00239 spin_unlock(&this->chip_lock);
00240 }
00241 #endif
00242 }
00243
00250 static u_char nand_read_byte(struct mtd_info *mtd)
00251 {
00252 u_char tmp;
00253 struct nand_chip *this = mtd->priv;
00254 tmp = readb(this->IO_ADDR_R);
00255 dprintf(">nand_read_byte(%s) = 0x%x\n", __FILE__, tmp);
00256 return tmp;
00257 }
00258
00266 static void nand_write_byte(struct mtd_info *mtd, u_char byte)
00267 {
00268 struct nand_chip *this = mtd->priv;
00269 dprintf(">nand_write_byte(%s) 0x%x = 0x%x\n", __FILE__, this->IO_ADDR_W, byte);
00270 writeb(byte, this->IO_ADDR_W);
00271
00272 #if GPIO_SYNC
00273
00274
00275
00276
00277
00278
00279
00280
00281 (void) readb(this->IO_ADDR_W);
00282 #endif
00283 }
00284
00292 #if NAND_BUSWIDTH16_SUPPORT
00293 static u_char nand_read_byte16(struct mtd_info *mtd)
00294 {
00295 struct nand_chip *this = mtd->priv;
00296 return (u_char) cpu_to_le16(readw(this->IO_ADDR_R));
00297 }
00298 #endif
00299
00308 #if NAND_BUSWIDTH16_SUPPORT
00309 static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
00310 {
00311 struct nand_chip *this = mtd->priv;
00312 writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
00313 }
00314 #endif
00315
00323 static u16 nand_read_word(struct mtd_info *mtd)
00324 {
00325 struct nand_chip *this = mtd->priv;
00326 return readw(this->IO_ADDR_R);
00327 }
00328
00337 static void nand_write_word(struct mtd_info *mtd, u16 word)
00338 {
00339 struct nand_chip *this = mtd->priv;
00340 writew(word, this->IO_ADDR_W);
00341 }
00342
00350 static void nand_select_chip(struct mtd_info *mtd, int chip)
00351 {
00352 struct nand_chip *this = mtd->priv;
00353 switch(chip) {
00354 case -1:
00355 this->hwcontrol(mtd, NAND_CTL_CLRNCE);
00356 break;
00357 case 0:
00358 this->hwcontrol(mtd, NAND_CTL_SETNCE);
00359 break;
00360
00361 default:
00362 D(printk("nand_select_chip: invalid chip no %d\n", chip));
00363 BUG();
00364 }
00365 }
00366
00375 static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
00376 {
00377 int i;
00378 struct nand_chip *this = mtd->priv;
00379
00380 dprintf(">nand_write_buf len %d\n", len);
00381
00382 for (i=0; i<len; i++) {
00383 dprintf(">nand_write_buf 0x%x\n", buf[i]);
00384 writeb(buf[i], this->IO_ADDR_W);
00385 }
00386 }
00387
00396 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
00397 {
00398 int i;
00399 struct nand_chip *this = mtd->priv;
00400
00401 for (i=0; i<len; i++) {
00402 buf[i] = readb(this->IO_ADDR_R);
00403 dprintf(">%s(%s) 0x%x 0x%x\n", __FUNCTION__, __FILE__, &buf[i], buf[i]);
00404 }
00405 }
00406
00415 static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
00416 {
00417 int i;
00418 struct nand_chip *this = mtd->priv;
00419
00420 for (i=0; i<len; i++)
00421 if (buf[i] != readb(this->IO_ADDR_R))
00422 return -EFAULT;
00423
00424 return 0;
00425 }
00426
00435 #if NAND_BUSWIDTH16_SUPPORT
00436 static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
00437 {
00438 int i;
00439 struct nand_chip *this = mtd->priv;
00440 u16 *p = (u16 *) buf;
00441 len >>= 1;
00442
00443 for (i=0; i<len; i++)
00444 writew(p[i], this->IO_ADDR_W);
00445
00446 }
00447 #endif
00448
00457 #if NAND_BUSWIDTH16_SUPPORT
00458 static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
00459 {
00460 int i;
00461 struct nand_chip *this = mtd->priv;
00462 u16 *p = (u16 *) buf;
00463 len >>= 1;
00464
00465 for (i=0; i<len; i++)
00466 p[i] = readw(this->IO_ADDR_R);
00467 }
00468 #endif
00469
00478 #if NAND_BUSWIDTH16_SUPPORT
00479 static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
00480 {
00481 int i;
00482 struct nand_chip *this = mtd->priv;
00483 u16 *p = (u16 *) buf;
00484 len >>= 1;
00485
00486 for (i=0; i<len; i++)
00487 if (p[i] != readw(this->IO_ADDR_R))
00488 return -EFAULT;
00489
00490 return 0;
00491 }
00492 #endif
00493
00502 static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
00503 {
00504 int page, chipnr, res = 0;
00505 struct nand_chip *this = mtd->priv;
00506 #if NAND_BUSWIDTH16_SUPPORT
00507 u16 bad;
00508 #endif
00509
00510 dprintf(">nand_block_bad(%s) %d\n", __FILE__, ofs);
00511
00512 dprintf(">nand_block_bad(%s) ignore %d\n", __FILE__, mtd->ignore_bad);
00513
00514 if (mtd->ignore_bad) {
00515 return 0;
00516 }
00517
00518 if (getchip) {
00519 page = (int)(ofs >> this->page_shift);
00520 dprintf("page %d %d\n", page, this->page_shift);
00521 chipnr = (int)(ofs >> this->chip_shift);
00522
00523
00524 nand_get_device (this, mtd, FL_READING);
00525
00526
00527 this->select_chip(mtd, chipnr);
00528 } else
00529 page = (int) ofs;
00530
00531 #if NAND_BUSWIDTH16_SUPPORT
00532 if (this->options & NAND_BUSWIDTH_16) {
00533 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
00534 bad = cpu_to_le16(this->read_word(mtd));
00535 if (this->badblockpos & 0x1)
00536 bad >>= 8;
00537 if ((bad & 0xFF) != 0xff)
00538 res = 1;
00539 } else
00540 #endif
00541 {
00542 this->cmdfunc(mtd, NAND_CMD_READOOB, this->badblockpos, page & this->pagemask);
00543 if (this->read_byte(mtd) != 0xff)
00544 res = 1;
00545 }
00546
00547 if (getchip) {
00548
00549 nand_release_device(mtd);
00550 }
00551
00552 return res;
00553 }
00554
00563 #if NAND_WRITE_SUPPORT
00564 static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
00565 {
00566 struct nand_chip *this = mtd->priv;
00567 u_char buf[2] = {0, 0};
00568 size_t retlen;
00569 int block;
00570
00571
00572 block = ((int) ofs) >> this->bbt_erase_shift;
00573 if (this->bbt)
00574 this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
00575
00576 #if NAND_BBT_SUPPORT
00577
00578 if (this->options & NAND_USE_FLASH_BBT)
00579 return nand_update_bbt (mtd, ofs);
00580 #endif
00581
00582
00583
00584 ofs += (this->badblockpos & ~0x01);
00585 return nand_write_oob(mtd, ofs , 2, &retlen, buf);
00586 }
00587 #endif
00588
00596 #if NAND_WRITE_SUPPORT
00597 static int nand_check_wp (struct mtd_info *mtd)
00598 {
00599 struct nand_chip *this = mtd->priv;
00600
00601 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
00602 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
00603 }
00604 #endif
00605
00616 static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
00617 {
00618 struct nand_chip *this = mtd->priv;
00619
00620 dprintf(">nand_block_checkbad(%s) %d\n", __FILE__, ofs);
00621
00622 if (!this->bbt)
00623 return this->block_bad(mtd, ofs, getchip);
00624
00625 #if NAND_BBT_SUPPORT
00626
00627 return nand_isbad_bbt (mtd, ofs, allowbbt);
00628 #endif
00629 D(printk("nand_block_checkbad: device has bbt but no bbt support configured\n"));
00630 BUG();
00631 }
00632
00633
00634
00635
00636
00637 static void nand_wait_ready(struct mtd_info *mtd)
00638 {
00639 struct nand_chip *this = mtd->priv;
00640
00641
00642 do {
00643 if (this->dev_ready(mtd))
00644 return;
00645 } while (1);
00646 }
00647
00648 char*
00649 command_str(unsigned cmd) {
00650 switch(cmd) {
00651 case 0x00:
00652 return "READ1";
00653 case 0x10:
00654 return "PAGE PROGRAM(2)";
00655 case 0x50:
00656 return "READ2";
00657 case 0x60:
00658 return "ERASE";
00659 case 0x70:
00660 return "READ STATUS";
00661 case 0x80:
00662 return "PAGE PROGRAM";
00663 case 0x90:
00664 return "READ ID";
00665 case 0xd0:
00666 return "ERASE(2)";
00667 case 0xff:
00668 return "RESET";
00669 default:
00670 return "UNKNOWN";
00671 }
00672 }
00673
00684 static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
00685 {
00686 register struct nand_chip *this = mtd->priv;
00687
00688
00689 dprintf(">nand_command(%s): mtd_info: 0x%8.8x, command %s(0x%2x), col %d, page_addr %d\n",
00690 __FILE__, mtd, command_str(command), command, column, page_addr);
00691
00692 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00693
00694
00695
00696 if (command == NAND_CMD_SEQIN) {
00697 int readcmd;
00698
00699 if (column >= mtd->oobblock) {
00700
00701 column -= mtd->oobblock;
00702 readcmd = NAND_CMD_READOOB;
00703 } else if (column < 256) {
00704
00705 readcmd = NAND_CMD_READ0;
00706 } else {
00707 column -= 256;
00708 readcmd = NAND_CMD_READ1;
00709 }
00710 this->write_byte(mtd, readcmd);
00711 }
00712
00713 this->write_byte(mtd, command);
00714
00715
00716 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00717
00718 if (column != -1 || page_addr != -1) {
00719
00720 this->hwcontrol(mtd, NAND_CTL_SETALE);
00721
00722
00723 if (column != -1) {
00724
00725 if (this->options & NAND_BUSWIDTH_16)
00726 column >>= 1;
00727 this->write_byte(mtd, column);
00728 }
00729 if (page_addr != -1) {
00730 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
00731 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
00732
00733 if (this->chipsize > (32 << 20))
00734 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
00735 }
00736
00737 this->hwcontrol(mtd, NAND_CTL_CLRALE);
00738 }
00739
00740
00741
00742
00743
00744 switch (command) {
00745
00746 case NAND_CMD_PAGEPROG:
00747 case NAND_CMD_ERASE1:
00748 case NAND_CMD_ERASE2:
00749 case NAND_CMD_SEQIN:
00750 case NAND_CMD_STATUS:
00751 return;
00752
00753 case NAND_CMD_RESET:
00754 if (this->dev_ready)
00755 break;
00756 udelay(this->chip_delay);
00757 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00758 this->write_byte(mtd, NAND_CMD_STATUS);
00759 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00760 while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
00761 return;
00762
00763
00764 default:
00765
00766
00767
00768
00769 if (!this->dev_ready) {
00770 udelay (this->chip_delay);
00771 return;
00772 }
00773 }
00774
00775
00776 ndelay (100);
00777
00778 nand_wait_ready(mtd);
00779
00780 }
00781
00794 static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr)
00795 {
00796 register struct nand_chip *this = mtd->priv;
00797
00798
00799 if (command == NAND_CMD_READOOB) {
00800 column += mtd->oobblock;
00801 command = NAND_CMD_READ0;
00802 }
00803
00804
00805
00806 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00807
00808 this->write_byte(mtd, (command & 0xff));
00809
00810 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00811
00812 if (column != -1 || page_addr != -1) {
00813 this->hwcontrol(mtd, NAND_CTL_SETALE);
00814
00815
00816 if (column != -1) {
00817
00818 if (this->options & NAND_BUSWIDTH_16)
00819 column >>= 1;
00820 this->write_byte(mtd, column & 0xff);
00821 this->write_byte(mtd, column >> 8);
00822 }
00823 if (page_addr != -1) {
00824 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
00825 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
00826
00827 if (this->chipsize > (128 << 20))
00828 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff));
00829 }
00830
00831 this->hwcontrol(mtd, NAND_CTL_CLRALE);
00832 }
00833
00834
00835
00836
00837
00838 switch (command) {
00839
00840 case NAND_CMD_CACHEDPROG:
00841 case NAND_CMD_PAGEPROG:
00842 case NAND_CMD_ERASE1:
00843 case NAND_CMD_ERASE2:
00844 case NAND_CMD_SEQIN:
00845 case NAND_CMD_STATUS:
00846 case NAND_CMD_DEPLETE1:
00847 return;
00848
00849
00850
00851
00852 case NAND_CMD_STATUS_ERROR:
00853 case NAND_CMD_STATUS_ERROR0:
00854 case NAND_CMD_STATUS_ERROR1:
00855 case NAND_CMD_STATUS_ERROR2:
00856 case NAND_CMD_STATUS_ERROR3:
00857 udelay(this->chip_delay);
00858 return;
00859
00860 case NAND_CMD_RESET:
00861 if (this->dev_ready)
00862 break;
00863 udelay(this->chip_delay);
00864 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00865 this->write_byte(mtd, NAND_CMD_STATUS);
00866 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00867 while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
00868 return;
00869
00870 case NAND_CMD_READ0:
00871
00872 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00873
00874 this->write_byte(mtd, NAND_CMD_READSTART);
00875
00876 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00877
00878
00879
00880 default:
00881
00882
00883
00884
00885 if (!this->dev_ready) {
00886 udelay (this->chip_delay);
00887 return;
00888 }
00889 }
00890
00891
00892
00893 ndelay (100);
00894
00895 nand_wait_ready(mtd);
00896 }
00897
00906 static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
00907 {
00908 this->state = new_state;
00909 return 0;
00910 #if 0
00911 struct nand_chip *active;
00912 spinlock_t *lock;
00913 wait_queue_head_t *wq;
00914 DECLARE_WAITQUEUE (wait, current);
00915
00916 lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
00917 wq = (this->controller) ? &this->controller->wq : &this->wq;
00918 retry:
00919 active = this;
00920 spin_lock(lock);
00921
00922
00923 if (this->controller) {
00924 if (this->controller->active)
00925 active = this->controller->active;
00926 else
00927 this->controller->active = this;
00928 }
00929 if (active == this && this->state == FL_READY) {
00930 this->state = new_state;
00931 spin_unlock(lock);
00932 return 0;
00933 }
00934 if (new_state == FL_PM_SUSPENDED) {
00935 spin_unlock(lock);
00936 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
00937 }
00938 set_current_state(TASK_UNINTERRUPTIBLE);
00939 add_wait_queue(wq, &wait);
00940 spin_unlock(lock);
00941 schedule();
00942 remove_wait_queue(wq, &wait);
00943 goto retry;
00944 #endif
00945 }
00946
00958 static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
00959 {
00960
00961 #if 0
00962 unsigned long timeo = jiffies;
00963 #endif
00964 int status;
00965
00966 dprintf(">%s(%s)\n", __FUNCTION__, __FILE__);
00967 #if 0
00968 if (state == FL_ERASING)
00969 timeo += (HZ * 400) / 1000;
00970 else
00971 timeo += (HZ * 20) / 1000;
00972 #endif
00973
00974
00975
00976 ndelay (100);
00977
00978 if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
00979 this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
00980 else
00981 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
00982
00983 #if 0
00984 while (time_before(jiffies, timeo)) {
00985
00986 if (this->state != state)
00987 return 0;
00988 #endif
00989 while (1) {
00990
00991 if (this->dev_ready) {
00992 if (this->dev_ready(mtd))
00993 break;
00994 } else {
00995 if (this->read_byte(mtd) & NAND_STATUS_READY)
00996 break;
00997 }
00998
00999 #if 0
01000 cond_resched();
01001 #endif
01002 }
01003 status = (int) this->read_byte(mtd);
01004 return status;
01005 }
01006
01022 #if NAND_WRITE_SUPPORT
01023 static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
01024 u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
01025 {
01026 int i, status;
01027 u_char ecc_code[32];
01028 int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
01029 int *oob_config = oobsel->eccpos;
01030 int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
01031 int eccbytes = 0;
01032
01033
01034
01035 cached = 0;
01036
01037
01038 this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
01039
01040
01041 switch (eccmode) {
01042
01043 case NAND_ECC_NONE:
01044 D(printk("Writing data without ECC to NAND-FLASH is not recommended\n"));
01045 this->write_buf(mtd, this->data_poi, mtd->oobblock);
01046 break;
01047
01048
01049 case NAND_ECC_SOFT:
01050
01051 for (; eccsteps; eccsteps--) {
01052 this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
01053 for (i = 0; i < 3; i++, eccidx++) {
01054 oob_buf[oob_config[eccidx]] = ecc_code[i];
01055
01056 }
01057 datidx += this->eccsize;
01058 }
01059
01060 this->write_buf(mtd, this->data_poi, mtd->oobblock);
01061 break;
01062 default:
01063 eccbytes = this->eccbytes;
01064 for (; eccsteps; eccsteps--) {
01065
01066 this->enable_hwecc(mtd, NAND_ECC_WRITE);
01067 this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
01068 this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
01069 for (i = 0; i < eccbytes; i++, eccidx++)
01070 oob_buf[oob_config[eccidx]] = ecc_code[i];
01071
01072
01073
01074 if (this->options & NAND_HWECC_SYNDROME)
01075 this->write_buf(mtd, ecc_code, eccbytes);
01076 datidx += this->eccsize;
01077 }
01078 break;
01079 }
01080
01081
01082 if (this->options & NAND_HWECC_SYNDROME)
01083 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
01084 else {
01085
01086 this->write_buf(mtd, oob_buf, mtd->oobsize);
01087 }
01088
01089
01090 this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
01091
01092 if (!cached) {
01093
01094 status = this->waitfunc (mtd, this, FL_WRITING);
01095
01096
01097 if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
01098 status = this->errstat(mtd, this, FL_WRITING, status, page);
01099 }
01100
01101
01102 if (status & NAND_STATUS_FAIL) {
01103 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
01104 return -EIO;
01105 }
01106 } else {
01107
01108
01109
01110 }
01111 return 0;
01112 }
01113 #endif
01114
01115 #if NAND_WRITE_SUPPORT
01116 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
01117
01136 static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
01137 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
01138 {
01139 int i, j, datidx = 0, oobofs = 0, res = -EIO;
01140 int eccsteps = this->eccsteps;
01141 int hweccbytes;
01142 u_char oobdata[64];
01143
01144 hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
01145
01146
01147 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
01148
01149 for(;;) {
01150 for (j = 0; j < eccsteps; j++) {
01151
01152 if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) {
01153 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
01154 goto out;
01155 }
01156 datidx += mtd->eccsize;
01157
01158 if (!hweccbytes)
01159 continue;
01160 if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
01161 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
01162 goto out;
01163 }
01164 oobofs += hweccbytes;
01165 }
01166
01167
01168
01169
01170 if (oobmode) {
01171 if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) {
01172 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
01173 goto out;
01174 }
01175 } else {
01176
01177 this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);
01178
01179 if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
01180 int ecccnt = oobsel->eccbytes;
01181
01182 for (i = 0; i < ecccnt; i++) {
01183 int idx = oobsel->eccpos[i];
01184 if (oobdata[idx] != oob_buf[oobofs + idx] ) {
01185 DEBUG (MTD_DEBUG_LEVEL0,
01186 "%s: Failed ECC write "
01187 "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
01188 goto out;
01189 }
01190 }
01191 }
01192 }
01193 oobofs += mtd->oobsize - hweccbytes * eccsteps;
01194 page++;
01195 numpages--;
01196
01197
01198
01199
01200
01201
01202
01203
01204 if (!this->dev_ready)
01205 udelay (this->chip_delay);
01206 else
01207 nand_wait_ready(mtd);
01208
01209
01210 if (!numpages)
01211 return 0;
01212
01213
01214
01215 if (!NAND_CANAUTOINCR(this))
01216 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
01217 }
01218
01219
01220
01221
01222 out:
01223 this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
01224 return res;
01225 }
01226 #endif
01227 #endif
01228
01240 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
01241 {
01242 return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
01243 }
01244
01245
01258 static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
01259 size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
01260 {
01261
01262 if (oobsel == NULL)
01263 oobsel = &mtd->oobinfo;
01264 return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff);
01265 }
01266
01267
01284 int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
01285 size_t * retlen, u_char * buf, u_char * oob_buf,
01286 struct nand_oobinfo *oobsel, int flags)
01287 {
01288
01289 int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
01290 int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
01291 struct nand_chip *this = mtd->priv;
01292 u_char *data_poi, *oob_data = oob_buf;
01293 u_char ecc_calc[32];
01294 u_char ecc_code[32];
01295 int eccmode, eccsteps;
01296 int *oob_config, datidx;
01297 int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
01298 int eccbytes;
01299 int compareecc = 1;
01300 int oobreadlen;
01301
01302 DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
01303
01304
01305 if ((from + len) > mtd->size) {
01306 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of device\n");
01307 *retlen = 0;
01308 return -EINVAL;
01309 }
01310
01311
01312 if (flags & NAND_GET_DEVICE)
01313 nand_get_device (this, mtd, FL_READING);
01314
01315
01316 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
01317 oobsel = this->autooob;
01318
01319 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
01320 oob_config = oobsel->eccpos;
01321
01322
01323 chipnr = (int)(from >> this->chip_shift);
01324 this->select_chip(mtd, chipnr);
01325
01326
01327 realpage = (int) (from >> this->page_shift);
01328 page = realpage & this->pagemask;
01329
01330
01331 col = from & (mtd->oobblock - 1);
01332
01333 end = mtd->oobblock;
01334 ecc = this->eccsize;
01335 eccbytes = this->eccbytes;
01336
01337 if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
01338 compareecc = 0;
01339
01340 oobreadlen = mtd->oobsize;
01341 if (this->options & NAND_HWECC_SYNDROME)
01342 oobreadlen -= oobsel->eccbytes;
01343
01344
01345 while (read < len) {
01346
01347 int aligned = (!col && (len - read) >= end);
01348
01349
01350
01351
01352 if (aligned)
01353 data_poi = &buf[read];
01354 else
01355 data_poi = this->data_buf;
01356
01357
01358
01359
01360
01361
01362 if (realpage == this->pagebuf && !oob_buf) {
01363
01364 if (aligned)
01365 memcpy (data_poi, this->data_buf, end);
01366 goto readdata;
01367 }
01368
01369
01370 if (sndcmd) {
01371 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
01372 sndcmd = 0;
01373 }
01374
01375
01376 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
01377 oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
01378 oob_data = &this->data_buf[end];
01379
01380 eccsteps = this->eccsteps;
01381
01382 switch (eccmode) {
01383 case NAND_ECC_NONE: {
01384 #if 0
01385 static unsigned long lastwhinge = 0;
01386 if ((lastwhinge / HZ) != (jiffies / HZ)) {
01387 D(printk ("Reading data from NAND FLASH without ECC is not recommended\n"));
01388 lastwhinge = jiffies;
01389 }
01390 #endif
01391 this->read_buf(mtd, data_poi, end);
01392 break;
01393 }
01394
01395 case NAND_ECC_SOFT:
01396 this->read_buf(mtd, data_poi, end);
01397 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
01398 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
01399 break;
01400
01401 default:
01402 #if NAND_HWECC_SUPPORT
01403 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
01404 this->enable_hwecc(mtd, NAND_ECC_READ);
01405 this->read_buf(mtd, &data_poi[datidx], ecc);
01406
01407
01408
01409 if (!compareecc) {
01410
01411
01412 this->enable_hwecc(mtd, NAND_ECC_READSYN);
01413 this->read_buf(mtd, &oob_data[i], eccbytes);
01414
01415
01416
01417 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
01418 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
01419 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
01420 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
01421 ecc_failed++;
01422 }
01423 } else {
01424 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
01425 }
01426 }
01427 #endif
01428 break;
01429 }
01430
01431
01432 this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
01433
01434
01435 if (!compareecc)
01436 goto readoob;
01437
01438
01439 for (j = 0; j < oobsel->eccbytes; j++)
01440 ecc_code[j] = oob_data[oob_config[j]];
01441
01442
01443 for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
01444 ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
01445
01446
01447 j += eccbytes;
01448
01449
01450
01451
01452
01453 if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
01454 int *p = (int *)(&oob_data[mtd->oobsize]);
01455 p[i] = ecc_status;
01456 }
01457
01458 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
01459 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
01460 ecc_failed++;
01461 }
01462 }
01463
01464 readoob:
01465
01466 if (oob_buf) {
01467
01468 switch(oobsel->useecc) {
01469 case MTD_NANDECC_AUTOPLACE:
01470 case MTD_NANDECC_AUTOPL_USR:
01471
01472 for (i = 0; oobsel->oobfree[i][1]; i++) {
01473 int from = oobsel->oobfree[i][0];
01474 int num = oobsel->oobfree[i][1];
01475 memcpy(&oob_buf[oob], &oob_data[from], num);
01476 oob += num;
01477 }
01478 break;
01479 case MTD_NANDECC_PLACE:
01480
01481 oob_data += this->eccsteps * sizeof (int);
01482 default:
01483 oob_data += mtd->oobsize;
01484 }
01485 }
01486 readdata:
01487
01488 if (!aligned) {
01489 for (j = col; j < end && read < len; j++)
01490 buf[read++] = data_poi[j];
01491 this->pagebuf = realpage;
01492 } else
01493 read += mtd->oobblock;
01494
01495
01496
01497
01498
01499
01500 if (!this->dev_ready)
01501 udelay (this->chip_delay);
01502 else
01503 nand_wait_ready(mtd);
01504
01505 if (read == len)
01506 break;
01507
01508
01509 col = 0;
01510
01511 realpage++;
01512
01513 page = realpage & this->pagemask;
01514
01515 if (!page) {
01516 chipnr++;
01517 this->select_chip(mtd, -1);
01518 this->select_chip(mtd, chipnr);
01519 }
01520
01521
01522
01523 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
01524 sndcmd = 1;
01525 }
01526
01527
01528 if (flags & NAND_GET_DEVICE)
01529 nand_release_device(mtd);
01530
01531
01532
01533
01534
01535
01536 *retlen = read;
01537 return ecc_failed ? -EBADMSG : 0;
01538 }
01539
01550 static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
01551 {
01552 int i, col, page, chipnr;
01553 struct nand_chip *this = mtd->priv;
01554 int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
01555
01556 DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
01557
01558
01559 page = (int)(from >> this->page_shift);
01560 chipnr = (int)(from >> this->chip_shift);
01561
01562
01563 col = from & (mtd->oobsize - 1);
01564
01565
01566 *retlen = 0;
01567
01568
01569 if ((from + len) > mtd->size) {
01570 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of device\n");
01571 *retlen = 0;
01572 return -EINVAL;
01573 }
01574
01575
01576 nand_get_device(this, mtd , FL_READING);
01577
01578
01579 this->select_chip(mtd, chipnr);
01580
01581
01582 this->cmdfunc(mtd, NAND_CMD_READOOB, col, page & this->pagemask);
01583
01584
01585
01586
01587 i = 0;
01588 while (i < len) {
01589 int thislen = mtd->oobsize - col;
01590 thislen = min_t(int, thislen, len);
01591 this->read_buf(mtd, &buf[i], thislen);
01592 i += thislen;
01593
01594
01595 if (i < len) {
01596 page++;
01597 col = 0;
01598
01599
01600 if (!(page & this->pagemask)) {
01601 chipnr++;
01602 this->select_chip(mtd, -1);
01603 this->select_chip(mtd, chipnr);
01604 }
01605
01606
01607
01608
01609
01610
01611 if (!this->dev_ready)
01612 udelay(this->chip_delay);
01613 else
01614 nand_wait_ready(mtd);
01615
01616
01617
01618
01619 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
01620
01621 this->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
01622 }
01623 }
01624 }
01625
01626
01627 nand_release_device(mtd);
01628
01629
01630 *retlen = len;
01631 return 0;
01632 }
01633
01644 int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen)
01645 {
01646 struct nand_chip *this = mtd->priv;
01647 int page = (int) (from >> this->page_shift);
01648 int chip = (int) (from >> this->chip_shift);
01649 int sndcmd = 1;
01650 int cnt = 0;
01651 int pagesize = mtd->oobblock + mtd->oobsize;
01652 int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
01653
01654 dprintf(">nand_read_raw(%s) from 0x%x, len %d\n", __FILE__, from , len);
01655
01656
01657 if ((from + len) > mtd->size) {
01658 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt read beyond end of device\n");
01659 return -EINVAL;
01660 }
01661
01662
01663 nand_get_device (this, mtd , FL_READING);
01664
01665 this->select_chip (mtd, chip);
01666
01667
01668 len += ooblen;
01669
01670 while (len) {
01671 if (sndcmd)
01672 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
01673 sndcmd = 0;
01674
01675 this->read_buf (mtd, &buf[cnt], pagesize);
01676
01677 len -= pagesize;
01678 cnt += pagesize;
01679 page++;
01680
01681 if (!this->dev_ready)
01682 udelay (this->chip_delay);
01683 else
01684 nand_wait_ready(mtd);
01685
01686
01687 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
01688 sndcmd = 1;
01689 }
01690
01691
01692 nand_release_device(mtd);
01693 return 0;
01694 }
01695
01696
01720 #if NAND_WRITE_SUPPORT
01721 static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel,
01722 int autoplace, int numpages)
01723 {
01724 struct nand_chip *this = mtd->priv;
01725 int i, len, ofs;
01726
01727
01728 if (fsbuf && !autoplace)
01729 return fsbuf;
01730
01731
01732 if (this->oobdirty) {
01733 memset (this->oob_buf, 0xff,
01734 mtd->oobsize << (this->phys_erase_shift - this->page_shift));
01735 this->oobdirty = 0;
01736 }
01737
01738
01739 if (!autoplace || !fsbuf)
01740 return this->oob_buf;
01741
01742
01743 this->oobdirty = 1;
01744 ofs = 0;
01745 while (numpages--) {
01746 for (i = 0, len = 0; len < mtd->oobavail; i++) {
01747 int to = ofs + oobsel->oobfree[i][0];
01748 int num = oobsel->oobfree[i][1];
01749 memcpy (&this->oob_buf[to], fsbuf, num);
01750 len += num;
01751 fsbuf += num;
01752 }
01753 ofs += mtd->oobavail;
01754 }
01755 return this->oob_buf;
01756 }
01757 #endif
01758
01759 #define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
01760
01772 #if NAND_WRITE_SUPPORT
01773 static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
01774 {
01775 return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
01776 }
01777 #endif
01778
01791 #if NAND_WRITE_SUPPORT
01792 static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
01793 size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
01794 {
01795 int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr;
01796 int autoplace = 0, numpages, totalpages;
01797 struct nand_chip *this = mtd->priv;
01798 u_char *oobbuf, *bufstart;
01799 int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
01800
01801
01802 DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
01803
01804
01805 *retlen = 0;
01806
01807
01808 if ((to + len) > mtd->size) {
01809 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
01810 return -EINVAL;
01811 }
01812
01813
01814 if (NOTALIGNED (to) || NOTALIGNED(len)) {
01815 D(printk("nand_write_ecc: Attempt to write not page aligned data\n"));
01816 return -EINVAL;
01817 }
01818
01819
01820 nand_get_device (this, mtd, FL_WRITING);
01821
01822
01823 chipnr = (int)(to >> this->chip_shift);
01824
01825 this->select_chip(mtd, chipnr);
01826
01827
01828 if (nand_check_wp(mtd))
01829 goto out;
01830
01831
01832 if (oobsel == NULL)
01833 oobsel = &mtd->oobinfo;
01834
01835
01836 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
01837 oobsel = this->autooob;
01838 autoplace = 1;
01839 }
01840 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
01841 autoplace = 1;
01842
01843
01844 totalpages = len >> this->page_shift;
01845 page = (int) (to >> this->page_shift);
01846
01847 if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
01848 this->pagebuf = -1;
01849
01850
01851 page &= this->pagemask;
01852 startpage = page;
01853
01854 numpages = min_t (int, ppblock - (startpage & (ppblock - 1)), totalpages);
01855 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
01856 bufstart = (u_char *)buf;
01857
01858
01859 while (written < len) {
01860
01861 this->data_poi = (u_char*) &buf[written];
01862
01863
01864
01865
01866
01867 ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
01868 if (ret) {
01869 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
01870 goto out;
01871 }
01872
01873 oob += mtd->oobsize;
01874
01875 written += mtd->oobblock;
01876 if (written == len)
01877 goto cmp;
01878
01879
01880 page++;
01881
01882
01883
01884
01885
01886 if (!(page & (ppblock - 1))){
01887 int ofs;
01888 this->data_poi = bufstart;
01889 ret = nand_verify_pages (mtd, this, startpage,
01890 page - startpage,
01891 oobbuf, oobsel, chipnr, (eccbuf != NULL));
01892 if (ret) {
01893 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
01894 goto out;
01895 }
01896 *retlen = written;
01897
01898 ofs = autoplace ? mtd->oobavail : mtd->oobsize;
01899 if (eccbuf)
01900 eccbuf += (page - startpage) * ofs;
01901 totalpages -= page - startpage;
01902 numpages = min_t (int, totalpages, ppblock);
01903 page &= this->pagemask;
01904 startpage = page;
01905 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
01906 autoplace, numpages);
01907 oob = 0;
01908
01909 if (!page) {
01910 chipnr++;
01911 this->select_chip(mtd, -1);
01912 this->select_chip(mtd, chipnr);
01913 }
01914 }
01915 }
01916
01917 cmp:
01918 this->data_poi = bufstart;
01919 ret = nand_verify_pages (mtd, this, startpage, totalpages,
01920 oobbuf, oobsel, chipnr, (eccbuf != NULL));
01921 if (!ret)
01922 *retlen = written;
01923 else
01924 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
01925
01926 out:
01927
01928 nand_release_device(mtd);
01929
01930 return ret;
01931 }
01932 #endif
01933
01934
01945 #if NAND_WRITE_SUPPORT
01946 static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
01947 {
01948 int column, page, status, ret = -EIO, chipnr;
01949 struct nand_chip *this = mtd->priv;
01950
01951 DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
01952 (unsigned int) to, (int) len);
01953
01954 dprintf(">nand_write_oob(%s) %d %d\n", __FILE__, to, len);
01955
01956
01957 page = (int) (to >> this->page_shift);
01958 chipnr = (int) (to >> this->chip_shift);
01959
01960
01961 column = to & (mtd->oobsize - 1);
01962
01963 dprintf(">nand_write_oob(%s) page %d col %d\n", __FILE__, page, column);
01964
01965
01966 *retlen = 0;
01967
01968
01969 if ((column + len) > mtd->oobsize) {
01970 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
01971 return -EINVAL;
01972 }
01973
01974
01975 nand_get_device (this, mtd, FL_WRITING);
01976
01977
01978 this->select_chip(mtd, chipnr);
01979
01980
01981
01982
01983
01984
01985 this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
01986
01987
01988 if (nand_check_wp(mtd)) {
01989 goto out;
01990 }
01991
01992
01993 if (page == this->pagebuf)
01994 this->pagebuf = -1;
01995
01996 if (NAND_MUST_PAD(this)) {
01997 this->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
01998
01999
02000 this->write_buf(mtd, ffchars, column);
02001
02002 this->write_buf(mtd, buf, len);
02003
02004 this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
02005 } else {
02006
02007 this->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
02008
02009 this->write_buf(mtd, buf, len);
02010 }
02011
02012 this->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
02013
02014 status = this->waitfunc (mtd, this, FL_WRITING);
02015
02016
02017 if (status & NAND_STATUS_FAIL) {
02018 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
02019 ret = -EIO;
02020 goto out;
02021 }
02022
02023 *retlen = len;
02024
02025 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
02026
02027 this->cmdfunc(mtd, NAND_CMD_READOOB, column, page & this->pagemask);
02028
02029 if (this->verify_buf(mtd, buf, len)) {
02030 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
02031 ret = -EIO;
02032 goto out;
02033 }
02034 #endif
02035 ret = 0;
02036 out:
02037
02038 nand_release_device(mtd);
02039
02040 return ret;
02041 }
02042 #endif
02043
02044
02055 #if NAND_KVEC_SUPPORT
02056 #if NAND_WRITE_SUPPORT
02057 static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
02058 loff_t to, size_t * retlen)
02059 {
02060 return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
02061 }
02062 #endif
02063 #endif
02064
02077 #if NAND_KVEC_SUPPORT
02078 #if NAND_WRITE_SUPPORT
02079 static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
02080 loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
02081 {
02082 int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
02083 int oob, numpages, autoplace = 0, startpage;
02084 struct nand_chip *this = mtd->priv;
02085 int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
02086 u_char *oobbuf, *bufstart;
02087
02088
02089 *retlen = 0;
02090
02091
02092 total_len = 0;
02093 for (i = 0; i < count; i++)
02094 total_len += (int) vecs[i].iov_len;
02095
02096 DEBUG (MTD_DEBUG_LEVEL3,
02097 "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
02098
02099
02100 if ((to + total_len) > mtd->size) {
02101 DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
02102 return -EINVAL;
02103 }
02104
02105
02106 if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
02107 D(printk("nand_write_ecc: Attempt to write not page aligned data\n"));
02108 return -EINVAL;
02109 }
02110
02111
02112 nand_get_device (this, mtd, FL_WRITING);
02113
02114
02115 chipnr = (int) (to >> this->chip_shift);
02116
02117 this->select_chip(mtd, chipnr);
02118
02119
02120 if (nand_check_wp(mtd))
02121 goto out;
02122
02123
02124 if (oobsel == NULL)
02125 oobsel = &mtd->oobinfo;
02126
02127
02128 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
02129 oobsel = this->autooob;
02130 autoplace = 1;
02131 }
02132 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
02133 autoplace = 1;
02134
02135
02136 page = (int) (to >> this->page_shift);
02137
02138 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
02139 this->pagebuf = -1;
02140
02141 startpage = page & this->pagemask;
02142
02143
02144 len = 0;
02145 while (count) {
02146
02147
02148
02149 if ((vecs->iov_len - len) >= mtd->oobblock) {
02150
02151
02152 numpages = (vecs->iov_len - len) >> this->page_shift;
02153
02154 numpages = min_t (int, ppblock - (startpage & (ppblock - 1)), numpages);
02155 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
02156 bufstart = (u_char *)vecs->iov_base;
02157 bufstart += len;
02158 this->data_poi = bufstart;
02159 oob = 0;
02160 for (i = 1; i <= numpages; i++) {
02161
02162
02163
02164
02165 ret = nand_write_page (mtd, this, page & this->pagemask,
02166 &oobbuf[oob], oobsel, i != numpages);
02167 if (ret)
02168 goto out;
02169 this->data_poi += mtd->oobblock;
02170 len += mtd->oobblock;
02171 oob += mtd->oobsize;
02172 page++;
02173 }
02174
02175 if (len >= (int) vecs->iov_len) {
02176 vecs++;
02177 len = 0;
02178 count--;
02179 }
02180 } else {
02181
02182
02183
02184 int cnt = 0;
02185 while (cnt < mtd->oobblock) {
02186 if (vecs->iov_base != NULL && vecs->iov_len)
02187 this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
02188
02189 if (len >= (int) vecs->iov_len) {
02190 vecs++;
02191 len = 0;
02192 count--;
02193 }
02194 }
02195 this->pagebuf = page;
02196 this->data_poi = this->data_buf;
02197 bufstart = this->data_poi;
02198 numpages = 1;
02199 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
02200 ret = nand_write_page (mtd, this, page & this->pagemask,
02201 oobbuf, oobsel, 0);
02202 if (ret)
02203 goto out;
02204 page++;
02205 }
02206
02207 this->data_poi = bufstart;
02208 ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
02209 if (ret)
02210 goto out;
02211
02212 written += mtd->oobblock * numpages;
02213
02214 if (!count)
02215 break;
02216
02217 startpage = page & this->pagemask;
02218
02219 if (!startpage) {
02220 chipnr++;
02221 this->select_chip(mtd, -1);
02222 this->select_chip(mtd, chipnr);
02223 }
02224 }
02225 ret = 0;
02226 out:
02227
02228 nand_release_device(mtd);
02229
02230 *retlen = written;
02231 return ret;
02232 }
02233 #endif
02234 #endif
02235
02243 #if NAND_ERASE_SUPPORT
02244 static void single_erase_cmd (struct mtd_info *mtd, int page)
02245 {
02246 struct nand_chip *this = mtd->priv;
02247
02248 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
02249 this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
02250 }
02251 #endif
02252
02261 #if NAND_ERASE_SUPPORT
02262 static void multi_erase_cmd (struct mtd_info *mtd, int page)
02263 {
02264 struct nand_chip *this = mtd->priv;
02265
02266 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
02267 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
02268 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++);
02269 this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
02270 this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
02271 }
02272 #endif
02273
02281 #if NAND_ERASE_SUPPORT
02282 static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
02283 {
02284 return nand_erase_nand (mtd, instr, 0);
02285 }
02286 #endif
02287
02288 #define BBT_PAGE_MASK 0xffffff3f
02289
02297 #if NAND_ERASE_SUPPORT
02298 int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt)
02299 {
02300 int page, len, status, pages_per_block, ret, chipnr;
02301 struct nand_chip *this = mtd->priv;
02302 int rewrite_bbt[NAND_MAX_CHIPS]={0};
02303 unsigned int bbt_masked_page;
02304
02305
02306
02307
02308 DEBUG (MTD_DEBUG_LEVEL3,
02309 ">nand_erase_nand(%s): start = 0x%08x, len = %i\n",
02310 __FILE__, (unsigned int) instr->addr, (unsigned int) instr->len);
02311
02312
02313 if (instr->addr & ((1 << this->phys_erase_shift) - 1)) {
02314
02315 printk("nand_erase: Unaligned address\n");
02316 return -EINVAL;
02317 }
02318
02319
02320 if (instr->len & ((1 << this->phys_erase_shift) - 1)) {
02321
02322 printk("nand_erase: Length not block aligned\n");
02323 return -EINVAL;
02324 }
02325
02326
02327 if ((instr->len + instr->addr) > mtd->size) {
02328
02329 printk("nand_erase: Erase past end of device\n");
02330 return -EINVAL;
02331 }
02332
02333 instr->fail_addr = 0xffffffff;
02334
02335
02336 nand_get_device (this, mtd, FL_ERASING);
02337
02338
02339 page = (int) (instr->addr >> this->page_shift);
02340 chipnr = (int) (instr->addr >> this->chip_shift);
02341
02342
02343 pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
02344
02345
02346 this->select_chip(mtd, chipnr);
02347
02348
02349
02350 if (nand_check_wp(mtd)) {
02351
02352 printk("nand_erase: Device is write protected!!!\n");
02353 instr->state = MTD_ERASE_FAILED;
02354 goto erase_exit;
02355 }
02356
02357
02358 if (this->options & BBT_AUTO_REFRESH) {
02359 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
02360 } else {
02361 bbt_masked_page = 0xffffffff;
02362 }
02363
02364
02365 len = instr->len;
02366
02367 instr->state = MTD_ERASING;
02368
02369 while (len) {
02370
02371 if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
02372
02373 printk("nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
02374 instr->state = MTD_ERASE_FAILED;
02375 goto erase_exit;
02376 }
02377
02378
02379
02380 if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
02381 this->pagebuf = -1;
02382
02383 this->erase_cmd (mtd, page & this->pagemask);
02384
02385 status = this->waitfunc (mtd, this, FL_ERASING);
02386
02387
02388 if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
02389 status = this->errstat(mtd, this, FL_ERASING, status, page);
02390 }
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412 if (status & NAND_STATUS_FAIL) {
02413
02414 printk("nand_erase: " "Failed erase, page 0x%08x\n", page);
02415 printf("%s(%s) erase failed\n", __FUNCTION__, __FILE__);
02416 instr->state = MTD_ERASE_FAILED;
02417 instr->fail_addr = (page << this->page_shift);
02418 goto erase_exit;
02419 }
02420
02421
02422 if (this->options & BBT_AUTO_REFRESH) {
02423 if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
02424 (page != this->bbt_td->pages[chipnr])) {
02425 rewrite_bbt[chipnr] = (page << this->page_shift);
02426 }
02427 }
02428
02429
02430 len -= (1 << this->phys_erase_shift);
02431 page += pages_per_block;
02432
02433
02434 if (len && !(page & this->pagemask)) {
02435 chipnr++;
02436 this->select_chip(mtd, -1);
02437 this->select_chip(mtd, chipnr);
02438
02439
02440
02441 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
02442 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
02443 }
02444
02445 }
02446 }
02447 instr->state = MTD_ERASE_DONE;
02448
02449 erase_exit:
02450
02451 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
02452 #if 0
02453
02454 if (!ret)
02455 mtd_erase_callback(instr);
02456 #endif
02457
02458
02459 nand_release_device(mtd);
02460
02461 #if NAND_BBT_SUPPORT
02462
02463 if ((this->options & BBT_AUTO_REFRESH) && (!ret)) {
02464 for (chipnr = 0; chipnr < this->numchips; chipnr++) {
02465 if (rewrite_bbt[chipnr]) {
02466
02467 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
02468 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
02469 nand_update_bbt (mtd, rewrite_bbt[chipnr]);
02470 }
02471 }
02472 }
02473 #endif
02474
02475
02476 return ret;
02477 }
02478 #endif
02479
02486 #if 0
02487 static void nand_sync (struct mtd_info *mtd)
02488 {
02489 struct nand_chip *this = mtd->priv;
02490
02491 DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n");
02492
02493
02494 nand_get_device (this, mtd, FL_SYNCING);
02495
02496 nand_release_device (mtd);
02497 }
02498 #endif
02499
02500
02506 static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
02507 {
02508
02509 dprintf(">nand_block_isbad(%s) %d\n", __FILE__, ofs);
02510
02511
02512 if (ofs > mtd->size)
02513 return -EINVAL;
02514
02515 return nand_block_checkbad (mtd, ofs, 1, 0);
02516 }
02517
02523 #if NAND_WRITE_SUPPORT
02524 static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
02525 {
02526 struct nand_chip *this = mtd->priv;
02527 int ret;
02528
02529 if ((ret = nand_block_isbad(mtd, ofs))) {
02530
02531 if (ret > 0)
02532 return 0;
02533 return ret;
02534 }
02535
02536 return this->block_markbad(mtd, ofs);
02537 }
02538 #endif
02539
02544 #if 0
02545 static int nand_suspend(struct mtd_info *mtd)
02546 {
02547 struct nand_chip *this = mtd->priv;
02548
02549 return nand_get_device (this, mtd, FL_PM_SUSPENDED);
02550 }
02551 #endif
02552
02557 #if 0
02558 static void nand_resume(struct mtd_info *mtd)
02559 {
02560 struct nand_chip *this = mtd->priv;
02561
02562 if (this->state == FL_PM_SUSPENDED)
02563 nand_release_device(mtd);
02564 else
02565 D(printk("resume() called for the chip which is not "
02566 "in suspended state\n"));
02567
02568 }
02569 #endif
02570
02571
02584 int nand_scan (struct mtd_info *mtd, int maxchips)
02585 {
02586 int i, nand_maf_id, nand_dev_id, busw, maf_id;
02587 struct nand_chip *this = mtd->priv;
02588
02589 dprintf(">nand_scan(%s)\n", __FILE__);
02590
02591
02592 busw = this->options & NAND_BUSWIDTH_16;
02593 #if !NAND_BUSWIDTH16_SUPPORT
02594 if (busw) {
02595 D(printk("nand_scan: support for 16 bit flash chips not enabled\n"));
02596 BUG();
02597 }
02598 #endif
02599
02600
02601 if (!this->chip_delay)
02602 this->chip_delay = 20;
02603
02604
02605 if (this->cmdfunc == NULL)
02606 this->cmdfunc = nand_command;
02607
02608
02609 if (this->waitfunc == NULL)
02610 this->waitfunc = nand_wait;
02611
02612 if (!this->select_chip)
02613 this->select_chip = nand_select_chip;
02614 if (!this->write_byte)
02615 this->write_byte =
02616 #if NAND_BUSWIDTH16_SUPPORT
02617 busw ? nand_write_byte16 :
02618 #endif
02619 nand_write_byte;
02620 if (!this->read_byte)
02621 this->read_byte =
02622 #if NAND_BUSWIDTH16_SUPPORT
02623 busw ? nand_read_byte16 :
02624 #endif
02625 nand_read_byte;
02626 if (!this->write_word)
02627 this->write_word = nand_write_word;
02628 if (!this->read_word)
02629 this->read_word = nand_read_word;
02630 if (!this->block_bad)
02631 this->block_bad = nand_block_bad;
02632 #if NAND_WRITE_SUPPORT
02633 if (!this->block_markbad)
02634 this->block_markbad = nand_default_block_markbad;
02635 #endif
02636 if (!this->write_buf)
02637 this->write_buf =
02638 #if NAND_BUSWIDTH16_SUPPORT
02639 busw ? nand_write_buf16 :
02640 #endif
02641 nand_write_buf;
02642 if (!this->read_buf)
02643 this->read_buf =
02644 #if NAND_BUSWIDTH16_SUPPORT
02645 busw ? nand_read_buf16 :
02646 #endif
02647 nand_read_buf;
02648 if (!this->verify_buf)
02649 this->verify_buf =
02650 #if NAND_BUSWIDTH16_SUPPORT
02651 busw ? nand_verify_buf16 :
02652 #endif
02653 nand_verify_buf;
02654 #if NAND_BBT_SUPPORT
02655 if (!this->scan_bbt)
02656 this->scan_bbt = nand_default_bbt;
02657 #endif
02658
02659
02660 this->select_chip(mtd, 0);
02661
02662
02663
02664 this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
02665
02666
02667 nand_maf_id = this->read_byte(mtd);
02668 nand_dev_id = this->read_byte(mtd);
02669 printk("nand_scan(): nand_maf_if == 0x%02X; nand_dev_id == 0x%02X\n", nand_maf_id, nand_dev_id);
02670
02671
02672 this->select_chip(mtd, 0);
02673
02674
02675
02676 this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
02677
02678
02679 nand_maf_id = this->read_byte(mtd);
02680 nand_dev_id = this->read_byte(mtd);
02681 printk("nand_scan(): nand_maf_if == 0x%02X; nand_dev_id == 0x%02X\n", nand_maf_id, nand_dev_id);
02682
02683
02684
02685 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
02686
02687 if (nand_dev_id != nand_flash_ids[i].id)
02688 continue;
02689
02690 if (!mtd->name) mtd->name = nand_flash_ids[i].name;
02691 this->chipsize = nand_flash_ids[i].chipsize << 20;
02692
02693
02694 if (!nand_flash_ids[i].pagesize) {
02695 int extid;
02696
02697 extid = this->read_byte(mtd);
02698
02699 extid = this->read_byte(mtd);
02700
02701 mtd->oobblock = 1024 << (extid & 0x3);
02702 extid >>= 2;
02703
02704 mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
02705 extid >>= 2;
02706
02707 mtd->erasesize = (64 * 1024) << (extid & 0x03);
02708 extid >>= 2;
02709
02710 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
02711
02712 } else {
02713
02714
02715 mtd->erasesize = nand_flash_ids[i].erasesize;
02716 mtd->oobblock = nand_flash_ids[i].pagesize;
02717 mtd->oobsize = mtd->oobblock / 32;
02718 busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
02719 }
02720
02721
02722 for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {
02723 if (nand_manuf_ids[maf_id].id == nand_maf_id)
02724 break;
02725 }
02726
02727
02728
02729 if (busw != (this->options & NAND_BUSWIDTH_16)) {
02730 D(printk("NAND device: Manufacturer ID:"
02731 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
02732 nand_manuf_ids[maf_id].name , mtd->name));
02733 D(printk("NAND bus width %d instead %d bit\n",
02734 (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
02735 busw ? 16 : 8));
02736 this->select_chip(mtd, -1);
02737 return 1;
02738 }
02739
02740
02741 this->page_shift = ffs(mtd->oobblock) - 1;
02742 this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
02743 this->chip_shift = ffs(this->chipsize) - 1;
02744
02745
02746 this->badblockpos = mtd->oobblock > 512 ?
02747 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
02748
02749
02750 this->options &= ~NAND_CHIPOPTIONS_MSK;
02751 this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
02752
02753 this->options |= NAND_NO_AUTOINCR;
02754
02755
02756
02757 if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
02758 this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
02759
02760 #if NAND_ERASE_SUPPORT
02761
02762 if (this->options & NAND_4PAGE_ARRAY)
02763 this->erase_cmd = multi_erase_cmd;
02764 else
02765 this->erase_cmd = single_erase_cmd;
02766 #endif
02767
02768
02769 if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
02770 this->cmdfunc = nand_command_lp;
02771
02772 D(printk ("NAND device: Manufacturer ID:"
02773 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
02774 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name));
02775 break;
02776 }
02777
02778
02779 if (!nand_flash_ids[i].name) {
02780 D(printk("No NAND device found!!!\n"));
02781 this->select_chip(mtd, -1);
02782 return 1;
02783 }
02784
02785 #if NAND_MULTICHIP_SUPPORT
02786 for (i=1; i < maxchips; i++) {
02787 this->select_chip(mtd, i);
02788
02789
02790 this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
02791
02792
02793 if (nand_maf_id != this->read_byte(mtd) ||
02794 nand_dev_id != this->read_byte(mtd))
02795 break;
02796 }
02797 if (i > 1)
02798 D(printk("%d NAND chips detected\n", i));
02799 #endif
02800
02801
02802
02803 if (!this->oob_buf) {
02804 #if NAND_HAS_MALLOC
02805 size_t len;
02806 len = mtd->oobsize << (this->phys_erase_shift - this->page_shift);
02807
02808 this->oob_buf = malloc (len);
02809 printk("malloc for oob %d bytes at 0x%08X\n", len, this->oob_buf);
02810 if (!this->oob_buf) {
02811 D(printk("nand_scan(): Cannot allocate oob_buf\n"));
02812 return -ENOMEM;
02813 }
02814 this->options |= NAND_OOBBUF_ALLOC;
02815 #else
02816 D(printk("nand_scan: No oob_buf allocated.\n"));
02817 return -1;
02818 #endif
02819 }
02820
02821
02822 if (!this->data_buf) {
02823 #if NAND_HAS_MALLOC
02824 size_t len;
02825 len = mtd->oobblock + mtd->oobsize;
02826
02827 this->data_buf = malloc (len);
02828 if (!this->data_buf) {
02829 if (this->options & NAND_OOBBUF_ALLOC)
02830 free (this->oob_buf);
02831 D(printk("nand_scan(): Cannot allocate data_buf\n"));
02832 return -ENOMEM;
02833 }
02834 this->options |= NAND_DATABUF_ALLOC;
02835 #else
02836 D(printk("nand_scan: No oob_buf allocated.\n"));
02837 return -1;
02838 #endif
02839 }
02840
02841
02842 #if NAND_MULTICHIP_SUPPORT
02843
02844 this->numchips = i;
02845 mtd->size = i * this->chipsize;
02846 #else
02847
02848 this->numchips = 1;
02849 mtd->size = this->chipsize;
02850 #endif
02851
02852
02853
02854 this->pagemask = (this->chipsize >> this->page_shift) - 1;
02855
02856
02857
02858 printk("mtd->oobsize == 0x%08X\n", mtd->oobsize);
02859 printk("this->phys_erase_shift == 0x%08X\n", this->phys_erase_shift);
02860 printk("this->page_shift == 0x%08X\n", this->page_shift);
02861 printk("mtd->oobsize << ... == 0x%08X\n", mtd->oobsize << (this->phys_erase_shift - this->page_shift));
02862 memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift));
02863
02864
02865
02866
02867 if (!this->autooob) {
02868
02869
02870 switch (mtd->oobsize) {
02871 case 8:
02872 this->autooob = &nand_oob_8;
02873 break;
02874 case 16:
02875 this->autooob = &nand_oob_16;
02876 break;
02877 case 64:
02878 this->autooob = &nand_oob_64;
02879 break;
02880 default:
02881 D(printk("No oob scheme defined for oobsize %d\n",
02882 mtd->oobsize));
02883 BUG();
02884 }
02885 }
02886
02887
02888
02889
02890 mtd->oobavail = 0;
02891 for (i = 0; this->autooob->oobfree[i][1]; i++)
02892 mtd->oobavail += this->autooob->oobfree[i][1];
02893
02894
02895
02896
02897
02898
02899 this->eccsize = 256;
02900 this->eccbytes = 3;
02901
02902
02903 printk("1... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
02904
02905 switch (this->eccmode) {
02906 #if NAND_HWECC_SUPPORT
02907 case NAND_ECC_HW12_2048:
02908 if (mtd->oobblock < 2048) {
02909 D(printk("2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
02910 mtd->oobblock));
02911 this->eccmode = NAND_ECC_SOFT;
02912 this->calculate_ecc = nand_calculate_ecc;
02913 this->correct_data = nand_correct_data;
02914 } else
02915 this->eccsize = 2048;
02916 break;
02917
02918 case NAND_ECC_HW3_512:
02919 case NAND_ECC_HW6_512:
02920 case NAND_ECC_HW8_512:
02921 if (mtd->oobblock == 256) {
02922 D(printk("512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"));
02923 this->eccmode = NAND_ECC_SOFT;
02924 this->calculate_ecc = nand_calculate_ecc;
02925 this->correct_data = nand_correct_data;
02926 } else
02927 this->eccsize = 512;
02928 break;
02929
02930 case NAND_ECC_HW3_256:
02931 break;
02932 #endif
02933
02934 case NAND_ECC_NONE:
02935 D(printk ("NAND_ECC_NONE selected by board driver. This is not recommended !!\n"));
02936 this->eccmode = NAND_ECC_NONE;
02937 break;
02938
02939 case NAND_ECC_SOFT:
02940 this->calculate_ecc = nand_calculate_ecc;
02941 this->correct_data = nand_correct_data;
02942 break;
02943
02944 default:
02945 D(printk("Invalid NAND_ECC_MODE %d\n", this->eccmode));
02946 BUG();
02947 }
02948
02949
02950
02951
02952 switch (this->eccmode) {
02953 case NAND_ECC_HW12_2048:
02954 this->eccbytes += 4;
02955 case NAND_ECC_HW8_512:
02956 this->eccbytes += 2;
02957 case NAND_ECC_HW6_512:
02958 this->eccbytes += 3;
02959 case NAND_ECC_HW3_512:
02960 case NAND_ECC_HW3_256:
02961 if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
02962 break;
02963 D(printk("No ECC functions supplied, Hardware ECC not possible\n"));
02964 BUG();
02965 }
02966
02967 mtd->eccsize = this->eccsize;
02968
02969
02970 switch (this->eccmode) {
02971 case NAND_ECC_HW12_2048:
02972 this->eccsteps = mtd->oobblock / 2048;
02973 break;
02974 case NAND_ECC_HW3_512:
02975 case NAND_ECC_HW6_512:
02976 case NAND_ECC_HW8_512:
02977 this->eccsteps = mtd->oobblock / 512;
02978 break;
02979 case NAND_ECC_HW3_256:
02980 case NAND_ECC_SOFT:
02981 this->eccsteps = mtd->oobblock / 256;
02982 break;
02983
02984 case NAND_ECC_NONE:
02985 this->eccsteps = 1;
02986 break;
02987 }
02988
02989
02990 this->state = FL_READY;
02991 #if 0
02992 init_waitqueue_head (&this->wq);
02993 spin_lock_init (&this->chip_lock);
02994 #endif
02995
02996
02997 this->select_chip(mtd, -1);
02998
02999
03000 this->pagebuf = -1;
03001
03002
03003 mtd->type = MTD_NANDFLASH;
03004 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
03005 mtd->ecctype = MTD_ECC_SW;
03006 #if NAND_ERASE_SUPPORT
03007 mtd->erase = nand_erase;
03008 #endif
03009 #if 0
03010 mtd->point = NULL;
03011 mtd->unpoint = NULL;
03012 #endif
03013 mtd->read = nand_read;
03014 #if NAND_WRITE_SUPPORT
03015 mtd->write = nand_write;
03016 #endif
03017 mtd->read_ecc = nand_read_ecc;
03018 #if NAND_WRITE_SUPPORT
03019 mtd->write_ecc = nand_write_ecc;
03020 #endif
03021 mtd->read_oob = nand_read_oob;
03022 #if NAND_WRITE_SUPPORT
03023 mtd->write_oob = nand_write_oob;
03024 #endif
03025 #if NAND_KVEC_SUPPORT
03026 mtd->readv = NULL;
03027 #endif
03028 #if NAND_WRITE_SUPPORT && NAND_KVEC_SUPPORT
03029 mtd->writev = nand_writev;
03030 mtd->writev_ecc = nand_writev_ecc;
03031 #endif
03032 #if 0
03033 mtd->sync = nand_sync;
03034 mtd->lock = NULL;
03035 mtd->unlock = NULL;
03036 mtd->suspend = nand_suspend;
03037 mtd->resume = nand_resume;
03038 #endif
03039 mtd->block_isbad = nand_block_isbad;
03040 #if NAND_WRITE_SUPPORT
03041 mtd->block_markbad = nand_block_markbad;
03042 #endif
03043
03044
03045 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
03046
03047 #ifdef THIS_MODULE
03048 mtd->owner = THIS_MODULE;
03049 #endif
03050
03051
03052 if (this->options & NAND_SKIP_BBTSCAN)
03053 return 0;
03054
03055 #if NAND_BBT_SUPPORT
03056
03057 return this->scan_bbt (mtd);
03058 #else
03059 return -1;
03060 #endif
03061 }
03062
03067 #if 0
03068 void nand_release (struct mtd_info *mtd)
03069 {
03070 struct nand_chip *this = mtd->priv;
03071
03072 #if 0
03073 #ifdef CONFIG_MTD_PARTITIONS
03074
03075 del_mtd_partitions (mtd);
03076 #endif
03077
03078 del_mtd_device (mtd);
03079 #endif
03080
03081
03082 free (this->bbt);
03083
03084 if (this->options & NAND_OOBBUF_ALLOC)
03085 free (this->oob_buf);
03086
03087 if (this->options & NAND_DATABUF_ALLOC)
03088 free (this->data_buf);
03089 }
03090 #endif