os/nandboot-R2_0_4/mtd/nand_base.c

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

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