diff options
| author | William Juul <william.juul@datarespons.no> | 2007-10-31 13:53:06 +0100 | 
|---|---|---|
| committer | Scott Wood <scottwood@freescale.com> | 2008-08-12 11:31:15 -0500 | 
| commit | cfa460adfdefcc30d104e1a9ee44994ee349bb7b (patch) | |
| tree | 59400f96629aec9c968b0e3251628302824f5d35 /drivers/mtd/nand/diskonchip.c | |
| parent | cd82919e6c8a73b363a26f34b734923844e52d1c (diff) | |
| download | olio-uboot-2014.01-cfa460adfdefcc30d104e1a9ee44994ee349bb7b.tar.xz olio-uboot-2014.01-cfa460adfdefcc30d104e1a9ee44994ee349bb7b.zip | |
Update MTD to that of Linux 2.6.22.1
A lot changed in the Linux MTD code, since it was last ported from
Linux to U-Boot. This patch takes U-Boot NAND support to the level
of Linux 2.6.22.1 and will enable support for very large NAND devices
(4KB pages) and ease the compatibility between U-Boot and Linux
filesystems.
This patch is tested on two custom boards with PPC and ARM
processors running YAFFS in U-Boot and Linux using gcc-4.1.2
cross compilers.
MAKEALL ppc/arm has some issues:
 * DOC/OneNand/nand_spl is not building (I have not tried porting
   these parts, and since I do not have any HW and I am not familiar
   with this code/HW I think its best left to someone else.)
Except for the issues mentioned above, I have ported all drivers
necessary to run MAKEALL ppc/arm without errors and warnings. Many
drivers were trivial to port, but some were not so trivial. The
following drivers must be examined carefully and maybe rewritten to
some degree:
 cpu/ppc4xx/ndfc.c
 cpu/arm926ejs/davinci/nand.c
 board/delta/nand.c
 board/zylonite/nand.c
Signed-off-by: William Juul <william.juul@tandberg.com>
Signed-off-by: Stig Olsen <stig.olsen@tandberg.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'drivers/mtd/nand/diskonchip.c')
| -rw-r--r-- | drivers/mtd/nand/diskonchip.c | 552 | 
1 files changed, 278 insertions, 274 deletions
| diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index fdd85c159..a03f982be 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -16,7 +16,7 @@   *   * Interface to generic NAND code for M-Systems DiskOnChip devices   * - * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $ + * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $   */  #include <common.h> @@ -39,13 +39,13 @@  #include <linux/mtd/inftl.h>  /* Where to look for the devices? */ -#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS -#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0 +#ifndef CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS +#define CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS 0  #endif  static unsigned long __initdata doc_locations[] = {  #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) -#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH +#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH  	0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,  	0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,  	0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, @@ -65,7 +65,7 @@ static unsigned long __initdata doc_locations[] = {  	0xff000000,  #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)  	0xff000000, -##else +#else  #warning Unknown architecture for DiskOnChip. No default probe locations defined  #endif  	0xffffffff }; @@ -77,7 +77,7 @@ struct doc_priv {  	unsigned long physadr;  	u_char ChipID;  	u_char CDSNControl; -	int chips_per_floor; /* The number of chips detected on each floor */ +	int chips_per_floor;	/* The number of chips detected on each floor */  	int curfloor;  	int curchip;  	int mh0_page; @@ -85,14 +85,10 @@ struct doc_priv {  	struct mtd_info *nextdoc;  }; -/* Max number of eraseblocks to scan (from start of device) for the (I)NFTL -   MediaHeader.  The spec says to just keep going, I think, but that's just -   silly. */ -#define MAX_MEDIAHEADER_SCAN 8 -  /* This is the syndrome computed by the HW ecc generator upon reading an empty     page, one with all 0xff for data and stored ecc code. */  static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a }; +  /* This is the ecc value computed by the HW ecc generator upon writing an empty     page, one with all 0xff for data. */  static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 }; @@ -103,35 +99,36 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };  #define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)  #define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k) -static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd); +static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, +			      unsigned int bitmask);  static void doc200x_select_chip(struct mtd_info *mtd, int chip); -static int debug=0; +static int debug = 0;  module_param(debug, int, 0); -static int try_dword=1; +static int try_dword = 1;  module_param(try_dword, int, 0); -static int no_ecc_failures=0; +static int no_ecc_failures = 0;  module_param(no_ecc_failures, int, 0); -#ifdef CONFIG_MTD_PARTITIONS -static int no_autopart=0; +static int no_autopart = 0;  module_param(no_autopart, int, 0); -#endif -#ifdef MTD_NAND_DISKONCHIP_BBTWRITE -static int inftl_bbt_write=1; +static int show_firmware_partition = 0; +module_param(show_firmware_partition, int, 0); + +#ifdef CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE +static int inftl_bbt_write = 1;  #else -static int inftl_bbt_write=0; +static int inftl_bbt_write = 0;  #endif  module_param(inftl_bbt_write, int, 0); -static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS; +static unsigned long doc_config_location = CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS;  module_param(doc_config_location, ulong, 0);  MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip"); -  /* Sector size for HW ECC */  #define SECTOR_SIZE 512  /* The sector bytes are packed into NB_DATA 10 bit words */ @@ -155,7 +152,7 @@ static struct rs_control *rs_decoder;   * some comments, improved a minor bit and converted it to make use   * of the generic Reed-Solomon libary. tglx   */ -static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) +static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)  {  	int i, j, nerr, errpos[8];  	uint8_t parity; @@ -176,11 +173,11 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)  	 *  s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]  	 *  where x = alpha^(FCR + i)  	 */ -	for(j = 1; j < NROOTS; j++) { -		if(ds[j] == 0) +	for (j = 1; j < NROOTS; j++) { +		if (ds[j] == 0)  			continue;  		tmp = rs->index_of[ds[j]]; -		for(i = 0; i < NROOTS; i++) +		for (i = 0; i < NROOTS; i++)  			s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)];  	} @@ -201,7 +198,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)  	 * but they are given by the design of the de/encoder circuit  	 * in the DoC ASIC's.  	 */ -	for(i = 0;i < nerr; i++) { +	for (i = 0; i < nerr; i++) {  		int index, bitpos, pos = 1015 - errpos[i];  		uint8_t val;  		if (pos >= NB_DATA && pos < 1019) @@ -213,8 +210,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)  			   can be modified since pos is even */  			index = (pos >> 3) ^ 1;  			bitpos = pos & 7; -			if ((index >= 0 && index < SECTOR_SIZE) || -			    index == (SECTOR_SIZE + 1)) { +			if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) {  				val = (uint8_t) (errval[i] >> (2 + bitpos));  				parity ^= val;  				if (index < SECTOR_SIZE) @@ -224,9 +220,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)  			bitpos = (bitpos + 10) & 7;  			if (bitpos == 0)  				bitpos = 8; -			if ((index >= 0 && index < SECTOR_SIZE) || -			    index == (SECTOR_SIZE + 1)) { -				val = (uint8_t)(errval[i] << (8 - bitpos)); +			if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) { +				val = (uint8_t) (errval[i] << (8 - bitpos));  				parity ^= val;  				if (index < SECTOR_SIZE)  					data[index] ^= val; @@ -261,7 +256,8 @@ static int _DoC_WaitReady(struct doc_priv *doc)  	void __iomem *docptr = doc->virtadr;  	unsigned long timeo = jiffies + (HZ * 10); -	if(debug) printk("_DoC_WaitReady...\n"); +	if (debug) +		printk("_DoC_WaitReady...\n");  	/* Out-of-line routine to wait for chip response */  	if (DoC_is_MillenniumPlus(doc)) {  		while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) { @@ -306,7 +302,8 @@ static inline int DoC_WaitReady(struct doc_priv *doc)  		DoC_Delay(doc, 2);  	} -	if(debug) printk("DoC_WaitReady OK\n"); +	if (debug) +		printk("DoC_WaitReady OK\n");  	return ret;  } @@ -316,7 +313,8 @@ static void doc2000_write_byte(struct mtd_info *mtd, u_char datum)  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr; -	if(debug)printk("write_byte %02x\n", datum); +	if (debug) +		printk("write_byte %02x\n", datum);  	WriteDOC(datum, docptr, CDSNSlowIO);  	WriteDOC(datum, docptr, 2k_CDSN_IO);  } @@ -331,37 +329,39 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)  	ReadDOC(docptr, CDSNSlowIO);  	DoC_Delay(doc, 2);  	ret = ReadDOC(docptr, 2k_CDSN_IO); -	if (debug) printk("read_byte returns %02x\n", ret); +	if (debug) +		printk("read_byte returns %02x\n", ret);  	return ret;  } -static void doc2000_writebuf(struct mtd_info *mtd, -			     const u_char *buf, int len) +static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr;  	int i; -	if (debug)printk("writebuf of %d bytes: ", len); -	for (i=0; i < len; i++) { +	if (debug) +		printk("writebuf of %d bytes: ", len); +	for (i = 0; i < len; i++) {  		WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i);  		if (debug && i < 16)  			printk("%02x ", buf[i]);  	} -	if (debug) printk("\n"); +	if (debug) +		printk("\n");  } -static void doc2000_readbuf(struct mtd_info *mtd, -			    u_char *buf, int len) +static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr;  	int i; -	if (debug)printk("readbuf of %d bytes: ", len); +	if (debug) +		printk("readbuf of %d bytes: ", len); -	for (i=0; i < len; i++) { +	for (i = 0; i < len; i++) {  		buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i);  	}  } @@ -374,28 +374,28 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd,  	void __iomem *docptr = doc->virtadr;  	int i; -	if (debug) printk("readbuf_dword of %d bytes: ", len); +	if (debug) +		printk("readbuf_dword of %d bytes: ", len); -	if (unlikely((((unsigned long)buf)|len) & 3)) { -		for (i=0; i < len; i++) { -			*(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i); +	if (unlikely((((unsigned long)buf) | len) & 3)) { +		for (i = 0; i < len; i++) { +			*(uint8_t *) (&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i);  		}  	} else { -		for (i=0; i < len; i+=4) { -			*(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i); +		for (i = 0; i < len; i += 4) { +			*(uint32_t*) (&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i);  		}  	}  } -static int doc2000_verifybuf(struct mtd_info *mtd, -			      const u_char *buf, int len) +static int doc2000_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr;  	int i; -	for (i=0; i < len; i++) +	for (i = 0; i < len; i++)  		if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO))  			return -EFAULT;  	return 0; @@ -408,12 +408,15 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)  	uint16_t ret;  	doc200x_select_chip(mtd, nr); -	doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); -	this->write_byte(mtd, NAND_CMD_READID); -	doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); -	doc200x_hwcontrol(mtd, NAND_CTL_SETALE); -	this->write_byte(mtd, 0); -	doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); +	doc200x_hwcontrol(mtd, NAND_CMD_READID, +			  NAND_CTRL_CLE | NAND_CTRL_CHANGE); +	doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); +	doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + +	/* We cant' use dev_ready here, but at least we wait for the +	 * command to complete +	 */ +	udelay(50);  	ret = this->read_byte(mtd) << 8;  	ret |= this->read_byte(mtd); @@ -426,12 +429,13 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)  		} ident;  		void __iomem *docptr = doc->virtadr; -		doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); -		doc2000_write_byte(mtd, NAND_CMD_READID); -		doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); -		doc200x_hwcontrol(mtd, NAND_CTL_SETALE); -		doc2000_write_byte(mtd, 0); -		doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); +		doc200x_hwcontrol(mtd, NAND_CMD_READID, +				  NAND_CTRL_CLE | NAND_CTRL_CHANGE); +		doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); +		doc200x_hwcontrol(mtd, NAND_CMD_NONE, +				  NAND_NCE | NAND_CTRL_CHANGE); + +		udelay(50);  		ident.dword = readl(docptr + DoC_2k_CDSN_IO);  		if (((ident.byte[0] << 8) | ident.byte[1]) == ret) { @@ -465,7 +469,7 @@ static void __init doc2000_count_chips(struct mtd_info *mtd)  	printk(KERN_DEBUG "Detected %d chips per floor.\n", i);  } -static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this)  {  	struct doc_priv *doc = this->priv; @@ -496,30 +500,28 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr; -	/*ReadDOC(docptr, CDSNSlowIO); */ +	//ReadDOC(docptr, CDSNSlowIO);  	/* 11.4.5 -- delay twice to allow extended length cycle */  	DoC_Delay(doc, 2);  	ReadDOC(docptr, ReadPipeInit); -	/*return ReadDOC(docptr, Mil_CDSN_IO); */ +	//return ReadDOC(docptr, Mil_CDSN_IO);  	return ReadDOC(docptr, LastDataRead);  } -static void doc2001_writebuf(struct mtd_info *mtd, -			     const u_char *buf, int len) +static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr;  	int i; -	for (i=0; i < len; i++) +	for (i = 0; i < len; i++)  		WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);  	/* Terminate write pipeline */  	WriteDOC(0x00, docptr, WritePipeTerm);  } -static void doc2001_readbuf(struct mtd_info *mtd, -			    u_char *buf, int len) +static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; @@ -529,15 +531,14 @@ static void doc2001_readbuf(struct mtd_info *mtd,  	/* Start read pipeline */  	ReadDOC(docptr, ReadPipeInit); -	for (i=0; i < len-1; i++) +	for (i = 0; i < len - 1; i++)  		buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));  	/* Terminate read pipeline */  	buf[i] = ReadDOC(docptr, LastDataRead);  } -static int doc2001_verifybuf(struct mtd_info *mtd, -			     const u_char *buf, int len) +static int doc2001_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; @@ -547,7 +548,7 @@ static int doc2001_verifybuf(struct mtd_info *mtd,  	/* Start read pipeline */  	ReadDOC(docptr, ReadPipeInit); -	for (i=0; i < len-1; i++) +	for (i = 0; i < len - 1; i++)  		if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {  			ReadDOC(docptr, LastDataRead);  			return i; @@ -567,81 +568,84 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)  	ReadDOC(docptr, Mplus_ReadPipeInit);  	ReadDOC(docptr, Mplus_ReadPipeInit);  	ret = ReadDOC(docptr, Mplus_LastDataRead); -	if (debug) printk("read_byte returns %02x\n", ret); +	if (debug) +		printk("read_byte returns %02x\n", ret);  	return ret;  } -static void doc2001plus_writebuf(struct mtd_info *mtd, -			     const u_char *buf, int len) +static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr;  	int i; -	if (debug)printk("writebuf of %d bytes: ", len); -	for (i=0; i < len; i++) { +	if (debug) +		printk("writebuf of %d bytes: ", len); +	for (i = 0; i < len; i++) {  		WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);  		if (debug && i < 16)  			printk("%02x ", buf[i]);  	} -	if (debug) printk("\n"); +	if (debug) +		printk("\n");  } -static void doc2001plus_readbuf(struct mtd_info *mtd, -			    u_char *buf, int len) +static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr;  	int i; -	if (debug)printk("readbuf of %d bytes: ", len); +	if (debug) +		printk("readbuf of %d bytes: ", len);  	/* Start read pipeline */  	ReadDOC(docptr, Mplus_ReadPipeInit);  	ReadDOC(docptr, Mplus_ReadPipeInit); -	for (i=0; i < len-2; i++) { +	for (i = 0; i < len - 2; i++) {  		buf[i] = ReadDOC(docptr, Mil_CDSN_IO);  		if (debug && i < 16)  			printk("%02x ", buf[i]);  	}  	/* Terminate read pipeline */ -	buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead); +	buf[len - 2] = ReadDOC(docptr, Mplus_LastDataRead);  	if (debug && i < 16) -		printk("%02x ", buf[len-2]); -	buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead); +		printk("%02x ", buf[len - 2]); +	buf[len - 1] = ReadDOC(docptr, Mplus_LastDataRead);  	if (debug && i < 16) -		printk("%02x ", buf[len-1]); -	if (debug) printk("\n"); +		printk("%02x ", buf[len - 1]); +	if (debug) +		printk("\n");  } -static int doc2001plus_verifybuf(struct mtd_info *mtd, -			     const u_char *buf, int len) +static int doc2001plus_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr;  	int i; -	if (debug)printk("verifybuf of %d bytes: ", len); +	if (debug) +		printk("verifybuf of %d bytes: ", len);  	/* Start read pipeline */  	ReadDOC(docptr, Mplus_ReadPipeInit);  	ReadDOC(docptr, Mplus_ReadPipeInit); -	for (i=0; i < len-2; i++) +	for (i = 0; i < len - 2; i++)  		if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {  			ReadDOC(docptr, Mplus_LastDataRead);  			ReadDOC(docptr, Mplus_LastDataRead);  			return i;  		} -	if (buf[len-2] != ReadDOC(docptr, Mplus_LastDataRead)) -		return len-2; -	if (buf[len-1] != ReadDOC(docptr, Mplus_LastDataRead)) -		return len-1; +	if (buf[len - 2] != ReadDOC(docptr, Mplus_LastDataRead)) +		return len - 2; +	if (buf[len - 1] != ReadDOC(docptr, Mplus_LastDataRead)) +		return len - 1;  	return 0;  } @@ -652,7 +656,8 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)  	void __iomem *docptr = doc->virtadr;  	int floor = 0; -	if(debug)printk("select chip (%d)\n", chip); +	if (debug) +		printk("select chip (%d)\n", chip);  	if (chip == -1) {  		/* Disable flash internally */ @@ -661,7 +666,7 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)  	}  	floor = chip / doc->chips_per_floor; -	chip -= (floor *  doc->chips_per_floor); +	chip -= (floor * doc->chips_per_floor);  	/* Assert ChipEnable and deassert WriteProtect */  	WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect); @@ -678,65 +683,54 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip)  	void __iomem *docptr = doc->virtadr;  	int floor = 0; -	if(debug)printk("select chip (%d)\n", chip); +	if (debug) +		printk("select chip (%d)\n", chip);  	if (chip == -1)  		return;  	floor = chip / doc->chips_per_floor; -	chip -= (floor *  doc->chips_per_floor); +	chip -= (floor * doc->chips_per_floor);  	/* 11.4.4 -- deassert CE before changing chip */ -	doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE); +	doc200x_hwcontrol(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);  	WriteDOC(floor, docptr, FloorSelect);  	WriteDOC(chip, docptr, CDSNDeviceSelect); -	doc200x_hwcontrol(mtd, NAND_CTL_SETNCE); +	doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);  	doc->curchip = chip;  	doc->curfloor = floor;  } -static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) +#define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE) + +static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, +			      unsigned int ctrl)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr; -	switch(cmd) { -	case NAND_CTL_SETNCE: -		doc->CDSNControl |= CDSN_CTRL_CE; -		break; -	case NAND_CTL_CLRNCE: -		doc->CDSNControl &= ~CDSN_CTRL_CE; -		break; -	case NAND_CTL_SETCLE: -		doc->CDSNControl |= CDSN_CTRL_CLE; -		break; -	case NAND_CTL_CLRCLE: -		doc->CDSNControl &= ~CDSN_CTRL_CLE; -		break; -	case NAND_CTL_SETALE: -		doc->CDSNControl |= CDSN_CTRL_ALE; -		break; -	case NAND_CTL_CLRALE: -		doc->CDSNControl &= ~CDSN_CTRL_ALE; -		break; -	case NAND_CTL_SETWP: -		doc->CDSNControl |= CDSN_CTRL_WP; -		break; -	case NAND_CTL_CLRWP: -		doc->CDSNControl &= ~CDSN_CTRL_WP; -		break; +	if (ctrl & NAND_CTRL_CHANGE) { +		doc->CDSNControl &= ~CDSN_CTRL_MSK; +		doc->CDSNControl |= ctrl & CDSN_CTRL_MSK; +		if (debug) +			printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl); +		WriteDOC(doc->CDSNControl, docptr, CDSNControl); +		/* 11.4.3 -- 4 NOPs after CSDNControl write */ +		DoC_Delay(doc, 4); +	} +	if (cmd != NAND_CMD_NONE) { +		if (DoC_is_2000(doc)) +			doc2000_write_byte(mtd, cmd); +		else +			doc2001_write_byte(mtd, cmd);  	} -	if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl); -	WriteDOC(doc->CDSNControl, docptr, CDSNControl); -	/* 11.4.3 -- 4 NOPs after CSDNControl write */ -	DoC_Delay(doc, 4);  } -static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) +static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; @@ -757,9 +751,9 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col  	if (command == NAND_CMD_SEQIN) {  		int readcmd; -		if (column >= mtd->oobblock) { +		if (column >= mtd->writesize) {  			/* OOB area */ -			column -= mtd->oobblock; +			column -= mtd->writesize;  			readcmd = NAND_CMD_READOOB;  		} else if (column < 256) {  			/* First 256 bytes --> READ0 */ @@ -783,25 +777,26 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col  			WriteDOC(column, docptr, Mplus_FlashAddress);  		}  		if (page_addr != -1) { -			WriteDOC((unsigned char) (page_addr & 0xff), docptr, Mplus_FlashAddress); -			WriteDOC((unsigned char) ((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress); +			WriteDOC((unsigned char)(page_addr & 0xff), docptr, Mplus_FlashAddress); +			WriteDOC((unsigned char)((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);  			/* One more address cycle for higher density devices */  			if (this->chipsize & 0x0c000000) { -				WriteDOC((unsigned char) ((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress); +				WriteDOC((unsigned char)((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);  				printk("high density\n");  			}  		}  		WriteDOC(0, docptr, Mplus_WritePipeTerm);  		WriteDOC(0, docptr, Mplus_WritePipeTerm);  		/* deassert ALE */ -		if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || command == NAND_CMD_READOOB || command == NAND_CMD_READID) +		if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || +		    command == NAND_CMD_READOOB || command == NAND_CMD_READID)  			WriteDOC(0, docptr, Mplus_FlashControl);  	}  	/*  	 * program and erase have their own busy handlers  	 * status and sequential in needs no delay -	*/ +	 */  	switch (command) {  	case NAND_CMD_PAGEPROG: @@ -818,26 +813,26 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col  		WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd);  		WriteDOC(0, docptr, Mplus_WritePipeTerm);  		WriteDOC(0, docptr, Mplus_WritePipeTerm); -		while ( !(this->read_byte(mtd) & 0x40)); +		while (!(this->read_byte(mtd) & 0x40)) ;  		return; -	/* This applies to read commands */ +		/* This applies to read commands */  	default:  		/*  		 * If we don't have access to the busy pin, we apply the given  		 * command delay -		*/ +		 */  		if (!this->dev_ready) { -			udelay (this->chip_delay); +			udelay(this->chip_delay);  			return;  		}  	}  	/* Apply this short delay always to ensure that we do wait tWB in  	 * any case on any machine. */ -	ndelay (100); +	ndelay(100);  	/* wait until command is processed */ -	while (!this->dev_ready(mtd)); +	while (!this->dev_ready(mtd)) ;  }  static int doc200x_dev_ready(struct mtd_info *mtd) @@ -850,23 +845,25 @@ static int doc200x_dev_ready(struct mtd_info *mtd)  		/* 11.4.2 -- must NOP four times before checking FR/B# */  		DoC_Delay(doc, 4);  		if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) { -			if(debug) +			if (debug)  				printk("not ready\n");  			return 0;  		} -		if (debug)printk("was ready\n"); +		if (debug) +			printk("was ready\n");  		return 1;  	} else {  		/* 11.4.2 -- must NOP four times before checking FR/B# */  		DoC_Delay(doc, 4);  		if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { -			if(debug) +			if (debug)  				printk("not ready\n");  			return 0;  		}  		/* 11.4.2 -- Must NOP twice if it's ready */  		DoC_Delay(doc, 2); -		if (debug)printk("was ready\n"); +		if (debug) +			printk("was ready\n");  		return 1;  	}  } @@ -885,7 +882,7 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode)  	void __iomem *docptr = doc->virtadr;  	/* Prime the ECC engine */ -	switch(mode) { +	switch (mode) {  	case NAND_ECC_READ:  		WriteDOC(DOC_ECC_RESET, docptr, ECCConf);  		WriteDOC(DOC_ECC_EN, docptr, ECCConf); @@ -904,7 +901,7 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)  	void __iomem *docptr = doc->virtadr;  	/* Prime the ECC engine */ -	switch(mode) { +	switch (mode) {  	case NAND_ECC_READ:  		WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);  		WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); @@ -917,8 +914,7 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)  }  /* This code is only called on write */ -static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, -				 unsigned char *ecc_code) +static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; @@ -962,7 +958,8 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,  		   often.  It could be optimized away by examining the data in  		   the writebuf routine, and remembering the result. */  		for (i = 0; i < 512; i++) { -			if (dat[i] == 0xff) continue; +			if (dat[i] == 0xff) +				continue;  			emptymatch = 0;  			break;  		} @@ -970,17 +967,20 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,  	/* If emptymatch still =1, we do have an all-0xff data buffer.  	   Return all-0xff ecc value instead of the computed one, so  	   it'll look just like a freshly-erased page. */ -	if (emptymatch) memset(ecc_code, 0xff, 6); +	if (emptymatch) +		memset(ecc_code, 0xff, 6);  #endif  	return 0;  } -static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) +static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, +				u_char *read_ecc, u_char *isnull)  {  	int i, ret = 0;  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv;  	void __iomem *docptr = doc->virtadr; +	uint8_t calc_ecc[6];  	volatile u_char dummy;  	int emptymatch = 1; @@ -1013,18 +1013,20 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_  		   all-0xff data and stored ecc block.  Check the stored ecc. */  		if (emptymatch) {  			for (i = 0; i < 6; i++) { -				if (read_ecc[i] == 0xff) continue; +				if (read_ecc[i] == 0xff) +					continue;  				emptymatch = 0;  				break;  			}  		}  		/* If emptymatch still =1, check the data block. */  		if (emptymatch) { -		/* Note: this somewhat expensive test should not be triggered -		   often.  It could be optimized away by examining the data in -		   the readbuf routine, and remembering the result. */ +			/* Note: this somewhat expensive test should not be triggered +			   often.  It could be optimized away by examining the data in +			   the readbuf routine, and remembering the result. */  			for (i = 0; i < 512; i++) { -				if (dat[i] == 0xff) continue; +				if (dat[i] == 0xff) +					continue;  				emptymatch = 0;  				break;  			} @@ -1033,7 +1035,8 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_  		   erased block, in which case the ECC will not come out right.  		   We'll suppress the error and tell the caller everything's  		   OK.  Because it is. */ -		if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); +		if (!emptymatch) +			ret = doc_ecc_decode(rs_decoder, dat, calc_ecc);  		if (ret > 0)  			printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);  	} @@ -1048,13 +1051,22 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_  	return ret;  } -/*u_char mydatabuf[528]; */ +//u_char mydatabuf[528]; -static struct nand_oobinfo doc200x_oobinfo = { -	.useecc = MTD_NANDECC_AUTOPLACE, +/* The strange out-of-order .oobfree list below is a (possibly unneeded) + * attempt to retain compatibility.  It used to read: + * 	.oobfree = { {8, 8} } + * Since that leaves two bytes unusable, it was changed.  But the following + * scheme might affect existing jffs2 installs by moving the cleanmarker: + * 	.oobfree = { {6, 10} } + * jffs2 seems to handle the above gracefully, but the current scheme seems + * safer.  The only problem with it is that any code that parses oobfree must + * be able to handle out-of-order segments. + */ +static struct nand_ecclayout doc200x_oobinfo = {  	.eccbytes = 6,  	.eccpos = {0, 1, 2, 3, 4, 5}, -	.oobfree = { {8, 8} } +	.oobfree = {{8, 8}, {6, 2}}  };  /* Find the (I)NFTL Media Header, and optionally also the mirror media header. @@ -1063,28 +1075,28 @@ static struct nand_oobinfo doc200x_oobinfo = {     either "ANAND" or "BNAND".  If findmirror=1, also look for the mirror media     header.  The page #s of the found media headers are placed in mh0_page and     mh1_page in the DOC private structure. */ -static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, -				     const char *id, int findmirror) +static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const char *id, int findmirror)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; -	unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift); +	unsigned offs;  	int ret;  	size_t retlen; -	end = min(end, mtd->size); /* paranoia */ -	for (offs = 0; offs < end; offs += mtd->erasesize) { -		ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); -		if (retlen != mtd->oobblock) continue; +	for (offs = 0; offs < mtd->size; offs += mtd->erasesize) { +		ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf); +		if (retlen != mtd->writesize) +			continue;  		if (ret) { -			printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n", -				offs); +			printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n", offs);  		} -		if (memcmp(buf, id, 6)) continue; +		if (memcmp(buf, id, 6)) +			continue;  		printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs);  		if (doc->mh0_page == -1) {  			doc->mh0_page = offs >> this->page_shift; -			if (!findmirror) return 1; +			if (!findmirror) +				return 1;  			continue;  		}  		doc->mh1_page = offs >> this->page_shift; @@ -1097,8 +1109,8 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,  	/* Only one mediaheader was found.  We want buf to contain a  	   mediaheader on return, so we'll have to re-read the one we found. */  	offs = doc->mh0_page << this->page_shift; -	ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); -	if (retlen != mtd->oobblock) { +	ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf); +	if (retlen != mtd->writesize) {  		/* Insanity.  Give up. */  		printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n");  		return 0; @@ -1106,8 +1118,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,  	return 1;  } -static inline int __init nftl_partscan(struct mtd_info *mtd, -				struct mtd_partition *parts) +static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; @@ -1115,19 +1126,23 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,  	u_char *buf;  	struct NFTLMediaHeader *mh;  	const unsigned psize = 1 << this->page_shift; +	int numparts = 0;  	unsigned blocks, maxblocks;  	int offs, numheaders; -	buf = kmalloc(mtd->oobblock, GFP_KERNEL); +	buf = kmalloc(mtd->writesize, GFP_KERNEL);  	if (!buf) {  		printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");  		return 0;  	} -	if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out; -	mh = (struct NFTLMediaHeader *) buf; +	if (!(numheaders = find_media_headers(mtd, buf, "ANAND", 1))) +		goto out; +	mh = (struct NFTLMediaHeader *)buf; + +	mh->NumEraseUnits = le16_to_cpu(mh->NumEraseUnits); +	mh->FirstPhysicalEUN = le16_to_cpu(mh->FirstPhysicalEUN); +	mh->FormattedSize = le32_to_cpu(mh->FormattedSize); -/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */ -/*	if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */  	printk(KERN_INFO "    DataOrgID        = %s\n"  			 "    NumEraseUnits    = %d\n"  			 "    FirstPhysicalEUN = %d\n" @@ -1136,7 +1151,6 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,  		mh->DataOrgID, mh->NumEraseUnits,  		mh->FirstPhysicalEUN, mh->FormattedSize,  		mh->UnitSizeFactor); -/*#endif */  	blocks = mtd->size >> this->phys_erase_shift;  	maxblocks = min(32768U, mtd->erasesize - psize); @@ -1145,8 +1159,8 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,  		/* Auto-determine UnitSizeFactor.  The constraints are:  		   - There can be at most 32768 virtual blocks.  		   - There can be at most (virtual block size - page size) -		     virtual blocks (because MediaHeader+BBT must fit in 1). -		*/ +		   virtual blocks (because MediaHeader+BBT must fit in 1). +		 */  		mh->UnitSizeFactor = 0xff;  		while (blocks > maxblocks) {  			blocks >>= 1; @@ -1179,31 +1193,35 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,  	offs <<= this->page_shift;  	offs += mtd->erasesize; -	/*parts[0].name = " DiskOnChip Boot / Media Header partition"; */ -	/*parts[0].offset = 0; */ -	/*parts[0].size = offs; */ +	if (show_firmware_partition == 1) { +		parts[0].name = " DiskOnChip Firmware / Media Header partition"; +		parts[0].offset = 0; +		parts[0].size = offs; +		numparts = 1; +	} + +	parts[numparts].name = " DiskOnChip BDTL partition"; +	parts[numparts].offset = offs; +	parts[numparts].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift; -	parts[0].name = " DiskOnChip BDTL partition"; -	parts[0].offset = offs; -	parts[0].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift; +	offs += parts[numparts].size; +	numparts++; -	offs += parts[0].size;  	if (offs < mtd->size) { -		parts[1].name = " DiskOnChip Remainder partition"; -		parts[1].offset = offs; -		parts[1].size = mtd->size - offs; -		ret = 2; -		goto out; +		parts[numparts].name = " DiskOnChip Remainder partition"; +		parts[numparts].offset = offs; +		parts[numparts].size = mtd->size - offs; +		numparts++;  	} -	ret = 1; -out: + +	ret = numparts; + out:  	kfree(buf);  	return ret;  }  /* This is a stripped-down copy of the code in inftlmount.c */ -static inline int __init inftl_partscan(struct mtd_info *mtd, -				 struct mtd_partition *parts) +static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts)  {  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; @@ -1220,15 +1238,16 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,  	if (inftl_bbt_write)  		end -= (INFTL_BBT_RESERVED_BLOCKS << this->phys_erase_shift); -	buf = kmalloc(mtd->oobblock, GFP_KERNEL); +	buf = kmalloc(mtd->writesize, GFP_KERNEL);  	if (!buf) {  		printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");  		return 0;  	} -	if (!find_media_headers(mtd, buf, "BNAND", 0)) goto out; +	if (!find_media_headers(mtd, buf, "BNAND", 0)) +		goto out;  	doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift); -	mh = (struct INFTLMediaHeader *) buf; +	mh = (struct INFTLMediaHeader *)buf;  	mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);  	mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions); @@ -1237,8 +1256,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,  	mh->FormatFlags = le32_to_cpu(mh->FormatFlags);  	mh->PercentUsed = le32_to_cpu(mh->PercentUsed); -/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */ -/*	if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */  	printk(KERN_INFO "    bootRecordID          = %s\n"  			 "    NoOfBootImageBlocks   = %d\n"  			 "    NoOfBinaryPartitions  = %d\n" @@ -1256,7 +1273,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,  		((unsigned char *) &mh->OsakVersion)[2] & 0xf,  		((unsigned char *) &mh->OsakVersion)[3] & 0xf,  		mh->PercentUsed); -/*#endif */  	vshift = this->phys_erase_shift + mh->BlockMultiplierBits; @@ -1282,8 +1298,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,  		ip->spareUnits = le32_to_cpu(ip->spareUnits);  		ip->Reserved0 = le32_to_cpu(ip->Reserved0); -/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */ -/*		if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */  		printk(KERN_INFO	"    PARTITION[%d] ->\n"  			"        virtualUnits    = %d\n"  			"        firstUnit       = %d\n" @@ -1293,16 +1307,14 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,  			i, ip->virtualUnits, ip->firstUnit,  			ip->lastUnit, ip->flags,  			ip->spareUnits); -/*#endif */ -/* -		if ((i == 0) && (ip->firstUnit > 0)) { +		if ((show_firmware_partition == 1) && +		    (i == 0) && (ip->firstUnit > 0)) {  			parts[0].name = " DiskOnChip IPL / Media Header partition";  			parts[0].offset = 0;  			parts[0].size = mtd->erasesize * ip->firstUnit;  			numparts = 1;  		} -*/  		if (ip->flags & INFTL_BINARY)  			parts[numparts].name = " DiskOnChip BDK partition"; @@ -1311,8 +1323,10 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,  		parts[numparts].offset = ip->firstUnit << vshift;  		parts[numparts].size = (1 + ip->lastUnit - ip->firstUnit) << vshift;  		numparts++; -		if (ip->lastUnit > lastvunit) lastvunit = ip->lastUnit; -		if (ip->flags & INFTL_LAST) break; +		if (ip->lastUnit > lastvunit) +			lastvunit = ip->lastUnit; +		if (ip->flags & INFTL_LAST) +			break;  	}  	lastvunit++;  	if ((lastvunit << vshift) < end) { @@ -1322,7 +1336,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,  		numparts++;  	}  	ret = numparts; -out: + out:  	kfree(buf);  	return ret;  } @@ -1334,11 +1348,12 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd)  	struct doc_priv *doc = this->priv;  	struct mtd_partition parts[2]; -	memset((char *) parts, 0, sizeof(parts)); +	memset((char *)parts, 0, sizeof(parts));  	/* On NFTL, we have to find the media headers before we can read the  	   BBTs, since they're stored in the media header eraseblocks. */  	numparts = nftl_partscan(mtd, parts); -	if (!numparts) return -EIO; +	if (!numparts) +		return -EIO;  	this->bbt_td->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT |  				NAND_BBT_SAVECONTENT | NAND_BBT_WRITE |  				NAND_BBT_VERSION; @@ -1385,8 +1400,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)  		this->bbt_td->pages[0] = 2;  		this->bbt_md = NULL;  	} else { -		this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | -					NAND_BBT_VERSION; +		this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | NAND_BBT_VERSION;  		if (inftl_bbt_write)  			this->bbt_td->options |= NAND_BBT_WRITE;  		this->bbt_td->offs = 8; @@ -1396,8 +1410,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)  		this->bbt_td->reserved_block_code = 0x01;  		this->bbt_td->pattern = "MSYS_BBT"; -		this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | -					NAND_BBT_VERSION; +		this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | NAND_BBT_VERSION;  		if (inftl_bbt_write)  			this->bbt_md->options |= NAND_BBT_WRITE;  		this->bbt_md->offs = 8; @@ -1412,12 +1425,13 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)  	   At least as nand_bbt.c is currently written. */  	if ((ret = nand_scan_bbt(mtd, NULL)))  		return ret; -	memset((char *) parts, 0, sizeof(parts)); +	memset((char *)parts, 0, sizeof(parts));  	numparts = inftl_partscan(mtd, parts);  	/* At least for now, require the INFTL Media Header.  We could probably  	   do without it for non-INFTL use, since all it gives us is  	   autopartitioning, but I want to give it more thought. */ -	if (!numparts) return -EIO; +	if (!numparts) +		return -EIO;  	add_mtd_device(mtd);  #ifdef CONFIG_MTD_PARTITIONS  	if (!no_autopart) @@ -1431,7 +1445,6 @@ static inline int __init doc2000_init(struct mtd_info *mtd)  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; -	this->write_byte = doc2000_write_byte;  	this->read_byte = doc2000_read_byte;  	this->write_buf = doc2000_writebuf;  	this->read_buf = doc2000_readbuf; @@ -1449,7 +1462,6 @@ static inline int __init doc2001_init(struct mtd_info *mtd)  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; -	this->write_byte = doc2001_write_byte;  	this->read_byte = doc2001_read_byte;  	this->write_buf = doc2001_writebuf;  	this->read_buf = doc2001_readbuf; @@ -1481,16 +1493,15 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)  	struct nand_chip *this = mtd->priv;  	struct doc_priv *doc = this->priv; -	this->write_byte = NULL;  	this->read_byte = doc2001plus_read_byte;  	this->write_buf = doc2001plus_writebuf;  	this->read_buf = doc2001plus_readbuf;  	this->verify_buf = doc2001plus_verifybuf;  	this->scan_bbt = inftl_scan_bbt; -	this->hwcontrol = NULL; +	this->cmd_ctrl = NULL;  	this->select_chip = doc2001plus_select_chip;  	this->cmdfunc = doc2001plus_command; -	this->enable_hwecc = doc2001plus_enable_hwecc; +	this->ecc.hwctl = doc2001plus_enable_hwecc;  	doc->chips_per_floor = 1;  	mtd->name = "DiskOnChip Millennium Plus"; @@ -1498,7 +1509,7 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd)  	return 1;  } -static inline int __init doc_probe(unsigned long physadr) +static int __init doc_probe(unsigned long physadr)  {  	unsigned char ChipID;  	struct mtd_info *mtd; @@ -1527,20 +1538,16 @@ static inline int __init doc_probe(unsigned long physadr)  	save_control = ReadDOC(virtadr, DOCControl);  	/* Reset the DiskOnChip ASIC */ -	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, -		 virtadr, DOCControl); -	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, -		 virtadr, DOCControl); +	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl); +	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl);  	/* Enable the DiskOnChip ASIC */ -	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, -		 virtadr, DOCControl); -	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, -		 virtadr, DOCControl); +	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl); +	WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl);  	ChipID = ReadDOC(virtadr, ChipID); -	switch(ChipID) { +	switch (ChipID) {  	case DOC_ChipID_Doc2k:  		reg = DoC_2k_ECCStatus;  		break; @@ -1556,15 +1563,13 @@ static inline int __init doc_probe(unsigned long physadr)  			ReadDOC(virtadr, Mplus_Power);  		/* Reset the Millennium Plus ASIC */ -		tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | -			DOC_MODE_BDECT; +		tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT;  		WriteDOC(tmp, virtadr, Mplus_DOCControl);  		WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);  		mdelay(1);  		/* Enable the Millennium Plus ASIC */ -		tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | -			DOC_MODE_BDECT; +		tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT;  		WriteDOC(tmp, virtadr, Mplus_DOCControl);  		WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);  		mdelay(1); @@ -1588,7 +1593,7 @@ static inline int __init doc_probe(unsigned long physadr)  		goto notfound;  	}  	/* Check the TOGGLE bit in the ECC register */ -	tmp  = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; +	tmp = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;  	tmpb = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;  	tmpc = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT;  	if ((tmp == tmpb) || (tmp != tmpc)) { @@ -1618,11 +1623,11 @@ static inline int __init doc_probe(unsigned long physadr)  		if (ChipID == DOC_ChipID_DocMilPlus16) {  			WriteDOC(~newval, virtadr, Mplus_AliasResolution);  			oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution); -			WriteDOC(newval, virtadr, Mplus_AliasResolution); /* restore it */ +			WriteDOC(newval, virtadr, Mplus_AliasResolution);	// restore it  		} else {  			WriteDOC(~newval, virtadr, AliasResolution);  			oldval = ReadDOC(doc->virtadr, AliasResolution); -			WriteDOC(newval, virtadr, AliasResolution); /* restore it */ +			WriteDOC(newval, virtadr, AliasResolution);	// restore it  		}  		newval = ~newval;  		if (oldval == newval) { @@ -1634,16 +1639,13 @@ static inline int __init doc_probe(unsigned long physadr)  	printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr);  	len = sizeof(struct mtd_info) + -	      sizeof(struct nand_chip) + -	      sizeof(struct doc_priv) + -	      (2 * sizeof(struct nand_bbt_descr)); -	mtd =  kmalloc(len, GFP_KERNEL); +	    sizeof(struct nand_chip) + sizeof(struct doc_priv) + (2 * sizeof(struct nand_bbt_descr)); +	mtd = kzalloc(len, GFP_KERNEL);  	if (!mtd) {  		printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len);  		ret = -ENOMEM;  		goto fail;  	} -	memset(mtd, 0, len);  	nand			= (struct nand_chip *) (mtd + 1);  	doc			= (struct doc_priv *) (nand + 1); @@ -1655,17 +1657,19 @@ static inline int __init doc_probe(unsigned long physadr)  	nand->priv		= doc;  	nand->select_chip	= doc200x_select_chip; -	nand->hwcontrol		= doc200x_hwcontrol; +	nand->cmd_ctrl		= doc200x_hwcontrol;  	nand->dev_ready		= doc200x_dev_ready;  	nand->waitfunc		= doc200x_wait;  	nand->block_bad		= doc200x_block_bad; -	nand->enable_hwecc	= doc200x_enable_hwecc; -	nand->calculate_ecc	= doc200x_calculate_ecc; -	nand->correct_data	= doc200x_correct_data; +	nand->ecc.hwctl		= doc200x_enable_hwecc; +	nand->ecc.calculate	= doc200x_calculate_ecc; +	nand->ecc.correct	= doc200x_correct_data; -	nand->autooob		= &doc200x_oobinfo; -	nand->eccmode		= NAND_ECC_HW6_512; -	nand->options		= NAND_USE_FLASH_BBT | NAND_HWECC_SYNDROME; +	nand->ecc.layout	= &doc200x_oobinfo; +	nand->ecc.mode		= NAND_ECC_HW_SYNDROME; +	nand->ecc.size		= 512; +	nand->ecc.bytes		= 6; +	nand->options		= NAND_USE_FLASH_BBT;  	doc->physadr		= physadr;  	doc->virtadr		= virtadr; @@ -1699,11 +1703,11 @@ static inline int __init doc_probe(unsigned long physadr)  	doclist = mtd;  	return 0; -notfound: + notfound:  	/* Put back the contents of the DOCControl register, in case it's not  	   actually a DiskOnChip.  */  	WriteDOC(save_control, virtadr, DOCControl); -fail: + fail:  	iounmap(virtadr);  	return ret;  } @@ -1740,7 +1744,7 @@ static int __init init_nanddoc(void)  	 */  	rs_decoder = init_rs(10, 0x409, FCR, 1, NROOTS);  	if (!rs_decoder) { -		printk (KERN_ERR "DiskOnChip: Could not create a RS decoder\n"); +		printk(KERN_ERR "DiskOnChip: Could not create a RS decoder\n");  		return -ENOMEM;  	} @@ -1750,7 +1754,7 @@ static int __init init_nanddoc(void)  		if (ret < 0)  			goto outerr;  	} else { -		for (i=0; (doc_locations[i] != 0xffffffff); i++) { +		for (i = 0; (doc_locations[i] != 0xffffffff); i++) {  			doc_probe(doc_locations[i]);  		}  	} @@ -1762,7 +1766,7 @@ static int __init init_nanddoc(void)  		goto outerr;  	}  	return 0; -outerr: + outerr:  	free_rs(rs_decoder);  	return ret;  } |