diff --git a/Makefile b/Makefile
index b3f8b2f..62c6a74 100644
--- a/Makefile
+++ b/Makefile
@@ -38,16 +38,15 @@ LDFLAGS += -framework IOKit -framework DirectIO -L/opt/local/lib -L/usr/local/li
 endif
 ifeq ($(OS_ARCH), FreeBSD)
 CPPFLAGS += -I/usr/local/include
 LDFLAGS += -L/usr/local/lib
 endif
 
 CHIP_OBJS = jedec.o stm50flw0x0x.o w39v080fa.o sharplhf00l04.o w29ee011.o \
-	sst28sf040.o am29f040b.o mx29f002.o m29f400bt.o pm29f002.o w39v040c.o \
-	w49f002u.o 82802ab.o pm49fl00x.o sst49lf040.o en29f002a.o m29f002.o \
+	sst28sf040.o m29f400bt.o 82802ab.o pm49fl00x.o \
 	sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o
 
 LIB_OBJS = layout.o
 
 CLI_OBJS = flashrom.o cli_classic.o cli_output.o print.o
 
 PROGRAMMER_OBJS = udelay.o programmer.o
diff --git a/flash.h b/flash.h
index f0ac246..8f3e11d 100644
--- a/flash.h
+++ b/flash.h
@@ -150,16 +150,22 @@ enum chipbustype {
 /*
  * How many different erase functions do we have per chip?
  */
 #define NUM_ERASEFUNCTIONS 5
 
 #define FEATURE_REGISTERMAP	(1 << 0)
 #define FEATURE_BYTEWRITES	(1 << 1)
+#define FEATURE_SHORT_RESET	(1 << 4)
 #define FEATURE_ADDR_FULL	(0 << 2)
 #define FEATURE_ADDR_MASK	(3 << 2)
+#define FEATURE_ADDR_2AA	(1 << 2)
+#define FEATURE_ADDR_AAA	(2 << 2)
+#define FEATURE_ADDR_555	0
+#define FEATURE_ADDR_FWH	0
+#define FEATURE_ADDR_SPI	0
 
 struct flashchip {
 	const char *vendor;
 	const char *name;
 
 	enum chipbustype bustype;
 
diff --git a/flashchips.c b/flashchips.c
index 70954b8..6b8f6ca 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -58,40 +58,42 @@ struct flashchip flashchips[] = {
 		.vendor		= "AMD",
 		.name		= "Am29F010A/B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMD_ID,
 		.model_id	= AM_29F010B,	/* Same as Am29F010A */
 		.total_size	= 128,
 		.page_size	= 16 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_OK_PRW,
-		.probe		= probe_29f040b,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {16 * 1024, 8} },
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {128 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_pm29f002,
+		.write		= write_jedec,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "AMD",
 		.name		= "Am29F002(N)BB",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMD_ID,
 		.model_id	= AM_29F002BB,
 		.total_size	= 256,
 		.page_size	= 256,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -115,14 +117,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "AMD",
 		.name		= "Am29F002(N)BT",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMD_ID,
 		.model_id	= AM_29F002BT,
 		.total_size	= 256,
 		.page_size	= 256,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -146,144 +149,150 @@ struct flashchip flashchips[] = {
 		.vendor		= "AMD",
 		.name		= "Am29F016D",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMD_ID,
 		.model_id	= AM_29F016D,
 		.total_size	= 2 * 1024,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_29f040b,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (am29f040b.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 32} },
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {2048 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_29f040b,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "AMD",
 		.name		= "Am29F040B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMD_ID,
 		.model_id	= AM_29F040B,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_OK_PRW,
-		.probe		= probe_29f040b,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (am29f040b.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 8} },
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_29f040b,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "AMD",
 		.name		= "Am29F080B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMD_ID,
 		.model_id	= AM_29F080B,
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 16} },
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {1024 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_29f040b,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "AMD",
 		.name		= "Am29LV040B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMD_ID,
 		.model_id	= AM_29LV040B,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_29f040b,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (am29f040b.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 8} },
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_29f040b,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "AMD",
 		.name		= "Am29LV081B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMD_ID,
 		.model_id	= AM_29LV080B,
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_29f040b,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (am29f040b.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 16} },
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {1024 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_29f040b,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "ASD",
 		.name		= "AE49F2008",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ASD_ID,
 		.model_id	= ASD_AE49F2008,
 		.total_size	= 256,
 		.page_size	= 128,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_FIXME, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -837,14 +846,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Atmel",
 		.name		= "AT29C512",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= AT_29C512,
 		.total_size	= 64,
 		.page_size	= 128,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10000, /* 10mS, Enter=Exec */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -861,14 +871,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Atmel",
 		.name		= "AT29C010A",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= AT_29C010A,
 		.total_size	= 128,
 		.page_size	= 128,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= 10000, /* 10mS, Enter=Exec */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -884,14 +895,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Atmel",
 		.name		= "AT29C020",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= AT_29C020,
 		.total_size	= 256,
 		.page_size	= 256,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10000,			/* 10ms */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -907,14 +919,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Atmel",
 		.name		= "AT29C040A",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= AT_29C040A,
 		.total_size	= 512,
 		.page_size	= 256,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= 10000,			/* 10 ms */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -1074,37 +1087,39 @@ struct flashchip flashchips[] = {
 		.vendor		= "Atmel",
 		.name		= "AT49BV512",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= AT_49BV512,
 		.total_size	= 64,
 		.page_size	= 64,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Atmel",
 		.name		= "AT49F002(N)",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= AT_49F002N,
 		.total_size	= 256,
 		.page_size	= 256,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -1116,26 +1131,27 @@ struct flashchip flashchips[] = {
 				},
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Atmel",
 		.name		= "AT49F002(N)T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ATMEL_ID,
 		.model_id	= AT_49F002NT,
 		.total_size	= 256,
 		.page_size	= 256,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -1147,15 +1163,15 @@ struct flashchip flashchips[] = {
 				},
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	/* The next two chip definitions have top/bottom boot blocks, but has no
 	device differenciation between the two */
 	{
 		.vendor		= "AMIC",
@@ -1225,91 +1241,94 @@ struct flashchip flashchips[] = {
 		.vendor		= "AMIC",
 		.name		= "A29002B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMIC_ID_NOPREFIX,
 		.model_id	= AMIC_A29002B,
 		.total_size	= 256,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA|FEATURE_SHORT_RESET,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_29f002,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { 
 					{16 * 1024, 1},
 					{8 * 1024, 2},
 					{32 * 1024, 1},
 					{64 * 1024, 3},
 				},
-				.block_erase = erase_sector_29f002,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
-				.block_erase = erase_chip_29f002,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
 		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "AMIC",
 		.name		= "A29002T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMIC_ID_NOPREFIX,
 		.model_id	= AMIC_A29002T,
 		.total_size	= 256,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA|FEATURE_SHORT_RESET,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_29f002,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { 
 					{64 * 1024, 3},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
 					{16 * 1024, 1},
 				},
-				.block_erase = erase_sector_29f002,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
-				.block_erase = erase_chip_29f002,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
 		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "AMIC",
 		.name		= "A29040B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= AMIC_ID_NOPREFIX,
 		.model_id	= AMIC_A29040B,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_29f040b,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (am29f040b.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 8} },
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_29f040b,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "AMIC",
 		.name		= "A49LF040A",
 		.bustype	= CHIP_BUSTYPE_LPC,
@@ -1340,14 +1359,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "EMST",
 		.name		= "F49B002UA",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= EMST_ID,
 		.model_id	= EMST_F49B002UA,
 		.total_size	= 256,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -1359,15 +1379,15 @@ struct flashchip flashchips[] = {
 				},
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Eon",
 		.name		= "EN25B05",
 		.bustype	= CHIP_BUSTYPE_SPI,
@@ -2147,14 +2167,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "EON",
 		.name		= "EN29F002(A)(N)B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= EON_ID,
 		.model_id	= EN_29F002B,
 		.total_size	= 256,
 		.page_size	= 256,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -2178,14 +2199,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "EON",
 		.name		= "EN29F002(A)(N)T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= EON_ID,
 		.model_id	= EN_29F002T,
 		.total_size	= 256,
 		.page_size	= 256,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -2209,76 +2231,79 @@ struct flashchip flashchips[] = {
 		.vendor		= "Fujitsu",
 		.name		= "MBM29F004BC",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= FUJITSU_ID,
 		.model_id	= MBM29F004BC,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { 
 					{16 * 1024, 1},
 					{8 * 1024, 2},
 					{32 * 1024, 1},
 					{64 * 1024, 7},
 				},
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
 		.write		= NULL,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Fujitsu",
 		.name		= "MBM29F004TC",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= FUJITSU_ID,
 		.model_id	= MBM29F004TC,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { 
 					{64 * 1024, 7},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
 					{16 * 1024, 1},
 				},
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
 		.write		= NULL,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Fujitsu",
 		.name		= "MBM29F400BC",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= FUJITSU_ID,
 		.model_id	= MBM29F400BC,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_555,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_m29f400bt,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (m29f400bt.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -2302,14 +2327,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Fujitsu",
 		.name		= "MBM29F400TC",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= FUJITSU_ID,
 		.model_id	= MBM29F400TC,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_555,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_m29f400bt,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (m29f400bt.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -2333,14 +2359,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Intel",
 		.name		= "28F001BX-B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= INTEL_ID,
 		.model_id	= P28F001BXB,
 		.total_size	= 128,
 		.page_size	= 128 * 1024, /* 8k + 2x4k + 112k */
+		.feature_bits = 0,
 		.tested		= TEST_BAD_WRITE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -2360,14 +2387,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Intel",
 		.name		= "28F001BX-T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= INTEL_ID,
 		.model_id	= P28F001BXT,
 		.total_size	= 128,
 		.page_size	= 128 * 1024, /* 112k + 2x4k + 8k */
+		.feature_bits = 0,
 		.tested		= TEST_OK_PR|TEST_BAD_WRITE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -2387,14 +2415,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Intel",
 		.name		= "82802AB",
 		.bustype	= CHIP_BUSTYPE_FWH,
 		.manufacture_id	= INTEL_ID,
 		.model_id	= I_82802AB,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_82802ab,
 		.probe_timing	= TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -2410,14 +2439,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Intel",
 		.name		= "82802AC",
 		.bustype	= CHIP_BUSTYPE_FWH,
 		.manufacture_id	= INTEL_ID,
 		.model_id	= I_82802AC,
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_82802ab,
 		.probe_timing	= TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -2800,152 +2830,157 @@ struct flashchip flashchips[] = {
 		.vendor		= "Macronix",
 		.name		= "MX29F001B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= MX_ID,
 		.model_id	= MX_29F001B,
 		.total_size	= 128,
 		.page_size	= 32 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA|FEATURE_SHORT_RESET,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_29f002,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { 
 					{8 * 1024, 1},
 					{4 * 1024, 2},
 					{8 * 1024, 2},
 					{32 * 1024, 1},
 					{64 * 1024, 1},
 				},
-				.block_erase = erase_sector_29f002,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {128 * 1024, 1} },
-				.block_erase = erase_chip_29f002,
+				.block_erase = erase_chip_block_jedec,
 			}
 		},
 		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Macronix",
 		.name		= "MX29F001T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= MX_ID,
 		.model_id	= MX_29F001T,
 		.total_size	= 128,
 		.page_size	= 32 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA|FEATURE_SHORT_RESET,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_29f002,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { 
 					{64 * 1024, 1},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
 					{4 * 1024, 2},
 					{8 * 1024, 1},
 				},
-				.block_erase = erase_sector_29f002,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {128 * 1024, 1} },
-				.block_erase = erase_chip_29f002,
+				.block_erase = erase_chip_block_jedec,
 			}
 		},
 		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Macronix",
 		.name		= "MX29F002B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= MX_ID,
 		.model_id	= MX_29F002B,
 		.total_size	= 256,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA|FEATURE_SHORT_RESET,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_29f002,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = {
 					{16 * 1024, 1},
 					{8 * 1024, 2},
 					{32 * 1024, 1},
 					{64 * 1024, 3},
 				},
-				.block_erase = erase_sector_29f002,	/* This erase function has 64k blocksize for eLiteFlash */
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
-				.block_erase = erase_chip_29f002,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
 		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Macronix",
 		.name		= "MX29F002T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= MX_ID,
 		.model_id	= MX_29F002T,
 		.total_size	= 256,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA|FEATURE_SHORT_RESET,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_29f002,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = {
 					{64 * 1024, 3},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
 					{16 * 1024, 1},
 				},
-				.block_erase = erase_sector_29f002,	/* This erase function has 64k blocksize for eLiteFlash */
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
-				.block_erase = erase_chip_29f002,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
 		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Macronix",
 		.name		= "MX29LV040",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= MX_ID,
 		.model_id	= MX_29LV040,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA|FEATURE_SHORT_RESET,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_29f002,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 8}, },
-				.block_erase = erase_sector_29f002,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
-				.block_erase = erase_chip_29f002,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
 		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
@@ -3283,76 +3318,79 @@ struct flashchip flashchips[] = {
 		.vendor		= "PMC",
 		.name		= "Pm29F002T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= PMC_ID_NOPREFIX,
 		.model_id	= PMC_29F002T,
 		.total_size	= 256,
 		.page_size	= 8 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_OK_PRW,
-		.probe		= probe_29f040b,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_FIXME, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = {
 					{128 * 1024, 1},
 					{96 * 1024, 1},
 					{8 * 1024, 2},
 					{16 * 1024, 1},
 				},
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_pm29f002,
+		.write		= write_jedec,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm29F002B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= PMC_ID_NOPREFIX,
 		.model_id	= PMC_29F002B,
 		.total_size	= 256,
 		.page_size	= 8 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_29f040b,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_FIXME, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = {
 					{16 * 1024, 1},
 					{8 * 1024, 2},
 					{96 * 1024, 1},
 					{128 * 1024, 1},
 				},
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_pm29f002,
+		.write		= write_jedec,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm39LV010",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= PMC_ID_NOPREFIX,
 		.model_id	= PMC_39F010,
 		.total_size	= 128,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -3362,15 +3400,15 @@ struct flashchip flashchips[] = {
 				.eraseblocks = { {64 * 1024, 2} },
 				.block_erase = erase_block_jedec,
 			}, {
 				.eraseblocks = { {128 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm49FL002",
 		.bustype	= CHIP_BUSTYPE_LPC|CHIP_BUSTYPE_FWH, /* A/A Mux*/
@@ -3460,14 +3498,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Sharp",
 		.name		= "LHF00L04",
 		.bustype	= CHIP_BUSTYPE_FWH, /* A/A Mux */
 		.manufacture_id	= SHARP_ID,
 		.model_id	= SHARP_LHF00L04,
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_49lfxxxc,
 		.probe_timing	= TIMING_ZERO,
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -3747,14 +3786,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST28SF040A",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_28SF040,
 		.total_size	= 512,
 		.page_size	= 256,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_28sf040,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (sst28sf040.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -3773,14 +3813,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST29EE010",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_29EE010,
 		.total_size	= 128,
 		.page_size	= 128,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -3796,14 +3837,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST29LE010",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_29LE010,
 		.total_size	= 128,
 		.page_size	= 128,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -3819,14 +3861,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST29EE020A",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_29EE020A,
 		.total_size	= 256,
 		.page_size	= 128,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10,
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -3842,14 +3885,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST29LE020",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_29LE020,
 		.total_size	= 256,
 		.page_size	= 128,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -3865,196 +3909,204 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST39SF010A",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_39SF010,
 		.total_size	= 128,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {4 * 1024, 32} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {128 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST39SF020A",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_39SF020,
 		.total_size	= 256,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {4 * 1024, 64} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST39SF040",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_39SF040,
 		.total_size	= 512,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {4 * 1024, 128} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST39VF512",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_39VF512,
 		.total_size	= 64,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns*/ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {4 * 1024, 16} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {64 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST39VF010",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_39VF010,
 		.total_size	= 128,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {4 * 1024, 32} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {128 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST39VF020",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_39VF020,
 		.total_size	= 256,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {4 * 1024, 64} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST39VF040",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_39VF040,
 		.total_size	= 512,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PROBE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {4 * 1024, 128} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST39VF080",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_39VF080,
 		.total_size	= 1024,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4064,15 +4116,15 @@ struct flashchip flashchips[] = {
 				.eraseblocks = { {64 * 1024, 16} },
 				.block_erase = erase_block_jedec,
 			}, {
 				.eraseblocks = { {1024 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST49LF002A/B",
 		.bustype	= CHIP_BUSTYPE_FWH, /* A/A Mux */
@@ -4169,14 +4221,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST49LF004C",
 		.bustype	= CHIP_BUSTYPE_FWH,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_49LF004C,
 		.total_size	= 512,
 		.page_size	= 4 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_49lfxxxc,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4230,14 +4283,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST49LF008C",
 		.bustype	= CHIP_BUSTYPE_FWH,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_49LF008C,
 		.total_size	= 1024,
 		.page_size	= 4 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_49lfxxxc,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4261,14 +4315,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST49LF016C",
 		.bustype	= CHIP_BUSTYPE_FWH,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_49LF016C,
 		.total_size	= 2048,
 		.page_size	= 4 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_49lfxxxc,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4292,14 +4347,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "SST",
 		.name		= "SST49LF020",
 		.bustype	= CHIP_BUSTYPE_LPC,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_49LF020,
 		.total_size	= 256,
 		.page_size	= 16 * 1024,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4309,26 +4365,27 @@ struct flashchip flashchips[] = {
 				.eraseblocks = { {16 * 1024, 16} },
 				.block_erase = erase_block_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = NULL,
 			}
 		},
-		.write		= write_49lf040,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST49LF020A",
 		.bustype	= CHIP_BUSTYPE_LPC,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_49LF020A,
 		.total_size	= 256,
 		.page_size	= 4 * 1024,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4338,26 +4395,27 @@ struct flashchip flashchips[] = {
 				.eraseblocks = { {16 * 1024, 16} },
 				.block_erase = erase_block_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = NULL,
 			}
 		},
-		.write		= write_49lf040,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST49LF040",
 		.bustype	= CHIP_BUSTYPE_LPC,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_49LF040,
 		.total_size	= 512,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */ 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4367,27 +4425,27 @@ struct flashchip flashchips[] = {
 				.eraseblocks = { {64 * 1024, 8} },
 				.block_erase = erase_block_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = NULL,
 			}
 		},
-		.write		= write_49lf040,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST49LF040B",
 		.bustype	= CHIP_BUSTYPE_LPC, /* A/A Mux */
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_49LF040B,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
-		.feature_bits	= FEATURE_REGISTERMAP,
+		.feature_bits	= 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,		/* 150ns | routine is wrapper to probe_jedec (sst_fwhub.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4397,26 +4455,27 @@ struct flashchip flashchips[] = {
 				.eraseblocks = { {64 * 1024, 8} },
 				.block_erase = erase_block_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = NULL,
 			}
 		},
-		.write		= write_49lf040,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST49LF080A",
 		.bustype	= CHIP_BUSTYPE_LPC, /* A/A Mux */
 		.manufacture_id	= SST_ID,
  		.model_id	= SST_49LF080A,
 		.total_size	= 1024,
 		.page_size	= 4096,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_FIXME, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4426,26 +4485,27 @@ struct flashchip flashchips[] = {
 				.eraseblocks = { {64 * 1024, 16} },
 				.block_erase = erase_block_jedec,
 			}, {
 				.eraseblocks = { {1024 * 1024, 1} },
 				.block_erase = NULL,
 			}
 		},
-		.write		= write_49lf040,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST49LF160C",
 		.bustype	= CHIP_BUSTYPE_LPC,
 		.manufacture_id	= SST_ID,
 		.model_id	= SST_49LF160C,
 		.total_size	= 2048,
 		.page_size	= 4 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_49lfxxxc,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */
 		.erase		= erase_49lfxxxc,
 		.erase		= NULL,
 		.block_erasers	=
 		{
@@ -4788,14 +4848,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "ST",
 		.name		= "M29F002B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M29F002B,
 		.total_size	= 256,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_AAA,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4807,26 +4868,27 @@ struct flashchip flashchips[] = {
 				},
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_m29f002b,
+		.write		= write_jedec,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "ST",
 		.name		= "M29F002T/NT",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M29F002T,
 		.total_size	= 256,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_AAA,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4838,52 +4900,54 @@ struct flashchip flashchips[] = {
 				},
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_m29f002t,
+		.write		= write_jedec,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "ST",
 		.name		= "M29F040B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M29F040B,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_2AA,
 		.tested		= TEST_OK_PRW,
-		.probe		= probe_29f040b,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (am29f040b.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 8}, },
-				.block_erase = erase_sector_29f040b,
+				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
-				.block_erase = erase_chip_29f040b,
+				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_29f040b,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "ST",
 		.name		= "M29F400BT",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M29F400BT,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_555,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_m29f400bt,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (m29f400bt.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4907,14 +4971,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "ST",
 		.name		= "M29W010B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M29W010B,
 		.total_size	= 128,
 		.page_size	= 16 * 1024,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -4933,14 +4998,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "ST",
 		.name		= "M29W040B",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M29W040B,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5099,14 +5165,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "ST",
 		.name		= "M50FW002",
 		.bustype	= CHIP_BUSTYPE_FWH, /* A/A Mux */
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M50FW002,
 		.total_size	= 256,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_49lfxxxc,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5130,14 +5197,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "ST",
 		.name		= "M50FW016",
 		.bustype	= CHIP_BUSTYPE_FWH, /* A/A Mux */
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M50FW016,
 		.total_size	= 2048,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_82802ab,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (82802ab.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5156,14 +5224,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "ST",
 		.name		= "M50FW040",
 		.bustype	= CHIP_BUSTYPE_FWH, /* A/A Mux */
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M50FW040,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_82802ab,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (82802ab.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5182,14 +5251,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "ST",
 		.name		= "M50FW080",
 		.bustype	= CHIP_BUSTYPE_FWH, /* A/A Mux */
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M50FW080,
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
+		.feature_bits = FEATURE_ADDR_FWH,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_82802ab,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (82802ab.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5208,14 +5278,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "ST",
 		.name		= "M50LPW116",
 		.bustype	= CHIP_BUSTYPE_LPC, /* A/A Mux */
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M50LPW116,
 		.total_size	= 2048,
 		.page_size	= 64 * 1024,
+		.feature_bits	= FEATURE_REGISTERMAP,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5240,118 +5311,123 @@ struct flashchip flashchips[] = {
 		.vendor		= "SyncMOS",
 		.name		= "S29C31004T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SYNCMOS_ID,
 		.model_id	= S29C31004T,
 		.total_size	= 512,
 		.page_size	= 128,
+		.feature_bits	= 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {1 * 1024, 512} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SyncMOS",
 		.name		= "S29C51001T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SYNCMOS_ID,
 		.model_id	= S29C51001T,
 		.total_size	= 128,
 		.page_size	= 128,
+		.feature_bits	= 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {512, 256} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {128 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SyncMOS",
 		.name		= "S29C51002T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SYNCMOS_ID,
 		.model_id	= S29C51002T,
 		.total_size	= 256,
 		.page_size	= 128,
+		.feature_bits	= 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {512, 512} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "SyncMOS",
 		.name		= "S29C51004T",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= SYNCMOS_ID,
 		.model_id	= S29C51004T,
 		.total_size	= 512,
 		.page_size	= 128,
+		.feature_bits	= 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {1 * 1024, 512} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			},
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "TI",
 		.name		= "TMS29F002RB",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= TI_OLD_ID,
 		.model_id	= TI_TMS29F002RB,
 		.total_size	= 256,
 		.page_size	= 16384, /* Non-uniform sectors */
+		.feature_bits	= 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5375,14 +5451,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "TI",
 		.name		= "TMS29F002RT",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= TI_OLD_ID,
 		.model_id	= TI_TMS29F002RT,
 		.total_size	= 256,
 		.page_size	= 16384, /* Non-uniform sectors */
+		.feature_bits	= 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5651,14 +5728,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Winbond",
 		.name		= "W29C011",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_29C011,
 		.total_size	= 128,
 		.page_size	= 128,
+		.feature_bits	= 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10,		/* used datasheet for the W29C011A */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5697,14 +5775,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Winbond",
 		.name		= "W29C040P",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_29C040P,
 		.total_size	= 512,
 		.page_size	= 256,
+		.feature_bits	= 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5720,14 +5799,15 @@ struct flashchip flashchips[] = {
 		.vendor		= "Winbond",
 		.name		= "W29EE011",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_29C011,
 		.total_size	= 128,
 		.page_size	= 128,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_w29ee011,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (w29ee011.c) */
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5743,92 +5823,96 @@ struct flashchip flashchips[] = {
 		.vendor		= "Winbond",
 		.name		= "W39V040A",
 		.bustype	= CHIP_BUSTYPE_LPC,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_39V040A,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits	= 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 8} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Winbond",
 		.name		= "W39V040B",
 		.bustype	= CHIP_BUSTYPE_LPC,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_39V040B,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits	= 0,
 		.tested		= TEST_OK_PR | TEST_BAD_WRITE,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 8} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Winbond",
 		.name		= "W39V040C",
 		.bustype	= CHIP_BUSTYPE_LPC,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_39V040C,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits = 0,
 		.tested		= TEST_OK_PRW,
-		.probe		= probe_w39v040c,
+		.probe		= probe_jedec,
 		.probe_timing	= TIMING_FIXME,
 		.erase		= NULL, /* Was erase_w39v040c */
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 8} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_w39v040c,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Winbond",
 		.name		= "W39V040FA",
 		.bustype	= CHIP_BUSTYPE_FWH,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_39V040FA,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
+		.feature_bits	= 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5838,52 +5922,54 @@ struct flashchip flashchips[] = {
 				.eraseblocks = { {64 * 1024, 8} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {512 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Winbond",
 		.name		= "W39V080A",
 		.bustype	= CHIP_BUSTYPE_LPC,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_39V080A,
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
+		.feature_bits	= 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
 				.eraseblocks = { {64 * 1024, 16} },
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {1024 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Winbond",
 		.name		= "W49F002U",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_49F002U,
 		.total_size	= 256,
 		.page_size	= 128,
+		.feature_bits	= 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10,
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5895,26 +5981,27 @@ struct flashchip flashchips[] = {
 				},
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Winbond",
 		.name		= "W49V002A",
 		.bustype	= CHIP_BUSTYPE_LPC,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_49V002A,
 		.total_size	= 256,
 		.page_size	= 128,
+		.feature_bits	= 0,
 		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5926,26 +6013,27 @@ struct flashchip flashchips[] = {
 				},
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Winbond",
 		.name		= "W49V002FA",
 		.bustype	= CHIP_BUSTYPE_FWH,
 		.manufacture_id	= WINBOND_ID,
 		.model_id	= W_49V002FA,
 		.total_size	= 256,
 		.page_size	= 128,
+		.feature_bits	= 0,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
 		.probe_timing	= 10,
 		.erase		= NULL,
 		.block_erasers	=
 		{
 			{
@@ -5957,15 +6045,15 @@ struct flashchip flashchips[] = {
 				},
 				.block_erase = erase_sector_jedec,
 			}, {
 				.eraseblocks = { {256 * 1024, 1} },
 				.block_erase = erase_chip_block_jedec,
 			}
 		},
-		.write		= write_49f002,
+		.write		= write_jedec_1,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Winbond",
 		.name		= "W39V080FA",
 		.bustype	= CHIP_BUSTYPE_FWH,
diff --git a/jedec.c b/jedec.c
index 055fbc3..7330185 100644
--- a/jedec.c
+++ b/jedec.c
@@ -23,14 +23,15 @@
  */
 
 #include "flash.h"
 
 #define MAX_REFLASH_TRIES 0x10
 #define MASK_FULL 0xffff
 #define MASK_2AA 0x7ff
+#define MASK_AAA 0xfff
 
 /* Check one byte for odd parity */
 uint8_t oddparity(uint8_t val)
 {
 	val = (val ^ (val >> 4)) & 0xf;
 	val = (val ^ (val >> 2)) & 0x3;
 	return (val ^ (val >> 1)) & 0x1;
@@ -94,16 +95,15 @@ void start_program_jedec_common(struct flashchip *flash, unsigned int mask)
 {
 	chipaddr bios = flash->virtual_memory;
 	chip_writeb(0xAA, bios + (0x5555 & mask));
 	chip_writeb(0x55, bios + (0x2AAA & mask));
 	chip_writeb(0xA0, bios + (0x5555 & mask));
 }
 
-int probe_jedec_common(struct flashchip *flash,
-			unsigned int mask, int long_reset)
+int probe_jedec_common(struct flashchip *flash, unsigned int mask)
 {
 	chipaddr bios = flash->virtual_memory;
 	uint8_t id1, id2;
 	uint32_t largeid1, largeid2;
 	uint32_t flashcontent1, flashcontent2;
 	int probe_timing_enter, probe_timing_exit;
 
@@ -148,15 +148,15 @@ int probe_jedec_common(struct flashchip *flash,
 	if (id2 == 0x7F) {
 		largeid2 <<= 8;
 		id2 = chip_readb(bios + 0x101);
 		largeid2 |= id2;
 	}
 
 	/* Issue JEDEC Product ID Exit command */
-	if (long_reset)
+	if (flash->feature_bits & FEATURE_SHORT_RESET)
 	{
 		chip_writeb(0xAA, bios + (0x5555 & mask));
 		if (probe_timing_exit)
 			programmer_delay(10);
 		chip_writeb(0x55, bios + (0x2AAA & mask));
 		if (probe_timing_exit)
 			programmer_delay(10);
@@ -375,99 +375,123 @@ retry:
 
 int getaddrmask(struct flashchip *flash)
 {
 	switch (flash->feature_bits & FEATURE_ADDR_MASK) {
 	case FEATURE_ADDR_FULL:
 		return MASK_FULL;
 		break;
+	case FEATURE_ADDR_2AA:
+		return MASK_2AA;
+		break;
+	case FEATURE_ADDR_AAA:
+		return MASK_AAA;
+		break;
 	default:
 		fprintf(stderr, "%s called with unknown mask\n", __func__);
 		return 0;
 		break;
 	}
 }
 
 int write_jedec(struct flashchip *flash, uint8_t *buf)
 {
+	int mask;
+
+	mask = getaddrmask(flash);
 	int i, failed = 0;
 	int total_size = flash->total_size * 1024;
 	int page_size = flash->page_size;
 
 	if (erase_chip_jedec(flash)) {
 		fprintf(stderr,"ERASE FAILED!\n");
 		return -1;
 	}
 	
 	printf("Programming page: ");
 	for (i = 0; i < total_size / page_size; i++) {
 		printf("%04d at address: 0x%08x", i, i * page_size);
 		if (write_page_write_jedec_common(flash, buf + i * page_size,
-					   i * page_size, page_size, MASK_FULL))
+					   i * page_size, page_size, mask))
 			failed = 1;
 		printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
 	}
 	printf("\n");
 
 	return failed;
 }
 
 int write_jedec_1(struct flashchip *flash, uint8_t * buf)
 {
 	int i;
 	chipaddr bios = flash->virtual_memory;
 	chipaddr dst = bios;
+	int mask;
+
+	mask = getaddrmask(flash);
 
 	programmer_delay(10);
 	if (erase_flash(flash)) {
 		fprintf(stderr, "ERASE FAILED!\n");
 		return -1;
 	}
 
 	printf("Programming page: ");
 	for (i = 0; i < flash->total_size; i++) {
 		if ((i & 0x3) == 0)
 			printf("address: 0x%08lx", (unsigned long)i * 1024);
 
-                write_sector_jedec_common(flash, buf + i * 1024, dst + i * 1024, 1024, MASK_FULL);
+                write_sector_jedec_common(flash, buf + i * 1024, dst + i * 1024, 1024, mask);
 
 		if ((i & 0x3) == 0)
 			printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
 	}
 
 	printf("\n");
 	return 0;
 }
 
 /* erase chip with block_erase() prototype */
 int erase_chip_block_jedec(struct flashchip *flash, unsigned int addr,
 			   unsigned int blocksize)
 {
+	int mask;
+
+	mask = getaddrmask(flash);
 	if ((addr != 0) || (blocksize != flash->total_size * 1024)) {
 		fprintf(stderr, "%s called with incorrect arguments\n",
 			__func__);
 		return -1;
 	}
-	return erase_chip_jedec_common(flash, MASK_FULL);
+	return erase_chip_jedec_common(flash, mask);
 }
 
 int probe_jedec(struct flashchip *flash)
 {
 	int mask;
 
 	mask = getaddrmask(flash);
-	return probe_jedec_common(flash, mask, 1);
+	return probe_jedec_common(flash, mask);
 }
 
 int erase_sector_jedec(struct flashchip *flash, unsigned int page, unsigned int size)
 {
-	return erase_sector_jedec_common(flash, page, size, MASK_FULL);
+	int mask;
+
+	mask = getaddrmask(flash);
+	return erase_sector_jedec_common(flash, page, size, mask);
 }
 
 int erase_block_jedec(struct flashchip *flash, unsigned int page, unsigned int size)
 {
-	return erase_block_jedec_common(flash, page, size, MASK_FULL);
+	int mask;
+
+	mask = getaddrmask(flash);
+	return erase_block_jedec_common(flash, page, size, mask);
 }
 
 int erase_chip_jedec(struct flashchip *flash)
 {
-	return erase_chip_jedec_common(flash, MASK_FULL);
+	int mask;
+
+	mask = getaddrmask(flash);
+	return erase_chip_jedec_common(flash, mask);
 }
