aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand/onenand_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/onenand/onenand_base.c')
-rw-r--r--drivers/mtd/onenand/onenand_base.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 6d4e67f6c295..9e14a26ca4e8 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -836,7 +836,7 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
836 int readcol = column; 836 int readcol = column;
837 int readend = column + thislen; 837 int readend = column + thislen;
838 int lastgap = 0; 838 int lastgap = 0;
839 uint8_t *oob_buf = this->page_buf + mtd->writesize; 839 uint8_t *oob_buf = this->oob_buf;
840 840
841 for (free = this->ecclayout->oobfree; free->length; ++free) { 841 for (free = this->ecclayout->oobfree; free->length; ++free) {
842 if (readcol >= lastgap) 842 if (readcol >= lastgap)
@@ -1356,7 +1356,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1356 /* Grab the lock and see if the device is available */ 1356 /* Grab the lock and see if the device is available */
1357 onenand_get_device(mtd, FL_WRITING); 1357 onenand_get_device(mtd, FL_WRITING);
1358 1358
1359 oobbuf = this->page_buf + mtd->writesize; 1359 oobbuf = this->oob_buf;
1360 1360
1361 /* Loop until all data write */ 1361 /* Loop until all data write */
1362 while (written < len) { 1362 while (written < len) {
@@ -2332,15 +2332,25 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2332 2332
2333 /* Allocate buffers, if necessary */ 2333 /* Allocate buffers, if necessary */
2334 if (!this->page_buf) { 2334 if (!this->page_buf) {
2335 size_t len; 2335 this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
2336 len = mtd->writesize + mtd->oobsize;
2337 this->page_buf = kmalloc(len, GFP_KERNEL);
2338 if (!this->page_buf) { 2336 if (!this->page_buf) {
2339 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); 2337 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
2340 return -ENOMEM; 2338 return -ENOMEM;
2341 } 2339 }
2342 this->options |= ONENAND_PAGEBUF_ALLOC; 2340 this->options |= ONENAND_PAGEBUF_ALLOC;
2343 } 2341 }
2342 if (!this->oob_buf) {
2343 this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
2344 if (!this->oob_buf) {
2345 printk(KERN_ERR "onenand_scan(): Can't allocate oob_buf\n");
2346 if (this->options & ONENAND_PAGEBUF_ALLOC) {
2347 this->options &= ~ONENAND_PAGEBUF_ALLOC;
2348 kfree(this->page_buf);
2349 }
2350 return -ENOMEM;
2351 }
2352 this->options |= ONENAND_OOBBUF_ALLOC;
2353 }
2344 2354
2345 this->state = FL_READY; 2355 this->state = FL_READY;
2346 init_waitqueue_head(&this->wq); 2356 init_waitqueue_head(&this->wq);
@@ -2437,9 +2447,11 @@ void onenand_release(struct mtd_info *mtd)
2437 kfree(bbm->bbt); 2447 kfree(bbm->bbt);
2438 kfree(this->bbm); 2448 kfree(this->bbm);
2439 } 2449 }
2440 /* Buffer allocated by onenand_scan */ 2450 /* Buffers allocated by onenand_scan */
2441 if (this->options & ONENAND_PAGEBUF_ALLOC) 2451 if (this->options & ONENAND_PAGEBUF_ALLOC)
2442 kfree(this->page_buf); 2452 kfree(this->page_buf);
2453 if (this->options & ONENAND_OOBBUF_ALLOC)
2454 kfree(this->oob_buf);
2443} 2455}
2444 2456
2445EXPORT_SYMBOL_GPL(onenand_scan); 2457EXPORT_SYMBOL_GPL(onenand_scan);