]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
[MTD] [OneNAND] Classify the page data and oob buffer
authorKyungmin Park <kyungmin.park@samsung.com>
Fri, 9 Mar 2007 01:08:11 +0000 (10:08 +0900)
committerDavid Woodhouse <dwmw2@infradead.org>
Fri, 9 Mar 2007 08:08:09 +0000 (08:08 +0000)
Classify the page data and oob buffer
and it prevents the memory fragementation (writesize + oobsize)

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
drivers/mtd/onenand/onenand_base.c
include/linux/mtd/onenand.h

index 6d4e67f6c295ac2b9c97a27c16d5b9373c17d327..9e14a26ca4e82ba07b4b328811f2f5f661eb1a60 100644 (file)
@@ -836,7 +836,7 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
        int readcol = column;
        int readend = column + thislen;
        int lastgap = 0;
-       uint8_t *oob_buf = this->page_buf + mtd->writesize;
+       uint8_t *oob_buf = this->oob_buf;
 
        for (free = this->ecclayout->oobfree; free->length; ++free) {
                if (readcol >= lastgap)
@@ -1356,7 +1356,7 @@ 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;
+       oobbuf = this->oob_buf;
 
        /* Loop until all data write */
        while (written < len) {
@@ -2332,15 +2332,25 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 
        /* Allocate buffers, if necessary */
        if (!this->page_buf) {
-               size_t len;
-               len = mtd->writesize + mtd->oobsize;
-               this->page_buf = kmalloc(len, GFP_KERNEL);
+               this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
                if (!this->page_buf) {
                        printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
                        return -ENOMEM;
                }
                this->options |= ONENAND_PAGEBUF_ALLOC;
        }
+       if (!this->oob_buf) {
+               this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
+               if (!this->oob_buf) {
+                       printk(KERN_ERR "onenand_scan(): Can't allocate oob_buf\n");
+                       if (this->options & ONENAND_PAGEBUF_ALLOC) {
+                               this->options &= ~ONENAND_PAGEBUF_ALLOC;
+                               kfree(this->page_buf);
+                       }
+                       return -ENOMEM;
+               }
+               this->options |= ONENAND_OOBBUF_ALLOC;
+       }
 
        this->state = FL_READY;
        init_waitqueue_head(&this->wq);
@@ -2437,9 +2447,11 @@ void onenand_release(struct mtd_info *mtd)
                kfree(bbm->bbt);
                kfree(this->bbm);
        }
-       /* Buffer allocated by onenand_scan */
+       /* Buffers allocated by onenand_scan */
        if (this->options & ONENAND_PAGEBUF_ALLOC)
                kfree(this->page_buf);
+       if (this->options & ONENAND_OOBBUF_ALLOC)
+               kfree(this->oob_buf);
 }
 
 EXPORT_SYMBOL_GPL(onenand_scan);
index d8af8a95e58d86305227afb9a8385911b4b67b18..a56d24ada5057eacddc91cb51ee4254cfdcfed13 100644 (file)
@@ -82,7 +82,8 @@ struct onenand_bufferram {
  * @wq:                        [INTERN] wait queue to sleep on if a OneNAND
  *                     operation is in progress
  * @state:             [INTERN] the current state of the OneNAND device
- * @page_buf:          data buffer
+ * @page_buf:          [INTERN] page main data buffer
+ * @oob_buf:           [INTERN] page oob data buffer
  * @subpagesize:       [INTERN] holds the subpagesize
  * @ecclayout:         [REPLACEABLE] the default ecc placement scheme
  * @bbm:               [REPLACEABLE] pointer to Bad Block Management
@@ -122,6 +123,7 @@ struct onenand_chip {
        wait_queue_head_t       wq;
        onenand_state_t         state;
        unsigned char           *page_buf;
+       unsigned char           *oob_buf;
 
        int                     subpagesize;
        struct nand_ecclayout   *ecclayout;
@@ -156,6 +158,7 @@ struct onenand_chip {
 #define ONENAND_HAS_CONT_LOCK          (0x0001)
 #define ONENAND_HAS_UNLOCK_ALL         (0x0002)
 #define ONENAND_PAGEBUF_ALLOC          (0x1000)
+#define ONENAND_OOBBUF_ALLOC           (0x2000)
 
 /*
  * OneNAND Flash Manufacturer ID Codes