[U-Boot] [PATCH V3] NAND: Allow per-buffer allocation

Marek Vasut marek.vasut at gmail.com
Wed Aug 10 04:13:23 CEST 2011


Don't allocate NAND buffers as one block, but allocate them separately. This can
be beneficial for example for systems, which need DMA buffers to be aligned.
With this patch, such systems can allocate aligned buffers and avoid memcpy()ing
data in place.

Signed-off-by: Marek Vasut <marek.vasut at gmail.com>
---
 drivers/mtd/nand/nand_base.c |   30 +++++++++++++++++++++++-------
 include/linux/mtd/nand.h     |    7 ++++---
 2 files changed, 27 insertions(+), 10 deletions(-)

V2: Fix the chip->buffers->buffer condition

V3: Fix compiler warning due to bad cast in chip->buffers->buffer and patch
description

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1a95a91..a5f872e 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2749,13 +2749,27 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
  */
 int nand_scan_tail(struct mtd_info *mtd)
 {
-	int i;
+	int i, bufsize;
+	uint8_t *buf;
 	struct nand_chip *chip = mtd->priv;
 
-	if (!(chip->options & NAND_OWN_BUFFERS))
-		chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
-	if (!chip->buffers)
-		return -ENOMEM;
+	if (!(chip->options & NAND_OWN_BUFFERS)) {
+		chip->buffers = malloc(sizeof(struct nand_buffers));
+		if (!chip->buffers)
+			return -ENOMEM;
+
+		bufsize = NAND_MAX_PAGESIZE + (3 * NAND_MAX_OOBSIZE);
+		buf = malloc(bufsize);
+		if (!buf) {
+			free(chip->buffers);
+			return -ENOMEM;
+		}
+
+		chip->buffers->buffer = buf;
+		chip->buffers->ecccalc = buf;
+		chip->buffers->ecccode = buf + NAND_MAX_OOBSIZE;
+		chip->buffers->databuf = buf + (2 * NAND_MAX_OOBSIZE);
+	}
 
 	/* Set the internal oob buffer location, just after the page data */
 	chip->oob_poi = chip->buffers->databuf + mtd->writesize;
@@ -2996,6 +3010,8 @@ void nand_release(struct mtd_info *mtd)
 
 	/* Free bad block table memory */
 	kfree(chip->bbt);
-	if (!(chip->options & NAND_OWN_BUFFERS))
-		kfree(chip->buffers);
+	if (!(chip->options & NAND_OWN_BUFFERS)) {
+		free(chip->buffers->buffer);
+		free(chip->buffers);
+	}
 }
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 987a2ec..c3449a9 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -370,9 +370,10 @@ struct nand_ecc_ctrl {
  * consecutive order.
  */
 struct nand_buffers {
-	uint8_t	ecccalc[NAND_MAX_OOBSIZE];
-	uint8_t	ecccode[NAND_MAX_OOBSIZE];
-	uint8_t databuf[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE];
+	uint8_t *buffer;
+	uint8_t	*ecccalc;
+	uint8_t	*ecccode;
+	uint8_t *databuf;
 };
 
 /**
-- 
1.7.5.4



More information about the U-Boot mailing list