Merge branch 'patman' of git://git.denx.de/u-boot-x86
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 3f0d414..0a17782 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -5,8 +5,8 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <div64.h>
 #include <common.h>
+#include <div64.h>
 #include <malloc.h>
 #include <spi_flash.h>
 
diff --git a/common/cmd_test.c b/common/cmd_test.c
index d4ec186..acc0ecf 100644
--- a/common/cmd_test.c
+++ b/common/cmd_test.c
@@ -21,6 +21,15 @@
  * MA 02111-1307 USA
  */
 
+/*
+ * Define _STDBOOL_H here to avoid macro expansion of true and false.
+ * If the future code requires macro true or false, remove this define
+ * and undef true and false before U_BOOT_CMD. This define and comment
+ * shall be removed if change to U_BOOT_CMD is made to take string
+ * instead of stringifying it.
+ */
+#define _STDBOOL_H
+
 #include <common.h>
 #include <command.h>
 
diff --git a/common/env_dataflash.c b/common/env_dataflash.c
index 0591b99..38c9615 100644
--- a/common/env_dataflash.c
+++ b/common/env_dataflash.c
@@ -30,7 +30,6 @@
 env_t *env_ptr;
 
 char *env_name_spec = "dataflash";
-static char env_buf[CONFIG_ENV_SIZE];
 
 uchar env_get_char_spec(int index)
 {
@@ -43,9 +42,11 @@
 
 void env_relocate_spec(void)
 {
-	read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, env_buf);
+	char buf[CONFIG_ENV_SIZE];
 
-	env_import(env_buf, 1);
+	read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, buf);
+
+	env_import(buf, 1);
 }
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
@@ -54,20 +55,20 @@
 
 int saveenv(void)
 {
-	env_t	*env_new = (env_t *)env_buf;
+	env_t	env_new;
 	ssize_t	len;
 	char	*res;
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new.data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
 		return 1;
 	}
-	env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+	env_new.crc = crc32(0, env_new.data, ENV_SIZE);
 
 	return write_dataflash(CONFIG_ENV_ADDR,
-				(unsigned long)env_new,
+				(unsigned long)&env_new,
 				CONFIG_ENV_SIZE);
 }
 
diff --git a/common/env_eeprom.c b/common/env_eeprom.c
index b136f04..45c935b 100644
--- a/common/env_eeprom.c
+++ b/common/env_eeprom.c
@@ -38,7 +38,6 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 env_t *env_ptr;
-static char env_buf[CONFIG_ENV_SIZE];
 
 char *env_name_spec = "EEPROM";
 int env_eeprom_bus = -1;
@@ -112,7 +111,7 @@
 
 void env_relocate_spec(void)
 {
-	char *buf = env_buf;
+	char buf[CONFIG_ENV_SIZE];
 	unsigned int off = CONFIG_ENV_OFFSET;
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
@@ -127,7 +126,7 @@
 
 int saveenv(void)
 {
-	env_t	*env_new = (env_t *)env_buf;
+	env_t	env_new;
 	ssize_t	len;
 	char	*res;
 	int	rc;
@@ -139,13 +138,13 @@
 
 	BUG_ON(env_ptr != NULL);
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new.data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
 		return 1;
 	}
-	env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+	env_new.crc = crc32(0, env_new.data, ENV_SIZE);
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
 	if (gd->env_valid == 1) {
@@ -153,11 +152,11 @@
 		off_red	= CONFIG_ENV_OFFSET;
 	}
 
-	env_new->flags = ACTIVE_FLAG;
+	env_new.flags = ACTIVE_FLAG;
 #endif
 
 	rc = eeprom_bus_write(CONFIG_SYS_DEF_EEPROM_ADDR,
-			      off, (uchar *)env_new, CONFIG_ENV_SIZE);
+			      off, (uchar *)&env_new, CONFIG_ENV_SIZE);
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
 	if (rc == 0) {
diff --git a/common/env_fat.c b/common/env_fat.c
index dd7139d..c0f18ab 100644
--- a/common/env_fat.c
+++ b/common/env_fat.c
@@ -37,7 +37,6 @@
 char *env_name_spec = "FAT";
 
 env_t *env_ptr;
-static char env_buf[CONFIG_ENV_SIZE];
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -53,7 +52,7 @@
 #ifdef CONFIG_CMD_SAVEENV
 int saveenv(void)
 {
-	env_t	*env_new = env_buf;
+	env_t	env_new;
 	ssize_t	len;
 	char	*res;
 	block_dev_desc_t *dev_desc = NULL;
@@ -61,7 +60,7 @@
 	int part = FAT_ENV_PART;
 	int err;
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new.data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
@@ -96,8 +95,8 @@
 		return 1;
 	}
 
-	env_new->crc = crc32(0, env_new->data, ENV_SIZE);
-	err = file_fat_write(FAT_ENV_FILE, (void *)env_new, sizeof(env_t));
+	env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+	err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t));
 	if (err == -1) {
 		printf("\n** Unable to write \"%s\" from %s%d:%d **\n",
 			FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part);
@@ -111,7 +110,7 @@
 
 void env_relocate_spec(void)
 {
-	char *buf = env_buf;
+	char buf[CONFIG_ENV_SIZE];
 	block_dev_desc_t *dev_desc = NULL;
 	int dev = FAT_ENV_DEVICE;
 	int part = FAT_ENV_PART;
diff --git a/common/env_mmc.c b/common/env_mmc.c
index f568013..02bd5ae 100644
--- a/common/env_mmc.c
+++ b/common/env_mmc.c
@@ -40,8 +40,6 @@
 env_t *env_ptr;
 #endif /* ENV_IS_EMBEDDED */
 
-DEFINE_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE);
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #if !defined(CONFIG_ENV_OFFSET)
@@ -114,7 +112,7 @@
 
 int saveenv(void)
 {
-	env_t *env_new = (env_t *)env_buf;
+	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
 	ssize_t	len;
 	char	*res;
 	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
@@ -129,7 +127,7 @@
 		goto fini;
 	}
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new->data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
@@ -137,7 +135,7 @@
 		goto fini;
 	}
 
-	env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+	env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE);
 	printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV);
 	if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) {
 		puts("failed\n");
@@ -171,6 +169,7 @@
 void env_relocate_spec(void)
 {
 #if !defined(ENV_IS_EMBEDDED)
+	ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
 	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
 	u32 offset;
 	int ret;
@@ -185,12 +184,12 @@
 		goto fini;
 	}
 
-	if (read_env(mmc, CONFIG_ENV_SIZE, offset, env_buf)) {
+	if (read_env(mmc, CONFIG_ENV_SIZE, offset, buf)) {
 		ret = 1;
 		goto fini;
 	}
 
-	env_import(env_buf, 1);
+	env_import(buf, 1);
 	ret = 0;
 
 fini:
diff --git a/common/env_nand.c b/common/env_nand.c
index 8cc2055..5b69889 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -64,8 +64,6 @@
 env_t *env_ptr;
 #endif /* ENV_IS_EMBEDDED */
 
-DEFINE_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE);
-
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -175,7 +173,7 @@
 
 int saveenv(void)
 {
-	env_t	*env_new = (env_t *)env_buf;
+	env_t	env_new;
 	ssize_t	len;
 	char	*res;
 	int	ret = 0;
@@ -187,14 +185,14 @@
 	if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
 		return 1;
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new.data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
 		return 1;
 	}
-	env_new->crc	= crc32(0, env_new->data, ENV_SIZE);
-	env_new->flags	= ++env_flags; /* increase the serial */
+	env_new.crc	= crc32(0, env_new.data, ENV_SIZE);
+	env_new.flags	= ++env_flags; /* increase the serial */
 
 	if (gd->env_valid == 1) {
 		puts("Erasing redundant NAND...\n");
@@ -203,7 +201,7 @@
 			return 1;
 
 		puts("Writing to redundant NAND... ");
-		ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *)env_new);
+		ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *)&env_new);
 	} else {
 		puts("Erasing NAND...\n");
 		nand_erase_options.offset = CONFIG_ENV_OFFSET;
@@ -211,7 +209,7 @@
 			return 1;
 
 		puts("Writing to NAND... ");
-		ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)env_new);
+		ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new);
 	}
 	if (ret) {
 		puts("FAILED!\n");
@@ -228,7 +226,7 @@
 int saveenv(void)
 {
 	int	ret = 0;
-	env_t	*env_new = (env_t *)env_buf;
+	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
 	ssize_t	len;
 	char	*res;
 	nand_erase_options_t nand_erase_options;
@@ -240,7 +238,7 @@
 	if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
 		return 1;
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new->data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
@@ -406,6 +404,7 @@
 {
 #if !defined(ENV_IS_EMBEDDED)
 	int ret;
+	ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
 
 #if defined(CONFIG_ENV_OFFSET_OOB)
 	ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset);
@@ -421,13 +420,13 @@
 	}
 #endif
 
-	ret = readenv(CONFIG_ENV_OFFSET, (u_char *)env_buf);
+	ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf);
 	if (ret) {
 		set_default_env("!readenv() failed");
 		return;
 	}
 
-	env_import(env_buf, 1);
+	env_import(buf, 1);
 #endif /* ! ENV_IS_EMBEDDED */
 }
 #endif /* CONFIG_ENV_OFFSET_REDUND */
diff --git a/common/env_nvram.c b/common/env_nvram.c
index ff74a6c..eab0e7b 100644
--- a/common/env_nvram.c
+++ b/common/env_nvram.c
@@ -60,10 +60,6 @@
 char *env_name_spec = "NVRAM";
 
 #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
-static char env_buf[CONFIG_ENV_SIZE];
-#endif
-
-#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
 uchar env_get_char_spec(int index)
 {
 	uchar c;
@@ -76,38 +72,36 @@
 
 void env_relocate_spec(void)
 {
-	char *buf;
+	char buf[CONFIG_ENV_SIZE];
 
 #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE)
-	buf = env_buf;
 	nvram_read(buf, CONFIG_ENV_ADDR, CONFIG_ENV_SIZE);
 #else
-	buf = (void *)CONFIG_ENV_ADDR;
+	memcpy(buf, (void *)CONFIG_ENV_ADDR, CONFIG_ENV_SIZE);
 #endif
 	env_import(buf, 1);
 }
 
 int saveenv(void)
 {
-#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
-	env_t	*env_new = (env_t *)env_buf;
-#else
-	env_t	*env_new = (env_t *)CONFIG_ENV_ADDR;
-#endif
+	env_t	env_new;
 	ssize_t	len;
 	char	*res;
 	int	rcode = 0;
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new.data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
 		return 1;
 	}
-	env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+	env_new.crc = crc32(0, env_new.data, ENV_SIZE);
 
 #ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
-	nvram_write(CONFIG_ENV_ADDR, env_new, CONFIG_ENV_SIZE);
+	nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE);
+#else
+	if (memcpy((char *)CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE) == NULL)
+		rcode = 1;
 #endif
 	return rcode;
 }
@@ -121,7 +115,7 @@
 {
 #if defined(CONFIG_SYS_NVRAM_ACCESS_ROUTINE)
 	ulong crc;
-	uchar *data = env_buf;
+	uchar data[ENV_SIZE];
 
 	nvram_read(&crc, CONFIG_ENV_ADDR, sizeof(ulong));
 	nvram_read(data, CONFIG_ENV_ADDR + sizeof(ulong), ENV_SIZE);
diff --git a/common/env_onenand.c b/common/env_onenand.c
index 6fd5613..faa903d 100644
--- a/common/env_onenand.c
+++ b/common/env_onenand.c
@@ -42,8 +42,6 @@
 #define ONENAND_MAX_ENV_SIZE	CONFIG_ENV_SIZE
 #define ONENAND_ENV_SIZE(mtd)	(ONENAND_MAX_ENV_SIZE - ENV_HEADER_SIZE)
 
-static char env_buf[CONFIG_ENV_SIZE];
-
 DECLARE_GLOBAL_DATA_PTR;
 
 void env_relocate_spec(void)
@@ -58,7 +56,8 @@
 	char *buf = (char *)&environment;
 #else
 	loff_t env_addr = CONFIG_ENV_ADDR;
-	char *buf = env_buf;
+	char onenand_env[ONENAND_MAX_ENV_SIZE];
+	char *buf = (char *)&onenand_env[0];
 #endif /* ENV_IS_EMBEDDED */
 
 #ifndef ENV_IS_EMBEDDED
@@ -82,7 +81,7 @@
 
 int saveenv(void)
 {
-	env_t	*env_new = env_buf;
+	env_t	env_new;
 	ssize_t	len;
 	char	*res;
 	struct mtd_info *mtd = &onenand_mtd;
@@ -95,13 +94,13 @@
 		.callback	= NULL,
 	};
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new.data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
 		return 1;
 	}
-	env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+	env_new.crc = crc32(0, env_new.data, ENV_SIZE);
 
 	instr.len = CONFIG_ENV_SIZE;
 #ifdef CONFIG_ENV_ADDR_FLEX
@@ -120,7 +119,7 @@
 	}
 
 	if (mtd->write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen,
-			(u_char *)env_new)) {
+			(u_char *)&env_new)) {
 		printf("OneNAND: write failed at 0x%llx\n", instr.addr);
 		return 2;
 	}
diff --git a/common/env_sf.c b/common/env_sf.c
index 9a592ba..d9e9085 100644
--- a/common/env_sf.c
+++ b/common/env_sf.c
@@ -58,12 +58,11 @@
 char *env_name_spec = "SPI Flash";
 
 static struct spi_flash *env_flash;
-static char env_buf[CONFIG_ENV_SIZE];
 
 #if defined(CONFIG_ENV_OFFSET_REDUND)
 int saveenv(void)
 {
-	env_t	*env_new = (env_t *)env_buf;
+	env_t	env_new;
 	ssize_t	len;
 	char	*res, *saved_buffer = NULL, flag = OBSOLETE_FLAG;
 	u32	saved_size, saved_offset, sector = 1;
@@ -79,14 +78,14 @@
 		}
 	}
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new.data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
 		return 1;
 	}
-	env_new->crc	= crc32(0, env_new->data, ENV_SIZE);
-	env_new->flags	= ACTIVE_FLAG;
+	env_new.crc	= crc32(0, env_new.data, ENV_SIZE);
+	env_new.flags	= ACTIVE_FLAG;
 
 	if (gd->env_valid == 1) {
 		env_new_offset = CONFIG_ENV_OFFSET_REDUND;
@@ -126,7 +125,7 @@
 	puts("Writing to SPI flash...");
 
 	ret = spi_flash_write(env_flash, env_new_offset,
-		CONFIG_ENV_SIZE, env_new);
+		CONFIG_ENV_SIZE, &env_new);
 	if (ret)
 		goto done;
 
@@ -138,7 +137,7 @@
 	}
 
 	ret = spi_flash_write(env_flash, env_offset + offsetof(env_t, flags),
-				sizeof(env_new->flags), &flag);
+				sizeof(env_new.flags), &flag);
 	if (ret)
 		goto done;
 
@@ -244,7 +243,7 @@
 	u32	saved_size, saved_offset, sector = 1;
 	char	*res, *saved_buffer = NULL;
 	int	ret = 1;
-	env_t	*env_new = (env_t *)env_buf;
+	env_t	env_new;
 	ssize_t	len;
 
 	if (!env_flash) {
@@ -277,13 +276,13 @@
 			sector++;
 	}
 
-	res = (char *)env_new->data;
+	res = (char *)&env_new.data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
 		goto done;
 	}
-	env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+	env_new.crc = crc32(0, env_new.data, ENV_SIZE);
 
 	puts("Erasing SPI flash...");
 	ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET,
@@ -293,7 +292,7 @@
 
 	puts("Writing to SPI flash...");
 	ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET,
-		CONFIG_ENV_SIZE, env_new);
+		CONFIG_ENV_SIZE, &env_new);
 	if (ret)
 		goto done;
 
@@ -316,7 +315,7 @@
 
 void env_relocate_spec(void)
 {
-	char *buf = env_buf;
+	char buf[CONFIG_ENV_SIZE];
 	int ret;
 
 	env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 083d745..afd3506 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -72,10 +72,10 @@
 			(unsigned int) buf, dfu->name, *len);
 		break;
 	case DFU_FS_EXT4:
-		sprintf(cmd_buf, "ext4%s mmc %d:%d /%s 0x%x %ld",
+		sprintf(cmd_buf, "ext4%s mmc %d:%d 0x%x /%s %ld",
 			op == DFU_OP_READ ? "load" : "write",
 			dfu->data.mmc.dev, dfu->data.mmc.part,
-			dfu->name, (unsigned int) buf, *len);
+			(unsigned int) buf, dfu->name, *len);
 		break;
 	default:
 		printf("%s: Layout (%s) not (yet) supported!\n", __func__,
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 60dbb78..cf10b0d 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -210,9 +210,11 @@
 static inline void *
 flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
 {
-	unsigned int byte_offset = offset * info->portwidth;
+	unsigned int byte_offset = offset * info->portwidth / info->chipwidth;
+	unsigned int addr = (info->start[sect] + byte_offset);
+	unsigned int mask = 0xffffffff << (info->portwidth - 1);
 
-	return (void *)(info->start[sect] + byte_offset);
+	return (void *)(uintptr_t)(addr & mask);
 }
 
 static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
@@ -398,6 +400,8 @@
 #endif
 		flash_write64(cword.ll, addr);
 		break;
+	default:
+		printf("fwc: Unknown port width %d\n", info->portwidth);
 	}
 
 	/* Ensure all the instructions are fully finished */
@@ -585,7 +589,6 @@
 				prompt, info->start[sector],
 				flash_read_long (info, sector, 0));
 			flash_write_cmd (info, sector, 0, info->cmd_reset);
-			udelay(1);
 			return ERR_TIMOUT;
 		}
 		udelay (1);		/* also triggers watchdog */
@@ -753,12 +756,8 @@
 static flash_sect_t find_sector (flash_info_t * info, ulong addr)
 {
 	static flash_sect_t saved_sector; /* previously found sector */
-	static flash_info_t *saved_info; /* previously used flash bank */
 	flash_sect_t sector = saved_sector;
 
-	if ((info != saved_info) || (sector >= info->sector_count))
-		sector = 0;
-
 	while ((info->start[sector] < addr)
 			&& (sector < info->sector_count - 1))
 		sector++;
@@ -770,7 +769,6 @@
 		sector--;
 
 	saved_sector = sector;
-	saved_info = info;
 	return sector;
 }
 
@@ -787,12 +785,15 @@
 	/* Check if Flash is (sufficiently) erased */
 	switch (info->portwidth) {
 	case FLASH_CFI_8BIT:
+		debug("%s: 8-bit 0x%02x\n", __func__, cword.c);
 		flag = ((flash_read8(dstaddr) & cword.c) == cword.c);
 		break;
 	case FLASH_CFI_16BIT:
+		debug("%s: 16-bit 0x%04x\n", __func__, cword.w);
 		flag = ((flash_read16(dstaddr) & cword.w) == cword.w);
 		break;
 	case FLASH_CFI_32BIT:
+		debug("%s: 32-bit 0x%08lx\n", __func__, cword.l);
 		flag = ((flash_read32(dstaddr) & cword.l) == cword.l);
 		break;
 	case FLASH_CFI_64BIT:
@@ -1053,6 +1054,8 @@
 	flash_sect_t sect;
 	int st;
 
+	debug("%s: erasing sectors %d to %d\n", __func__, s_first, s_last);
+
 	if (info->flash_id != FLASH_MAN_CFI) {
 		puts ("Can't erase unknown flash type - aborted\n");
 		return 1;
@@ -1162,6 +1165,9 @@
 				rcode = 1;
 			else if (flash_verbose)
 				putc ('.');
+		} else {
+			debug("\nSector %d is protected.\n",
+						info->protect[sect]);
 		}
 	}
 
@@ -1857,7 +1863,7 @@
 	unsigned int i;
 
 	for (i = 0; i < len; i++)
-		p[i] = flash_read_uchar(info, start + i);
+		p[i] = flash_read_uchar(info, start + (i * 2));
 }
 
 static void __flash_cmd_reset(flash_info_t *info)
@@ -1878,21 +1884,40 @@
 {
 	int cfi_offset;
 
-	/* Issue FLASH reset command */
-	flash_cmd_reset(info);
-
 	for (cfi_offset=0;
 	     cfi_offset < sizeof(flash_offset_cfi) / sizeof(uint);
 	     cfi_offset++) {
+		/* Issue FLASH reset command */
+		flash_cmd_reset(info);
 		flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset],
 				 FLASH_CMD_CFI);
-		if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
-		    && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
-		    && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
+		if (flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP, 'Q') &&
+			flash_isequal(info, 0,
+					FLASH_OFFSET_CFI_RESP + 2, 'R') &&
+			flash_isequal(info, 0,
+					FLASH_OFFSET_CFI_RESP + 4, 'Y')) {
 			flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
 					sizeof(struct cfi_qry));
+#ifdef CONFIG_SYS_FLASH_INTERFACE_WIDTH
+			info->interface = CONFIG_SYS_FLASH_INTERFACE_WIDTH;
+#else
 			info->interface	= le16_to_cpu(qry->interface_desc);
-
+			/* Some flash chips can support multiple bus widths.
+			 * In this case, override the interface width and
+			 * limit it to the port width.
+			 */
+			if ((info->interface == FLASH_CFI_X8X16) &&
+				(info->portwidth == FLASH_CFI_8BIT)) {
+					debug("Overriding 16-bit interface"
+						" width to 8-bit port width.\n");
+				info->interface = FLASH_CFI_X8;
+			} else if ((info->interface == FLASH_CFI_X16X32) &&
+				(info->portwidth == FLASH_CFI_16BIT)) {
+					debug("Overriding 16-bit interface"
+						" width to 16-bit port width.\n");
+				info->interface = FLASH_CFI_X16;
+			}
+#endif
 			info->cfi_offset = flash_offset_cfi[cfi_offset];
 			debug ("device interface is %d\n",
 			       info->interface);
@@ -1903,8 +1928,8 @@
 			       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 
 			/* calculate command offsets as in the Linux driver */
-			info->addr_unlock1 = 0x555;
-			info->addr_unlock2 = 0x2aa;
+			info->addr_unlock1 = 0xaaa;
+			info->addr_unlock2 = 0x555;
 
 			/*
 			 * modify the unlock address if we are
@@ -1938,8 +1963,12 @@
 		for (info->chipwidth = FLASH_CFI_BY8;
 		     info->chipwidth <= info->portwidth;
 		     info->chipwidth <<= 1)
-			if (__flash_detect_cfi(info, qry))
+			if (__flash_detect_cfi(info, qry)) {
+				debug("Found CFI flash, portwidth %d,"
+					" chipwidth %d\n",
+					info->portwidth, info->chipwidth);
 				return 1;
+			}
 	}
 	debug ("not found\n");
 	return 0;
@@ -1958,7 +1987,7 @@
 			/* CFI < 1.1, try to guess from device id */
 			if ((info->device_id & 0x80) != 0)
 				cfi_reverse_geometry(qry);
-		} else if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
+		} else if (flash_read_uchar(info, info->ext_addr + 0x1e) == 3) {
 			/* CFI >= 1.1, deduct from top/bottom flag */
 			/* note: ext_addr is valid since cfi_version > 0 */
 			cfi_reverse_geometry(qry);
@@ -2024,6 +2053,26 @@
 	}
 }
 
+static void flash_fixup_num(flash_info_t *info, struct cfi_qry *qry)
+{
+	/*
+	 * The M29EW devices seem to report the CFI information wrong
+	 * when it's in 8 bit mode.
+	 * There's an app note from Numonyx on this issue.
+	 * So adjust the buffer size for M29EW while operating in 8-bit mode
+	 */
+	if (((qry->max_buf_write_size) > 0x8) &&
+			(info->device_id == 0x7E) &&
+			(info->device_id2 == 0x2201 ||
+			info->device_id2 == 0x2301 ||
+			info->device_id2 == 0x2801 ||
+			info->device_id2 == 0x4801)) {
+		debug("Adjusted buffer size on Numonyx flash"
+			" M29EW family in 8 bit mode\n");
+		qry->max_buf_write_size = 0x8;
+	}
+}
+
 /*
  * The following code cannot be run from FLASH!
  *
@@ -2054,14 +2103,15 @@
 
 	if (flash_detect_cfi (info, &qry)) {
 		info->vendor = le16_to_cpu(qry.p_id);
-		info->ext_addr = le16_to_cpu(qry.p_adr);
+		info->ext_addr = le16_to_cpu(qry.p_adr) * 2;
+		debug("extended address is 0x%x\n", info->ext_addr);
 		num_erase_regions = qry.num_erase_regions;
 
 		if (info->ext_addr) {
 			info->cfi_version = (ushort) flash_read_uchar (info,
-						info->ext_addr + 3) << 8;
+						info->ext_addr + 6) << 8;
 			info->cfi_version |= (ushort) flash_read_uchar (info,
-						info->ext_addr + 4);
+						info->ext_addr + 8);
 		}
 
 #ifdef DEBUG
@@ -2105,6 +2155,9 @@
 		case 0x00bf: /* SST */
 			flash_fixup_sst(info, &qry);
 			break;
+		case 0x0089: /* Numonyx */
+			flash_fixup_num(info, &qry);
+			break;
 		}
 
 		debug ("manufacturer is %d\n", info->vendor);
@@ -2112,6 +2165,8 @@
 		debug ("device id is 0x%x\n", info->device_id);
 		debug ("device id2 is 0x%x\n", info->device_id2);
 		debug ("cfi version is 0x%04x\n", info->cfi_version);
+		debug("port width: %d, chipwidth: %d, interface: %d\n",
+			info->portwidth, info->chipwidth, info->interface);
 
 		size_ratio = info->portwidth / info->chipwidth;
 		/* if the chip is x8/x16 reduce the ratio by half */
diff --git a/include/dfu.h b/include/dfu.h
index 5350d79..784d8a4 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -59,7 +59,7 @@
 
 #define DFU_NAME_SIZE 32
 #define DFU_CMD_BUF_SIZE 128
-#define DFU_DATA_BUF_SIZE (1024*1024*4) /* 4 MiB */
+#define DFU_DATA_BUF_SIZE (1024*1024*8) /* 8 MiB */
 
 struct dfu_entity {
 	char			name[DFU_NAME_SIZE];
diff --git a/include/mtd/cfi_flash.h b/include/mtd/cfi_flash.h
index 966b5e0..9bd76eb 100644
--- a/include/mtd/cfi_flash.h
+++ b/include/mtd/cfi_flash.h
@@ -78,29 +78,30 @@
 #define FLASH_CONTINUATION_CODE		0x7F
 
 #define FLASH_OFFSET_MANUFACTURER_ID	0x00
-#define FLASH_OFFSET_DEVICE_ID		0x01
-#define FLASH_OFFSET_DEVICE_ID2		0x0E
-#define FLASH_OFFSET_DEVICE_ID3		0x0F
-#define FLASH_OFFSET_CFI		0x55
+#define FLASH_OFFSET_DEVICE_ID		0x02
+#define FLASH_OFFSET_DEVICE_ID2		0x1C
+#define FLASH_OFFSET_DEVICE_ID3		0x1E
+#define FLASH_OFFSET_CFI		0xAA
+
 #define FLASH_OFFSET_CFI_ALT		0x555
-#define FLASH_OFFSET_CFI_RESP		0x10
-#define FLASH_OFFSET_PRIMARY_VENDOR	0x13
+#define FLASH_OFFSET_CFI_RESP          0x20
+#define FLASH_OFFSET_PRIMARY_VENDOR    0x26
 /* extended query table primary address */
-#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR	0x15
+#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR   0x2A
 #define FLASH_OFFSET_WTOUT		0x1F
-#define FLASH_OFFSET_WBTOUT		0x20
-#define FLASH_OFFSET_ETOUT		0x21
-#define FLASH_OFFSET_CETOUT		0x22
-#define FLASH_OFFSET_WMAX_TOUT		0x23
-#define FLASH_OFFSET_WBMAX_TOUT		0x24
-#define FLASH_OFFSET_EMAX_TOUT		0x25
-#define FLASH_OFFSET_CEMAX_TOUT		0x26
-#define FLASH_OFFSET_SIZE		0x27
-#define FLASH_OFFSET_INTERFACE		0x28
-#define FLASH_OFFSET_BUFFER_SIZE	0x2A
-#define FLASH_OFFSET_NUM_ERASE_REGIONS	0x2C
-#define FLASH_OFFSET_ERASE_REGIONS	0x2D
-#define FLASH_OFFSET_PROTECT		0x02
+#define FLASH_OFFSET_WBTOUT            0x40
+#define FLASH_OFFSET_ETOUT             0x4A
+#define FLASH_OFFSET_CETOUT            0x44
+#define FLASH_OFFSET_WMAX_TOUT         0x46
+#define FLASH_OFFSET_WBMAX_TOUT		0x48
+#define FLASH_OFFSET_EMAX_TOUT         0x4A
+#define FLASH_OFFSET_CEMAX_TOUT		0x4C
+#define FLASH_OFFSET_SIZE              0x4E
+#define FLASH_OFFSET_INTERFACE         0x50
+#define FLASH_OFFSET_BUFFER_SIZE       0x54
+#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x58
+#define FLASH_OFFSET_ERASE_REGIONS     0x5A
+#define FLASH_OFFSET_PROTECT           0x04
 #define FLASH_OFFSET_USER_PROTECTION	0x85
 #define FLASH_OFFSET_INTEL_PROTECTION	0x81