Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -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);
+4 −1
Original line number Diff line number Diff line
@@ -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