[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: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
This commit is contained in:
parent
5bc399e9ef
commit
470bc84436
2 changed files with 22 additions and 7 deletions
|
@ -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,
|
||||||
/* 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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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 {
|
||||||
* @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 {
|
||||||
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 {
|
||||||
#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
|
||||||
|
|
Loading…
Reference in a new issue