[PATCH] mtd onenand driver: reduce stack usage
Kyungmin Park [Fri, 16 Dec 2005 02:17:29 +0000 (11:17 +0900)]
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/onenand_bbt.c
include/linux/mtd/onenand.h

index d57afba..a53a73f 100644 (file)
@@ -940,7 +940,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
        u_char *eccbuf, struct nand_oobinfo *oobsel)
 {
        struct onenand_chip *this = mtd->priv;
-       unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf;
+       unsigned char *pbuf;
        size_t total_len, len;
        int i, written = 0;
        int ret = 0;
@@ -975,7 +975,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
        /* Loop until all keve's data has been written */
        len = 0;
        while (count) {
-               pbuf = buffer;
+               pbuf = this->page_buf;
                /*
                 * If the given tuple is >= pagesize then
                 * write it out from the iov
@@ -995,7 +995,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
                        int cnt = 0, thislen;
                        while (cnt < mtd->oobblock) {
                                thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
-                               memcpy(buffer + cnt, vecs->iov_base + len, thislen);
+                               memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
                                cnt += thislen;
                                len += thislen;
 
@@ -1519,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
                this->read_bufferram = onenand_sync_read_bufferram;
        }
 
+       /* Allocate buffers, if necessary */
+       if (!this->page_buf) {
+               size_t len;
+               len = mtd->oobblock + mtd->oobsize;
+               this->page_buf = kmalloc(len, GFP_KERNEL);
+               if (!this->page_buf) {
+                       printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
+                       return -ENOMEM;
+               }
+               this->options |= ONENAND_PAGEBUF_ALLOC;
+       }
+
        this->state = FL_READY;
        init_waitqueue_head(&this->wq);
        spin_lock_init(&this->chip_lock);
@@ -1580,12 +1592,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
  */
 void onenand_release(struct mtd_info *mtd)
 {
+       struct onenand_chip *this = mtd->priv;
+
 #ifdef CONFIG_MTD_PARTITIONS
        /* Deregister partitions */
        del_mtd_partitions (mtd);
 #endif
        /* Deregister the device */
        del_mtd_device (mtd);
+
+       /* Free bad block table memory, if allocated */
+       if (this->bbm)
+               kfree(this->bbm);
+       /* Buffer allocated by onenand_scan */
+       if (this->options & ONENAND_PAGEBUF_ALLOC)
+               kfree(this->page_buf);
 }
 
 EXPORT_SYMBOL_GPL(onenand_scan);
index f40190f..4510d33 100644 (file)
@@ -118,10 +118,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
  */
 static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
-       unsigned char data_buf[MAX_ONENAND_PAGESIZE];
+       struct onenand_chip *this = mtd->priv;
 
         bd->options &= ~NAND_BBT_SCANEMPTY;
-        return create_bbt(mtd, data_buf, bd, -1);
+       return create_bbt(mtd, this->page_buf, bd, -1);
 }
 
 /**
index 53423d3..7419b5f 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/mtd/bbm.h>
 
 #define MAX_BUFFERRAM          2
-#define MAX_ONENAND_PAGESIZE   (2048 + 64)
 
 /* Scan and identify a OneNAND device */
 extern int onenand_scan(struct mtd_info *mtd, int max_chips);
@@ -110,6 +109,7 @@ struct onenand_chip {
        spinlock_t              chip_lock;
        wait_queue_head_t       wq;
        onenand_state_t         state;
+       unsigned char           *page_buf;
 
        struct nand_oobinfo     *autooob;
 
@@ -134,7 +134,7 @@ struct onenand_chip {
  * Options bits
  */
 #define ONENAND_CONT_LOCK              (0x0001)
-
+#define ONENAND_PAGEBUF_ALLOC          (0x1000)
 
 /*
  * OneNAND Flash Manufacturer ID Codes