diff --git a/chipdrivers.h b/chipdrivers.h
index e7261e0..496aa7e 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -34,14 +34,15 @@ 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_chip_erase_60_c7(struct flashchip *flash);
 int spi_chip_erase_d8(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);
 int spi_block_erase_d8(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
 int spi_block_erase_60(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
 int spi_block_erase_c7(struct flashchip *flash, unsigned int addr, unsigned int blocklen);
 int spi_chip_write_1(struct flashchip *flash, uint8_t *buf);
 int spi_chip_write_256(struct flashchip *flash, uint8_t *buf);
 int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 uint8_t spi_read_status_register(void);
diff --git a/flashchips.c b/flashchips.c
index 8e90d2a..a702870 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -2955,15 +2955,28 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M25PE10,
 		.total_size	= 128,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_d8,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 32} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 2} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {128 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "Numonyx",
 		.name		= "M25PE20",
@@ -2971,31 +2984,57 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M25PE20,
 		.total_size	= 256,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_d8,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 64} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 4} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {256 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "Numonyx",
 		.name		= "M25PE40",
 		.bustype	= CHIP_BUSTYPE_SPI,
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M25PE40,
-		.total_size	= 256,
+		.total_size	= 512,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_d8,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 128} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 8} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {512 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "Numonyx",
 		.name		= "M25PE80",
@@ -3003,15 +3042,28 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M25PE80,
 		.total_size	= 1024,
 		.page_size	= 256,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_d8,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 256} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 16} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "Numonyx",
 		.name		= "M25PE16",
@@ -3019,15 +3071,28 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= ST_ID,
 		.model_id	= ST_M25PE16,
 		.total_size	= 2048,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_d8,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 512} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 32} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {2 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm25LV010",
@@ -3035,15 +3100,28 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= PMC_ID,
 		.model_id	= PMC_25LV010,
 		.total_size	= 128,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_c7,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 32} },
+				.block_erase = spi_block_erase_d7,
+			}, {
+				.eraseblocks = { {32 * 1024, 4} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {128 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm25LV016B",
@@ -3051,15 +3129,34 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= PMC_ID,
 		.model_id	= PMC_25LV016B,
 		.total_size	= 2048,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_c7,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 512} },
+				.block_erase = spi_block_erase_d7,
+			}, {
+				.eraseblocks = { {4 * 1024, 512} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 32} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {2 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_60,
+			}, {
+				.eraseblocks = { {2 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm25LV020",
@@ -3067,15 +3164,28 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= PMC_ID,
 		.model_id	= PMC_25LV020,
 		.total_size	= 256,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_c7,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 64} },
+				.block_erase = spi_block_erase_d7,
+			}, {
+				.eraseblocks = { {64 * 1024, 4} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {256 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm25LV040",
@@ -3083,15 +3193,28 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= PMC_ID,
 		.model_id	= PMC_25LV040,
 		.total_size	= 512,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_c7,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 128} },
+				.block_erase = spi_block_erase_d7,
+			}, {
+				.eraseblocks = { {64 * 1024, 8} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {512 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm25LV080B",
@@ -3099,15 +3222,34 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= PMC_ID,
 		.model_id	= PMC_25LV080B,
 		.total_size	= 1024,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_c7,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 256} },
+				.block_erase = spi_block_erase_d7,
+			}, {
+				.eraseblocks = { {4 * 1024, 256} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 16} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {1024 * 1024, 1} },
+				.block_erase = spi_block_erase_60,
+			}, {
+				.eraseblocks = { {1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm25LV512",
@@ -3115,15 +3257,28 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= PMC_ID,
 		.model_id	= PMC_25LV512,
 		.total_size	= 64,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_c7,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 16} },
+				.block_erase = spi_block_erase_d7,
+			}, {
+				.eraseblocks = { {32 * 1024, 2} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {64 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm29F002T",
@@ -3190,52 +3345,91 @@ struct flashchip flashchips[] = {
 		.vendor		= "PMC",
 		.name		= "Pm39LV010",
 		.bustype	= CHIP_BUSTYPE_PARALLEL,
 		.manufacture_id	= PMC_ID_NOPREFIX,
 		.model_id	= PMC_39F010,
 		.total_size	= 128,
 		.page_size	= 4096,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
-		.erase		= erase_chip_jedec,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 32} },
+				.block_erase = erase_sector_jedec,
+			}, {
+				.eraseblocks = { {64 * 1024, 2} },
+				.block_erase = erase_block_jedec,
+			}, {
+				.eraseblocks = { {128 * 1024, 1} },
+				.block_erase = erase_chip_block_jedec,
+			}
+		},
 		.write		= write_49f002,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm49FL002",
 		.bustype	= CHIP_BUSTYPE_LPC|CHIP_BUSTYPE_FWH, /* A/A Mux*/
 		.manufacture_id	= PMC_ID_NOPREFIX,
 		.model_id	= PMC_49FL002,
 		.total_size	= 256,
 		.page_size	= 16 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* routine is wrapper to probe_jedec (pm49fl00x.c) */
-		.erase		= erase_49fl00x,
+		.erase		= NULL, /* Was: erase_49fl00x */
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 64} },
+				.block_erase = erase_sector_jedec,
+			}, {
+				.eraseblocks = { {16 * 1024, 16} },
+				.block_erase = erase_block_jedec,
+			}, {
+				.eraseblocks = { {256 * 1024, 1} },
+				.block_erase = erase_chip_block_jedec,
+			}
+		},
 		.write		= write_49fl00x,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "PMC",
 		.name		= "Pm49FL004",
 		.bustype	= CHIP_BUSTYPE_LPC|CHIP_BUSTYPE_FWH, /* A/A Mux*/
 		.manufacture_id	= PMC_ID_NOPREFIX,
 		.model_id	= PMC_49FL004,
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,	/* routine is wrapper to probe_jedec (pm49fl00x.c) */
-		.erase		= erase_49fl00x,
+		.erase		= NULL, /* Was: erase_49fl00x */
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 128} },
+				.block_erase = erase_sector_jedec,
+			}, {
+				.eraseblocks = { {64 * 1024, 8} },
+				.block_erase = erase_block_jedec,
+			}, {
+				.eraseblocks = { {512 * 1024, 1} },
+				.block_erase = erase_chip_block_jedec,
+			}
+		},
 		.write		= write_49fl00x,
 		.read		= read_memmapped,
 	},
 
 	{
 		.vendor		= "Sanyo",
 		.name		= "LF25FW203A",
@@ -3243,15 +3437,25 @@ struct flashchip flashchips[] = {
 		.manufacture_id	= SANYO_ID,
 		.model_id	= SANYO_LE25FW203A,
 		.total_size	= 2048,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_c7,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {64 * 1024, 32} },
+				.block_erase = spi_block_erase_d8,
+			},	{
+				.eraseblocks = { {2 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "Sharp",
 		.name		= "LHF00L04",
@@ -3313,18 +3517,28 @@ struct flashchip flashchips[] = {
 		.vendor		= "Spansion",
 		.name		= "S25FL016A",
 		.bustype	= CHIP_BUSTYPE_SPI,
 		.manufacture_id	= SPANSION_ID,
 		.model_id	= SPANSION_S25FL016A,
 		.total_size	= 2048,
 		.page_size	= 256,
-		.tested		= TEST_OK_PREW,
+		.tested		= TEST_OK_PRW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.erase		= spi_chip_erase_c7,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {64 * 1024, 32} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
 
 	{
 		.vendor		= "SST",
 		.name		= "SST25VF016B",
diff --git a/spi.c b/spi.c
index 952952f..685c917 100644
--- a/spi.c
+++ b/spi.c
@@ -697,14 +697,56 @@ int spi_block_erase_d8(struct flashchip *flash, unsigned int addr, unsigned int
 	if (check_erased_range(flash, addr, blocklen)) {
 		fprintf(stderr, "ERASE FAILED!\n");
 		return -1;
 	}
 	return 0;
 }
 
+/* Block size is usually
+ * 4k for PMC
+ */
+int spi_block_erase_d7(struct flashchip *flash, unsigned int addr, unsigned int blocklen)
+{
+	int result;
+	struct spi_command cmds[] = {
+	{
+		.writecnt	= JEDEC_WREN_OUTSIZE,
+		.writearr	= (const unsigned char[]){ JEDEC_WREN },
+		.readcnt	= 0,
+		.readarr	= NULL,
+	}, {
+		.writecnt	= JEDEC_BE_D7_OUTSIZE,
+		.writearr	= (const unsigned char[]){ JEDEC_BE_D7, (addr >> 16) & 0xff, (addr >> 8) & 0xff, (addr & 0xff) },
+		.readcnt	= 0,
+		.readarr	= NULL,
+	}, {
+		.writecnt	= 0,
+		.writearr	= NULL,
+		.readcnt	= 0,
+		.readarr	= NULL,
+	}};
+
+	result = spi_send_multicommand(cmds);
+	if (result) {
+		fprintf(stderr, "%s failed during command execution at address 0x%x\n",
+			__func__, addr);
+		return result;
+	}
+	/* Wait until the Write-In-Progress bit is cleared.
+	 * This usually takes 100-4000 ms, so wait in 100 ms steps.
+	 */
+	while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
+		programmer_delay(100 * 1000);
+	if (check_erased_range(flash, addr, blocklen)) {
+		fprintf(stderr, "ERASE FAILED!\n");
+		return -1;
+	}
+	return 0;
+}
+
 int spi_chip_erase_d8(struct flashchip *flash)
 {
 	int i, rc = 0;
 	int total_size = flash->total_size * 1024;
 	int erase_size = 64 * 1024;
 
 	spi_disable_blockprotect();
diff --git a/spi.h b/spi.h
index 2fa7dcd..1b49d59 100644
--- a/spi.h
+++ b/spi.h
@@ -70,14 +70,19 @@
 #define JEDEC_BE_52_INSIZE	0x00
 
 /* Block Erase 0xd8 is supported by EON/Macronix chips. */
 #define JEDEC_BE_D8		0xd8
 #define JEDEC_BE_D8_OUTSIZE	0x04
 #define JEDEC_BE_D8_INSIZE	0x00
 
+/* Block Erase 0xd7 is supported by PMC chips. */
+#define JEDEC_BE_D7		0xd7
+#define JEDEC_BE_D7_OUTSIZE	0x04
+#define JEDEC_BE_D7_INSIZE	0x00
+
 /* Sector Erase 0x20 is supported by Macronix/SST chips. */
 #define JEDEC_SE		0x20
 #define JEDEC_SE_OUTSIZE	0x04
 #define JEDEC_SE_INSIZE		0x00
 
 /* Read Status Register */
 #define JEDEC_RDSR		0x05
