Fix OneNAND build break
authorKyungmin Park <kmpark@infradead.org>
Wed, 13 Aug 2008 00:11:02 +0000 (09:11 +0900)
committerScott Wood <scottwood@freescale.com>
Wed, 13 Aug 2008 16:00:19 +0000 (11:00 -0500)
Since page size field is changed from oobblock to writesize. But OneNAND is not updated.
- fix bufferram management at erase operation
This patch includes the NAND/OneNAND state filed too.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
common/env_onenand.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/onenand_bbt.c
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/mtd/nand_legacy.h
include/linux/mtd/onenand.h

index dbd0883fa8a651d717e71e64f0385bf55d6d2f1a..d5c907c6f0aa303065e5a4a695878f4e1d026917 100644 (file)
@@ -40,7 +40,7 @@ extern struct onenand_chip onenand_chip;
 /* References to names in env_common.c */
 extern uchar default_environment[];
 
-#define ONENAND_ENV_SIZE(mtd)  (mtd.oobblock - ENV_HEADER_SIZE)
+#define ONENAND_ENV_SIZE(mtd)  (mtd.writesize - ENV_HEADER_SIZE)
 
 char *env_name_spec = "OneNAND";
 
@@ -68,12 +68,12 @@ void env_relocate_spec(void)
        env_addr = CFG_ENV_ADDR;
 
        /* Check OneNAND exist */
-       if (onenand_mtd.oobblock)
+       if (onenand_mtd.writesize)
                /* Ignore read fail */
-               onenand_read(&onenand_mtd, env_addr, onenand_mtd.oobblock,
+               onenand_read(&onenand_mtd, env_addr, onenand_mtd.writesize,
                             &retlen, (u_char *) env_ptr);
        else
-               onenand_mtd.oobblock = MAX_ONENAND_PAGESIZE;
+               onenand_mtd.writesize = MAX_ONENAND_PAGESIZE;
 
        if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) !=
            env_ptr->crc)
@@ -109,7 +109,7 @@ int saveenv(void)
        env_ptr->crc =
            crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd));
 
-       if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.oobblock, &retlen,
+       if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.writesize, &retlen,
             (u_char *) env_ptr)) {
                printf("OneNAND: write failed at 0x%08x\n", instr.addr);
                return 2;
index ded1706abbef7985a05f9480e9714945253b56d8..eaa48f94873887fdb472ef7d118b21d1d810d7fd 100644 (file)
@@ -331,7 +331,7 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
 
        if (ONENAND_CURRENT_BUFFERRAM(this)) {
                if (area == ONENAND_DATARAM)
-                       return mtd->oobblock;
+                       return mtd->writesize;
                if (area == ONENAND_SPARERAM)
                        return mtd->oobsize;
        }
@@ -481,6 +481,30 @@ static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
        return 0;
 }
 
+/**
+ * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
+ * @param mtd           MTD data structure
+ * @param addr          start address to invalidate
+ * @param len           length to invalidate
+ *
+ * Invalidate BufferRAM information
+ */
+static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
+                                         unsigned int len)
+{
+       struct onenand_chip *this = mtd->priv;
+       int i;
+       loff_t end_addr = addr + len;
+
+       /* Invalidate BufferRAM */
+       for (i = 0; i < MAX_BUFFERRAM; i++) {
+               loff_t buf_addr = this->bufferram[i].block << this->erase_shift;
+
+               if (buf_addr >= addr && buf_addr < end_addr)
+                       this->bufferram[i].valid = 0;
+       }
+}
+
 /**
  * onenand_get_device - [GENERIC] Get chip for selected access
  * @param mtd          MTD device structure
@@ -541,15 +565,15 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
        onenand_get_device(mtd, FL_READING);
 
        while (read < len) {
-               thislen = min_t(int, mtd->oobblock, len - read);
+               thislen = min_t(int, mtd->writesize, len - read);
 
-               column = from & (mtd->oobblock - 1);
-               if (column + thislen > mtd->oobblock)
-                       thislen = mtd->oobblock - column;
+               column = from & (mtd->writesize - 1);
+               if (column + thislen > mtd->writesize)
+                       thislen = mtd->writesize - column;
 
                if (!onenand_check_bufferram(mtd, from)) {
                        this->command(mtd, ONENAND_CMD_READ, from,
-                                     mtd->oobblock);
+                                     mtd->writesize);
                        ret = this->wait(mtd, FL_READING);
                        /* First copy data and check return value for ECC handling */
                        onenand_update_bufferram(mtd, from, 1);
@@ -664,7 +688,7 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
                /* Read more? */
                if (read < len) {
                        /* Page size */
-                       from += mtd->oobblock;
+                       from += mtd->writesize;
                        column = 0;
                }
        }
@@ -691,7 +715,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
        void __iomem *dataram0, *dataram1;
        int ret = 0;
 
-       this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
+       this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
 
        ret = this->wait(mtd, FL_READING);
        if (ret)
@@ -701,9 +725,9 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
 
        /* Check, if the two dataram areas are same */
        dataram0 = this->base + ONENAND_DATARAM;
-       dataram1 = dataram0 + mtd->oobblock;
+       dataram1 = dataram0 + mtd->writesize;
 
-       if (memcmp(dataram0, dataram1, mtd->oobblock))
+       if (memcmp(dataram0, dataram1, mtd->writesize))
                return -EBADMSG;
 
        return 0;
@@ -712,7 +736,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
 #define onenand_verify_page(...)       (0)
 #endif
 
-#define NOTALIGNED(x)  ((x & (mtd->oobblock - 1)) != 0)
+#define NOTALIGNED(x)  ((x & (mtd->writesize - 1)) != 0)
 
 /**
  * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
@@ -760,15 +784,15 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 
        /* Loop until all data write */
        while (written < len) {
-               int thislen = min_t(int, mtd->oobblock, len - written);
+               int thislen = min_t(int, mtd->writesize, len - written);
 
-               this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
+               this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);
 
                this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
                this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
                                      mtd->oobsize);
 
-               this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
+               this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
 
                onenand_update_bufferram(mtd, to, 1);
 
@@ -892,6 +916,25 @@ int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
        return 0;
 }
 
+/**
+ * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
+ * @param mtd          MTD device structure
+ * @param ofs          offset from device start
+ * @param allowbbt     1, if its allowed to access the bbt area
+ *
+ * Check, if the block is bad, Either by reading the bad block table or
+ * calling of the scan function.
+ */
+static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
+{
+       struct onenand_chip *this = mtd->priv;
+       struct bbm_info *bbm = this->bbm;
+
+       /* Return info from the table */
+       return bbm->isbad_bbt(mtd, ofs, allowbbt);
+}
+
+
 /**
  * onenand_erase - [MTD Interface] erase block(s)
  * @param mtd          MTD device structure
@@ -950,6 +993,8 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
 
                this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
 
+               onenand_invalidate_bufferram(mtd, addr, block_size);
+
                ret = this->wait(mtd, FL_ERASING);
                /* Check, if it is write protected */
                if (ret) {
@@ -1005,30 +1050,45 @@ void onenand_sync(struct mtd_info *mtd)
  * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
  * @param mtd          MTD device structure
  * @param ofs          offset relative to mtd start
+ *
+ * Check whether the block is bad
  */
 int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
-       /*
-        * TODO
-        * 1. Bad block table (BBT)
-        *   -> using NAND BBT to support JFFS2
-        * 2. Bad block management (BBM)
-        *   -> bad block replace scheme
-        *
-        * Currently we do nothing
-        */
-       return 0;
+       int ret;
+
+       /* Check for invalid offset */
+       if (ofs > mtd->size)
+               return -EINVAL;
+
+       onenand_get_device(mtd, FL_READING);
+       ret = onenand_block_isbad_nolock(mtd,ofs, 0);
+       onenand_release_device(mtd);
+       return ret;
 }
 
 /**
  * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
  * @param mtd          MTD device structure
  * @param ofs          offset relative to mtd start
+ *
+ * Mark the block as bad
  */
 int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
-       /* see above */
-       return 0;
+       struct onenand_chip *this = mtd->priv;
+       int ret;
+
+       ret = onenand_block_isbad(mtd, ofs);
+       if (ret) {
+               /* If it was bad already, return success and do nothing */
+               if (ret > 0)
+                       return 0;
+               return ret;
+       }
+
+       ret = this->block_markbad(mtd, ofs);
+       return ret;
 }
 
 /**
@@ -1184,10 +1244,8 @@ static int onenand_probe(struct mtd_info *mtd)
        /* Reset OneNAND to read default register values */
        this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
 
-       {
-               int i;
-               for (i = 0; i < 10000; i++) ;
-       }
+       /* Wait reset */
+       this->wait(mtd, FL_RESETING);
 
        /* Read manufacturer and device IDs from Register */
        maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
@@ -1212,16 +1270,16 @@ static int onenand_probe(struct mtd_info *mtd)
 
        /* OneNAND page size & block size */
        /* The data buffer size is equal to page size */
-       mtd->oobblock =
+       mtd->writesize =
            this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
-       mtd->oobsize = mtd->oobblock >> 5;
+       mtd->oobsize = mtd->writesize >> 5;
        /* Pagers per block is always 64 in OneNAND */
-       mtd->erasesize = mtd->oobblock << 6;
+       mtd->erasesize = mtd->writesize << 6;
 
        this->erase_shift = ffs(mtd->erasesize) - 1;
-       this->page_shift = ffs(mtd->oobblock) - 1;
+       this->page_shift = ffs(mtd->writesize) - 1;
        this->ppb_shift = (this->erase_shift - this->page_shift);
-       this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
+       this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
 
        /* REVIST: Multichip handling */
 
@@ -1240,11 +1298,10 @@ static int onenand_probe(struct mtd_info *mtd)
                this->options |= ONENAND_CONT_LOCK;
        }
 
+       mtd->flags = MTD_CAP_NANDFLASH;
        mtd->erase = onenand_erase;
        mtd->read = onenand_read;
        mtd->write = onenand_write;
-       mtd->read_ecc = onenand_read_ecc;
-       mtd->write_ecc = onenand_write_ecc;
        mtd->read_oob = onenand_read_oob;
        mtd->write_oob = onenand_write_oob;
        mtd->sync = onenand_sync;
index 87344ab65f194e7c204657ba7790d694f8a82911..318d877bfbbd99bfe4080f341c4c38f68b8d1582 100644 (file)
@@ -97,7 +97,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
                        /* No need to read pages fully,
                         * just read required OOB bytes */
                        ret = onenand_read_oob(mtd,
-                                            from + j * mtd->oobblock +
+                                            from + j * mtd->writesize +
                                             bd->offs, readlen, &retlen,
                                             &buf[0]);
 
@@ -107,7 +107,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
                        }
 
                        if (check_short_pattern
-                           (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+                           (&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
                                bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
                                printk(KERN_WARNING
                                       "Bad eraseblock %d at 0x%08x\n", i >> 1,
index 8e0dc00f757131e452243b3be04d236c63fb7801..14815c219b3daac59423eac9af0e0e84fb6785d4 100644 (file)
 #define MTD_ERASE_DONE          0x08
 #define MTD_ERASE_FAILED        0x10
 
+/*
+ * Enumeration for NAND/OneNAND flash chip state
+ */
+enum {
+       FL_READY,
+       FL_READING,
+       FL_WRITING,
+       FL_ERASING,
+       FL_SYNCING,
+       FL_CACHEDPRG,
+       FL_RESETING,
+       FL_UNLOCKING,
+       FL_LOCKING,
+       FL_PM_SUSPENDED,
+};
+
 /* If the erase fails, fail_addr might indicate exactly which block failed.  If
    fail_addr = 0xffffffff, the failure was not at the device level or was not
    specific to any particular block. */
index 2993a89e1b3cdae4995f0dce5d587f59e3b28ca0..7ac72de95e21d3103ec5ea7bad80d54b3a429b96 100644 (file)
@@ -213,20 +213,6 @@ typedef enum {
 #define NAND_CI_CHIPNR_MSK     0x03
 #define NAND_CI_CELLTYPE_MSK   0x0C
 
-/*
- * nand_state_t - chip states
- * Enumeration for NAND flash chip state
- */
-typedef enum {
-       FL_READY,
-       FL_READING,
-       FL_WRITING,
-       FL_ERASING,
-       FL_SYNCING,
-       FL_CACHEDPRG,
-       FL_PM_SUSPENDED,
-} nand_state_t;
-
 /* Keep gcc happy */
 struct nand_chip;
 
@@ -416,7 +402,7 @@ struct nand_chip {
        uint8_t         cellinfo;
        int             badblockpos;
 
-       nand_state_t    state;
+       int             state;
 
        uint8_t         *oob_poi;
        struct nand_hw_control  *controller;
index b05e7267e49aa1ffbf7582c05d3956928efb1a40..bb66e4547017265be04e2b6a90127bf579c5643b 100644 (file)
 #define NAND_CMD_ERASE2                0xd0
 #define NAND_CMD_RESET         0xff
 
-/*
- * Enumeration for NAND flash chip state
- */
-typedef enum {
-       FL_READY,
-       FL_READING,
-       FL_WRITING,
-       FL_ERASING,
-       FL_SYNCING
-} nand_state_t;
-
-
 /*
  * NAND Private Flash Chip Data
  *
index 4b0c2dfaaaa412305ae301ef93e7c9d0dd58277b..8a0fd0de97efb4b2a42c83fd5c0a7d06970e6f34 100644 (file)
@@ -17,6 +17,7 @@
 /* Note: The header order is impoertant */
 #include <onenand_uboot.h>
 
+#include <linux/mtd/compat.h>
 #include <linux/mtd/bbm.h>
 
 #define MAX_BUFFERRAM          2
@@ -27,20 +28,6 @@ extern int onenand_scan (struct mtd_info *mtd, int max_chips);
 /* Free resources held by the OneNAND device */
 extern void onenand_release (struct mtd_info *mtd);
 
-/**
- * onenand_state_t - chip states
- * Enumeration for OneNAND flash chip state
- */
-typedef enum {
-       FL_READY,
-       FL_READING,
-       FL_WRITING,
-       FL_ERASING,
-       FL_SYNCING,
-       FL_UNLOCKING,
-       FL_LOCKING,
-} onenand_state_t;
-
 /**
  * struct onenand_bufferram - OneNAND BufferRAM Data
  * @param block                block address in BufferRAM
@@ -103,10 +90,12 @@ struct onenand_chip {
        unsigned short (*read_word) (void __iomem * addr);
        void (*write_word) (unsigned short value, void __iomem * addr);
        void (*mmcontrol) (struct mtd_info * mtd, int sync_read);
+       int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
+       int (*scan_bbt)(struct mtd_info *mtd);
 
        spinlock_t chip_lock;
        wait_queue_head_t wq;
-       onenand_state_t state;
+       int state;
 
        struct nand_oobinfo *autooob;