From 1f92267c51a514f35ad5b0fd46cb099c0980b679 Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Tue, 6 Mar 2007 16:56:34 +0300 Subject: [MTD] [NAND] make oobavail public During the MTD rework the oobavail parameter of mtd_info structure has become private. This is not quite correct in terms of integrity and logic. If we have means to write to OOB area, then we'd like to know upfront how many bytes out of OOB are spare per page to be able to adapt to specific cases. The patch inlined adds the public oobavail parameter. Signed-off-by: Vitaly Wool Signed-off-by: David Woodhouse --- include/linux/mtd/mtd.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 6a8570be331b..3d956c3abb31 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -121,6 +121,7 @@ struct mtd_info { u_int32_t writesize; u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) + u_int32_t oobavail; // Available OOB bytes per block // Kernel-only stuff starts here. char *name; -- cgit v1.2.3 From 470bc844361b238bcbe6a07ba47d51fca25f2742 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Fri, 9 Mar 2007 10:08:11 +0900 Subject: [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 Signed-off-by: David Woodhouse --- drivers/mtd/onenand/onenand_base.c | 24 ++++++++++++++++++------ include/linux/mtd/onenand.h | 5 ++++- 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'include/linux') 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 int readcol = column; int readend = column + thislen; 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) { 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 */ onenand_get_device(mtd, FL_WRITING); - oobbuf = this->page_buf + mtd->writesize; + oobbuf = this->oob_buf; /* Loop until all data write */ while (written < len) { @@ -2332,15 +2332,25 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) /* Allocate buffers, if necessary */ if (!this->page_buf) { - size_t len; - len = mtd->writesize + mtd->oobsize; - this->page_buf = kmalloc(len, GFP_KERNEL); + this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL); if (!this->page_buf) { printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); return -ENOMEM; } 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; init_waitqueue_head(&this->wq); @@ -2437,9 +2447,11 @@ void onenand_release(struct mtd_info *mtd) kfree(bbm->bbt); kfree(this->bbm); } - /* Buffer allocated by onenand_scan */ + /* Buffers allocated by onenand_scan */ if (this->options & ONENAND_PAGEBUF_ALLOC) kfree(this->page_buf); + if (this->options & ONENAND_OOBBUF_ALLOC) + kfree(this->oob_buf); } EXPORT_SYMBOL_GPL(onenand_scan); diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index d8af8a95e58d..a56d24ada505 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -82,7 +82,8 @@ struct onenand_bufferram { * @wq: [INTERN] wait queue to sleep on if a OneNAND * operation is in progress * @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 * @ecclayout: [REPLACEABLE] the default ecc placement scheme * @bbm: [REPLACEABLE] pointer to Bad Block Management @@ -122,6 +123,7 @@ struct onenand_chip { wait_queue_head_t wq; onenand_state_t state; unsigned char *page_buf; + unsigned char *oob_buf; int subpagesize; struct nand_ecclayout *ecclayout; @@ -156,6 +158,7 @@ struct onenand_chip { #define ONENAND_HAS_CONT_LOCK (0x0001) #define ONENAND_HAS_UNLOCK_ALL (0x0002) #define ONENAND_PAGEBUF_ALLOC (0x1000) +#define ONENAND_OOBBUF_ALLOC (0x2000) /* * OneNAND Flash Manufacturer ID Codes -- cgit v1.2.3