Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d178214 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.infradead.org/mtd-2.6:
  [JFFS2][XATTR] Fix memory leak in POSIX-ACL support
  fs/jffs2/: make 2 functions static
  [MTD] NAND: Fix broken sharpsl driver
  [JFFS2][XATTR] Fix xd->refcnt race condition
  MTD: kernel-doc fixes + additions
  MTD: fix all kernel-doc warnings
  [MTD] DOC: Fixup read functions and do a little cleanup
parents 67ab33db c7afb0f9
Loading
Loading
Loading
Loading
+6 −5
Original line number Original line Diff line number Diff line
@@ -109,7 +109,7 @@
		for most of the implementations. These functions can be replaced by the
		for most of the implementations. These functions can be replaced by the
		board driver if neccecary. Those functions are called via pointers in the
		board driver if neccecary. Those functions are called via pointers in the
		NAND chip description structure. The board driver can set the functions which
		NAND chip description structure. The board driver can set the functions which
		should be replaced by board dependend functions before calling nand_scan().
		should be replaced by board dependent functions before calling nand_scan().
		If the function pointer is NULL on entry to nand_scan() then the pointer
		If the function pointer is NULL on entry to nand_scan() then the pointer
		is set to the default function which is suitable for the detected chip type.
		is set to the default function which is suitable for the detected chip type.
		</para></listitem>
		</para></listitem>
@@ -133,7 +133,7 @@
	  	[REPLACEABLE]</para><para>
	  	[REPLACEABLE]</para><para>
		Replaceable members hold hardware related functions which can be 
		Replaceable members hold hardware related functions which can be 
		provided by the board driver. The board driver can set the functions which
		provided by the board driver. The board driver can set the functions which
		should be replaced by board dependend functions before calling nand_scan().
		should be replaced by board dependent functions before calling nand_scan().
		If the function pointer is NULL on entry to nand_scan() then the pointer
		If the function pointer is NULL on entry to nand_scan() then the pointer
		is set to the default function which is suitable for the detected chip type.
		is set to the default function which is suitable for the detected chip type.
		</para></listitem>
		</para></listitem>
@@ -156,9 +156,8 @@
     	<title>Basic board driver</title>
     	<title>Basic board driver</title>
	<para>
	<para>
		For most boards it will be sufficient to provide just the
		For most boards it will be sufficient to provide just the
		basic functions and fill out some really board dependend
		basic functions and fill out some really board dependent
		members in the nand chip description structure.
		members in the nand chip description structure.
		See drivers/mtd/nand/skeleton for reference.
	</para>
	</para>
	<sect1>
	<sect1>
		<title>Basic defines</title>
		<title>Basic defines</title>
@@ -1295,7 +1294,9 @@ in this page</entry>
     </para>
     </para>
!Idrivers/mtd/nand/nand_base.c
!Idrivers/mtd/nand/nand_base.c
!Idrivers/mtd/nand/nand_bbt.c
!Idrivers/mtd/nand/nand_bbt.c
!Idrivers/mtd/nand/nand_ecc.c
<!-- No internal functions for kernel-doc:
X!Idrivers/mtd/nand/nand_ecc.c
-->
  </chapter>
  </chapter>


  <chapter id="credits">
  <chapter id="credits">
+73 −106
Original line number Original line Diff line number Diff line
@@ -55,10 +55,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
		    size_t *retlen, u_char *buf);
		    size_t *retlen, u_char *buf);
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
		     size_t *retlen, const u_char *buf);
		     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,
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
			struct mtd_oob_ops *ops);
			struct mtd_oob_ops *ops);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
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,
static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
		    size_t * retlen, u_char * buf)
		    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;
	struct DiskOnChip *this = mtd->priv;
	void __iomem *docptr = this->virtadr;
	void __iomem *docptr = this->virtadr;
	struct Nand *mychip;
	struct Nand *mychip;
	unsigned char syndrome[6];
	unsigned char syndrome[6], eccbuf[6];
	volatile char dummy;
	volatile char dummy;
	int i, len256 = 0, ret=0;
	int i, len256 = 0, ret=0;
	size_t left = len;
	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,
		DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
			    CDSN_CTRL_ECC_IO);
			    CDSN_CTRL_ECC_IO);


		if (eccbuf) {
		/* Prime the ECC engine */
		/* Prime the ECC engine */
		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
		WriteDOC(DOC_ECC_EN, 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);
		}


		/* treat crossing 256-byte sector for 2M x 8bits devices */
		/* treat crossing 256-byte sector for 2M x 8bits devices */
		if (this->page256 && from + len > (from | 0xff) + 1) {
		if (this->page256 && from + len > (from | 0xff) + 1) {
@@ -698,7 +681,6 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
		/* Let the caller know we completed it */
		/* Let the caller know we completed it */
		*retlen += len;
		*retlen += len;


		if (eccbuf) {
		/* Read the ECC data through the DiskOnChip ECC logic */
		/* Read the ECC data through the DiskOnChip ECC logic */
		/* Note: this will work even with 2M x 8bit devices as   */
		/* Note: this will work even with 2M x 8bit devices as   */
		/*       they have 8 bytes of OOB per 256 page. mf.      */
		/*       they have 8 bytes of OOB per 256 page. mf.      */
@@ -722,8 +704,9 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
#ifdef ECC_DEBUG
#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
#endif
				/* Read the ECC syndrom through the DiskOnChip ECC logic.
			/* Read the ECC syndrom through the DiskOnChip ECC
				   These syndrome will be all ZERO when there is no error */
			   logic.  These syndrome will be all ZERO when there
			   is no error */
			for (i = 0; i < 6; i++) {
			for (i = 0; i < 6; i++) {
				syndrome[i] =
				syndrome[i] =
					ReadDOC(docptr, ECCSyndrome0 + i);
					ReadDOC(docptr, ECCSyndrome0 + i);
@@ -734,9 +717,11 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
			printk(KERN_ERR "Errors corrected: %x\n", nb_errors);
			printk(KERN_ERR "Errors corrected: %x\n", nb_errors);
#endif
#endif
			if (nb_errors < 0) {
			if (nb_errors < 0) {
					/* We return error, but have actually done the read. Not that
				/* We return error, but have actually done the
					   this can be told to user-space, via sys_read(), but at least
				   read. Not that this can be told to
					   MTD-aware stuff can know about it by checking *retlen */
				   user-space, via sys_read(), but at least
				   MTD-aware stuff can know about it by
				   checking *retlen */
				ret = -EIO;
				ret = -EIO;
			}
			}
		}
		}
@@ -749,7 +734,6 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,


		/* disable the ECC engine */
		/* disable the ECC engine */
		WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
		WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
		}


		/* according to 11.4.1, we need to wait for the busy line
		/* according to 11.4.1, we need to wait for the busy line
	         * drop if we read to the end of the page.  */
	         * 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,
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
		     size_t * retlen, const u_char * buf)
		     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;
	struct DiskOnChip *this = mtd->priv;
	int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
	int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
	void __iomem *docptr = this->virtadr;
	void __iomem *docptr = this->virtadr;
	unsigned char eccbuf[6];
	volatile char dummy;
	volatile char dummy;
	int len256 = 0;
	int len256 = 0;
	struct Nand *mychip;
	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_Command(this, NAND_CMD_SEQIN, 0);
		DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
		DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);


		if (eccbuf) {
		/* Prime the ECC engine */
		/* Prime the ECC engine */
		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
		WriteDOC(DOC_ECC_EN | DOC_ECC_RW, 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);
		}


		/* treat crossing 256-byte sector for 2M x 8bits devices */
		/* treat crossing 256-byte sector for 2M x 8bits devices */
		if (this->page256 && to + len > (to | 0xff) + 1) {
		if (this->page256 && to + len > (to | 0xff) + 1) {
@@ -873,9 +844,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,


		DoC_WriteBuf(this, &buf[len256], len - len256);
		DoC_WriteBuf(this, &buf[len256], len - len256);


		if (eccbuf) {
		WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, CDSNControl);
			WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr,
				 CDSNControl);


		if (DoC_is_Millennium(this)) {
		if (DoC_is_Millennium(this)) {
			WriteDOC(0, docptr, NOP);
			WriteDOC(0, docptr, NOP);
@@ -904,8 +873,6 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
			 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
			 (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
			 eccbuf[4], eccbuf[5]);
			 eccbuf[4], eccbuf[5]);
#endif
#endif
		}

		DoC_Command(this, NAND_CMD_PAGEPROG, 0);
		DoC_Command(this, NAND_CMD_PAGEPROG, 0);


		DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
		DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+71 −108
Original line number Original line Diff line number Diff line
@@ -37,12 +37,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
		    size_t *retlen, u_char *buf);
		    size_t *retlen, u_char *buf);
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
		     size_t *retlen, const u_char *buf);
		     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,
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
			struct mtd_oob_ops *ops);
			struct mtd_oob_ops *ops);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
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,
static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
		     size_t *retlen, u_char *buf)
		     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;
	int i, ret;
	volatile char dummy;
	volatile char dummy;
	unsigned char syndrome[6];
	unsigned char syndrome[6], eccbuf[6];
	struct DiskOnChip *this = mtd->priv;
	struct DiskOnChip *this = mtd->priv;
	void __iomem *docptr = this->virtadr;
	void __iomem *docptr = this->virtadr;
	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
	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_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00);
	DoC_WaitReady(docptr);
	DoC_WaitReady(docptr);


	if (eccbuf) {
	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
	WriteDOC (DOC_ECC_EN, 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);
	}


	/* Read the data via the internal pipeline through CDSN IO register,
	/* Read the data via the internal pipeline through CDSN IO register,
	   see Pipelined Read Operations 11.3 */
	   see Pipelined Read Operations 11.3 */
@@ -465,7 +445,6 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
	*retlen = len;
	*retlen = len;
        ret = 0;
        ret = 0;


	if (eccbuf) {
	/* Read the ECC data from Spare Data Area,
	/* Read the ECC data from Spare Data Area,
	   see Reed-Solomon EDC/ECC 11.1 */
	   see Reed-Solomon EDC/ECC 11.1 */
	dummy = ReadDOC(docptr, ReadPipeInit);
	dummy = ReadDOC(docptr, ReadPipeInit);
@@ -516,23 +495,15 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,


	/* disable the ECC engine */
	/* disable the ECC engine */
	WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
	WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
	}


	return ret;
	return ret;
}
}


static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
		      size_t *retlen, const u_char *buf)
		      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;
	int i,ret = 0;
	char eccbuf[6];
	volatile char dummy;
	volatile char dummy;
	struct DiskOnChip *this = mtd->priv;
	struct DiskOnChip *this = mtd->priv;
	void __iomem *docptr = this->virtadr;
	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_Address(docptr, 3, to, 0x00, 0x00);
	DoC_WaitReady(docptr);
	DoC_WaitReady(docptr);


	if (eccbuf) {
	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
	WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
	WriteDOC (DOC_ECC_EN | DOC_ECC_RW, 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);
	}


	/* Write the data via the internal pipeline through CDSN IO register,
	/* Write the data via the internal pipeline through CDSN IO register,
	   see Pipelined Write Operations 11.2 */
	   see Pipelined Write Operations 11.2 */
@@ -596,7 +561,6 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
#endif
#endif
	WriteDOC(0x00, docptr, WritePipeTerm);
	WriteDOC(0x00, docptr, WritePipeTerm);


	if (eccbuf) {
	/* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
	/* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
	   see Reed-Solomon EDC/ECC 11.1 */
	   see Reed-Solomon EDC/ECC 11.1 */
	WriteDOC(0, docptr, NOP);
	WriteDOC(0, docptr, NOP);
@@ -635,7 +599,6 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
	       (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
	       (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
	       eccbuf[4], eccbuf[5]);
	       eccbuf[4], eccbuf[5]);
#endif
#endif
	}


	/* Commit the Page Program command and wait for ready
	/* Commit the Page Program command and wait for ready
	   see Software Requirement 11.4 item 1.*/
	   see Software Requirement 11.4 item 1.*/
+63 −101
Original line number Original line Diff line number Diff line
@@ -41,12 +41,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
		size_t *retlen, u_char *buf);
		size_t *retlen, u_char *buf);
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
		size_t *retlen, const u_char *buf);
		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,
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
			struct mtd_oob_ops *ops);
			struct mtd_oob_ops *ops);
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
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,
static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
		    size_t *retlen, u_char *buf)
		    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;
	int ret, i;
	volatile char dummy;
	volatile char dummy;
	loff_t fofs;
	loff_t fofs;
	unsigned char syndrome[6];
	unsigned char syndrome[6], eccbuf[6];
	struct DiskOnChip *this = mtd->priv;
	struct DiskOnChip *this = mtd->priv;
	void __iomem * docptr = this->virtadr;
	void __iomem * docptr = this->virtadr;
	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
@@ -644,14 +630,9 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
	WriteDOC(0, docptr, Mplus_FlashControl);
	WriteDOC(0, docptr, Mplus_FlashControl);
	DoC_WaitReady(docptr);
	DoC_WaitReady(docptr);


	if (eccbuf) {
	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
	WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
	WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
	} else {
		/* disable the ECC engine */
		WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
	}


	/* Let the caller know we completed it */
	/* Let the caller know we completed it */
	*retlen = len;
	*retlen = len;
@@ -660,7 +641,6 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
	ReadDOC(docptr, Mplus_ReadPipeInit);
	ReadDOC(docptr, Mplus_ReadPipeInit);
	ReadDOC(docptr, Mplus_ReadPipeInit);
	ReadDOC(docptr, Mplus_ReadPipeInit);


	if (eccbuf) {
	/* Read the data via the internal pipeline through CDSN IO
	/* Read the data via the internal pipeline through CDSN IO
	   register, see Pipelined Read Operations 11.3 */
	   register, see Pipelined Read Operations 11.3 */
	MemReadDOC(docptr, buf, len);
	MemReadDOC(docptr, buf, len);
@@ -691,9 +671,10 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
		printk("ECC Errors corrected: %x\n", nb_errors);
		printk("ECC Errors corrected: %x\n", nb_errors);
#endif
#endif
		if (nb_errors < 0) {
		if (nb_errors < 0) {
				/* We return error, but have actually done the read. Not that
			/* We return error, but have actually done the
				   this can be told to user-space, via sys_read(), but at least
			   read. Not that this can be told to user-space, via
				   MTD-aware stuff can know about it by checking *retlen */
			   sys_read(), but at least MTD-aware stuff can know
			   about it by checking *retlen */
#ifdef ECC_DEBUG
#ifdef ECC_DEBUG
			printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
			printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
				__FILE__, __LINE__, (int)from);
				__FILE__, __LINE__, (int)from);
@@ -715,16 +696,8 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
	       (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
	       (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
	       eccbuf[4], eccbuf[5]);
	       eccbuf[4], eccbuf[5]);
#endif
#endif

	/* disable the ECC engine */
	/* disable the ECC engine */
	WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
	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 flash internally */
	/* Disable flash internally */
	WriteDOC(0, docptr, Mplus_FlashSelect);
	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,
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
		     size_t *retlen, const u_char *buf)
		     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;
	int i, before, ret = 0;
	loff_t fto;
	loff_t fto;
	volatile char dummy;
	volatile char dummy;
	char eccbuf[6];
	struct DiskOnChip *this = mtd->priv;
	struct DiskOnChip *this = mtd->priv;
	void __iomem * docptr = this->virtadr;
	void __iomem * docptr = this->virtadr;
	struct Nand *mychip = &this->chips[to >> (this->chipshift)];
	struct Nand *mychip = &this->chips[to >> (this->chipshift)];
@@ -795,7 +761,6 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
	/* Disable the ECC engine */
	/* Disable the ECC engine */
	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
	WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);


	if (eccbuf) {
	if (before) {
	if (before) {
		/* Write the block status BLOCK_USED (0x5555) */
		/* Write the block status BLOCK_USED (0x5555) */
		WriteDOC(0x55, docptr, Mil_CDSN_IO);
		WriteDOC(0x55, docptr, Mil_CDSN_IO);
@@ -804,11 +769,9 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,


	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	/* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
	WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
	WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
	}


	MemWriteDOC(docptr, (unsigned char *) buf, len);
	MemWriteDOC(docptr, (unsigned char *) buf, len);


	if (eccbuf) {
	/* Write ECC data to flash, the ECC info is generated by
	/* Write ECC data to flash, the ECC info is generated by
	   the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
	   the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
	DoC_Delay(docptr, 3);
	DoC_Delay(docptr, 3);
@@ -834,7 +797,6 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
	       (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
	       (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
	       eccbuf[4], eccbuf[5]);
	       eccbuf[4], eccbuf[5]);
#endif
#endif
	}


	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
	WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+8 −8
Original line number Original line Diff line number Diff line
@@ -155,7 +155,7 @@ static u16 nand_read_word(struct mtd_info *mtd)
/**
/**
 * nand_select_chip - [DEFAULT] control CE line
 * nand_select_chip - [DEFAULT] control CE line
 * @mtd:	MTD device structure
 * @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.
 * 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
 * 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 dont have the separate regions as we have in the small page
 * devices.  We must emulate NAND_CMD_READOOB to keep the code compatible.
 * devices.  We must emulate NAND_CMD_READOOB to keep the code compatible.
 *
 */
 */
static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
			    int column, int page_addr)
			    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
 * nand_get_device - [GENERIC] Get chip for selected access
 * @this:	the nand chip descriptor
 * @chip:	the nand chip descriptor
 * @mtd:	MTD device structure
 * @mtd:	MTD device structure
 * @new_state:	the state which is requested
 * @new_state:	the state which is requested
 *
 *
@@ -696,12 +695,11 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
/**
/**
 * nand_wait - [DEFAULT]  wait until the command is done
 * nand_wait - [DEFAULT]  wait until the command is done
 * @mtd:	MTD device structure
 * @mtd:	MTD device structure
 * @this:	NAND chip structure
 * @chip:	NAND chip structure
 *
 *
 * Wait for command done. This applies to erase and program only
 * Wait for command done. This applies to erase and program only
 * Erase can take up to 400ms and program up to 20ms according to
 * Erase can take up to 400ms and program up to 20ms according to
 * general NAND and SmartMedia specs
 * general NAND and SmartMedia specs
 *
 */
 */
static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
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
 * nand_transfer_oob - [Internal] Transfer oob to client buffer
 * @chip:	nand chip structure
 * @chip:	nand chip structure
 * @oob:	oob destination address
 * @ops:	oob ops structure
 * @ops:	oob ops structure
 */
 */
static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
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
 * @mtd:	MTD device structure
 * @from:	offset to read from
 * @from:	offset to read from
 * @ops:	oob ops structure
 *
 *
 * Internal function. Called with chip held.
 * 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
 * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
 * @mtd:	MTD device structure
 * @mtd:	MTD device structure
 * @from:	offset to read from
 * @to:		offset to write to
 * @ops:	oob operation description structure
 * @ops:	oob operation description structure
 */
 */
static int nand_write_oob(struct mtd_info *mtd, loff_t to,
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
 * nand_block_isbad - [MTD Interface] Check if block at offset is bad
 * @mtd:	MTD device structure
 * @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)
static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
{
{
Loading