diff options
Diffstat (limited to 'drivers/mtd/devices/doc2001.c')
| -rw-r--r-- | drivers/mtd/devices/doc2001.c | 179 | 
1 files changed, 71 insertions, 108 deletions
| diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 0cf022a69e65..0e2a9326f717 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.*/ | 
