diff options
Diffstat (limited to 'drivers/mtd/onenand/onenand_base.c')
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 24 |
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 | ||
2445 | EXPORT_SYMBOL_GPL(onenand_scan); | 2457 | EXPORT_SYMBOL_GPL(onenand_scan); |