Commit 470bc844 authored by Kyungmin Park's avatar Kyungmin Park Committed by David Woodhouse

[MTD] [OneNAND] Classify the page data and oob buffer

Classify the page data and oob buffer
and it prevents the memory fragementation (writesize + oobsize)
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 5bc399e9
...@@ -836,7 +836,7 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col ...@@ -836,7 +836,7 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
int readcol = column; int readcol = column;
int readend = column + thislen; int readend = column + thislen;
int lastgap = 0; 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) { for (free = this->ecclayout->oobfree; free->length; ++free) {
if (readcol >= lastgap) if (readcol >= lastgap)
...@@ -1356,7 +1356,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len, ...@@ -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 */ /* Grab the lock and see if the device is available */
onenand_get_device(mtd, FL_WRITING); onenand_get_device(mtd, FL_WRITING);
oobbuf = this->page_buf + mtd->writesize; oobbuf = this->oob_buf;
/* Loop until all data write */ /* Loop until all data write */
while (written < len) { while (written < len) {
...@@ -2332,15 +2332,25 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) ...@@ -2332,15 +2332,25 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
/* Allocate buffers, if necessary */ /* Allocate buffers, if necessary */
if (!this->page_buf) { if (!this->page_buf) {
size_t len; this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
len = mtd->writesize + mtd->oobsize;
this->page_buf = kmalloc(len, GFP_KERNEL);
if (!this->page_buf) { if (!this->page_buf) {
printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
return -ENOMEM; return -ENOMEM;
} }
this->options |= ONENAND_PAGEBUF_ALLOC; 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; this->state = FL_READY;
init_waitqueue_head(&this->wq); init_waitqueue_head(&this->wq);
...@@ -2437,9 +2447,11 @@ void onenand_release(struct mtd_info *mtd) ...@@ -2437,9 +2447,11 @@ void onenand_release(struct mtd_info *mtd)
kfree(bbm->bbt); kfree(bbm->bbt);
kfree(this->bbm); kfree(this->bbm);
} }
/* Buffer allocated by onenand_scan */ /* Buffers allocated by onenand_scan */
if (this->options & ONENAND_PAGEBUF_ALLOC) if (this->options & ONENAND_PAGEBUF_ALLOC)
kfree(this->page_buf); kfree(this->page_buf);
if (this->options & ONENAND_OOBBUF_ALLOC)
kfree(this->oob_buf);
} }
EXPORT_SYMBOL_GPL(onenand_scan); EXPORT_SYMBOL_GPL(onenand_scan);
......
...@@ -82,7 +82,8 @@ struct onenand_bufferram { ...@@ -82,7 +82,8 @@ struct onenand_bufferram {
* @wq: [INTERN] wait queue to sleep on if a OneNAND * @wq: [INTERN] wait queue to sleep on if a OneNAND
* operation is in progress * operation is in progress
* @state: [INTERN] the current state of the OneNAND device * @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 * @subpagesize: [INTERN] holds the subpagesize
* @ecclayout: [REPLACEABLE] the default ecc placement scheme * @ecclayout: [REPLACEABLE] the default ecc placement scheme
* @bbm: [REPLACEABLE] pointer to Bad Block Management * @bbm: [REPLACEABLE] pointer to Bad Block Management
...@@ -122,6 +123,7 @@ struct onenand_chip { ...@@ -122,6 +123,7 @@ struct onenand_chip {
wait_queue_head_t wq; wait_queue_head_t wq;
onenand_state_t state; onenand_state_t state;
unsigned char *page_buf; unsigned char *page_buf;
unsigned char *oob_buf;
int subpagesize; int subpagesize;
struct nand_ecclayout *ecclayout; struct nand_ecclayout *ecclayout;
...@@ -156,6 +158,7 @@ struct onenand_chip { ...@@ -156,6 +158,7 @@ struct onenand_chip {
#define ONENAND_HAS_CONT_LOCK (0x0001) #define ONENAND_HAS_CONT_LOCK (0x0001)
#define ONENAND_HAS_UNLOCK_ALL (0x0002) #define ONENAND_HAS_UNLOCK_ALL (0x0002)
#define ONENAND_PAGEBUF_ALLOC (0x1000) #define ONENAND_PAGEBUF_ALLOC (0x1000)
#define ONENAND_OOBBUF_ALLOC (0x2000)
/* /*
* OneNAND Flash Manufacturer ID Codes * OneNAND Flash Manufacturer ID Codes
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment