[PATCH v2 6/6]nand/denali: change denali write page method

Chuanxiao.Dong chuanxiao.dong at intel.com
Thu Aug 12 06:51:58 EDT 2010


From 51c0771e113f9707a7cb6ff3d3300196c8ba4379 Mon Sep 17 00:00:00 2001
From: Chuanxiao Dong <chuanxiao.dong at intel.com>
Date: Thu, 12 Aug 2010 18:41:32 +0800
Subject: [PATCH 6/6] nand/denali: change denali write page method

In this way, driver will write data to MAIN and OOB area at
the same time. This feature will be used by Spectra FTL

Signed-off-by: Chuanxiao Dong <chuanxiao.dong at intel.com>
---
 drivers/mtd/nand/denali.c |   48 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index aa8f334..a807c1d 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1077,23 +1077,43 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
 	 * !raw_xfer - enable ecc
 	 * raw_xfer - transfer spare
 	 */
-	setup_ecc_for_xfer(denali, !raw_xfer, raw_xfer);
-
+	setup_ecc_for_xfer(denali, !raw_xfer, true);
+	clear_interrupts(denali);
 	/* copy buffer into DMA buffer */
-	memcpy(denali->buf.buf, buf, mtd->writesize);
-
 	if (raw_xfer) {
+		memcpy(denali->buf.buf, buf, mtd->writesize);
 		/* transfer the data to the spare area */
 		memcpy(denali->buf.buf + mtd->writesize,
 			chip->oob_poi,
 			mtd->oobsize);
+	} else {
+		uint8_t *datadest, *oobsrc;
+		const uint8_t *src;
+		uint32_t i, cpysize;
+		datadest = denali->buf.buf;
+		src = buf;
+		oobsrc = chip->oob_poi + (mtd->oobsize - mtd->oobavail);
+		for (i = 0; i < chip->ecc.steps - 1; i++,
+				src += chip->ecc.size,
+				datadest += chip->ecc.size + chip->ecc.bytes)
+			memcpy(datadest, src, chip->ecc.size);
+		cpysize = mtd->writesize -
+			(chip->ecc.size + chip->ecc.bytes) * i;
+		memcpy(datadest, src, cpysize);
+		src += cpysize;
+		datadest += cpysize;
+		for (i = 0; i < denali->bbtskipbytes; i++)
+			*datadest++ = 0xff;
+		cpysize = mtd->oobsize - mtd->oobavail -
+			denali->bbtskipbytes - chip->ecc.bytes;
+		memcpy(datadest, src, cpysize);
+		datadest += cpysize + chip->ecc.bytes;
+		memcpy(datadest, oobsrc, mtd->oobavail);
 	}
+	denali_enable_dma(denali, true);
 
 	pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_TODEVICE);
 
-	clear_interrupts(denali);
-	denali_enable_dma(denali, true);
-
 	denali_setup_dma(denali, DENALI_WRITE);
 
 	/* wait for operation to complete */
@@ -1103,13 +1123,17 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
 		dev_err(&denali->dev->dev,
 				"timeout on write_page (type = %d)\n",
 				raw_xfer);
-		denali->status =
-			(irq_status & INTR_STATUS0__PROGRAM_FAIL) ?
-			NAND_STATUS_FAIL : PASS;
-	}
+		denali->status = NAND_STATUS_FAIL;
+	} else if (irq_status & INTR_STATUS0__PROGRAM_FAIL)
+		denali->status = NAND_STATUS_FAIL;
+	else
+		denali->status = PASS;
 
-	denali_enable_dma(denali, false);
 	pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_TODEVICE);
+
+	denali_enable_dma(denali, false);
+
+	memset(chip->oob_poi, 0xff, mtd->oobsize);
 }
 
 /* NAND core entry points */
-- 
1.6.6.1




More information about the linux-mtd mailing list