Move implicit erase out of chip drivers

Flashrom had an implicit erase-on-write for most flash chip and
programmer drivers, but it was not entirely consistent.

Some drivers had their own hand-rolled partial update functionality
which made handling partial updates from generic code impossible.

Move implicit erase out of chip drivers, and kill some dead erase
functions at the same time. A full chip erase is now performed in the
generic code for all flash chips on write, and after that the whole chip
is written.

Corresponding to flashrom svn r1206.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Uwe Hermann <uwe@hermann-uwe.de>
diff --git a/82802ab.c b/82802ab.c
index 3935a7e..1f3a668 100644
--- a/82802ab.c
+++ b/82802ab.c
@@ -144,23 +144,6 @@
 	return 0;
 }
 
-int erase_82802ab(struct flashchip *flash)
-{
-	int i;
-	unsigned int total_size = flash->total_size * 1024;
-
-	msg_cspew("total_size is %d; flash->page_size is %d\n",
-	       total_size, flash->page_size);
-	for (i = 0; i < total_size; i += flash->page_size)
-		if (erase_block_82802ab(flash, i, flash->page_size)) {
-			msg_cerr("ERASE FAILED!\n");
-			return -1;
-		}
-	msg_cinfo("DONE ERASE\n");
-
-	return 0;
-}
-
 void write_page_82802ab(chipaddr bios, uint8_t *src,
 			chipaddr dst, int page_size)
 {
@@ -179,11 +162,6 @@
 	int i;
 	chipaddr bios = flash->virtual_memory;
 
-	if (erase_flash(flash)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
-
 	msg_cinfo("Programming at: ");
 	for (i = 0; i < flash->total_size; i++) {
 		if ((i & 0x3) == 0)
diff --git a/chipdrivers.h b/chipdrivers.h
index 94daafc..60220e6 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -33,8 +33,6 @@
 int probe_spi_res2(struct flashchip *flash);
 int spi_write_enable(void);
 int spi_write_disable(void);
-int spi_chip_erase_60(struct flashchip *flash);
-int spi_chip_erase_c7(struct flashchip *flash);
 int spi_block_erase_20(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
 int spi_block_erase_52(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
 int spi_block_erase_d7(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
@@ -69,7 +67,6 @@
 /* 82802ab.c */
 uint8_t wait_82802ab(chipaddr bios);
 int probe_82802ab(struct flashchip *flash);
-int erase_82802ab(struct flashchip *flash);
 int erase_block_82802ab(struct flashchip *flash, unsigned int page, unsigned int pagesize);
 int write_82802ab(struct flashchip *flash, uint8_t *buf);
 void print_status_82802ab(uint8_t status);
@@ -84,7 +81,6 @@
 int write_byte_program_jedec(chipaddr bios, uint8_t *src,
 			     chipaddr dst);
 int probe_jedec(struct flashchip *flash);
-int erase_chip_jedec(struct flashchip *flash);
 int write_jedec(struct flashchip *flash, uint8_t *buf);
 int write_jedec_1(struct flashchip *flash, uint8_t *buf);
 int erase_sector_jedec(struct flashchip *flash, unsigned int page, unsigned int pagesize);
@@ -94,7 +90,6 @@
 
 /* m29f400bt.c */
 int probe_m29f400bt(struct flashchip *flash);
-int erase_m29f400bt(struct flashchip *flash);
 int block_erase_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len);
 int block_erase_chip_m29f400bt(struct flashchip *flash, unsigned int start, unsigned int len);
 int write_m29f400bt(struct flashchip *flash, uint8_t *buf);
diff --git a/flashchips.c b/flashchips.c
index c0280b3..d1e4a99 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -65,7 +65,7 @@
 		.total_size	= 128,
 		.page_size	= 16 * 1024,
 		.feature_bits	= FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -231,7 +231,7 @@
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (am29f040b.c) */
 		.block_erasers	=
@@ -477,7 +477,7 @@
 		.model_id	= AMIC_A25L40PT,
 		.total_size	= 512,
 		.page_size	= 256,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid4,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -509,7 +509,7 @@
 		.model_id	= AMIC_A25L40PU,
 		.total_size	= 512,
 		.page_size	= 256,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid4,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -541,7 +541,7 @@
 		.model_id	= AMIC_A25L80P,
 		.total_size	= 1024,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid4,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -608,7 +608,7 @@
 		.model_id	= AMIC_A25L16PU,
 		.total_size	= 2048,
 		.page_size	= 256,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid4,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -927,7 +927,7 @@
 		.total_size	= 256,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */
 		.block_erasers	=
@@ -984,7 +984,7 @@
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* routine is wrapper to probe_jedec (pm49fl00x.c) */
 		.block_erasers	=
@@ -1196,7 +1196,7 @@
 		.total_size	= 4096,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -1658,7 +1658,7 @@
 		.total_size	= 128,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_LONG_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 10000, /* 10mS, Enter=Exec */
 		.block_erasers	=
@@ -1885,7 +1885,7 @@
 		.total_size	= 256,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
@@ -1939,7 +1939,7 @@
 		.total_size	= 256,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
@@ -2744,7 +2744,7 @@
 		.total_size	= 1024,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -2843,7 +2843,7 @@
 		.total_size	= 128,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
@@ -2870,7 +2870,7 @@
 		.total_size	= 256,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
@@ -2901,7 +2901,7 @@
 		.total_size	= 256,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
@@ -3057,7 +3057,7 @@
 		.total_size	= 256,
 		.page_size	= 256 * 1024,
 		.feature_bits	= FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO, /* Datasheet has no timing info specified */
 		.block_erasers	=
@@ -3196,7 +3196,7 @@
 		.model_id	= INTEL_28F002T,
 		.total_size	= 256,
 		.page_size	= 256 * 1024,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_82802ab,
 		.probe_timing	= TIMING_ZERO, /* Datasheet has no timing info specified */
 		.block_erasers	=
@@ -3510,7 +3510,7 @@
 		.total_size	= 512,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -3546,7 +3546,7 @@
 		.total_size	= 1024,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -3582,7 +3582,7 @@
 		.total_size	= 2048,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -3684,7 +3684,7 @@
 		.total_size	= 4096,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -3911,7 +3911,7 @@
 		.total_size	= 256,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (mx29f002.c) */
 		.block_erasers	=
@@ -4262,7 +4262,7 @@
 		.model_id	= ST_M25PE80,
 		.total_size	= 1024,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -4507,7 +4507,7 @@
 		.total_size	= 256,
 		.page_size	= 8 * 1024,
 		.feature_bits	= FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_FIXME, 
 		.block_erasers	=
@@ -4569,7 +4569,7 @@
 		.total_size	= 128,
 		.page_size	= 4096,
 		.feature_bits	= FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
@@ -4656,7 +4656,7 @@
 		.total_size	= 256,
 		.page_size	= 16 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* routine is wrapper to probe_jedec (pm49fl00x.c) */
 		.block_erasers	=
@@ -4686,7 +4686,7 @@
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* routine is wrapper to probe_jedec (pm49fl00x.c) */
 		.block_erasers	=
@@ -4773,7 +4773,7 @@
 		.model_id	= SPANSION_S25FL008A,
 		.total_size	= 1024,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -4799,7 +4799,7 @@
 		.model_id	= SPANSION_S25FL016A,
 		.total_size	= 2048,
 		.page_size	= 256,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -4825,7 +4825,7 @@
 		.model_id	= SST_SST25VF016B,
 		.total_size	= 2048,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -4860,7 +4860,7 @@
 		.model_id	= SST_SST25VF032B,
 		.total_size	= 4096,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -4895,7 +4895,7 @@
 		.model_id	= SST_SST25VF064C,
 		.total_size	= 8192,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -5058,7 +5058,7 @@
 		.model_id	= SST_SST25VF080B,
 		.total_size	= 1024,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -5120,7 +5120,7 @@
 		.total_size	= 128,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_LONG_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.block_erasers	=
@@ -5166,7 +5166,7 @@
 		.total_size	= 256,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_LONG_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 10,
 		.block_erasers	=
@@ -5189,7 +5189,7 @@
 		.total_size	= 256,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_LONG_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.block_erasers	=
@@ -5238,7 +5238,7 @@
 		.total_size	= 128,
 		.page_size	= 4096,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */
 		.block_erasers	=
@@ -5264,7 +5264,7 @@
 		.total_size	= 256,
 		.page_size	= 4096,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */
 		.block_erasers	=
@@ -5290,7 +5290,7 @@
 		.total_size	= 512,
 		.page_size	= 4096,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */
 		.block_erasers	=
@@ -5316,7 +5316,7 @@
 		.total_size	= 64,
 		.page_size	= 4096,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */
 		.block_erasers	=
@@ -5342,7 +5342,7 @@
 		.total_size	= 128,
 		.page_size	= 4096,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */
 		.block_erasers	=
@@ -5449,7 +5449,7 @@
 		.total_size	= 256,
 		.page_size	= 16 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,		/* 150 ns */
 		.block_erasers	=
@@ -5514,7 +5514,7 @@
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,		/* 150 ns */
 		.block_erasers	=
@@ -5577,7 +5577,7 @@
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,		/* 150 ns */
 		.block_erasers	=
@@ -5640,7 +5640,7 @@
 		.total_size	= 2048,
 		.page_size	= 4 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_82802ab,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */
 		.block_erasers	=
@@ -5672,7 +5672,7 @@
 		.total_size	= 256,
 		.page_size	= 16 * 1024,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */
 		.block_erasers	=
@@ -5701,7 +5701,7 @@
 		.total_size	= 256,
 		.page_size	= 4 * 1024,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */
 		.block_erasers	=
@@ -5730,7 +5730,7 @@
 		.total_size	= 512,
 		.page_size	= 4096,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,			/* 150 ns */
 		.block_erasers	=
@@ -5759,7 +5759,7 @@
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_EITHER_RESET | FEATURE_REGISTERMAP,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,		/* 150ns */
 		.block_erasers	=
@@ -5789,7 +5789,7 @@
 		.total_size	= 1024,
 		.page_size	= 4096,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_FIXME, 
 		.block_erasers	=
@@ -5818,7 +5818,7 @@
 		.total_size	= 2048,
 		.page_size	= 4 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_82802ab,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (sst49lfxxxc.c) */
 		.block_erasers	=
@@ -5906,7 +5906,7 @@
 		.model_id	= ST_M25P10A,
 		.total_size	= 128,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -5985,7 +5985,7 @@
 		.model_id	= ST_M25P40,
 		.total_size	= 512,
 		.page_size	= 256,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -6037,7 +6037,7 @@
 		.model_id	= ST_M25P80,
 		.total_size	= 1024,
 		.page_size	= 256,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -6063,7 +6063,7 @@
 		.model_id	= ST_M25P16,
 		.total_size	= 2048,
 		.page_size	= 256,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -6089,7 +6089,7 @@
 		.model_id	= ST_M25P32,
 		.total_size	= 4096,
 		.page_size	= 256,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -6167,7 +6167,7 @@
 		.model_id	= ST_M25PX32,
 		.total_size	= 4096,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -6196,7 +6196,7 @@
 		.model_id	= ST_M25PX64,
 		.total_size	= 8192,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -6429,7 +6429,7 @@
                 .total_size     = 64,
                 .page_size      = 64 * 1024,
                 .feature_bits   = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
-                .tested         = TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
                 .probe          = probe_jedec,
                 .probe_timing   = TIMING_ZERO,
                 .block_erasers  =
@@ -6522,7 +6522,7 @@
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_82802ab,
 		.probe_timing	= TIMING_FIXME,
 		.block_erasers	=
@@ -6816,7 +6816,7 @@
 		.total_size	= 256,
 		.page_size	= 512,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
@@ -7008,7 +7008,7 @@
 		.total_size	= 1024,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -7080,7 +7080,7 @@
 		.total_size	= 4096,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -7116,7 +7116,7 @@
 		.total_size	= 8192,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -7212,7 +7212,7 @@
 		.total_size	= 512,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -7242,7 +7242,7 @@
 		.total_size	= 1024,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -7272,7 +7272,7 @@
 		.total_size	= 2048,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -7380,7 +7380,7 @@
 		.total_size	= 128,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_LONG_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= 10,		/* used datasheet for the W29C011A */
 		.block_erasers	=
@@ -7403,7 +7403,7 @@
 		.total_size	= 256,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_LONG_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.block_erasers	=
@@ -7449,7 +7449,7 @@
 		.total_size	= 128,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_LONG_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_w29ee011,
 		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (w29ee011.c) */
 		.block_erasers	=
@@ -7472,7 +7472,7 @@
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.block_erasers	=
@@ -7498,7 +7498,7 @@
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.block_erasers	=
@@ -7551,7 +7551,7 @@
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.block_erasers	=
@@ -7608,7 +7608,7 @@
 		.total_size	= 256,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 10,
 		.block_erasers	=
@@ -7662,7 +7662,7 @@
 		.total_size	= 256,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= 10, 
 		.block_erasers	=
@@ -7693,7 +7693,7 @@
 		.total_size	= 256,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PRW,
+		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
 		.probe_timing	= 10,
 		.block_erasers	=
@@ -7724,7 +7724,7 @@
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_FIXME,
 		.block_erasers	=
diff --git a/flashrom.c b/flashrom.c
index e5e334c..2cf8075 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -1509,6 +1509,7 @@
 
 /* This function signature is horrible. We need to design a better interface,
  * but right now it allows us to split off the CLI code.
+ * Besides that, the function itself is a textbook example of abysmal code flow.
  */
 int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it)
 {
@@ -1563,12 +1564,7 @@
 			programmer_shutdown();
 			return 1;
 		}
-	} else {
-		struct stat image_stat;
-
-		if (flash->unlock)
-			flash->unlock(flash);
-
+	} else if (write_it) {
 		if (flash->tested & TEST_BAD_ERASE) {
 			msg_cerr("Erase is not working on this chip "
 				"and erase is needed for write. ");
@@ -1590,6 +1586,18 @@
 				msg_cerr("Continuing anyway.\n");
 			}
 		}
+		if (!flash->write) {
+			msg_cerr("Error: flashrom has no write function for this flash chip.\n");
+			programmer_shutdown();
+			return 1;
+		}
+		if (flash->unlock)
+			flash->unlock(flash);
+
+	}
+	if (write_it || verify_it) {
+		struct stat image_stat;
+
 		if ((image = fopen(filename, "rb")) == NULL) {
 			perror(filename);
 			programmer_shutdown();
@@ -1625,12 +1633,12 @@
 	// ////////////////////////////////////////////////////////////
 
 	if (write_it) {
-		msg_cinfo("Writing flash chip... ");
-		if (!flash->write) {
-			msg_cerr("Error: flashrom has no write function for this flash chip.\n");
+		if (erase_flash(flash)) {
+			emergency_help_message();
 			programmer_shutdown();
 			return 1;
 		}
+		msg_cinfo("Writing flash chip... ");
 		ret = flash->write(flash, buf);
 		if (ret) {
 			msg_cerr("FAILED!\n");
diff --git a/jedec.c b/jedec.c
index 05cba79..b4bd3f1 100644
--- a/jedec.c
+++ b/jedec.c
@@ -402,11 +402,6 @@
 
 	mask = getaddrmask(flash);
 
-	if (erase_chip_jedec(flash)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
-	
 	msg_cinfo("Programming page: ");
 	for (i = 0; i < total_size / page_size; i++) {
 		msg_cinfo("%04d at address: 0x%08x", i, i * page_size);
@@ -429,12 +424,6 @@
 
 	mask = getaddrmask(flash);
 
-	programmer_delay(10);
-	if (erase_flash(flash)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
-
 	msg_cinfo("Programming page: ");
 	for (i = 0; i < flash->total_size; i++) {
 		if ((i & 0x3) == 0)
diff --git a/m29f400bt.c b/m29f400bt.c
index 2a770ba..b6a3249 100644
--- a/m29f400bt.c
+++ b/m29f400bt.c
@@ -143,7 +143,6 @@
 	int page_size = flash->page_size;
 	chipaddr bios = flash->virtual_memory;
 
-	//erase_m29f400bt (flash);
 	msg_cinfo("Programming page:\n ");
 	/*********************************
 	*Pages for M29F400BT:
@@ -163,41 +162,21 @@
 	msg_cinfo("total_size/page_size = %d\n", total_size / page_size);
 	for (i = 0; i < (total_size / page_size) - 1; i++) {
 		msg_cinfo("%04d at address: 0x%08x\n", i, i * page_size);
-		if (block_erase_m29f400bt(flash, i * page_size, page_size)) {
-			msg_cerr("ERASE FAILED!\n");
-			return -1;
-		}
 		write_page_m29f400bt(bios, buf + i * page_size,
 				     bios + i * page_size, page_size);
 		msg_cinfo("\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");
 	}
 
 	msg_cinfo("%04d at address: 0x%08x\n", 7, 0x70000);
-	if (block_erase_m29f400bt(flash, 0x70000, 32 * 1024)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
 	write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024);
 
 	msg_cinfo("%04d at address: 0x%08x\n", 8, 0x78000);
-	if (block_erase_m29f400bt(flash, 0x78000, 8 * 1024)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
 	write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024);
 
 	msg_cinfo("%04d at address: 0x%08x\n", 9, 0x7a000);
-	if (block_erase_m29f400bt(flash, 0x7a000, 8 * 1024)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
 	write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024);
 
 	msg_cinfo("%04d at address: 0x%08x\n", 10, 0x7c000);
-	if (block_erase_m29f400bt(flash, 0x7c000, 16 * 1024)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
 	write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
 
 	msg_cinfo("\n");
diff --git a/sharplhf00l04.c b/sharplhf00l04.c
index a891e2c..ab1652d 100644
--- a/sharplhf00l04.c
+++ b/sharplhf00l04.c
@@ -65,10 +65,6 @@
 	int page_size = flash->page_size;
 	chipaddr bios = flash->virtual_memory;
 
-	if (erase_flash(flash)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
 	msg_cinfo("Programming page: ");
 	for (i = 0; i < total_size / page_size; i++) {
 		msg_cinfo("%04d at address: 0x%08x", i, i * page_size);
diff --git a/spi.c b/spi.c
index e52ea7a..85607e7 100644
--- a/spi.c
+++ b/spi.c
@@ -262,12 +262,6 @@
 {
 	int ret;
 
-	msg_pinfo("Erasing flash before programming... ");
-	if (erase_flash(flash)) {
-		msg_perr("ERASE FAILED!\n");
-		return -1;
-	}
-	msg_pinfo("done.\n");
 	msg_pinfo("Programming flash... ");
 	ret = spi_chip_write_256_new(flash, buf, 0, flash->total_size * 1024);
 	if (!ret)
diff --git a/spi25.c b/spi25.c
index 9aaefc4..bc2c86c 100644
--- a/spi25.c
+++ b/spi25.c
@@ -1321,14 +1321,6 @@
 
 int spi_chip_write_1(struct flashchip *flash, uint8_t *buf)
 {
-	/* Erase first */
-	msg_cinfo("Erasing flash before programming... ");
-	if (erase_flash(flash)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
-	msg_cinfo("done.\n");
-
 	return spi_chip_write_1_new(flash, buf, 0, flash->total_size * 1024);
 }
 
@@ -1426,14 +1418,6 @@
 
 int spi_aai_write(struct flashchip *flash, uint8_t *buf)
 {
-	/* Erase first */
-	msg_cinfo("Erasing flash before programming... ");
-	if (erase_flash(flash)) {
-		msg_cerr("ERASE FAILED!\n");
-		return -1;
-	}
-	msg_cinfo("done.\n");
-
 	return spi_aai_write_new(flash, buf, 0, flash->total_size * 1024);
 }
 
diff --git a/sst28sf040.c b/sst28sf040.c
index c5f27a4..9ba0541 100644
--- a/sst28sf040.c
+++ b/sst28sf040.c
@@ -122,12 +122,6 @@
 
 	msg_cinfo("Programming page: ");
 	for (i = 0; i < total_size / page_size; i++) {
-		/* erase the page before programming */
-		if (erase_sector_28sf040(flash, i * page_size, page_size)) {
-			msg_cerr("ERASE FAILED!\n");
-			return -1;
-		}
-
 		/* write to the sector */
 		msg_cinfo("%04d at address: 0x%08x", i, i * page_size);
 		write_sector_28sf040(bios, buf + i * page_size,
diff --git a/sst49lfxxxc.c b/sst49lfxxxc.c
index 2f14b7a..f31e22c 100644
--- a/sst49lfxxxc.c
+++ b/sst49lfxxxc.c
@@ -86,11 +86,6 @@
 	write_lockbits_49lfxxxc(flash, 0);
 	msg_cinfo("Programming page: ");
 	for (i = 0; i < total_size / page_size; i++) {
-		/* erase the page before programming */
-		if (erase_sector_49lfxxxc(flash, i * page_size, flash->page_size)) {
-			msg_cerr("ERASE FAILED!\n");
-			return -1;
-		}
 
 		/* write to the sector */
 		msg_cinfo("%04d at address: 0x%08x", i, i * page_size);
diff --git a/stm50flw0x0x.c b/stm50flw0x0x.c
index 6a3b17d..dd6cbe7 100644
--- a/stm50flw0x0x.c
+++ b/stm50flw0x0x.c
@@ -93,6 +93,7 @@
 	return 0;
 }
 
+/* This function is unused. */
 int erase_sector_stm50flw0x0x(struct flashchip *flash, unsigned int sector, unsigned int sectorsize)
 {
 	chipaddr bios = flash->virtual_memory + sector;
@@ -116,6 +117,7 @@
 	return 0;
 }
 
+/* FIXME: This function is not a real chip erase function. */
 int erase_chip_stm50flw0x0x(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
 {
 	int i;