diff options
author | Thomas Gleixner <tglx@cruncher.tec.linutronix.de> | 2006-06-28 10:11:33 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@cruncher.tec.linutronix.de> | 2006-06-28 10:11:33 +0200 |
commit | 7f8a894066b826a4baea49c2a3adbba0a56a192f (patch) | |
tree | 94833927f58f47a2b29b026ed1839b90a3ef29cf /drivers/mtd/devices/doc2001plus.c | |
parent | a39727f212426b9d5f9267b3318a2afaf9922d3b (diff) | |
download | op-kernel-dev-7f8a894066b826a4baea49c2a3adbba0a56a192f.zip op-kernel-dev-7f8a894066b826a4baea49c2a3adbba0a56a192f.tar.gz |
[MTD] DOC: Fixup read functions and do a little cleanup
The NAND rework resulted in non ECC based reads. Fix it up and
do a bit of cleanup while at it.
Pointed out by Adrian Bunk.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/mtd/devices/doc2001plus.c')
-rw-r--r-- | drivers/mtd/devices/doc2001plus.c | 164 |
1 files changed, 63 insertions, 101 deletions
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 66cb1e5..92dbb47 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -41,12 +41,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); -static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, - struct nand_oobinfo *oobsel); -static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, - struct nand_oobinfo *oobsel); static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, struct mtd_oob_ops *ops); static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, @@ -595,18 +589,10 @@ static int doc_dumpblk(struct mtd_info *mtd, loff_t from) static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - /* Just a special case of doc_read_ecc */ - return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL); -} - -static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf, - struct nand_oobinfo *oobsel) -{ int ret, i; volatile char dummy; loff_t fofs; - unsigned char syndrome[6]; + unsigned char syndrome[6], eccbuf[6]; struct DiskOnChip *this = mtd->priv; void __iomem * docptr = this->virtadr; struct Nand *mychip = &this->chips[from >> (this->chipshift)]; @@ -644,56 +630,51 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, WriteDOC(0, docptr, Mplus_FlashControl); DoC_WaitReady(docptr); - if (eccbuf) { - /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ - WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); - WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); - } else { - /* disable the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); - } + /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ + WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); + WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); /* Let the caller know we completed it */ *retlen = len; - ret = 0; + ret = 0; ReadDOC(docptr, Mplus_ReadPipeInit); ReadDOC(docptr, Mplus_ReadPipeInit); - if (eccbuf) { - /* Read the data via the internal pipeline through CDSN IO - register, see Pipelined Read Operations 11.3 */ - MemReadDOC(docptr, buf, len); + /* Read the data via the internal pipeline through CDSN IO + register, see Pipelined Read Operations 11.3 */ + MemReadDOC(docptr, buf, len); - /* Read the ECC data following raw data */ - MemReadDOC(docptr, eccbuf, 4); - eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead); - eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead); + /* Read the ECC data following raw data */ + MemReadDOC(docptr, eccbuf, 4); + eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead); + eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead); - /* Flush the pipeline */ - dummy = ReadDOC(docptr, Mplus_ECCConf); - dummy = ReadDOC(docptr, Mplus_ECCConf); + /* Flush the pipeline */ + dummy = ReadDOC(docptr, Mplus_ECCConf); + dummy = ReadDOC(docptr, Mplus_ECCConf); - /* Check the ECC Status */ - if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) { - int nb_errors; - /* There was an ECC error */ + /* Check the ECC Status */ + if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) { + int nb_errors; + /* There was an ECC error */ #ifdef ECC_DEBUG - printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); + printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); #endif - /* Read the ECC syndrom through the DiskOnChip ECC logic. - These syndrome will be all ZERO when there is no error */ - for (i = 0; i < 6; i++) - syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); + /* Read the ECC syndrom through the DiskOnChip ECC logic. + These syndrome will be all ZERO when there is no error */ + for (i = 0; i < 6; i++) + syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); - nb_errors = doc_decode_ecc(buf, syndrome); + nb_errors = doc_decode_ecc(buf, syndrome); #ifdef ECC_DEBUG - printk("ECC Errors corrected: %x\n", nb_errors); + printk("ECC Errors corrected: %x\n", nb_errors); #endif - if (nb_errors < 0) { - /* We return error, but have actually done the read. Not that - this can be told to user-space, via sys_read(), but at least - MTD-aware stuff can know about it by checking *retlen */ + if (nb_errors < 0) { + /* We return error, but have actually done the + read. Not that this can be told to user-space, via + sys_read(), but at least MTD-aware stuff can know + about it by checking *retlen */ #ifdef ECC_DEBUG printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n", __FILE__, __LINE__, (int)from); @@ -707,24 +688,16 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, eccbuf[3], eccbuf[4], eccbuf[5]); #endif ret = -EIO; - } } + } #ifdef PSYCHO_DEBUG - printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", - (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], - eccbuf[4], eccbuf[5]); + printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", + (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], + eccbuf[4], eccbuf[5]); #endif - - /* disable the ECC engine */ - WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf); - } else { - /* Read the data via the internal pipeline through CDSN IO - register, see Pipelined Read Operations 11.3 */ - MemReadDOC(docptr, buf, len-2); - buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead); - buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead); - } + /* disable the ECC engine */ + WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf); /* Disable flash internally */ WriteDOC(0, docptr, Mplus_FlashSelect); @@ -735,17 +708,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - char eccbuf[6]; - return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL); -} - -static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf, - struct nand_oobinfo *oobsel) -{ int i, before, ret = 0; loff_t fto; volatile char dummy; + char eccbuf[6]; struct DiskOnChip *this = mtd->priv; void __iomem * docptr = this->virtadr; struct Nand *mychip = &this->chips[to >> (this->chipshift)]; @@ -795,46 +761,42 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, /* Disable the ECC engine */ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); - if (eccbuf) { - if (before) { - /* Write the block status BLOCK_USED (0x5555) */ - WriteDOC(0x55, docptr, Mil_CDSN_IO); - WriteDOC(0x55, docptr, Mil_CDSN_IO); - } - - /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ - WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf); + if (before) { + /* Write the block status BLOCK_USED (0x5555) */ + WriteDOC(0x55, docptr, Mil_CDSN_IO); + WriteDOC(0x55, docptr, Mil_CDSN_IO); } + /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ + WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf); + MemWriteDOC(docptr, (unsigned char *) buf, len); - if (eccbuf) { - /* Write ECC data to flash, the ECC info is generated by - the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */ - DoC_Delay(docptr, 3); + /* Write ECC data to flash, the ECC info is generated by + the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */ + DoC_Delay(docptr, 3); - /* Read the ECC data through the DiskOnChip ECC logic */ - for (i = 0; i < 6; i++) - eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); + /* Read the ECC data through the DiskOnChip ECC logic */ + for (i = 0; i < 6; i++) + eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); - /* disable the ECC engine */ - WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); + /* disable the ECC engine */ + WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); - /* Write the ECC data to flash */ - MemWriteDOC(docptr, eccbuf, 6); + /* Write the ECC data to flash */ + MemWriteDOC(docptr, eccbuf, 6); - if (!before) { - /* Write the block status BLOCK_USED (0x5555) */ - WriteDOC(0x55, docptr, Mil_CDSN_IO+6); - WriteDOC(0x55, docptr, Mil_CDSN_IO+7); - } + if (!before) { + /* Write the block status BLOCK_USED (0x5555) */ + WriteDOC(0x55, docptr, Mil_CDSN_IO+6); + WriteDOC(0x55, docptr, Mil_CDSN_IO+7); + } #ifdef PSYCHO_DEBUG - printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", - (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], - eccbuf[4], eccbuf[5]); + printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", + (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], + eccbuf[4], eccbuf[5]); #endif - } WriteDOC(0x00, docptr, Mplus_WritePipeTerm); WriteDOC(0x00, docptr, Mplus_WritePipeTerm); |