diff options
| -rw-r--r-- | common/cmd_nand.c | 9 | ||||
| -rw-r--r-- | drivers/dfu/dfu_nand.c | 18 | ||||
| -rw-r--r-- | drivers/mtd/nand/docg4.c | 26 | ||||
| -rw-r--r-- | drivers/mtd/nand/docg4_spl.c | 15 | ||||
| -rw-r--r-- | drivers/mtd/nand/jz4740_nand.c | 2 | ||||
| -rw-r--r-- | drivers/mtd/nand/nand_util.c | 4 | ||||
| -rw-r--r-- | drivers/mtd/nand/s3c2410_nand.c | 4 | ||||
| -rw-r--r-- | include/nand.h | 2 | 
8 files changed, 46 insertions, 34 deletions
| diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 8b1e01ae8..886212aa0 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -426,7 +426,7 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,  }  /* Adjust a chip/partition size down for bad blocks so we don't - * read/write/erase past the end of a chip/partition by accident. + * read/write past the end of a chip/partition by accident.   */  static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev)  { @@ -546,7 +546,6 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		int scrub = !strncmp(cmd, "scrub", 5);  		int spread = 0;  		int args = 2; -		int adjust_size = 0;  		const char *scrub_warn =  			"Warning: "  			"scrub option will erase all factory set bad blocks!\n" @@ -563,10 +562,8 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  				spread = 1;  			} else if (!strcmp(&cmd[5], ".part")) {  				args = 1; -				adjust_size = 1;  			} else if (!strcmp(&cmd[5], ".chip")) {  				args = 0; -				adjust_size = 1;  			} else {  				goto usage;  			} @@ -586,10 +583,6 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  				 &maxsize) != 0)  			return 1; -		/* size is unspecified */ -		if (adjust_size && !scrub) -			adjust_size_for_badblocks(&size, off, dev); -  		nand = &nand_info[dev];  		memset(&opts, 0, sizeof(opts)); diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c index 7dc89b2f2..07dee8981 100644 --- a/drivers/dfu/dfu_nand.c +++ b/drivers/dfu/dfu_nand.c @@ -63,12 +63,26 @@ static int nand_block_op(enum dfu_nand_op op, struct dfu_entity *dfu,  	nand = &nand_info[nand_curr_device]; -	if (op == DFU_OP_READ) +	if (op == DFU_OP_READ) {  		ret = nand_read_skip_bad(nand, start, &count, &actual,  				lim, buf); -	else +	} else { +		nand_erase_options_t opts; + +		memset(&opts, 0, sizeof(opts)); +		opts.offset = start; +		opts.length = count; +		opts.spread = 1; +		opts.quiet = 1; +		opts.lim = lim; +		/* first erase */ +		ret = nand_erase_opts(nand, &opts); +		if (ret) +			return ret; +		/* then write */  		ret = nand_write_skip_bad(nand, start, &count, &actual,  				lim, buf, 0); +	}  	if (ret != 0) {  		printf("%s: nand_%s_skip_bad call failed at %llx!\n", diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 7dd9953be..09f01c80d 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c @@ -487,7 +487,7 @@ static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)  }  static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, -			  int page, int sndcmd) +			  int page)  {  	struct docg4_priv *doc = nand->priv;  	void __iomem *docptr = CONFIG_SYS_NAND_BASE; @@ -577,7 +577,7 @@ static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)  		writew(p[i], nand->IO_ADDR_W);  } -static void write_page(struct mtd_info *mtd, struct nand_chip *nand, +static int write_page(struct mtd_info *mtd, struct nand_chip *nand,  		       const uint8_t *buf, int use_ecc)  {  	void __iomem *docptr = CONFIG_SYS_NAND_BASE; @@ -626,16 +626,18 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *nand,  	write_nop(docptr);  	writew(0, docptr + DOC_DATAEND);  	write_nop(docptr); + +	return 0;  } -static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand, -				 const uint8_t *buf) +static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand, +				 const uint8_t *buf, int oob_required)  {  	return write_page(mtd, nand, buf, 0);  } -static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand, -			     const uint8_t *buf) +static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand, +			     const uint8_t *buf, int oob_required)  {  	return write_page(mtd, nand, buf, 1);  } @@ -706,13 +708,13 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,  static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand, -			       uint8_t *buf, int page) +			       uint8_t *buf, int oob_required, int page)  {  	return read_page(mtd, nand, buf, page, 0);  }  static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, -			   uint8_t *buf, int page) +			   uint8_t *buf, int oob_required, int page)  {  	return read_page(mtd, nand, buf, page, 1);  } @@ -779,7 +781,7 @@ static int read_factory_bbt(struct mtd_info *mtd)  		return -ENOMEM;  	read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); -	status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE); +	status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);  	if (status)  		goto exit; @@ -858,7 +860,7 @@ static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)  	/* write first page of block */  	write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); -	docg4_write_page(mtd, nand, buf); +	docg4_write_page(mtd, nand, buf, 1);  	ret = pageprog(mtd);  	if (!ret)  		mtd->ecc_stats.badblocks++; @@ -959,8 +961,8 @@ int docg4_nand_init(struct mtd_info *mtd, struct nand_chip *nand, int devnum)  	nand->ecc.size = DOCG4_PAGE_SIZE;  	nand->ecc.prepad = 8;  	nand->ecc.bytes	= 8; -	nand->options = -		NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR; +	nand->ecc.strength = DOCG4_T; +	nand->options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE;  	nand->controller = &nand->hwcontrol;  	/* methods */ diff --git a/drivers/mtd/nand/docg4_spl.c b/drivers/mtd/nand/docg4_spl.c index 95e856c21..734cbeb7c 100644 --- a/drivers/mtd/nand/docg4_spl.c +++ b/drivers/mtd/nand/docg4_spl.c @@ -113,7 +113,6 @@ static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)  	int g4_index = 0;  	uint16_t flash_status;  	uint16_t *buf; -	uint16_t discard, magic_high, magic_low;  	/* flash_offset must be aligned to the start of a block */  	if (flash_offset & 0x3ffff) @@ -154,9 +153,9 @@ static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)  	 * The IPL on the palmtreo680 requires that this contain a 32 bit magic  	 * number, or the load aborts.  We'll ignore it.  	 */ -	discard = readw(docptr + 0x103c); /* hw quirk; 1st read discarded */ -	magic_low = readw(docptr + 0x103c); -	magic_high = readw(docptr + DOCG4_MYSTERY_REG); +	readw(docptr + 0x103c); /* hw quirk; 1st read discarded */ +	readw(docptr + 0x103c);	/* lower 16 bits of magic number */ +	readw(docptr + DOCG4_MYSTERY_REG); /* upper 16 bits of magic number */  	writew(0, docptr + DOC_DATAEND);  	write_nop(docptr);  	write_nop(docptr); @@ -183,15 +182,15 @@ static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)  		write_nop(docptr);  		/* read the 512 bytes of page data, 2 bytes at a time */ -		discard = readw(docptr + 0x103c); +		readw(docptr + 0x103c); /* hw quirk */  		for (i = 0; i < 256; i++)  			*buf++ = readw(docptr + 0x103c);  		/* read oob, but discard it */  		for (i = 0; i < 7; i++) -			discard = readw(docptr + 0x103c); -		discard = readw(docptr + DOCG4_OOB_6_7); -		discard = readw(docptr + DOCG4_OOB_6_7); +			readw(docptr + 0x103c); +		readw(docptr + DOCG4_OOB_6_7); +		readw(docptr + DOCG4_OOB_6_7);  		writew(0, docptr + DOC_DATAEND);  		write_nop(docptr); diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index a691fbc40..9421e5661 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -256,7 +256,7 @@ int board_nand_init(struct nand_chip *nand)  	nand->ecc.strength	= 4;  	nand->ecc.layout	= &qi_lb60_ecclayout_2gb;  	nand->chip_delay	= 50; -	nand->options		= NAND_USE_FLASH_BBT; +	nand->bbt_options	|= NAND_BBT_USE_FLASH;  	return 0;  } diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index d81972ca2..1d22b5240 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -120,6 +120,10 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)  		WATCHDOG_RESET(); +		if (opts->lim && (erase.addr >= (opts->offset + opts->lim))) { +			puts("Size of erase exceeds limit\n"); +			return -EFBIG; +		}  		if (!opts->scrub && bbtest) {  			int ret = mtd_block_isbad(meminfo, erase.addr);  			if (ret > 0) { diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index 43d8213e0..1187b9fee 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -179,9 +179,7 @@ int board_nand_init(struct nand_chip *nand)  #endif  #ifdef CONFIG_S3C2410_NAND_BBT -	nand->options = NAND_USE_FLASH_BBT; -#else -	nand->options = 0; +	nand->bbt_options |= NAND_BBT_USE_FLASH;  #endif  	debug("end of nand_init\n"); diff --git a/include/nand.h b/include/nand.h index 26190e413..228d87127 100644 --- a/include/nand.h +++ b/include/nand.h @@ -125,6 +125,8 @@ struct nand_erase_options {  	/* Don't include skipped bad blocks in size to be erased */  	int spread; +	/* maximum size that actual may be in order to not exceed the buf */ +	loff_t lim;  };  typedef struct nand_erase_options nand_erase_options_t; |