[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