[#6049] page write/read flow is wrong in bfin nand driver
Submitted By: Barry Song
Open Date
2010-05-31 03:43:38 Close Date
2010-06-10 04:19:20
Priority:
Medium Assignee:
Barry Song
Status:
Closed Fixed In Release:
N/A
Found In Release:
2010R1 Release:
Category:
N/A Board:
N/A
Processor:
ALL Silicon Revision:
Is this bug repeatable?:
Yes Resolution:
Fixed
Uboot version or rev.:
Toolchain version or rev.:
all
App binary format:
N/A
Summary: page write/read flow is wrong in bfin nand driver
Details:
bfin nand write devices to use dma and hw ecc if len == page_size. The logic is wrong.
static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
const uint8_t *buf, int len)
{
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform;
unsigned short page_size = (plat->page_size ? 512 : 256);
dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len);
if (len == page_size)
bf5xx_nand_dma_rw(mtd, (uint8_t *)buf, 0);
else
bf5xx_nand_write_buf(mtd, buf, len);
}
In nand_base, write page by raw and hwecc have different path:
/**
* nand_write_page_raw - [Intern] raw page write function
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
*
* Not for syndrome calculating ecc controllers, which use a special oob layout
*/
static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf)
{
chip->write_buf(mtd, buf, mtd->writesize);
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
}
/**
* nand_write_page_hwecc - [REPLACABLE] hardware ecc based page write function
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
*/
static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf)
{
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
uint8_t *ecc_calc = chip->buffers->ecccalc;
const uint8_t *p = buf;
uint32_t *eccpos = chip->ecc.layout->eccpos;
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
chip->write_buf(mtd, p, eccsize);
chip->ecc.calculate(mtd, p, &ecc_calc[i]);
}
for (i = 0; i < chip->ecc.total; i++)
chip->oob_poi[eccpos[i]] = ecc_calc[i];
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
}
In fact, our driver always only support nand_write_page_hwecc and always is working for nand_write_page_hwecc.
It should be fixed.
Follow-ups
--- Barry Song 2010-06-10 04:16:47
Our write_buf/read_buf entries always do ECC for HW ECC mode. That is not needed
for raw mode.
In fact, write_buf/read_buf should be a pure function for data input/output,
chip->ecc.hwctl controls ECC. But unfortunately, we can't seperate ECC from
data input/output in our NFC, so our DMA write/read_buf entries couple with ECC
operations closely.
Then we need provide read_page_raw/write_page_raw entried to stop bottom level
write/read_buf entries being called from nand base. In those functions, we call
non-dma version without ECC.
Files
Changes
Commits
Dependencies
Duplicates
Associations
Tags
File Name File Type File Size Posted By
No Files Were Found