[MTD] DOC: Fixup read functions and do a little cleanup
authorThomas Gleixner <tglx@cruncher.tec.linutronix.de>
Wed, 28 Jun 2006 08:11:33 +0000 (10:11 +0200)
committerThomas Gleixner <tglx@cruncher.tec.linutronix.de>
Wed, 28 Jun 2006 08:11:33 +0000 (10:11 +0200)
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>
drivers/mtd/devices/doc2000.c
drivers/mtd/devices/doc2001.c
drivers/mtd/devices/doc2001plus.c

index c54e40464d8283eb3a0de099e0ef27a481faeed2..603a7951ac9b1e3e9b646811a840c4e8139745b8 100644 (file)
@@ -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,
@@ -614,18 +610,11 @@ 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.  */
@@ -770,18 +754,11 @@ 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);
index 0cf022a69e653433e9a5f941fd739fd4a712a13e..0e2a9326f717da9f18213b2032195e0529b7c132 100644 (file)
@@ -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,
@@ -396,18 +390,10 @@ 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,74 +445,65 @@ 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;
 }
 
 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.*/
index 66cb1e50469a1df22f0c409f90a2786ebe3e929c..92dbb47f2ac35597e5e4d18cc39bd079eb6dc0ed 100644 (file)
@@ -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,
@@ -594,19 +588,11 @@ 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);
@@ -734,18 +707,11 @@ 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);