]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/mtd/onenand/onenand_base.c
[MTD] [OneNAND] Exit the loop when transferring/filling of the oob is finished
[net-next-2.6.git] / drivers / mtd / onenand / onenand_base.c
index 7f1cb6e5dccb5b8463554cbf48e5227b66b1597d..6d4e67f6c295ac2b9c97a27c16d5b9373c17d327 100644 (file)
@@ -4,6 +4,11 @@
  *  Copyright (C) 2005-2007 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
+ *  Credits:
+ *     Adrian Hunter <ext-adrian.hunter@nokia.com>:
+ *     auto-placement support, read-while load support, various fixes
+ *     Copyright (C) Nokia Corporation, 2007
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -849,7 +854,8 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
                        int n = ed - st;
                        memcpy(buf, oob_buf + st, n);
                        buf += n;
-               }
+               } else
+                       break;
        }
        return 0;
 }
@@ -947,9 +953,9 @@ static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
 
 /**
  * onenand_read_oob - [MTD Interface] NAND write data and/or out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operation description structure
+ * @param mtd:         MTD device structure
+ * @param from:                offset to read from
+ * @param ops:         oob operation description structure
  */
 static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
                            struct mtd_oob_ops *ops)
@@ -1017,7 +1023,7 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state)
  * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
  * @param mtd          MTD device structure
  * @param from         offset to read from
- * @param @ops         oob operation description structure
+ * @param ops          oob operation description structure
  *
  * OneNAND read out-of-band data from the spare area for bbt scan
  */
@@ -1093,7 +1099,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
 static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
 {
        struct onenand_chip *this = mtd->priv;
-       char *readp = this->page_buf + mtd->writesize;
+       char oobbuf[64];
        int status, i;
 
        this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
@@ -1102,9 +1108,9 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
        if (status)
                return status;
 
-       this->read_bufferram(mtd, ONENAND_SPARERAM, readp, 0, mtd->oobsize);
-       for(i = 0; i < mtd->oobsize; i++)
-               if (buf[i] != 0xFF && buf[i] != readp[i])
+       this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
+       for (i = 0; i < mtd->oobsize; i++)
+               if (buf[i] != 0xFF && buf[i] != oobbuf[i])
                        return -EBADMSG;
 
        return 0;
@@ -1290,7 +1296,8 @@ static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
                        int n = ed - st;
                        memcpy(oob_buf + st, buf, n);
                        buf += n;
-               }
+               } else
+                       break;
        }
        return 0;
 }
@@ -1312,6 +1319,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
        struct onenand_chip *this = mtd->priv;
        int column, ret = 0, oobsize;
        int written = 0;
+       u_char *oobbuf;
 
        DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
 
@@ -1331,7 +1339,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
        }
 
        /* For compatibility with NAND: Do not allow write past end of page */
-       if (column + len > oobsize) {
+       if (unlikely(column + len > oobsize)) {
                printk(KERN_ERR "onenand_write_oob: "
                      "Attempt to write past end of page\n");
                return -EINVAL;
@@ -1348,6 +1356,8 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
        /* Grab the lock and see if the device is available */
        onenand_get_device(mtd, FL_WRITING);
 
+       oobbuf = this->page_buf + mtd->writesize;
+
        /* Loop until all data write */
        while (written < len) {
                int thislen = min_t(int, oobsize, len - written);
@@ -1358,12 +1368,12 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
 
                /* We send data to spare ram with oobsize
                 * to prevent byte access */
-               memset(this->page_buf, 0xff, mtd->oobsize);
+               memset(oobbuf, 0xff, mtd->oobsize);
                if (mode == MTD_OOB_AUTO)
-                       onenand_fill_auto_oob(mtd, this->page_buf, buf, column, thislen);
+                       onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
                else
-                       memcpy(this->page_buf + column, buf, thislen);
-               this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize);
+                       memcpy(oobbuf + column, buf, thislen);
+               this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
 
                this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
 
@@ -1375,7 +1385,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
                        break;
                }
 
-               ret = onenand_verify_oob(mtd, this->page_buf, to);
+               ret = onenand_verify_oob(mtd, oobbuf, to);
                if (ret) {
                        printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret);
                        break;
@@ -1400,9 +1410,9 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
 
 /**
  * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operation description structure
+ * @param mtd:         MTD device structure
+ * @param to:          offset to write
+ * @param ops:         oob operation description structure
  */
 static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
@@ -1616,6 +1626,7 @@ static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
  * @param mtd          MTD device structure
  * @param ofs          offset relative to mtd start
  * @param len          number of bytes to lock or unlock
+ * @param cmd          lock or unlock command
  *
  * Lock or unlock one or more blocks
  */
@@ -2117,10 +2128,11 @@ static void onenand_check_features(struct mtd_info *mtd)
 }
 
 /**
- * onenand_print_device_info - Print device ID
+ * onenand_print_device_info - Print device & version ID
  * @param device        device ID
+ * @param version      version ID
  *
- * Print device ID
+ * Print device & version ID
  */
 static void onenand_print_device_info(int device, int version)
 {
@@ -2367,6 +2379,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
        for (i = 0; this->ecclayout->oobfree[i].length; i++)
                this->ecclayout->oobavail +=
                        this->ecclayout->oobfree[i].length;
+       mtd->oobavail = this->ecclayout->oobavail;
 
        mtd->ecclayout = this->ecclayout;