mirror of
https://github.com/adulau/aha.git
synced 2025-01-03 14:43:17 +00:00
[PATCH] mtd onenand driver: reduce stack usage
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
20ba89a361
commit
532a37cf8d
3 changed files with 28 additions and 7 deletions
|
@ -940,7 +940,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
|
||||||
u_char *eccbuf, struct nand_oobinfo *oobsel)
|
u_char *eccbuf, struct nand_oobinfo *oobsel)
|
||||||
{
|
{
|
||||||
struct onenand_chip *this = mtd->priv;
|
struct onenand_chip *this = mtd->priv;
|
||||||
unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf;
|
unsigned char *pbuf;
|
||||||
size_t total_len, len;
|
size_t total_len, len;
|
||||||
int i, written = 0;
|
int i, written = 0;
|
||||||
int ret = 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 */
|
/* Loop until all keve's data has been written */
|
||||||
len = 0;
|
len = 0;
|
||||||
while (count) {
|
while (count) {
|
||||||
pbuf = buffer;
|
pbuf = this->page_buf;
|
||||||
/*
|
/*
|
||||||
* If the given tuple is >= pagesize then
|
* If the given tuple is >= pagesize then
|
||||||
* write it out from the iov
|
* 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;
|
int cnt = 0, thislen;
|
||||||
while (cnt < mtd->oobblock) {
|
while (cnt < mtd->oobblock) {
|
||||||
thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
|
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;
|
cnt += thislen;
|
||||||
len += thislen;
|
len += thislen;
|
||||||
|
|
||||||
|
@ -1519,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
|
||||||
this->read_bufferram = onenand_sync_read_bufferram;
|
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;
|
this->state = FL_READY;
|
||||||
init_waitqueue_head(&this->wq);
|
init_waitqueue_head(&this->wq);
|
||||||
spin_lock_init(&this->chip_lock);
|
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)
|
void onenand_release(struct mtd_info *mtd)
|
||||||
{
|
{
|
||||||
|
struct onenand_chip *this = mtd->priv;
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_PARTITIONS
|
#ifdef CONFIG_MTD_PARTITIONS
|
||||||
/* Deregister partitions */
|
/* Deregister partitions */
|
||||||
del_mtd_partitions (mtd);
|
del_mtd_partitions (mtd);
|
||||||
#endif
|
#endif
|
||||||
/* Deregister the device */
|
/* Deregister the device */
|
||||||
del_mtd_device (mtd);
|
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);
|
EXPORT_SYMBOL_GPL(onenand_scan);
|
||||||
|
|
|
@ -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)
|
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;
|
bd->options &= ~NAND_BBT_SCANEMPTY;
|
||||||
return create_bbt(mtd, data_buf, bd, -1);
|
return create_bbt(mtd, this->page_buf, bd, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include <linux/mtd/bbm.h>
|
#include <linux/mtd/bbm.h>
|
||||||
|
|
||||||
#define MAX_BUFFERRAM 2
|
#define MAX_BUFFERRAM 2
|
||||||
#define MAX_ONENAND_PAGESIZE (2048 + 64)
|
|
||||||
|
|
||||||
/* Scan and identify a OneNAND device */
|
/* Scan and identify a OneNAND device */
|
||||||
extern int onenand_scan(struct mtd_info *mtd, int max_chips);
|
extern int onenand_scan(struct mtd_info *mtd, int max_chips);
|
||||||
|
@ -110,6 +109,7 @@ struct onenand_chip {
|
||||||
spinlock_t chip_lock;
|
spinlock_t chip_lock;
|
||||||
wait_queue_head_t wq;
|
wait_queue_head_t wq;
|
||||||
onenand_state_t state;
|
onenand_state_t state;
|
||||||
|
unsigned char *page_buf;
|
||||||
|
|
||||||
struct nand_oobinfo *autooob;
|
struct nand_oobinfo *autooob;
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ struct onenand_chip {
|
||||||
* Options bits
|
* Options bits
|
||||||
*/
|
*/
|
||||||
#define ONENAND_CONT_LOCK (0x0001)
|
#define ONENAND_CONT_LOCK (0x0001)
|
||||||
|
#define ONENAND_PAGEBUF_ALLOC (0x1000)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OneNAND Flash Manufacturer ID Codes
|
* OneNAND Flash Manufacturer ID Codes
|
||||||
|
|
Loading…
Reference in a new issue