tools/build-R2_19_3/fsboot/cbl/nand/nand_base.c

Go to the documentation of this file.
00001 /*
00002  * Snitched from  drivers/mtd/nand_base.c
00003  * Modified to run outside Linux.
00004  * #if 0'd to remove non-essential functionality
00005  *
00006  *  Overview:
00007  *   This is the generic MTD driver for NAND flash devices. It should be
00008  *   capable of working with almost all NAND chips currently available.
00009  *   Basic support for AG-AND chips is provided.
00010  *
00011  *      Additional technical information is available on
00012  *      http://www.linux-mtd.infradead.org/tech/nand.html
00013  *
00014  *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
00015  *                2002 Thomas Gleixner (tglx@linutronix.de)
00016  *
00017  *  02-08-2004  tglx: support for strange chips, which cannot auto increment
00018  *              pages on read / read_oob
00019  *
00020  *  03-17-2004  tglx: Check ready before auto increment check. Simon Bayes
00021  *              pointed this out, as he marked an auto increment capable chip
00022  *              as NOAUTOINCR in the board driver.
00023  *              Make reads over block boundaries work too
00024  *
00025  *  04-14-2004  tglx: first working version for 2k page size chips
00026  *
00027  *  05-19-2004  tglx: Basic support for Renesas AG-AND chips
00028  *
00029  *  09-24-2004  tglx: add support for hardware controllers (e.g. ECC) shared
00030  *              among multiple independend devices. Suggestions and initial patch
00031  *              from Ben Dooks <ben-mtd@fluff.org>
00032  *
00033  *  12-05-2004  dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
00034  *              Basically, any block not rewritten may lose data when surrounding blocks
00035  *              are rewritten many times.  JFFS2 ensures this doesn't happen for blocks
00036  *              it uses, but the Bad Block Table(s) may not be rewritten.  To ensure they
00037  *              do not lose data, force them to be rewritten when some of the surrounding
00038  *              blocks are erased.  Rather than tracking a specific nearby block (which
00039  *              could itself go bad), use a page address 'mask' to select several blocks
00040  *              in the same area, and rewrite the BBT when any of them are erased.
00041  *
00042  *  01-03-2005  dmarlin: added support for the device recovery command sequence for Renesas
00043  *              AG-AND chips.  If there was a sudden loss of power during an erase operation,
00044  *              a "device recovery" operation must be performed when power is restored
00045  *              to ensure correct operation.
00046  *
00047  *  01-20-2005  dmarlin: added support for optional hardware specific callback routine to
00048  *              perform extra error status checks on erase and write failures.  This required
00049  *              adding a wrapper function for nand_read_ecc.
00050  *
00051  * 08-20-2005   vwool: suspend/resume added
00052  *
00053  * Credits:
00054  *      David Woodhouse for adding multichip support
00055  *
00056  *      Aleph One Ltd. and Toby Churchill Ltd. for supporting the
00057  *      rework for 2K page size chips
00058  *
00059  * TODO:
00060  *      Enable cached programming for 2k page size chips
00061  *      Check, if mtd->ecctype should be set to MTD_ECC_HW
00062  *      if we have HW ecc support.
00063  *      The AG-AND chips have nice features for speed improvement,
00064  *      which are not supported yet. Read / program 4 pages in one go.
00065  *
00066  * $Id: nand_base.c,v 1.1.1.1 2008/11/27 20:04:03 elphel Exp $
00067  *
00068  * This program is free software; you can redistribute it and/or modify
00069  * it under the terms of the GNU General Public License version 2 as
00070  * published by the Free Software Foundation.
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 //#include <cyg/hal/hardware.h>
00092 #include <bitops.h>
00093 
00094 #include <hal_intr.h>           /* HAL_DELAY_US */
00095 #include <string.h> /* memcpy */
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 //#include <cyg/hal/hal_intr.h>  /* for hal_delay_us */
00110 
00111 #include <axisrfl/linuxerr.h> /* must be after all eCos files */
00112 
00113 #define udelay(x) HAL_DELAY_US(x)
00114 #undef nop
00115 #define nop() __asm__("nop")
00116 /* only used for ndelay(100) so junk argument */
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 /* from mtd.h */
00123 #define DEBUG(n, args...) do { } while(0)
00124 
00125 #define D(x) x
00126 
00127 /* Define default oob placement schemes for large and small page devices */
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 /* This is used for padding purposes in nand_write_oob */
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  * NAND low-level MTD interface functions
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 /* not needed */
00194 static void nand_sync (struct mtd_info *mtd);
00195 #endif
00196 
00197 /* Some internal functions */
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         /* De-select the NAND device */
00224         this->select_chip(mtd, -1);
00225 #if 0
00226 
00227         if (this->controller) {
00228                 /* Release the controller and the chip */
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                 /* Release the chip */
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         /* Bus sync: Read from address we just wrote.
00274          * This generates no signal to the NAND flash, since only chip 
00275          * select lines are pulled out to the chip, and read is not 
00276          * gated with chip select for the write  area.
00277          * Turns out this is (probably) the wrong way to do it; the
00278          * right way is to set up suitable wait states in the kernel
00279          * config (CONFIG_ETRAX_MEM_GRP3_CONFIG).
00280          */
00281         (void) readb(this->IO_ADDR_W); /* that's right, 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                 /* Grab the lock and see if the device is available */
00524                 nand_get_device (this, mtd, FL_READING);
00525 
00526                 /* Select the NAND device */
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                 /* Deselect and wake up anyone waiting on the device */
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         /* Get block number */
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         /* Do we have a flash based bad block table ? */
00578         if (this->options & NAND_USE_FLASH_BBT)
00579                 return nand_update_bbt (mtd, ofs);
00580 #endif
00581 
00582         /* We write two bytes, so we dont have to mess with 16 bit access */
00583         //      ofs += mtd->oobsize + (this->badblockpos & ~0x01);
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         /* Check the WP bit */
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         /* Return info from the table */
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(); /* should not happen */
00631 }
00632 
00633 /*
00634  * Wait for the ready pin, after a command
00635  * The timeout is catched later.
00636  */
00637 static void nand_wait_ready(struct mtd_info *mtd)
00638 {
00639         struct nand_chip *this = mtd->priv;
00640 
00641         /* wait until command is processed or timeout occures */
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         //      while(1) {
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         /* Begin command latch cycle */
00692         this->hwcontrol(mtd, NAND_CTL_SETCLE);
00693         /*
00694          * Write out the command to the device.
00695          */
00696         if (command == NAND_CMD_SEQIN) {
00697                 int readcmd;
00698 
00699                 if (column >= mtd->oobblock) {
00700                         /* OOB area */
00701                         column -= mtd->oobblock;
00702                         readcmd = NAND_CMD_READOOB;
00703                 } else if (column < 256) {
00704                         /* First 256 bytes --> READ0 */
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         /* end command cycle, clear CLE */
00716         this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00717 
00718         if (column != -1 || page_addr != -1) {
00719           /* Set ALE to start address cycle */
00720                 this->hwcontrol(mtd, NAND_CTL_SETALE);
00721 
00722                 /* Serially input address */
00723                 if (column != -1) {
00724                         /* Adjust columns for 16 bit buswidth */
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                         /* One more address cycle for devices > 32MiB */
00733                         if (this->chipsize > (32 << 20))
00734                                 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
00735                 }
00736                 /* Latch in address */
00737                 this->hwcontrol(mtd, NAND_CTL_CLRALE);
00738         }
00739 
00740         /*
00741          * program and erase have their own busy handlers
00742          * status and sequential in needs no delay
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         /* This applies to read commands */
00764         default:
00765                 /*
00766                  * If we don't have access to the busy pin, we apply the given
00767                  * command delay
00768                 */
00769                 if (!this->dev_ready) {
00770                         udelay (this->chip_delay);
00771                         return;
00772                 }
00773         }
00774         /* Apply this short delay always to ensure that we do wait tWB in
00775          * any case on any machine. */
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         /* Emulate NAND_CMD_READOOB */
00799         if (command == NAND_CMD_READOOB) {
00800                 column += mtd->oobblock;
00801                 command = NAND_CMD_READ0;
00802         }
00803 
00804 
00805         /* Begin command latch cycle */
00806         this->hwcontrol(mtd, NAND_CTL_SETCLE);
00807         /* Write out the command to the device. */
00808         this->write_byte(mtd, (command & 0xff));
00809         /* End command latch cycle */
00810         this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00811 
00812         if (column != -1 || page_addr != -1) {
00813                 this->hwcontrol(mtd, NAND_CTL_SETALE);
00814 
00815                 /* Serially input address */
00816                 if (column != -1) {
00817                         /* Adjust columns for 16 bit buswidth */
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                         /* One more address cycle for devices > 128MiB */
00827                         if (this->chipsize > (128 << 20))
00828                                 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff));
00829                 }
00830                 /* Latch in address */
00831                 this->hwcontrol(mtd, NAND_CTL_CLRALE);
00832         }
00833 
00834         /*
00835          * program and erase have their own busy handlers
00836          * status, sequential in, and deplete1 need no delay
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          * read error status commands require only a short delay
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                 /* Begin command latch cycle */
00872                 this->hwcontrol(mtd, NAND_CTL_SETCLE);
00873                 /* Write out the start read command */
00874                 this->write_byte(mtd, NAND_CMD_READSTART);
00875                 /* End command latch cycle */
00876                 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
00877                 /* Fall through into ready check */
00878 
00879         /* This applies to read commands */
00880         default:
00881                 /*
00882                  * If we don't have access to the busy pin, we apply the given
00883                  * command delay
00884                 */
00885                 if (!this->dev_ready) {
00886                         udelay (this->chip_delay);
00887                         return;
00888                 }
00889         }
00890 
00891         /* Apply this short delay always to ensure that we do wait tWB in
00892          * any case on any machine. */
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         /* Hardware controller shared among independend devices */
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         /* Apply this short delay always to ensure that we do wait tWB in
00975          * any case on any machine. */
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                 /* Check, if we were interrupted */
00986                 if (this->state != state)
00987                         return 0;
00988 #endif
00989         while (1) { /* wait indefinitely */
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         //      printf("%s(%s)\n", __FUNCTION__, __FILE__);
01034         /* FIXME: Enable cached programming */
01035         cached = 0;
01036 
01037         /* Send command to begin auto page programming */
01038         this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
01039 
01040         /* Write out complete page of data, take care of eccmode */
01041         switch (eccmode) {
01042         /* No ecc, write all */
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         /* Software ecc 3/256, write all */
01049         case NAND_ECC_SOFT:
01050           //      printf("NAND_ECC_SOFT\n");
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                           //                      printf("oob[%d] = 0x%x\n", oob_config[eccidx],  ecc_code[i]);
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                         /* enable hardware ecc logic for write */
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                         /* If the hardware ecc provides syndromes then
01072                          * the ecc code must be written immidiately after
01073                          * the data bytes (words) */
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         /* Write out OOB data */
01082         if (this->options & NAND_HWECC_SYNDROME)
01083                 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
01084         else {
01085           //      printf("write oob\n");
01086           this->write_buf(mtd, oob_buf, mtd->oobsize);
01087         }
01088 
01089         /* Send command to actually program the data */
01090         this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1);
01091 
01092         if (!cached) {
01093                 /* call wait ready function */
01094                 status = this->waitfunc (mtd, this, FL_WRITING);
01095 
01096                 /* See if operation failed and additional status checks are available */
01097                 if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
01098                         status = this->errstat(mtd, this, FL_WRITING, status, page);
01099                 }
01100 
01101                 /* See if device thinks it succeeded */
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                 /* FIXME: Implement cached programming ! */
01108                 /* wait until cache is ready*/
01109                 // status = this->waitfunc (mtd, this, FL_CACHEDRPG);
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         /* Send command to read back the first page */
01147         this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
01148 
01149         for(;;) {
01150                 for (j = 0; j < eccsteps; j++) {
01151                         /* Loop through and verify the data */
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                         /* Have we a hw generator layout ? */
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                 /* check, if we must compare all data or if we just have to
01168                  * compare the ecc bytes
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                         /* Read always, else autoincrement fails */
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                 /* Apply delay or wait for ready/busy pin
01198                  * Do this before the AUTOINCR check, so no problems
01199                  * arise if a chip which does auto increment
01200                  * is marked as NOAUTOINCR by the board driver.
01201                  * Do this also before returning, so the chip is
01202                  * ready for the next command.
01203                 */
01204                 if (!this->dev_ready)
01205                         udelay (this->chip_delay);
01206                 else
01207                         nand_wait_ready(mtd);
01208 
01209                 /* All done, return happy */
01210                 if (!numpages)
01211                         return 0;
01212 
01213 
01214                 /* Check, if the chip supports auto page increment */
01215                 if (!NAND_CANAUTOINCR(this))
01216                         this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
01217         }
01218         /*
01219          * Terminate the read command. We come here in case of an error
01220          * So we must issue a reset command.
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         /* use userspace supplied oobinfo, if zero */
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         /* Do not allow reads past end of device */
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         /* Grab the lock and see if the device is available */
01312         if (flags & NAND_GET_DEVICE)
01313                 nand_get_device (this, mtd, FL_READING);
01314 
01315         /* Autoplace of oob data ? Use the default placement scheme */
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         /* Select the NAND device */
01323         chipnr = (int)(from >> this->chip_shift);
01324         this->select_chip(mtd, chipnr);
01325 
01326         /* First we calculate the starting page */
01327         realpage = (int) (from >> this->page_shift);
01328         page = realpage & this->pagemask;
01329 
01330         /* Get raw starting column */
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         /* Loop until all data read */
01345         while (read < len) {
01346 
01347                 int aligned = (!col && (len - read) >= end);
01348                 /*
01349                  * If the read is not page aligned, we have to read into data buffer
01350                  * due to ecc, else we read into return buffer direct
01351                  */
01352                 if (aligned)
01353                         data_poi = &buf[read];
01354                 else
01355                         data_poi = this->data_buf;
01356 
01357                 /* Check, if we have this page in the buffer
01358                  *
01359                  * FIXME: Make it work when we must provide oob data too,
01360                  * check the usage of data_buf oob field
01361                  */
01362                 if (realpage == this->pagebuf && !oob_buf) {
01363                         /* aligned read ? */
01364                         if (aligned)
01365                                 memcpy (data_poi, this->data_buf, end);
01366                         goto readdata;
01367                 }
01368 
01369                 /* Check, if we must send the read command */
01370                 if (sndcmd) {
01371                         this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
01372                         sndcmd = 0;
01373                 }
01374 
01375                 /* get oob area, if we have no oob buffer from fs-driver */
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: {   /* No ECC, Read in a page */
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:     /* Software ECC 3/256: Read in a page + oob data */
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                                 /* HW ecc with syndrome calculation must read the
01408                                  * syndrome from flash immidiately after the data */
01409                                 if (!compareecc) {
01410                                         /* Some hw ecc generators need to know when the
01411                                          * syndrome is read from flash */
01412                                         this->enable_hwecc(mtd, NAND_ECC_READSYN);
01413                                         this->read_buf(mtd, &oob_data[i], eccbytes);
01414                                         /* We calc error correction directly, it checks the hw
01415                                          * generator for an error, reads back the syndrome and
01416                                          * does the error correction on the fly */
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                 /* read oobdata */
01432                 this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
01433 
01434                 /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
01435                 if (!compareecc)
01436                         goto readoob;
01437 
01438                 /* Pick the ECC bytes out of the oob data */
01439                 for (j = 0; j < oobsel->eccbytes; j++)
01440                         ecc_code[j] = oob_data[oob_config[j]];
01441 
01442                 /* correct data, if neccecary */
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                         /* Get next chunk of ecc bytes */
01447                         j += eccbytes;
01448 
01449                         /* Check, if we have a fs supplied oob-buffer,
01450                          * This is the legacy mode. Used by YAFFS1
01451                          * Should go away some day
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                 /* check, if we have a fs supplied oob-buffer */
01466                 if (oob_buf) {
01467                         /* without autoplace. Legacy mode used by YAFFS1 */
01468                         switch(oobsel->useecc) {
01469                         case MTD_NANDECC_AUTOPLACE:
01470                         case MTD_NANDECC_AUTOPL_USR:
01471                                 /* Walk through the autoplace chunks */
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                                 /* YAFFS1 legacy mode */
01481                                 oob_data += this->eccsteps * sizeof (int);
01482                         default:
01483                                 oob_data += mtd->oobsize;
01484                         }
01485                 }
01486         readdata:
01487                 /* Partial page read, transfer data into fs buffer */
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                 /* Apply delay or wait for ready/busy pin
01496                  * Do this before the AUTOINCR check, so no problems
01497                  * arise if a chip which does auto increment
01498                  * is marked as NOAUTOINCR by the board driver.
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                 /* For subsequent reads align to page boundary. */
01509                 col = 0;
01510                 /* Increment page address */
01511                 realpage++;
01512 
01513                 page = realpage & this->pagemask;
01514                 /* Check, if we cross a chip boundary */
01515                 if (!page) {
01516                         chipnr++;
01517                         this->select_chip(mtd, -1);
01518                         this->select_chip(mtd, chipnr);
01519                 }
01520                 /* Check, if the chip supports auto page increment
01521                  * or if we have hit a block boundary.
01522                 */
01523                 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
01524                         sndcmd = 1;
01525         }
01526 
01527         /* Deselect and wake up anyone waiting on the device */
01528         if (flags & NAND_GET_DEVICE)
01529                 nand_release_device(mtd);
01530 
01531         /*
01532          * Return success, if no ECC failures, else -EBADMSG
01533          * fs driver will take care of that, because
01534          * retlen == desired len and result == -EBADMSG
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         /* Shift to get page */
01559         page = (int)(from >> this->page_shift);
01560         chipnr = (int)(from >> this->chip_shift);
01561 
01562         /* Mask to get column */
01563         col = from & (mtd->oobsize - 1);
01564 
01565         /* Initialize return length value */
01566         *retlen = 0;
01567 
01568         /* Do not allow reads past end of device */
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         /* Grab the lock and see if the device is available */
01576         nand_get_device(this, mtd , FL_READING);
01577 
01578         /* Select the NAND device */
01579         this->select_chip(mtd, chipnr);
01580 
01581         /* Send the read command */
01582         this->cmdfunc(mtd, NAND_CMD_READOOB, col, page & this->pagemask);
01583         /*
01584          * Read the data, if we read more than one page
01585          * oob data, let the device transfer the data !
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                 /* Read more ? */
01595                 if (i < len) {
01596                         page++;
01597                         col = 0;
01598 
01599                         /* Check, if we cross a chip boundary */
01600                         if (!(page & this->pagemask)) {
01601                                 chipnr++;
01602                                 this->select_chip(mtd, -1);
01603                                 this->select_chip(mtd, chipnr);
01604                         }
01605 
01606                         /* Apply delay or wait for ready/busy pin
01607                          * Do this before the AUTOINCR check, so no problems
01608                          * arise if a chip which does auto increment
01609                          * is marked as NOAUTOINCR by the board driver.
01610                          */
01611                         if (!this->dev_ready)
01612                           udelay(this->chip_delay);
01613                         else
01614                                 nand_wait_ready(mtd);
01615 
01616                         /* Check, if the chip supports auto page increment
01617                          * or if we have hit a block boundary.
01618                         */
01619                         if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
01620                                 /* For subsequent page reads set offset to 0 */
01621                                 this->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
01622                         }
01623                 }
01624         }
01625 
01626         /* Deselect and wake up anyone waiting on the device */
01627         nand_release_device(mtd);
01628 
01629         /* Return happy */
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         /* Do not allow reads past end of device */
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         /* Grab the lock and see if the device is available */
01663         nand_get_device (this, mtd , FL_READING);
01664 
01665         this->select_chip (mtd, chip);
01666 
01667         /* Add requested oob length */
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                 /* Check, if the chip supports auto page increment */
01687                 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
01688                         sndcmd = 1;
01689         }
01690 
01691         /* Deselect and wake up anyone waiting on the device */
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         /* Zero copy fs supplied buffer */
01728         if (fsbuf && !autoplace)
01729                 return fsbuf;
01730 
01731         /* Check, if the buffer must be filled with ff again */
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         /* If we have no autoplacement or no fs buffer use the internal one */
01739         if (!autoplace || !fsbuf)
01740                 return this->oob_buf;
01741 
01742         /* Walk through the pages and place the data */
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         //      printf("%s(%s)\n", __FUNCTION__, __FILE__);
01802         DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
01803 
01804         /* Initialize retlen, in case of early exit */
01805         *retlen = 0;
01806 
01807         /* Do not allow write past end of device */
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         /* reject writes, which are not page aligned */
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         /* Grab the lock and see if the device is available */
01820         nand_get_device (this, mtd, FL_WRITING);
01821 
01822         /* Calculate chipnr */
01823         chipnr = (int)(to >> this->chip_shift);
01824         /* Select the NAND device */
01825         this->select_chip(mtd, chipnr);
01826 
01827         /* Check, if it is write protected */
01828         if (nand_check_wp(mtd))
01829                 goto out;
01830 
01831         /* if oobsel is NULL, use chip defaults */
01832         if (oobsel == NULL)
01833                 oobsel = &mtd->oobinfo;
01834 
01835         /* Autoplace of oob data ? Use the default placement scheme */
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         /* Setup variables and oob buffer */
01844         totalpages = len >> this->page_shift;
01845         page = (int) (to >> this->page_shift);
01846         /* Invalidate the page cache, if we write to the cached page */
01847         if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
01848                 this->pagebuf = -1;
01849 
01850         /* Set it relative to chip */
01851         page &= this->pagemask;
01852         startpage = page;
01853         /* Calc number of pages we can write in one go */
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         /* Loop until all data is written */
01859         while (written < len) {
01860 
01861                 this->data_poi = (u_char*) &buf[written];
01862                 /* Write one page. If this is the last page to write
01863                  * or the last page in this block, then use the
01864                  * real pageprogram command, else select cached programming
01865                  * if supported by the chip.
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                 /* Next oob page */
01873                 oob += mtd->oobsize;
01874                 /* Update written bytes count */
01875                 written += mtd->oobblock;
01876                 if (written == len)
01877                         goto cmp;
01878 
01879                 /* Increment page address */
01880                 page++;
01881 
01882                 /* Have we hit a block boundary ? Then we have to verify and
01883                  * if verify is ok, we have to setup the oob buffer for
01884                  * the next pages.
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                         /* Check, if we cross a chip boundary */
01909                         if (!page) {
01910                                 chipnr++;
01911                                 this->select_chip(mtd, -1);
01912                                 this->select_chip(mtd, chipnr);
01913                         }
01914                 }
01915         }
01916         /* Verify the remaining pages */
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         /* Deselect and wake up anyone waiting on the device */
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         /* Shift to get page */
01957         page = (int) (to >> this->page_shift);
01958         chipnr = (int) (to >> this->chip_shift);
01959 
01960         /* Mask to get column */
01961         column = to & (mtd->oobsize - 1);
01962 
01963         dprintf(">nand_write_oob(%s) page %d col %d\n", __FILE__, page, column);
01964 
01965         /* Initialize return length value */
01966         *retlen = 0;
01967 
01968         /* Do not allow write past end of page */
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         /* Grab the lock and see if the device is available */
01975         nand_get_device (this, mtd, FL_WRITING);
01976 
01977         /* Select the NAND device */
01978         this->select_chip(mtd, chipnr);
01979 
01980         /* Reset the chip. Some chips (like the Toshiba TC5832DC found
01981            in one of my DiskOnChip 2000 test units) will clear the whole
01982            data page too if we don't do this. I have no clue why, but
01983            I seem to have 'fixed' it in the doc2000 driver in
01984            August 1999.  dwmw2. */
01985         this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
01986 
01987         /* Check, if it is write protected */
01988         if (nand_check_wp(mtd)) {
01989                 goto out;
01990         }
01991 
01992         /* Invalidate the page cache, if we write to the cached page */
01993         if (page == this->pagebuf)
01994                 this->pagebuf = -1;
01995 
01996         if (NAND_MUST_PAD(this)) {              /* Write out desired data */
01997           this->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
01998 
01999           /* prepad 0xff for partial programming */
02000           this->write_buf(mtd, ffchars, column);
02001           /* write data */
02002           this->write_buf(mtd, buf, len);
02003           /* postpad 0xff for partial programming */
02004           this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
02005         } else {
02006                 /* Write out desired data */
02007                 this->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask);
02008                 /* write data */
02009                 this->write_buf(mtd, buf, len);
02010         }
02011         /* Send command to program the OOB data */
02012         this->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
02013 
02014         status = this->waitfunc (mtd, this, FL_WRITING);
02015 
02016         /* See if device thinks it succeeded */
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         /* Return happy */
02023         *retlen = len;
02024 
02025 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
02026         /* Send command to read back the data */
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         /* Deselect and wake up anyone waiting on the device */
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         /* Preset written len for early exit */
02089         *retlen = 0;
02090 
02091         /* Calculate total length of data */
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         /* Do not allow write past end of page */
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         /* reject writes, which are not page aligned */
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         /* Grab the lock and see if the device is available */
02112         nand_get_device (this, mtd, FL_WRITING);
02113 
02114         /* Get the current chip-nr */
02115         chipnr = (int) (to >> this->chip_shift);
02116         /* Select the NAND device */
02117         this->select_chip(mtd, chipnr);
02118 
02119         /* Check, if it is write protected */
02120         if (nand_check_wp(mtd))
02121                 goto out;
02122 
02123         /* if oobsel is NULL, use chip defaults */
02124         if (oobsel == NULL)
02125                 oobsel = &mtd->oobinfo;
02126 
02127         /* Autoplace of oob data ? Use the default placement scheme */
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         /* Setup start page */
02136         page = (int) (to >> this->page_shift);
02137         /* Invalidate the page cache, if we write to the cached page */
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         /* Loop until all kvec' data has been written */
02144         len = 0;
02145         while (count) {
02146                 /* If the given tuple is >= pagesize then
02147                  * write it out from the iov
02148                  */
02149                 if ((vecs->iov_len - len) >= mtd->oobblock) {
02150                         /* Calc number of pages we can write
02151                          * out of this iov in one go */
02152                         numpages = (vecs->iov_len - len) >> this->page_shift;
02153                         /* Do not cross block boundaries */
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                                 /* Write one page. If this is the last page to write
02162                                  * then use the real pageprogram command, else select
02163                                  * cached programming if supported by the chip.
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                         /* Check, if we have to switch to the next tuple */
02175                         if (len >= (int) vecs->iov_len) {
02176                                 vecs++;
02177                                 len = 0;
02178                                 count--;
02179                         }
02180                 } else {
02181                         /* We must use the internal buffer, read data out of each
02182                          * tuple until we have a full page to write
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                                 /* Check, if we have to switch to the next tuple */
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                 /* All done ? */
02214                 if (!count)
02215                         break;
02216 
02217                 startpage = page & this->pagemask;
02218                 /* Check, if we cross a chip boundary */
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         /* Deselect and wake up anyone waiting on the device */
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         /* Send commands to erase a block */
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         /* Send commands to erase a block */
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};    /* flags to indicate the page, if bbt needs to be rewritten. */
02303         unsigned int bbt_masked_page;           /* bbt mask to compare to page being erased. */
02304                                                 /* It is used to see if the current page is in the same */
02305                                                 /*   256 block group and the same bank as the bbt. */
02306 
02307 //int b;
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         /* Start address must align on block boundary */
02313         if (instr->addr & ((1 << this->phys_erase_shift) - 1)) {
02314 //              DEBUG (MTD_DEBUG_LEVEL3, "nand_erase: Unaligned address\n");
02315                 printk("nand_erase: Unaligned address\n");
02316                 return -EINVAL;
02317         }
02318 
02319         /* Length must align on block boundary */
02320         if (instr->len & ((1 << this->phys_erase_shift) - 1)) {
02321 //              DEBUG (MTD_DEBUG_LEVEL3, "nand_erase: Length not block aligned\n");
02322                 printk("nand_erase: Length not block aligned\n");
02323                 return -EINVAL;
02324         }
02325 
02326         /* Do not allow erase past end of device */
02327         if ((instr->len + instr->addr) > mtd->size) {
02328 //              DEBUG (MTD_DEBUG_LEVEL3, "nand_erase: Erase past end of device\n");
02329                 printk("nand_erase: Erase past end of device\n");
02330                 return -EINVAL;
02331         }
02332 
02333         instr->fail_addr = 0xffffffff;
02334 
02335         /* Grab the lock and see if the device is available */
02336         nand_get_device (this, mtd, FL_ERASING);
02337 
02338         /* Shift to get first page */
02339         page = (int) (instr->addr >> this->page_shift);
02340         chipnr = (int) (instr->addr >> this->chip_shift);
02341 
02342         /* Calculate pages in each block */
02343         pages_per_block = 1 << (this->phys_erase_shift - this->page_shift);
02344 
02345         /* Select the NAND device */
02346         this->select_chip(mtd, chipnr);
02347 
02348         /* Check the WP bit */
02349         /* Check, if it is write protected */
02350         if (nand_check_wp(mtd)) {
02351 //              DEBUG (MTD_DEBUG_LEVEL3, "nand_erase: Device is write protected!!!\n");
02352                 printk("nand_erase: Device is write protected!!!\n");
02353                 instr->state = MTD_ERASE_FAILED;
02354                 goto erase_exit;
02355         }
02356 
02357         /* if BBT requires refresh, set the BBT page mask to see if the BBT should be rewritten */
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;   /* should not match anything */
02362         }
02363 
02364         /* Loop through the pages */
02365         len = instr->len;
02366 
02367         instr->state = MTD_ERASING;
02368 
02369         while (len) {
02370                 /* Check if we have a bad block, we do not erase bad blocks ! */
02371                 if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) {
02372 //                      D(printk("nand_erase: attempt to erase a bad block at page 0x%08x\n", page));
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                 /* Invalidate the page cache, if we erase the block which contains
02379                    the current cached page */
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                 /* See if operation failed and additional status checks are available */
02388                 if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
02389                         status = this->errstat(mtd, this, FL_ERASING, status, page);
02390                 }
02391 
02392 /*
02393 b = 0;
02394                 if((((loff_t) page) << this->page_shift) == 0x01240000)
02395                         b = 1;
02396                 if((((loff_t) page) << this->page_shift) == 0x01280000)
02397                         b = 1;
02398                 if((((loff_t) page) << this->page_shift) == 0x00240000)
02399                         b = 1;
02400                 if((((loff_t) page) << this->page_shift) == 0x00280000)
02401                         b = 1;
02402                 if((((loff_t) page) << this->page_shift) == 0x00040000)
02403                         b = 1;
02404                 if((((loff_t) page) << this->page_shift) == 0x00080000)
02405                         b = 1;
02406                 if(b) {
02407                         status |= NAND_STATUS_FAIL;
02408                 }
02409 */
02410 
02411                 /* See if block erase succeeded */
02412                 if (status & NAND_STATUS_FAIL) {
02413 //                DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
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                 /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
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                 /* Increment page address and decrement length */
02430                 len -= (1 << this->phys_erase_shift);
02431                 page += pages_per_block;
02432 
02433                 /* Check, if we cross a chip boundary */
02434                 if (len && !(page & this->pagemask)) {
02435                         chipnr++;
02436                         this->select_chip(mtd, -1);
02437                         this->select_chip(mtd, chipnr);
02438 
02439                         /* if BBT requires refresh and BBT-PERCHIP,
02440                          *   set the BBT page mask to see if this BBT should be rewritten */
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         /* Do call back function */
02454         if (!ret)
02455                 mtd_erase_callback(instr);
02456 #endif
02457 
02458         /* Deselect and wake up anyone waiting on the device */
02459         nand_release_device(mtd);
02460 
02461 #if NAND_BBT_SUPPORT
02462         /* if BBT requires refresh and erase was successful, rewrite any selected bad block tables */
02463         if ((this->options & BBT_AUTO_REFRESH) && (!ret)) {
02464                 for (chipnr = 0; chipnr < this->numchips; chipnr++) {
02465                         if (rewrite_bbt[chipnr]) {
02466                                 /* update the BBT for chip */
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         /* Return more or less happy */
02476         return ret;
02477 }
02478 #endif
02479 
02486 #if 0 /* not needed */
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         /* Grab the lock and see if the device is available */
02494         nand_get_device (this, mtd, FL_SYNCING);
02495         /* Release it and go back */
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         /* Check for invalid offset */
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                 /* If it was bad already, return success and do nothing. */
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 /* don't need it */
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 /* don't need it */
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         /* Get buswidth to select the correct functions*/
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         /* check for proper chip_delay setup, set 20us if not */
02601         if (!this->chip_delay)
02602                 this->chip_delay = 20;
02603 
02604         /* check, if a user supplied command function given */
02605         if (this->cmdfunc == NULL)
02606                 this->cmdfunc = nand_command;
02607 
02608         /* check, if a user supplied wait function given */
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         /* Select the device */
02660         this->select_chip(mtd, 0);
02661 
02662         //      while(1) {
02663         /* Send the command for reading device ID */
02664         this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
02665 
02666         /* Read manufacturer and device IDs */
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         /* Select the device */
02672         this->select_chip(mtd, 0);
02673 
02674         //      while(1) {
02675         /* Send the command for reading device ID */
02676         this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
02677 
02678         /* Read manufacturer and device IDs */
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 //printk("1... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
02683         //      }
02684         /* Print and store flash device information */
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                 /* New devices have all the information in additional id bytes */
02694                 if (!nand_flash_ids[i].pagesize) {
02695                         int extid;
02696                         /* The 3rd id byte contains non relevant data ATM */
02697                         extid = this->read_byte(mtd);
02698                         /* The 4th id byte is the important one */
02699                         extid = this->read_byte(mtd);
02700                         /* Calc pagesize */
02701                         mtd->oobblock = 1024 << (extid & 0x3);
02702                         extid >>= 2;
02703                         /* Calc oobsize */
02704                         mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
02705                         extid >>= 2;
02706                         /* Calc blocksize. Blocksize is multiples of 64KiB */
02707                         mtd->erasesize = (64 * 1024)  << (extid & 0x03);
02708                         extid >>= 2;
02709                         /* Get buswidth information */
02710                         busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
02711 
02712                 } else {
02713                         /* Old devices have this data hardcoded in the
02714                          * device id table */
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                 /* Try to identify manufacturer */
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                 /* Check, if buswidth is correct. Hardware drivers should set
02728                  * this correct ! */
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                 /* Calculate the address shift from the page size */
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                 /* Set the bad block position */
02746                 this->badblockpos = mtd->oobblock > 512 ?
02747                         NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
02748 
02749                 /* Get chip options, preserve non chip based options */
02750                 this->options &= ~NAND_CHIPOPTIONS_MSK;
02751                 this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK;
02752                 /* Set this as a default. Board drivers can override it, if neccecary */
02753                 this->options |= NAND_NO_AUTOINCR;
02754                 /* Check if this is a not a samsung device. Do not clear the options
02755                  * for chips which are not having an extended id.
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                 /* Check for AND chips with 4 page planes */
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                 /* Do not replace user supplied command function ! */
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 //printk("2... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
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                 /* Send the command for reading device ID */
02790                 this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
02791 
02792                 /* Read manufacturer and device IDs */
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 //printk("3... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
02802         /* Allocate buffers, if neccecary */
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                 /* len is 512 for 16384/512 chips, 32768 for 128k/2k chips */
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 //printk("4... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
02822         if (!this->data_buf) {
02823 #if NAND_HAS_MALLOC
02824                 size_t len;
02825                 len = mtd->oobblock + mtd->oobsize;
02826                 /* len is 512+16 for 16384/512 chips, 128k+2k for 128k/2k chips */
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 //printk("5... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
02842 #if NAND_MULTICHIP_SUPPORT
02843         /* Store the number of chips and calc total size for mtd */
02844         this->numchips = i;
02845         mtd->size = i * this->chipsize;
02846 #else
02847         /* Store the number of chips and calc total size for mtd */
02848         this->numchips = 1;
02849         mtd->size = this->chipsize;
02850 #endif
02851 
02852 //printk("6... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
02853         /* Convert chipsize to number of pages per chip -1. */
02854         this->pagemask = (this->chipsize >> this->page_shift) - 1;
02855         /* Preset the internal oob buffer */
02856 //printk("6.1... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
02857 //printk();
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 //printk("6.2... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
02865         /* If no default placement scheme is given, select an
02866          * appropriate one */
02867         if (!this->autooob) {
02868                 /* Select the appropriate default oob placement scheme for
02869                  * placement agnostic filesystems */
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 //printk("7... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
02888         /* The number of bytes available for the filesystem to place fs dependend
02889          * oob data */
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          * check ECC mode, default to software
02896          * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
02897          * fallback to software ECC
02898         */
02899         this->eccsize = 256;    /* set default eccsize */
02900         this->eccbytes = 3;
02901 
02902 //printk("8... nand_scan(): this->eccmode == %d\n", (int)this->eccmode);
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; /* set eccsize to 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         /* Check hardware ecc function availability and adjust number of ecc bytes per
02950          * calculation step
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         /* Set the number of read / write steps for one page to ensure ECC generation */
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         /* Initialize state, waitqueue and spinlock */
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         /* De-select the device */
02997         this->select_chip(mtd, -1);
02998 
02999         /* Invalidate the pagebuffer reference */
03000         this->pagebuf = -1;
03001 
03002         /* Fill in remaining MTD driver data */
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 /* not needed */
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 /* not needed */
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         /* and make the autooob the default one */
03045         memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
03046 
03047 #ifdef THIS_MODULE /* normally isn't for us */
03048         mtd->owner = THIS_MODULE;
03049 #endif
03050 
03051         /* Check, if we should skip the bad block table scan */
03052         if (this->options & NAND_SKIP_BBTSCAN)
03053                 return 0;
03054 
03055 #if NAND_BBT_SUPPORT
03056         /* Build bad block table */
03057         return this->scan_bbt (mtd);
03058 #else
03059         return -1;
03060 #endif
03061 }
03062 
03067 #if 0 /* don't need it */
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         /* Deregister partitions */
03075         del_mtd_partitions (mtd);
03076 #endif
03077         /* Deregister the device */
03078         del_mtd_device (mtd);
03079 #endif
03080 
03081         /* Free bad block table memory */
03082         free (this->bbt);
03083         /* Buffer allocated by nand_scan ? */
03084         if (this->options & NAND_OOBBUF_ALLOC)
03085                 free (this->oob_buf);
03086         /* Buffer allocated by nand_scan ? */
03087         if (this->options & NAND_DATABUF_ALLOC)
03088                 free (this->data_buf);
03089 }
03090 #endif

Generated on Fri Nov 28 00:06:24 2008 for elphel by  doxygen 1.5.1