diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/devices/doc2000.c | 179 | ||||
-rw-r--r-- | drivers/mtd/devices/doc2001.c | 179 | ||||
-rw-r--r-- | drivers/mtd/devices/doc2001plus.c | 164 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 16 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_ecc.c | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/sharpsl.c | 7 |
6 files changed, 216 insertions, 332 deletions
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index c54e404..603a795 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -55,10 +55,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, @@ -615,17 +611,10 @@ EXPORT_SYMBOL_GPL(DoC2k_init); 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) -{ struct DiskOnChip *this = mtd->priv; void __iomem *docptr = this->virtadr; struct Nand *mychip; - unsigned char syndrome[6]; + unsigned char syndrome[6], eccbuf[6]; volatile char dummy; int i, len256 = 0, ret=0; size_t left = len; @@ -673,15 +662,9 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP, CDSN_CTRL_ECC_IO); - if (eccbuf) { - /* Prime the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_EN, docptr, ECCConf); - } else { - /* disable the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_DIS, docptr, ECCConf); - } + /* Prime the ECC engine */ + WriteDOC(DOC_ECC_RESET, docptr, ECCConf); + WriteDOC(DOC_ECC_EN, docptr, ECCConf); /* treat crossing 256-byte sector for 2M x 8bits devices */ if (this->page256 && from + len > (from | 0xff) + 1) { @@ -698,58 +681,59 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, /* Let the caller know we completed it */ *retlen += len; - if (eccbuf) { - /* Read the ECC data through the DiskOnChip ECC logic */ - /* Note: this will work even with 2M x 8bit devices as */ - /* they have 8 bytes of OOB per 256 page. mf. */ - DoC_ReadBuf(this, eccbuf, 6); - - /* Flush the pipeline */ - if (DoC_is_Millennium(this)) { - dummy = ReadDOC(docptr, ECCConf); - dummy = ReadDOC(docptr, ECCConf); - i = ReadDOC(docptr, ECCConf); - } else { - dummy = ReadDOC(docptr, 2k_ECCStatus); - dummy = ReadDOC(docptr, 2k_ECCStatus); - i = ReadDOC(docptr, 2k_ECCStatus); - } + /* Read the ECC data through the DiskOnChip ECC logic */ + /* Note: this will work even with 2M x 8bit devices as */ + /* they have 8 bytes of OOB per 256 page. mf. */ + DoC_ReadBuf(this, eccbuf, 6); - /* Check the ECC Status */ - if (i & 0x80) { - int nb_errors; - /* There was an ECC error */ + /* Flush the pipeline */ + if (DoC_is_Millennium(this)) { + dummy = ReadDOC(docptr, ECCConf); + dummy = ReadDOC(docptr, ECCConf); + i = ReadDOC(docptr, ECCConf); + } else { + dummy = ReadDOC(docptr, 2k_ECCStatus); + dummy = ReadDOC(docptr, 2k_ECCStatus); + i = ReadDOC(docptr, 2k_ECCStatus); + } + + /* Check the ECC Status */ + if (i & 0x80) { + int nb_errors; + /* There was an ECC error */ #ifdef ECC_DEBUG - printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from); + printk(KERN_ERR "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, ECCSyndrome0 + i); - } - nb_errors = doc_decode_ecc(buf, syndrome); + /* 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, ECCSyndrome0 + i); + } + nb_errors = doc_decode_ecc(buf, syndrome); #ifdef ECC_DEBUG - printk(KERN_ERR "Errors corrected: %x\n", nb_errors); + printk(KERN_ERR "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 */ - ret = -EIO; - } + 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 */ + ret = -EIO; } + } #ifdef PSYCHO_DEBUG - printk(KERN_DEBUG "ECC DATA at %lxB: %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(KERN_DEBUG "ECC DATA at %lxB: %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 , ECCConf); - } + /* disable the ECC engine */ + WriteDOC(DOC_ECC_DIS, docptr , ECCConf); /* according to 11.4.1, we need to wait for the busy line * drop if we read to the end of the page. */ @@ -771,17 +755,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) -{ struct DiskOnChip *this = mtd->priv; int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */ void __iomem *docptr = this->virtadr; + unsigned char eccbuf[6]; volatile char dummy; int len256 = 0; struct Nand *mychip; @@ -835,15 +812,9 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, DoC_Command(this, NAND_CMD_SEQIN, 0); DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO); - if (eccbuf) { - /* Prime the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); - } else { - /* disable the ECC engine */ - WriteDOC(DOC_ECC_RESET, docptr, ECCConf); - WriteDOC(DOC_ECC_DIS, docptr, ECCConf); - } + /* Prime the ECC engine */ + WriteDOC(DOC_ECC_RESET, docptr, ECCConf); + WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); /* treat crossing 256-byte sector for 2M x 8bits devices */ if (this->page256 && to + len > (to | 0xff) + 1) { @@ -873,39 +844,35 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, DoC_WriteBuf(this, &buf[len256], len - len256); - if (eccbuf) { - WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, - CDSNControl); - - if (DoC_is_Millennium(this)) { - WriteDOC(0, docptr, NOP); - WriteDOC(0, docptr, NOP); - WriteDOC(0, docptr, NOP); - } else { - WriteDOC_(0, docptr, this->ioreg); - WriteDOC_(0, docptr, this->ioreg); - WriteDOC_(0, docptr, this->ioreg); - } + WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, CDSNControl); - WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr, - CDSNControl); + if (DoC_is_Millennium(this)) { + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); + } else { + WriteDOC_(0, docptr, this->ioreg); + WriteDOC_(0, docptr, this->ioreg); + WriteDOC_(0, docptr, this->ioreg); + } - /* Read the ECC data through the DiskOnChip ECC logic */ - for (di = 0; di < 6; di++) { - eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); - } + WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr, + CDSNControl); - /* Reset the ECC engine */ - WriteDOC(DOC_ECC_DIS, docptr, ECCConf); + /* Read the ECC data through the DiskOnChip ECC logic */ + for (di = 0; di < 6; di++) { + eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); + } + + /* Reset the ECC engine */ + WriteDOC(DOC_ECC_DIS, docptr, ECCConf); #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 - } - DoC_Command(this, NAND_CMD_PAGEPROG, 0); DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 0cf022a..0e2a932 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -37,12 +37,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, @@ -397,17 +391,9 @@ EXPORT_SYMBOL_GPL(DoCMil_init); 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 i, ret; volatile char dummy; - 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)]; @@ -437,15 +423,9 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00); DoC_WaitReady(docptr); - if (eccbuf) { - /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ - WriteDOC (DOC_ECC_RESET, docptr, ECCConf); - WriteDOC (DOC_ECC_EN, docptr, ECCConf); - } else { - /* disable the ECC engine */ - WriteDOC (DOC_ECC_RESET, docptr, ECCConf); - WriteDOC (DOC_ECC_DIS, docptr, ECCConf); - } + /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ + WriteDOC (DOC_ECC_RESET, docptr, ECCConf); + WriteDOC (DOC_ECC_EN, docptr, ECCConf); /* Read the data via the internal pipeline through CDSN IO register, see Pipelined Read Operations 11.3 */ @@ -465,58 +445,56 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, *retlen = len; ret = 0; - if (eccbuf) { - /* Read the ECC data from Spare Data Area, - see Reed-Solomon EDC/ECC 11.1 */ - dummy = ReadDOC(docptr, ReadPipeInit); + /* Read the ECC data from Spare Data Area, + see Reed-Solomon EDC/ECC 11.1 */ + dummy = ReadDOC(docptr, ReadPipeInit); #ifndef USE_MEMCPY - for (i = 0; i < 5; i++) { - /* N.B. you have to increase the source address in this way or the - ECC logic will not work properly */ - eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i); - } + for (i = 0; i < 5; i++) { + /* N.B. you have to increase the source address in this way or the + ECC logic will not work properly */ + eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i); + } #else - memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5); + memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5); #endif - eccbuf[5] = ReadDOC(docptr, LastDataRead); + eccbuf[5] = ReadDOC(docptr, LastDataRead); - /* Flush the pipeline */ - dummy = ReadDOC(docptr, ECCConf); - dummy = ReadDOC(docptr, ECCConf); + /* Flush the pipeline */ + dummy = ReadDOC(docptr, ECCConf); + dummy = ReadDOC(docptr, ECCConf); - /* Check the ECC Status */ - if (ReadDOC(docptr, ECCConf) & 0x80) { - int nb_errors; - /* There was an ECC error */ + /* Check the ECC Status */ + if (ReadDOC(docptr, 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, ECCSyndrome0 + i); - } - nb_errors = doc_decode_ecc(buf, syndrome); + /* 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, ECCSyndrome0 + i); + } + 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 */ - ret = -EIO; - } + 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 */ + 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 , ECCConf); - } + /* disable the ECC engine */ + WriteDOC(DOC_ECC_DIS, docptr , ECCConf); return ret; } @@ -524,15 +502,8 @@ 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,ret = 0; + char eccbuf[6]; volatile char dummy; struct DiskOnChip *this = mtd->priv; void __iomem *docptr = this->virtadr; @@ -573,15 +544,9 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, DoC_Address(docptr, 3, to, 0x00, 0x00); DoC_WaitReady(docptr); - if (eccbuf) { - /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ - WriteDOC (DOC_ECC_RESET, docptr, ECCConf); - WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); - } else { - /* disable the ECC engine */ - WriteDOC (DOC_ECC_RESET, docptr, ECCConf); - WriteDOC (DOC_ECC_DIS, docptr, ECCConf); - } + /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ + WriteDOC (DOC_ECC_RESET, docptr, ECCConf); + WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); /* Write the data via the internal pipeline through CDSN IO register, see Pipelined Write Operations 11.2 */ @@ -596,46 +561,44 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, #endif WriteDOC(0x00, docptr, WritePipeTerm); - if (eccbuf) { - /* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic - see Reed-Solomon EDC/ECC 11.1 */ - WriteDOC(0, docptr, NOP); - WriteDOC(0, docptr, NOP); - WriteDOC(0, docptr, NOP); + /* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic + see Reed-Solomon EDC/ECC 11.1 */ + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); - /* Read the ECC data through the DiskOnChip ECC logic */ - for (i = 0; i < 6; i++) { - eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i); - } + /* Read the ECC data through the DiskOnChip ECC logic */ + for (i = 0; i < 6; i++) { + eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i); + } - /* ignore the ECC engine */ - WriteDOC(DOC_ECC_DIS, docptr , ECCConf); + /* ignore the ECC engine */ + WriteDOC(DOC_ECC_DIS, docptr , ECCConf); #ifndef USE_MEMCPY - /* Write the ECC data to flash */ - for (i = 0; i < 6; i++) { - /* N.B. you have to increase the source address in this way or the - ECC logic will not work properly */ - WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i); - } + /* Write the ECC data to flash */ + for (i = 0; i < 6; i++) { + /* N.B. you have to increase the source address in this way or the + ECC logic will not work properly */ + WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i); + } #else - memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6); + memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6); #endif - /* write the block status BLOCK_USED (0x5555) at the end of ECC data - FIXME: this is only a hack for programming the IPL area for LinuxBIOS - and should be replace with proper codes in user space utilities */ - WriteDOC(0x55, docptr, Mil_CDSN_IO); - WriteDOC(0x55, docptr, Mil_CDSN_IO + 1); + /* write the block status BLOCK_USED (0x5555) at the end of ECC data + FIXME: this is only a hack for programming the IPL area for LinuxBIOS + and should be replace with proper codes in user space utilities */ + WriteDOC(0x55, docptr, Mil_CDSN_IO); + WriteDOC(0x55, docptr, Mil_CDSN_IO + 1); - WriteDOC(0x00, docptr, WritePipeTerm); + WriteDOC(0x00, docptr, WritePipeTerm); #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 - } /* Commit the Page Program command and wait for ready see Software Requirement 11.4 item 1.*/ 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); diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 80a7665..62b8613 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -155,7 +155,7 @@ static u16 nand_read_word(struct mtd_info *mtd) /** * nand_select_chip - [DEFAULT] control CE line * @mtd: MTD device structure - * @chip: chipnumber to select, -1 for deselect + * @chipnr: chipnumber to select, -1 for deselect * * Default select function for 1 chip devices. */ @@ -542,7 +542,6 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, * Send command to NAND device. This is the version for the new large page * devices We dont have the separate regions as we have in the small page * devices. We must emulate NAND_CMD_READOOB to keep the code compatible. - * */ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, int column, int page_addr) @@ -656,7 +655,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, /** * nand_get_device - [GENERIC] Get chip for selected access - * @this: the nand chip descriptor + * @chip: the nand chip descriptor * @mtd: MTD device structure * @new_state: the state which is requested * @@ -696,13 +695,12 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) /** * nand_wait - [DEFAULT] wait until the command is done * @mtd: MTD device structure - * @this: NAND chip structure + * @chip: NAND chip structure * * Wait for command done. This applies to erase and program only * Erase can take up to 400ms and program up to 20ms according to * general NAND and SmartMedia specs - * -*/ + */ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) { @@ -896,6 +894,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, /** * nand_transfer_oob - [Internal] Transfer oob to client buffer * @chip: nand chip structure + * @oob: oob destination address * @ops: oob ops structure */ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, @@ -946,6 +945,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, * * @mtd: MTD device structure * @from: offset to read from + * @ops: oob ops structure * * Internal function. Called with chip held. */ @@ -1760,7 +1760,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, /** * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band * @mtd: MTD device structure - * @from: offset to read from + * @to: offset to write to * @ops: oob operation description structure */ static int nand_write_oob(struct mtd_info *mtd, loff_t to, @@ -2055,7 +2055,7 @@ static void nand_sync(struct mtd_info *mtd) /** * nand_block_isbad - [MTD Interface] Check if block at offset is bad * @mtd: MTD device structure - * @ofs: offset relative to mtd start + * @offs: offset relative to mtd start */ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) { diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 2a163e4..dd438ca 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c @@ -65,8 +65,7 @@ static const u_char nand_ecc_precalc_table[] = { }; /** - * nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code - * for 256 byte block + * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block * @mtd: MTD block structure * @dat: raw data * @ecc_code: buffer for ECC diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 2174365..fbeedc3 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c @@ -237,11 +237,6 @@ static int __init sharpsl_nand_init(void) } } - if (machine_is_husky() || machine_is_borzoi() || machine_is_akita()) { - /* Need to use small eraseblock size for backward compatibility */ - sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS; - } - add_mtd_partitions(sharpsl_mtd, sharpsl_partition_info, nr_partitions); /* Return happy */ @@ -255,8 +250,6 @@ module_init(sharpsl_nand_init); */ static void __exit sharpsl_nand_cleanup(void) { - struct nand_chip *this = (struct nand_chip *)&sharpsl_mtd[1]; - /* Release resources, unregister device */ nand_release(sharpsl_mtd); |