Add a bunch of new/tested stuff and various small changes 14

Tested Mainboards:
OK:
 - ASUS M3A78-EH
   http://www.flashrom.org/pipermail/flashrom/2010-October/005297.html
 - ASUS P2B-LS
   http://www.flashrom.org/pipermail/flashrom/2010-November/005506.html
 - Biostar TA790GX A3+
   http://paste.flashrom.org/view.php?id=1350
 - ECS 848P-A7
   http://www.flashrom.org/pipermail/flashrom/2011-January/005781.html
 - GIGABYTE GA-G41MT-S2PT
   Reported on IRC
 - GIGABYTE GA-H77-D3H
   Reported and tested by Alexander Gordeev on IRC.
 - Gigabyte GA-X79-UD5
   http://www.flashrom.org/pipermail/flashrom/2012-August/009811.html
 - Shuttle FN78S
   http://www.flashrom.org/pipermail/flashrom/2012-August/009714.html
 - VIA EITX-3000
   Reported on IRC by Tuju

NOT OK:
 - Dell PowerEdge C6220 (0HYFFG)
   http://www.flashrom.org/pipermail/flashrom/2012-September/009900.html
 - Foxconn Q45M
   http://www.flashrom.org/pipermail/flashrom/2012-September/009923.html
 - MSI MS-7309 (K9N6SGM-V)
   http://www.flashrom.org/pipermail/flashrom/2012-August/009712.html
 - Supermicro X9QRi-F+
   http://www.flashrom.org/pipermail/flashrom/2012-September/009887.html
 - ZOTAC H61-ITX WiFi (H61ITX-A-E)
   http://www.flashrom.org/pipermail/flashrom/2012-August/009649.html

ASUS CUSL2-C has been tested to be working with the board enable once
implemented for the TUSL2-C board. They seem to have the same PCI IDs
as shown in the links below. Since only the CUSL2-C board enable has been
tested yet, we distinguish the two by DMI strings.
http://paste.flashrom.org/view.php?id=1393
http://www.flashrom.org/pipermail/flashrom/attachments/20091206/ddca2c6c/attachment-0002.eml

Tested flash chips:
 - Set EMST F25L008A to PREW (+PREW)
   http://www.flashrom.org/pipermail/flashrom/2012-August/009714.html
 - Set GigaDevice GD25Q64 to PREW (+PREW)
   http://git.chromium.org/gitweb/?p=chromiumos/third_party/flashrom.git;a=commit;h=9e8ef49b1f626c2197e131fba6c5b65c8af4eeea
 - Set Macronix MX25L12805 to P (+P)
   http://www.flashrom.org/pipermail/flashrom/2012-September/009887.html
 - Set SST SST49LF003A/B to PREW (+EW)
   http://paste.flashrom.org/view.php?id=467
 - Set Winbond W49V002FA to PREW (+EW)
   http://www.flashrom.org/pipermail/flashrom/2011-January/005781.html

Tested chipsets:
 - Intel X79 (0x1d41)
   http://www.flashrom.org/pipermail/flashrom/2012-August/009811.html

Board enables:
 - add ASUS P4P800-X
   Created by Idwer Vollering and tested by Mingsen Bao:
   http://paste.flashrom.org/view.php?id=467
 - add DMI string to P4P800-VM

Miscellaneous:
 - Add remaining Intel 7 series chipset (LPC) PCI IDs
 - Add generic SPI detection for chips from Winbond
 - Minor manpage changes
 - Minor other cleanups
 - Escape full stops after abbreviations in the manpage.
 - Add ICH9 and successors to spi_get_valid_read_addr

Corresponding to flashrom svn r1601.

Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
diff --git a/board_enable.c b/board_enable.c
index b23ef8f..7f30180 100644
--- a/board_enable.c
+++ b/board_enable.c
@@ -346,7 +346,7 @@
 		case WINBOND_W83627HF_ID:
 		case WINBOND_W83627EHF_ID:
 		case WINBOND_W83627THF_ID:
-			msg_pdbg("Found Winbond Super I/O, id %02hx\n", s.model);
+			msg_pdbg("Found Winbond Super I/O, id 0x%02hx\n", s.model);
 			register_superio(s);
 			break;
 		case WINBOND_W83697HF_ID:
@@ -355,7 +355,7 @@
 			if (((tmp == 0x00) && (s.port != WINBOND_SUPERIO_PORT1)) ||
 			    ((tmp == 0x40) && (s.port != WINBOND_SUPERIO_PORT2))) {
 				msg_pdbg("Winbond Super I/O probe weirdness: Port mismatch for ID "
-					 "%02x at port %04x\n", s.model, s.port);
+					 "0x%02x at port 0x%04x\n", s.model, s.port);
 				break;
 			}
 			tmp = w836xx_deviceid_hwmon(s.port);
@@ -365,11 +365,11 @@
 				break;
 			}
 			if (tmp != s.model) {
-				msg_pinfo("W83 series hardware monitor device ID weirdness: expected %02x, "
-					  "got %02x\n", WINBOND_W83697HF_ID, tmp);
+				msg_pinfo("W83 series hardware monitor device ID weirdness: expected 0x%02x, "
+					  "got 0x%02x\n", WINBOND_W83697HF_ID, tmp);
 				break;
 			}
-			msg_pinfo("Found Winbond Super I/O, id %02hx\n", s.model);
+			msg_pinfo("Found Winbond Super I/O, id 0x%02hx\n", s.model);
 			register_superio(s);
 			break;
 		}
@@ -1700,11 +1700,13 @@
 
 /*
  * Suited for:
+ *  - ASUS CUSL2-C: Intel socket370 + 815 + ICH2
  *  - ASUS P4B266LM (Sony Vaio PCV-RX650): socket478 + 845D + ICH2
  *  - ASUS P4C800-E Deluxe: socket478 + 875P + ICH5
  *  - ASUS P4P800: Intel socket478 + 865PE + ICH5R
  *  - ASUS P4P800-E Deluxe: Intel socket478 + 865PE + ICH5R
  *  - ASUS P4P800-VM: Intel socket478 + 865PE + ICH5R
+ *  - ASUS P4P800-X: Intel socket478 + 865PE + ICH5R
  *  - ASUS P5GD1 Pro: Intel LGA 775 + 915P + ICH6R
  *  - ASUS P5GD2 Premium: Intel LGA775 + 915G + ICH6R
  *  - ASUS P5GDC Deluxe: Intel socket775 + 915P + ICH6R
@@ -2333,8 +2335,9 @@
 	{0x8086, 0x2560, 0x103C, 0x2A00,  0x8086, 0x24C3, 0x103C, 0x2A01, "^Guppy",     NULL, NULL,           P3, "ASUS",        "P4GV-LA (Guppy)",       0,   OK, intel_ich_gpio21_raise},
 	{0x8086, 0x24D3, 0x1043, 0x80A6,  0x8086, 0x2578, 0x1043, 0x80F6, NULL,         NULL, NULL,           P3, "ASUS",        "P4C800-E Deluxe",       0,   OK, intel_ich_gpio21_raise},
 	{0x8086, 0x2570, 0x1043, 0x80F2,  0x8086, 0x24D5, 0x1043, 0x80F3, NULL,         NULL, NULL,           P3, "ASUS",        "P4P800",                0,   NT, intel_ich_gpio21_raise},
-	{0x8086, 0x2570, 0x1043, 0x80F2,  0x8086, 0x24D3, 0x1043, 0x80A6, "^P4P800-E$", NULL, NULL,           P3, "ASUS",        "P4P800-E Deluxe",       0,   OK, intel_ich_gpio21_raise},
-	{0x8086, 0x2570, 0x1043, 0x80A5,  0x8086, 0x24d0,      0,      0, NULL,         NULL, NULL,           P3, "ASUS",        "P4P800-VM",             0,   OK, intel_ich_gpio21_raise},
+	{0x8086, 0x2570, 0x1043, 0x80f2,  0x8086, 0x24d3, 0x1043, 0x80a6, "^P4P800-E$", NULL, NULL,           P3, "ASUS",        "P4P800-E Deluxe",       0,   OK, intel_ich_gpio21_raise},
+	{0x8086, 0x2570, 0x1043, 0x80a5,  0x8086, 0x24d3, 0x1043, 0x80a6, "^P4P800-VM$", NULL, NULL,          P3, "ASUS",        "P4P800-VM",             0,   OK, intel_ich_gpio21_raise},
+	{0x8086, 0x2570, 0x1043, 0x80f2,  0x8086, 0x24d3, 0x1043, 0x80a6, "^P4P800-X$", NULL, NULL,           P3, "ASUS",        "P4P800-X",              0,   OK, intel_ich_gpio21_raise},
 	{0x1039, 0x0651, 0x1043, 0x8081,  0x1039, 0x0962,      0,      0, NULL,         NULL, NULL,           P3, "ASUS",        "P4SC-E",                0,   OK, it8707f_write_enable_2e},
 	{0x8086, 0x2570, 0x1043, 0x80A5,  0x105A, 0x24D3, 0x1043, 0x80A6, NULL,         NULL, NULL,           P3, "ASUS",        "P4SD-LA",               0,   NT, intel_ich_gpio32_raise},
 	{0x1039, 0x0661, 0x1043, 0x8113,  0x1039, 0x5513, 0x1043, 0x8087, NULL,         NULL, NULL,           P3, "ASUS",        "P4S800-MX",             512, OK, w836xx_memw_enable_2e},
@@ -2356,8 +2359,9 @@
 	{0x10DE, 0x0260, 0x1043, 0x81BC,  0x10DE, 0x026C, 0x1043, 0x829E, "^P5N-D$",    NULL, NULL,           P3, "ASUS",        "P5N-D",                 0,   OK, it8718f_gpio63_raise},
 	{0x10DE, 0x0260, 0x1043, 0x81BC,  0x10DE, 0x026C, 0x1043, 0x8249, "^P5N-E SLI$",NULL, NULL,           P3, "ASUS",        "P5N-E SLI",             0,   NT, it8718f_gpio63_raise},
 	{0x8086, 0x24dd, 0x1043, 0x80a6,  0x8086, 0x2570, 0x1043, 0x8157, NULL,         NULL, NULL,           P3, "ASUS",        "P5PE-VM",               0,   OK, intel_ich_gpio21_raise},
-	{0x8086, 0x2443, 0x1043, 0x8027,  0x8086, 0x1130, 0x1043, 0x8027, NULL,         NULL, NULL,           P3, "ASUS",        "TUSL2-C",               0,   NT, intel_ich_gpio21_raise},
-	{0x1106, 0x3177, 0x1106, 0x3177,  0x1106, 0x3116, 0x1106, 0x3116, "^KM266-8235$", "biostar", "m7viq",         P3, "Biostar",     "M7VIQ",                 0,   NT, w83697xx_memw_enable_2e},
+	{0x8086, 0x2443, 0x1043, 0x8027,  0x8086, 0x1130, 0x1043, 0x8027, "^CUSL2-C",   NULL, NULL,           P3, "ASUS",        "CUSL2-C",               0,   OK, intel_ich_gpio21_raise},
+	{0x8086, 0x2443, 0x1043, 0x8027,  0x8086, 0x1130, 0x1043, 0x8027, "^TUSL2-C",   NULL, NULL,           P3, "ASUS",        "TUSL2-C",               0,   NT, intel_ich_gpio21_raise},
+	{0x1106, 0x3177, 0x1106, 0x3177,  0x1106, 0x3116, 0x1106, 0x3116, "^KM266-8235$", "biostar", "m7viq", P3, "Biostar",     "M7VIQ",                 0,   NT, w83697xx_memw_enable_2e},
 	{0x10b7, 0x9055, 0x1028, 0x0082,  0x8086, 0x7190,      0,      0, NULL,         NULL, NULL,           P3, "Dell",        "OptiPlex GX1",          0,   OK, intel_piix4_gpo30_lower},
 	{0x8086, 0x3590, 0x1028, 0x016c,  0x1000, 0x0030, 0x1028, 0x016c, NULL,         NULL, NULL,           P3, "Dell",        "PowerEdge 1850",        0,   OK, intel_ich_gpio23_raise},
 	{0x1106, 0x3189, 0x1106, 0x3189,  0x1106, 0x3177, 0x1106, 0x3177, "^AD77",      "dfi", "ad77",        P3, "DFI",         "AD77",                  0,   NT, w836xx_memw_enable_2e},
diff --git a/chipdrivers.h b/chipdrivers.h
index b8af62a..ea6c35f 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -27,7 +27,12 @@
 
 #include "flash.h"	/* for chipaddr and flashctx */
 
-/* spi.c, should probably be in spi_chip.c */
+/* spi.c */
+int spi_aai_write(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
+int spi_chip_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
+int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len);
+
+/* spi25.c */
 int probe_spi_rdid(struct flashctx *flash);
 int probe_spi_rdid4(struct flashctx *flash);
 int probe_spi_rems(struct flashctx *flash);
@@ -44,8 +49,6 @@
 int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
 erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode);
 int spi_chip_write_1(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
-int spi_chip_write_256(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
-int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len);
 uint8_t spi_read_status_register(struct flashctx *flash);
 int spi_write_status_register(struct flashctx *flash, int status);
 void spi_prettyprint_status_register_bit(uint8_t status, int bit);
@@ -58,7 +61,6 @@
 int spi_nbyte_read(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len);
 int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize);
 int spi_write_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize);
-int spi_aai_write(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
 
 /* sfdp.c */
 int probe_spi_sfdp(struct flashctx *flash);
diff --git a/chipset_enable.c b/chipset_enable.c
index e1684f9..0873b4e 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -1405,17 +1405,22 @@
 	{0x8086, 0x1c56, NT, "Intel", "C206",		enable_flash_pch6},
 	{0x8086, 0x1c5c, OK, "Intel", "H61",		enable_flash_pch6},
 	{0x8086, 0x1d40, OK, "Intel", "X79",		enable_flash_pch6},
-	{0x8086, 0x1d41, NT, "Intel", "X79",		enable_flash_pch6},
+	{0x8086, 0x1d41, OK, "Intel", "X79",		enable_flash_pch6},
 	{0x8086, 0x1e44, NT, "Intel", "Z77",		enable_flash_pch7},
 	{0x8086, 0x1e46, NT, "Intel", "Z75",		enable_flash_pch7},
+	{0x8086, 0x1e47, NT, "Intel", "Q77",		enable_flash_pch7},
+	{0x8086, 0x1e48, NT, "Intel", "Q75",		enable_flash_pch7},
 	{0x8086, 0x1e49, NT, "Intel", "B75",		enable_flash_pch7},
 	{0x8086, 0x1e4a, NT, "Intel", "H77",		enable_flash_pch7},
+	{0x8086, 0x1e53, NT, "Intel", "C216",		enable_flash_pch7},
 	{0x8086, 0x1e55, OK, "Intel", "QM77",		enable_flash_pch7},
+	{0x8086, 0x1e56, NT, "Intel", "QS77",		enable_flash_pch7},
 	{0x8086, 0x1e57, NT, "Intel", "HM77",		enable_flash_pch7},
 	{0x8086, 0x1e58, NT, "Intel", "UM77",		enable_flash_pch7},
 	{0x8086, 0x1e59, NT, "Intel", "HM76",		enable_flash_pch7},
 	{0x8086, 0x1e5d, NT, "Intel", "HM75",		enable_flash_pch7},
 	{0x8086, 0x1e5e, NT, "Intel", "HM70",		enable_flash_pch7},
+	{0x8086, 0x1e5f, NT, "Intel", "NM70",		enable_flash_pch7},
 	{0x8086, 0x2310, NT, "Intel", "DH89xxCC",	enable_flash_pch7},
 	{0x8086, 0x2410, OK, "Intel", "ICH",		enable_flash_ich_4e},
 	{0x8086, 0x2420, OK, "Intel", "ICH0",		enable_flash_ich_4e},
diff --git a/flash.h b/flash.h
index 2990202..4913536 100644
--- a/flash.h
+++ b/flash.h
@@ -59,6 +59,21 @@
 };
 
 /*
+ * The following write granularities are known:
+ * - 1 bit: Each bit can be cleared individually.
+ * - 1 byte: A byte can be written once. Further writes to an already written byte cause its contents to be
+ *   either undefined or to stay unchanged.
+ * - 128 bytes: If less than 128 bytes are written, the rest will be erased. Each write to a 128-byte region
+ *   will trigger an automatic erase before anything is written. Very uncommon behaviour.
+ * - 256 bytes: If less than 256 bytes are written, the contents of the unwritten bytes are undefined.
+ */
+enum write_granularity {
+	write_gran_1bit,
+	write_gran_1byte,
+	write_gran_256bytes,
+};
+
+/*
  * How many different contiguous runs of erase blocks with one size each do
  * we have for a given erase function?
  */
@@ -203,11 +218,6 @@
 void print_supported_wiki(void);
 
 /* flashrom.c */
-enum write_granularity {
-	write_gran_1bit,
-	write_gran_1byte,
-	write_gran_256bytes,
-};
 extern int verbose_screen;
 extern int verbose_logfile;
 extern const char flashrom_version[];
diff --git a/flashchips.c b/flashchips.c
index c794afc..a6c2004 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -2596,7 +2596,7 @@
 		.total_size	= 1024,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EITHER,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -3474,7 +3474,7 @@
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
-		.voltage        = {2700, 3600},
+		.voltage	= {2700, 3600},
 	},
 
 	{
@@ -3509,7 +3509,7 @@
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
-		.voltage        = {2700, 3600},
+		.voltage	= {2700, 3600},
 	},
 
 	{
@@ -3585,7 +3585,7 @@
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
-		.voltage        = {2700, 3600},
+		.voltage	= {2700, 3600},
 	},
 
 	{
@@ -3620,7 +3620,7 @@
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
-		.voltage        = {2700, 3600},
+		.voltage	= {2700, 3600},
 	},
 
 	{
@@ -4014,7 +4014,7 @@
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
-		.voltage        = {2700, 3600},
+		.voltage	= {2700, 3600},
 	},
 
 	{
@@ -4051,7 +4051,7 @@
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
-		.voltage        = {2700, 3600},
+		.voltage	= {2700, 3600},
 	},
 
 	{
@@ -4178,7 +4178,7 @@
 		.page_size	= 256,
 		/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42 */
 		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -5032,7 +5032,7 @@
 		.total_size	= 16384,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PROBE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -7044,7 +7044,7 @@
 		.total_size	= 384,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PR,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_jedec,
 		.probe_timing	= 1,		/* 150 ns */
 		.block_erasers	=
@@ -8060,29 +8060,29 @@
 		.voltage	= {2700, 3600},
 	},
 
-        {
-                .vendor         = "ST",
-                .name           = "M29W512B",
+	{
+		.vendor		= "ST",
+		.name		= "M29W512B",
 		.bustype	= BUS_PARALLEL,
-                .manufacture_id = ST_ID,
-                .model_id       = ST_M29W512B,
-                .total_size     = 64,
-                .page_size      = 64 * 1024,
-                .feature_bits   = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+		.manufacture_id = ST_ID,
+		.model_id	= ST_M29W512B,
+		.total_size	= 64,
+		.page_size	= 64 * 1024,
+		.feature_bits	= FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
 		.tested		= TEST_OK_PRE,
-                .probe          = probe_jedec,
-                .probe_timing   = TIMING_ZERO,
-                .block_erasers  =
-                {
-                        {
-                                .eraseblocks = { {64 * 1024, 1} },
-                                .block_erase = erase_chip_block_jedec,
-                        }
-                },
-                .write          = write_jedec_1,
-                .read           = read_memmapped,
+		.probe		= probe_jedec,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {64 * 1024, 1} },
+				.block_erase = erase_chip_block_jedec,
+			}
+		},
+		.write		= write_jedec_1,
+		.read		= read_memmapped,
 		.voltage	= {2700, 3600},
-        },
+	},
 
 	{
 		.vendor		= "ST",
@@ -9476,7 +9476,7 @@
 		.total_size	= 256,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PR,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_jedec,
 		.probe_timing	= 10,
 		.block_erasers	=
@@ -9722,6 +9722,21 @@
 	},
 
 	{
+		.vendor		= "Winbond",
+		.name		= "unknown Winbond (ex Nexcom) SPI chip",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= WINBOND_NEX_ID,
+		.model_id	= GENERIC_DEVICE_ID,
+		.total_size	= 0,
+		.page_size	= 256,
+		.tested		= TEST_BAD_PREW,
+		.probe		= probe_spi_rdid,
+		.probe_timing	= TIMING_ZERO,
+		.write		= NULL,
+		.read		= NULL,
+	},
+
+	{
 		.vendor		= "Generic",
 		.name		= "unknown SPI chip (RDID)",
 		.bustype	= BUS_SPI,
diff --git a/flashrom.8 b/flashrom.8
index cf07ccf..2519a78 100644
--- a/flashrom.8
+++ b/flashrom.8
@@ -291,8 +291,9 @@
 .BR \-r )
 and store it to a medium outside of your computer, like
 a USB drive or a network share. If you needed to run the board enable code
-already for probing, use it for reading too. Now you can try to write the
-new image. You should enable the board enable code in any case now, as it
+already for probing, use it for reading too.
+If reading succeeds and the contens of the read file look legit you can try to write the new image.
+You should enable the board enable code in any case now, as it
 has been written because it is known that writing/erasing without the board
 enable is going to fail. In any case (success or failure), please report to
 the flashrom mailing list, see below.
@@ -326,7 +327,7 @@
 .B Intel chipsets
 .sp
 If you have an Intel chipset with an ICH8 or later southbridge with SPI flash
-attached, and if a valid descriptor was written to it (e.g. by the vendor), the
+attached, and if a valid descriptor was written to it (e.g.\& by the vendor), the
 chipset provides an alternative way to access the flash chip(s) named
 .BR "Hardware Sequencing" .
 It is much simpler than the normal access method (called
@@ -341,7 +342,7 @@
 .BR auto ", " swseq " or " hwseq .
 By default
 .RB "(or when setting " ich_spi_mode=auto )
-the module tries to use swseq and only activates hwseq if need be (e.g. if
+the module tries to use swseq and only activates hwseq if need be (e.g.\& if
 important opcodes are inaccessible due to lockdown; or if more than one flash
 chip is attached). The other options (swseq, hwseq) select the respective mode
 (if possible).
@@ -482,7 +483,7 @@
 .sp
 syntax where
 .B size
-is the number of bytes (min. 1, max. 256).
+is the number of bytes (min.\& 1, max.\& 256).
 .sp
 Example:
 .sp
@@ -498,7 +499,7 @@
 syntax where
 .B commandlist
 is a list of two-digit hexadecimal representations of
-SPI commands. If commandlist is e.g. 0302, flashrom will behave as if the SPI
+SPI commands. If commandlist is e.g.\& 0302, flashrom will behave as if the SPI
 controller refuses to run command 0x03 (READ) and command 0x02 (WRITE).
 commandlist may be up to 512 characters (256 commands) long.
 Implementation note: flashrom will detect an error during command execution.
@@ -514,7 +515,7 @@
 syntax where
 .B commandlist
 is a list of two-digit hexadecimal representations of
-SPI commands. If commandlist is e.g. 0302, the emulated flash chip will ignore
+SPI commands. If commandlist is e.g.\& 0302, the emulated flash chip will ignore
 command 0x03 (READ) and command 0x02 (WRITE).  commandlist may be up to 512
 characters (256 commands) long.
 Implementation note: flashrom won't detect an error during command execution.
@@ -723,7 +724,7 @@
 you want to use with the
 .B pci=
 parameter as explained in the
-.B nic3com
+.B nic3com et al.\& 
 section above.
 .sp
 More information about the hardware is available at
@@ -828,11 +829,11 @@
 IRC channel on
 .BR chat.freenode.net .
 You are welcome to join and ask questions, send us bug and success reports there
-too. Please provide a way to contact you later (e.g. a mail address) and be
+too. Please provide a way to contact you later (e.g.\& a mail address) and be
 patient if there is no immediate reaction. Also, we provide a pastebin service
 at
 .B http://paste.flashrom.org
-that is very useful when you want to share logs etc. without spamming the
+that is very useful when you want to share logs etc.\& without spamming the
 channel.
 .SS
 .B Laptops
@@ -853,7 +854,7 @@
 .sp
 Some flash chips contain OTP memory often denoted as "security registers".
 They usually have a capacity in the range of some bytes to a few hundred
-bytes and can be used to give devices unique IDs etc. flashrom is not able
+bytes and can be used to give devices unique IDs etc.  flashrom is not able
 to read or write these memories and may therefore not be able to duplicate a
 chip completely. For chip types known to include OTP memories a warning is
 printed when they are detected.
diff --git a/flashrom.c b/flashrom.c
index fdc5412..a887e3b 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -631,16 +631,6 @@
  * erasing. This is only possible if all chunks of size @gran are either kept
  * as-is or changed from an all-ones state to any other state.
  *
- * The following write granularities (enum @gran) are known:
- * - 1 bit. Each bit can be cleared individually.
- * - 1 byte. A byte can be written once. Further writes to an already written
- *   byte cause the contents to be either undefined or to stay unchanged.
- * - 128 bytes. If less than 128 bytes are written, the rest will be
- *   erased. Each write to a 128-byte region will trigger an automatic erase
- *   before anything is written. Very uncommon behaviour and unsupported by
- *   this function.
- * - 256 bytes. If less than 256 bytes are written, the contents of the
- *   unwritten bytes are undefined.
  * Warning: This function assumes that @have and @want point to naturally
  * aligned regions.
  *
diff --git a/ichspi.c b/ichspi.c
index ce9c553..8dd1893 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -1689,7 +1689,7 @@
 		}
 
 		tmp = mmio_readl(ich_spibar + ICH9_REG_FADDR);
-		msg_pdbg("0x08: 0x%08x (FADDR)\n", tmp);
+		msg_pdbg2("0x08: 0x%08x (FADDR)\n", tmp);
 
 		if (desc_valid) {
 			tmp = mmio_readl(ich_spibar + ICH9_REG_FRAP);
@@ -1704,6 +1704,7 @@
 				ich_spi_rw_restricted |= ich9_handle_frap(tmp, i);
 		}
 
+		/* Handle PR registers */
 		for (i = 0; i < 5; i++) {
 			/* if not locked down try to disable PR locks first */
 			if (!ichspi_lock)
diff --git a/internal.c b/internal.c
index 7b6cff2..d31808d 100644
--- a/internal.c
+++ b/internal.c
@@ -344,9 +344,6 @@
 		return 1;
 	}
 
-	/* Even if chipset init returns an error code, we don't want to abort.
-	 * The error code might have been a warning only.
-	 */
 #if defined(__i386__) || defined(__x86_64__) || defined (__mips)
 	register_par_programmer(&par_programmer_internal, internal_buses_supported);
 	return 0;
diff --git a/layout.c b/layout.c
index 2348f8a..1bd3152 100644
--- a/layout.c
+++ b/layout.c
@@ -78,7 +78,7 @@
 		tstr1 = strtok(tempstr, ":");
 		tstr2 = strtok(NULL, ":");
 		if (!tstr1 || !tstr2) {
-			msg_gerr("Error parsing layout file.\n");
+			msg_gerr("Error parsing layout file. Offending string: \"%s\"\n", tempstr);
 			fclose(romlayout);
 			return 1;
 		}
diff --git a/print.c b/print.c
index 2d97ea8..eb99c07 100644
--- a/print.c
+++ b/print.c
@@ -608,8 +608,8 @@
 	B("ASUS",	"A7N8X Deluxe",		OK, "http://www.asus.com/Motherboards/AMD_Socket_A/A7N8X_Deluxe/", NULL),
 	B("ASUS",	"A7N8X-E Deluxe",	OK, "http://www.asus.com/Motherboards/AMD_Socket_A/A7N8XE_Deluxe/", NULL),
 	B("ASUS",	"A7N8X-VM/400",		OK, "http://www.asus.com/Motherboards/AMD_Socket_A/A7N8XVM400/", NULL),
-	B("ASUS",	"A7V133",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/socka/kt133a/a7v133/", NULL),
-	B("ASUS",	"A7V333",		OK, "ftp://ftp.asus.com.tw/pub/asus/mb/socka/kt333/a7v333/", NULL),
+	B("ASUS",	"A7V133",		OK, NULL, NULL),
+	B("ASUS",	"A7V333",		OK, NULL, NULL),
 	B("ASUS",	"A7V400-MX",		OK, "http://www.asus.com/Motherboards/AMD_Socket_A/A7V400MX/", NULL),
 	B("ASUS",	"A7V600-X",		OK, "http://www.asus.com/Motherboards/AMD_Socket_A/A7V600X/", NULL),
 	B("ASUS",	"A7V8X",		OK, "http://www.asus.com/Motherboards/AMD_Socket_A/A7V8X/", NULL),
@@ -650,6 +650,7 @@
 	B("ASUS",	"M2V-MX",		OK, "http://www.asus.com/Motherboards/AMD_AM2/M2VMX/", NULL),
 	B("ASUS",	"M3A",			OK, "http://www.asus.com/Motherboards/AMD_AM2Plus/M3A/", NULL),
 	B("ASUS",	"M3A76-CM",		OK, "http://www.asus.com/Motherboards/AMD_AM2Plus/M3A76CM/", NULL),
+	B("ASUS",	"M3A78-EH",		OK, "http://www.asus.com/Motherboards/AMD_AM2Plus/M3A78EH/", NULL),
 	B("ASUS",	"M3A78-EM",		OK, "http://www.asus.com/Motherboards/AMD_AM2Plus/M3A78EM/", NULL),
 	B("ASUS",	"M3N78 PRO",		OK, "http://www.asus.com/Motherboards/AMD_AM2Plus/M3N78_PRO/", NULL),
 	B("ASUS",	"M3N78-VM",		OK, "http://www.asus.com/Motherboards/AMD_AM2Plus/M3N78VM/", NULL),
@@ -666,33 +667,35 @@
 	B("ASUS",	"M5A78L-M LX",		OK, "http://www.asus.com/Motherboards/AMD_AM3Plus/M5A78LM_LX/", "The MAC address of the onboard LAN NIC is stored in flash, hence overwritten by flashrom; see http://www.flashrom.org/pipermail/flashrom/2012-May/009200.html"),
 	B("ASUS",	"M5A99X EVO",		OK, "http://www.asus.com/Motherboards/AMD_AM3Plus/M5A99X_EVO/", NULL),
 	B("ASUS",	"Maximus IV Extreme",	BAD, "http://www.asus.com/Motherboards/Intel_Socket_1155/Maximus_IV_Extreme/", "Probing works (Macronix MX25L3205, 4096 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked."),
-	B("ASUS",	"MEW-AM",		BAD, "ftp://ftp.asus.com.tw/pub/ASUS/mb/sock370/810/mew-am/", "No public report found. Owned by Uwe Hermann <uwe@hermann-uwe.de>. May work now."),
+	B("ASUS",	"MEW-AM",		BAD, NULL, "No public report found. Owned by Uwe Hermann <uwe@hermann-uwe.de>. May work now."),
 	B("ASUS",	"MEW-VM",		BAD, "http://www.elhvb.com/mboards/OEM/HP/manual/ASUS%20MEW-VM.htm", "No public report found. Owned by Uwe Hermann <uwe@hermann-uwe.de>. May work now."),
 	B("ASUS",	"OPLX-M",		NT, NULL, "Untested board enable."),
-	B("ASUS",	"P2B",			OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p2b/", NULL),
-	B("ASUS",	"P2B-D",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p2b-d/", NULL),
-	B("ASUS",	"P2B-DS",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p2b-ds/", NULL),
-	B("ASUS",	"P2B-F",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p2b-d/", NULL),
-	B("ASUS",	"P2B-N",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p2b-n/", NULL),
-	B("ASUS",	"P2E-M",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440ex/p2e-m/", NULL),
-	B("ASUS",	"P2L97-S",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440lx/p2l97-s/", NULL),
-	B("ASUS",	"P3B-F",		BAD, "ftp://ftp.asus.com.tw/pub/ASUS/mb/slot1/440bx/p3b-f/", "No public report found. Owned by Uwe Hermann <uwe@hermann-uwe.de>. May work now."),
-	B("ASUS",	"P4B266",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/sock478/p4b266/", NULL),
+	B("ASUS",	"P2B",			OK, NULL, NULL),
+	B("ASUS",	"P2B-D",		OK, NULL, NULL),
+	B("ASUS",	"P2B-DS",		OK, NULL, NULL),
+	B("ASUS",	"P2B-F",		OK, NULL, NULL),
+	B("ASUS",	"P2B-LS",		OK, NULL, NULL),
+	B("ASUS",	"P2B-N",		OK, NULL, NULL),
+	B("ASUS",	"P2E-M",		OK, NULL, NULL),
+	B("ASUS",	"P2L97-S",		OK, NULL, NULL),
+	B("ASUS",	"P3B-F",		BAD, NULL, "No public report found. Owned by Uwe Hermann <uwe@hermann-uwe.de>. May work now."),
+	B("ASUS",	"P4B266",		OK, NULL, NULL),
 	B("ASUS",	"P4B266-LM",		OK, "http://esupport.sony.com/US/perl/swu-list.pl?mdl=PCVRX650", NULL),
-	B("ASUS",	"P4B533-E",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/sock478/p4b533-e/", NULL),
+	B("ASUS",	"P4B533-E",		OK, NULL, NULL),
 	B("ASUS",	"P4C800-E Deluxe",	OK, "http://www.asus.com/Motherboards/Intel_Socket_478/P4C800E_Deluxe/", NULL),
 	B("ASUS",	"P4GV-LA (Guppy)",	OK, "http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=c00363478", NULL),
 	B("ASUS",	"P4P800",		OK, "http://www.asus.com/Motherboards/Intel_Socket_478/P4P800/", NULL),
 	B("ASUS",	"P4P800-E Deluxe",	OK, "http://www.asus.com/Motherboards/Intel_Socket_478/P4P800E_Deluxe/", NULL),
 	B("ASUS",	"P4P800-VM",		OK, "http://www.asus.com/Motherboards/Intel_Socket_478/P4P800VM/", NULL),
-	B("ASUS",	"P4S533-X",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/sock478/p4s533-x/", NULL),
+	B("ASUS",	"P4P800-X",		OK, "http://www.asus.com/Motherboards/Intel_Socket_478/P4P800X/", NULL),
+	B("ASUS",	"P4S533-X",		OK, NULL, NULL),
 	B("ASUS",	"P4S800-MX",		OK, "http://www.asus.com/Motherboards/Intel_Socket_478/P4S800MX/", NULL),
-	B("ASUS",	"P4SC-E",		OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/sock478/p4sc-e/", "Part of ASUS Terminator P4 533 barebone system"),
+	B("ASUS",	"P4SC-E",		OK, NULL, "Part of ASUS Terminator P4 533 barebone system"),
 	B("ASUS",	"P4SD-LA",		OK, "http://h10025.www1.hp.com/ewfrf/wc/document?docname=c00022505", NULL),
-	B("ASUS",	"P5A",			OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/sock7/ali/p5a/", NULL),
-	B("ASUS",	"P5B",			OK, "ftp://ftp.asus.com.tw/pub/ASUS/mb/socket775/P5B/", NULL),
+	B("ASUS",	"P5A",			OK, NULL, NULL),
+	B("ASUS",	"P5B",			OK, NULL, NULL),
 	B("ASUS",	"P5B-Deluxe",		OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5B_Deluxe/", NULL),
-	B("ASUS",	"P5BV-M",		BAD, "ftp://ftp.asus.com.tw/pub/ASUS/mb/socket775/P5B-VM/", "Reported by Bernhard M. Wiedemann <bernhard@uml12d.zq1.de> to flashrom@coreboot.org, no public archive. Missing board enable and/or SST49LF008A unlocking. May work now."),
+	B("ASUS",	"P5BV-M",		BAD, NULL, "Reported by Bernhard M. Wiedemann <bernhard@uml12d.zq1.de> to flashrom@coreboot.org, no public archive. Missing board enable and/or SST49LF008A unlocking. May work now."),
 	B("ASUS",	"P5BV-R",		OK, "http://www.asus.com/Server_Workstation/Servers/RS120E5PA2/", "Used in RS120-E5/PA2 servers."),
 	B("ASUS",	"P5GC-MX/1333",		OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5GCMX1333/", NULL),
 	B("ASUS",	"P5GD1 Pro",		OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5GD1_PRO/", NULL),
@@ -714,7 +717,6 @@
 	B("ASUS",	"P5LP-LE (Lithium-UL8E)", OK, "http://h10025.www1.hp.com/ewfrf/wc/document?docname=c00379616&tmp_task=prodinfoCategory&cc=us&dlc=en&lc=en&product=1159887", "This is an OEM board from HP."),
 	B("ASUS",	"P5LP-LE (Epson OEM)",	OK, NULL, "This is an OEM board from Epson (e.g. Endeavor MT7700)."),
 	B("ASUS",	"P5LP-LE",		NT, NULL, "This designation is used for OEM boards from HP, Epson and maybe others. The HP names vary and not all of them have been tested yet. Please report any success or failure, thanks."),
-	B("ASUS",	"P5N-E SLI",		NT, "http://www.asus.com/Motherboards/Intel_Socket_775/P5NE_SLI/", "Untested board enable"),
 	B("ASUS",	"P5N-D",		OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5ND/", NULL),
 	B("ASUS",	"P5N-E SLI",		NT, "http://www.asus.com/Motherboards/Intel_Socket_775/P5NE_SLI/", "Untested board enable."),
 	B("ASUS",	"P5N32-E SLI",		OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5N32E_SLI/", NULL),
@@ -741,6 +743,7 @@
 	B("ASUS",	"P8Z68-V PRO",		BAD, NULL, "Probing works (Winbond W25Q64, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked."),
 	B("ASUS",	"P8Z68-V PRO/GEN3",	OK, "http://www.asus.com/Motherboards/Intel_Socket_1155/P8Z68V_PROGEN3/", "Warning: MAC address of LOM is stored at 0x1000 - 0x1005 of the image."),
 	B("ASUS",	"SABERTOOTH 990FX",	OK, "http://www.asus.com/Motherboards/AMD_AM3Plus/SABERTOOTH_990FX/", NULL),
+	B("ASUS",	"CUSL2-C",		OK, NULL, "The image provided by ASUS is only 256 kB big and has to be written to the upper 256 kB of the 512 kB chip."),
 	B("ASUS",	"TUSL2-C",		NT, "http://support.asus.com/download.aspx?SLanguage=en&p=1&s=4&m=TUSL2-C&os=&hashedid=n/a", "Untested board enable."),
 	B("ASUS",	"Z8NA-D6C",		OK, "http://www.asus.com/Server_Workstation/Server_Motherboards/Z8NAD6C/", NULL),
 	B("ASUS",	"Z8PE-D12",		OK, "http://www.asus.com/Server_Workstation/Server_Motherboards/Z8PED12/", NULL),
@@ -749,33 +752,36 @@
 	B("Bifferos",	"Bifferboard",		OK, "http://bifferos.co.uk/", NULL),
 	B("Biostar",	"H61MU3",		BAD, NULL, "Probing works (Eon EN25Q32(A/B), 4096 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked."),
 	B("Biostar",	"M6TBA",		BAD, "ftp://ftp.biostar-usa.com/manuals/M6TBA/", "No public report found. Owned by Uwe Hermann <uwe@hermann-uwe.de>. May work now."),
-	B("Biostar",	"M7NCD Pro",		OK, "http://www.biostar.com.tw/app/en/mb/content.php?S_ID=260", NULL),
+	B("Biostar",	"M7NCD Pro",		OK, "http://www.biostar.com.tw/app/en/mb/introduction.php?S_ID=260", NULL),
 	B("Biostar",	"M7VIQ",		NT, NULL, NULL),
 	B("Biostar",	"N61PB-M2S",		OK, NULL, NULL),
 	B("Biostar",	"N68S3+",		OK, NULL, NULL),
 	B("Biostar",	"P4M80-M4",		OK, "http://www.biostar-usa.com/mbdetails.asp?model=p4m80-m4", NULL),
-	B("Biostar",	"TA780G M2+",		OK, "http://www.biostar.com.tw/app/en/t-series/content.php?S_ID=344", NULL),
+	B("Biostar",	"TA780G M2+",		OK, "http://www.biostar.com.tw/app/en/mb/introduction.php?S_ID=344", NULL),
+	B("Biostar",	"TA790GX A3+",		OK, "http://www.biostar.com.tw/app/en/mb/introduction.php?S_ID=395", NULL),
 	B("Boser",	"HS-6637",		BAD, "http://www.boser.com.tw/manual/HS-62376637v3.4.pdf", "Reported by Mark Robinson <mark@zl2tod.net> to flashrom@coreboot.org, no public archive. Missing board enable and/or F29C51002T unlocking. May work now."),
 	B("Congatec",	"conga-X852",		OK, "http://www.congatec.com/single_news+M57715f6263d.html?&L=1", NULL),
 	B("Dell",	"Inspiron 580",		BAD, "http://support.dell.com/support/edocs/systems/insp580/en/index.htm", "Probing works (Macronix MX25L6405, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME is locked."),
 	B("Dell",	"OptiPlex GX1",		OK, "http://support.dell.com/support/edocs/systems/ban_gx1/en/index.htm", NULL),
 	B("Dell",	"PowerEdge 1850",	OK, "http://support.dell.com/support/edocs/systems/pe1850/en/index.htm", NULL),
+	B("Dell",	"PowerEdge C6220",	BAD, NULL, "Mainboard model is 0HYFFG. Probing works (Macronix MX25L6405, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME is locked (and there are even overlapping PRs)."),
 	B("Dell",	"Vostro 460",		BAD, "http://support.dell.com/support/edocs/systems/vos460/en/index.htm", "Mainboard model is 0Y2MRG. Probing works (Macronix MX25L3205, 4096 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME is locked."),
 	B("DFI",	"855GME-MGF",		BAD, "http://www.dfi.com.tw/portal/CM/cmproduct/XX_cmproddetail/XX_WbProdsWindow?action=e&downloadType=&windowstate=normal&mode=view&downloadFlag=false&itemId=433", "Probably needs a board enable. http://www.coreboot.org/pipermail/coreboot/2009-May/048549.html"),
 	B("DFI",	"AD77",			NT, NULL, "Untested board enable."),
 	B("DFI",	"Blood-Iron P35 T2RL",	OK, "http://lp.lanparty.com.tw/portal/CM/cmproduct/XX_cmproddetail/XX_WbProdsWindow?itemId=516&downloadFlag=false&action=1", NULL),
-	B("Elitegroup",	"GeForce6100SM-M ",	OK, "http://www.ecs.com.tw/ECSWebSite/Product/Product_Detail.aspx?DetailID=685&MenuID=24", NULL),
-	B("Elitegroup", "GF7100PVT-M3 (V1.0)",	OK, "http://www.ecs.com.tw/ECSWebSite/Product/Product_Detail.aspx?DetailID=853&CategoryID=1&DetailName=Specification&MenuID=24&LanID=0", NULL),
-	B("Elitegroup", "GF8200A",		OK, "http://www.ecs.com.tw/ECSWebSite/Product/Product_Detail.aspx?DetailID=873&CategoryID=1&MenuID=20&LanID=0", NULL),
-	B("Elitegroup",	"K7S5A",		OK, "http://www.ecs.com.tw/ECSWebSite/Products/ProductsDetail.aspx?detailid=279&CategoryID=1&DetailName=Specification&MenuID=1&LanID=0", NULL),
-	B("Elitegroup",	"K7S6A",		OK, "http://www.ecs.com.tw/ECSWebSite/Products/ProductsDetail.aspx?detailid=77&CategoryID=1&DetailName=Specification&MenuID=52&LanID=0", NULL),
-	B("Elitegroup", "K7SEM (V1.0A)",	OK, "http://www.ecs.com.tw/ECSWebSite/Product/Product_Detail.aspx?DetailID=229&CategoryID=1&DetailName=Specification&MenuID=24&LanID=0", NULL),
-	B("Elitegroup",	"K7VTA3",		OK, "http://www.ecs.com.tw/ECSWebSite/Products/ProductsDetail.aspx?detailid=264&CategoryID=1&DetailName=Specification&MenuID=52&LanID=0", NULL),
-	B("Elitegroup",	"P4M800PRO-M (V1.0A, V2.0)", OK, "http://www.ecs.com.tw/ECSWebSite_2007/Products/ProductsDetail.aspx?CategoryID=1&DetailID=574&DetailName=Feature&MenuID=52&LanID=0", NULL),
+	B("Elitegroup",	"848P-A7",		OK, NULL, NULL),
+	B("Elitegroup",	"GeForce6100SM-M",	OK, NULL, NULL),
+	B("Elitegroup", "GF7100PVT-M3 (V1.0)",	OK, NULL, NULL),
+	B("Elitegroup", "GF8200A",		OK, NULL, NULL),
+	B("Elitegroup",	"K7S5A",		OK, NULL, NULL),
+	B("Elitegroup",	"K7S6A",		OK, NULL, NULL),
+	B("Elitegroup", "K7SEM (V1.0A)",	OK, NULL, NULL),
+	B("Elitegroup",	"K7VTA3",		OK, NULL, NULL),
+	B("Elitegroup",	"P4M800PRO-M (V1.0A, V2.0)", OK, NULL, NULL),
 	B("Elitegroup", "P4VXMS (V1.0A)",	OK, NULL, NULL),
-	B("Elitegroup",	"P6IWP-Fe",		OK, "http://www.ecs.com.tw/ECSWebSite_2007/Products/ProductsDetail.aspx?CategoryID=1&TypeID=3&DetailID=95&DetailName=Feature&MenuID=1&LanID=0", NULL),
-	B("Elitegroup",	"P6VAP-A+",		OK, "http://www.ecs.com.tw/ECSWebSite/Products/ProductsDetail.aspx?detailid=117&CategoryID=1&DetailName=Specification&MenuID=1&LanID=0", NULL),
-	B("Elitegroup", "RS485M-M",		OK, "http://www.ecs.com.tw/ECSWebSite_2007/Products/ProductsDetail.aspx?CategoryID=1&DetailID=654&DetailName=Feature&MenuID=1&LanID=0", NULL),
+	B("Elitegroup",	"P6IWP-Fe",		OK, NULL, NULL),
+	B("Elitegroup",	"P6VAP-A+",		OK, NULL, NULL),
+	B("Elitegroup", "RS485M-M",		OK, NULL, NULL),
 	B("Emerson",	"ATCA-7360",		OK, "http://www.emerson.com/sites/Network_Power/en-US/Products/Product_Detail/Product1/Pages/EmbCompATCA-7360.aspx", NULL),
 	B("EPoX",	"EP-3PTA",		BAD, NULL, "Missing board enable (W83627HF/F/HG/G), see http://www.flashrom.org/pipermail/flashrom/2012-April/009043.html"),
 	B("EPoX",	"EP-8K5A2",		OK, "http://www.epox.com/product.asp?ID=EP-8K5A2", NULL),
@@ -786,10 +792,11 @@
 	B("EVGA",	"132-CK-NF78",		OK, "http://www.evga.com/articles/385.asp", NULL),
 	B("EVGA",	"270-WS-W555-A2 (Classified SR-2)", OK, "http://www.evga.com/products/moreInfo.asp?pn=270-WS-W555-A2", NULL),
 	B("FIC",	"VA-502",		BAD, "ftp://ftp.fic.com.tw/motherboard/manual/socket7/va-502/", "No public report found. Owned by Uwe Hermann <uwe@hermann-uwe.de>. Seems the PCI subsystem IDs are identical with the Tekram P6Pro-A5. May work now."),
-	B("Foxconn",	"6150K8MD-8EKRSH",	OK, "http://www.foxconnchannel.com/product/motherboards/detail_overview.aspx?id=en-us0000157", NULL),
-	B("Foxconn",	"A6VMX",		OK, "http://www.foxconnchannel.com/product/motherboards/detail_overview.aspx?id=en-us0000346", NULL),
-	B("Foxconn",	"P4M800P7MA-RS2",	OK, "http://www.foxconnchannel.com/Product/Motherboards/detail_overview.aspx?id=en-us0000138", NULL),
+	B("Foxconn",	"6150K8MD-8EKRSH",	OK, "http://www.foxconnchannel.com/ProductDetail.aspx?T=Motherboard&U=en-us0000157", NULL),
+	B("Foxconn",	"A6VMX",		OK, "http://www.foxconnchannel.com/ProductDetail.aspx?T=Motherboard&U=en-us0000346", NULL),
+	B("Foxconn",	"P4M800P7MA-RS2",	OK, "http://www.foxconnchannel.com/ProductDetail.aspx?T=Motherboard&U=en-us0000138", NULL),
 	B("Freetech",	"P6F91i",		OK, "http://web.archive.org/web/20010417035034/http://www.freetech.com/prod/P6F91i.html", NULL),
+	B("Foxconn",	"Q45M",			BAD, "http://www.foxconnchannel.com/ProductDetail.aspx?T=Motherboard&U=en-us0000587", "Probing works (Hardware sequencing, 4096 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME is locked."),
 	B("Fujitsu-Siemens", "ESPRIMO P5915",	OK, "http://uk.ts.fujitsu.com/rl/servicesupport/techsupport/professionalpc/ESPRIMO/P/EsprimoP5915-6.htm", "Mainboard model is D2312-A2."),
 	B("Fujitsu-Siemens", "CELSIUS W410",	BAD, "ftp://ftp.ts.fujitsu.com/pub/mainboard-oem-sales/Products/Mainboards/Industrial&ExtendedLifetime/D3061&D3062/", "Mainboard model is D3062-A1. Probing works (Macronix MX25L6405, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME is locked."),
 	B("GIGABYTE",	"GA-2761GXDK",		OK, "http://www.computerbase.de/news/hardware/mainboards/amd-systeme/2007/mai/gigabyte_dtx-mainboard/", NULL),
@@ -814,8 +821,10 @@
 	B("GIGABYTE",	"GA-965P-DS4",		OK, "http://www.gigabyte.com/products/product-page.aspx?pid=2288", NULL),
 	B("GIGABYTE",	"GA-EP31-DS3L (rev. 2.1)", OK, "http://www.gigabyte.com/products/product-page.aspx?pid=2964", NULL),
 	B("GIGABYTE",	"GA-EP35-DS3L",		OK, "http://www.gigabyte.com/products/product-page.aspx?pid=2778", NULL),
+	B("GIGABYTE",	"GA-G41MT-S2PT",	OK, "http://www.gigabyte.com/products/product-page.aspx?pid=3960", NULL),
 	B("GIGABYTE",	"GA-H61M-D2-B3",	OK, "http://www.gigabyte.com/products/product-page.aspx?pid=3773", NULL),
 	B("GIGABYTE",	"GA-H61M-D2H-USB3",	OK, "http://www.gigabyte.com/products/product-page.aspx?pid=4004", NULL),
+	B("GIGABYTE",	"GA-H77-D3H",		OK, "http://www.gigabyte.com/products/product-page.aspx?pid=4141", "Does only work with -p internal:ich_spi_mode=hwseq due to an evil twin of MX25L6405 and ICH SPI lockdown."),
 	B("GIGABYTE",	"GA-EX58-UD4P",		OK, "http://www.gigabyte.com/products/product-page.aspx?pid=2986", NULL),
 	B("GIGABYTE",	"GA-K8N-SLI",		OK, "http://www.gigabyte.com/products/product-page.aspx?pid=1928", NULL),
 	B("GIGABYTE",	"GA-K8N51GMF",		OK, "http://www.gigabyte.com/products/product-page.aspx?pid=1950", NULL),
@@ -839,6 +848,7 @@
 	B("GIGABYTE",	"GA-P67A-UD3P",		OK, "http://www.gigabyte.com/products/product-page.aspx?pid=3649", NULL),
 	B("GIGABYTE",	"GA-X58A-UD7 (rev. 2.0)", OK, NULL, NULL),
 	B("GIGABYTE",	"GA-X58A-UDR3 (rev. 2.0)", OK, NULL, NULL),
+	B("GIGABYTE",	"GA-X79-UD5", OK, NULL, NULL),
 	B("GIGABYTE",	"GA-Z68MX-UD2H-B (rev. 1.3)", OK, "http://www.gigabyte.com/products/product-page.aspx?pid=3854", NULL),
 	B("GIGABYTE",	"GA-Z68XP-UD3 (rev. 1.0)", OK, "http://www.gigabyte.com/products/product-page.aspx?pid=3892", NULL),
 	B("HP",		"8100 Elite CMT PC (304Bh)", BAD, NULL, "SPI lock down, PR, read-only descriptor, locked ME region."),
@@ -909,6 +919,7 @@
 	B("MSI",	"MS-7253 (K9VGM-V)",	OK, "http://www.msi.com/product/mb/K9VGM-V.html", NULL),
 	B("MSI",	"MS-7255 (P4M890M)",	OK, "http://www.msi.com/product/mb/P4M890M-L-IL.html", NULL),
 	B("MSI",	"MS-7260 (K9N Neo PCB 1.0)", BAD, "http://www.msi.com/product/mb/K9N-Neo--PCB-1-0-.html", "Interestingly flashrom does not work when the vendor BIOS is booted, but it ''does'' work flawlessly when the machine is booted with coreboot. Owned by Uwe Hermann <uwe@hermann-uwe.de>."),
+	B("MSI",	"MS-7309 (K9N6SGM-V)", BAD, "http://www.msi.com/product/mb/K9N6SGM-V---K9N6PGM-FI---K9N6PGM-F.html", "Uses Fintek F71882F/F71883F/F71887 SPI-to-LPC translation."),
 	B("MSI",	"MS-7309 (K9N6PGM2-V2)", OK, "http://www.msi.com/product/mb/K9N6PGM2-V2.html", NULL),
 	B("MSI",	"MS-7312 (K9MM-V)",	OK, "http://www.msi.com/product/mb/K9MM-V.html", NULL),
 	B("MSI",	"MS-7345 (P35 Neo2-FIR)", OK, "http://www.msi.com/product/mb/P35-Neo2-FR---FIR.html", NULL),
@@ -953,6 +964,7 @@
 	B("Shuttle",	"FD37",			OK, "http://www.shuttle.eu/products/discontinued/barebones/sd37p2/", NULL),
 	B("Shuttle",	"FH67",			OK, "http://www.shuttle.eu/products/mini-pc/sh67h3/specification/", NULL),
 	B("Shuttle",	"FN25",			OK, "http://www.shuttle.eu/products/discontinued/barebones/sn25p/?0=", NULL),
+	B("Shuttle",	"FN78S",		OK, "http://www.shuttle.eu/products/discontinued/barebones/sn78sh7/", NULL),
 	B("Shuttle",	"X50/X50(B)",		OK, "http://au.shuttle.com/product_detail_spec.jsp?PI=1241", NULL),
 	B("Soyo",	"SY-5VD",		BAD, "http://www.soyo.com/content/Downloads/163/&c=80&p=464&l=English", "No public report found. Owned by Uwe Hermann <uwe@hermann-uwe.de>. May work now."),
 	B("Soyo",	"SY-6BA+ III",		OK, "http://www.motherboard.cz/mb/soyo/SY-6BA+III.htm", NULL),
@@ -977,6 +989,7 @@
 	B("Supermicro",	"X8SIE(-F)",		BAD, "http://www.supermicro.com/products/motherboard/Xeon3000/3400/X8SIE.cfm?IPMI=N&TYP=LN2", "Requires unlocking the ME although the registers are set up correctly by the descriptor/BIOS already (tested with swseq and hwseq)."),
 	B("Supermicro",	"X8STi",		OK, "http://www.supermicro.com/products/motherboard/Xeon3000/X58/X8STi.cfm", NULL),
 	B("Supermicro",	"X9DR3-F",		BAD, "http://www.supermicro.com/products/motherboard/xeon/c600/x9dr3-f.cfm", "Probing works (Numonyx N25Q128 (supported by SFDP only atm), 16384 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked."),
+	B("Supermicro",	"X9QRi-F+",		BAD, "http://www.supermicro.com/products/motherboard/Xeon/C600/X9QRi-F_.cfm", "Probing works (Macronix MX25L12805, 16384 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked; SMM protection enabled."),
 	B("Supermicro",	"X9SCA-F",		BAD, "http://www.supermicro.com/products/motherboard/Xeon/C202_C204/X9SCA-F.cfm", "Probing works (Winbond W25Q64, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked."),
 	B("Supermicro",	"X9SCL",		BAD, "http://www.supermicro.com/products/motherboard/Xeon/C202_C204/X9SCL.cfm", "Probing works (Winbond W25Q64, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked."),
 	B("T-Online",	"S-100",		OK, "http://wiki.freifunk-hannover.de/T-Online_S_100", NULL),
@@ -1014,6 +1027,7 @@
 	B("Tyan",	"S5377 (Tempest i5100T)", OK, "http://www.tyan.com/product_SKU_spec.aspx?ProductType=MB&pid=642&SKU=600000017", NULL),
 	B("Tyan",	"S5382 (Tempest i5000PW)", OK, "http://www.tyan.com/product_board_detail.aspx?pid=439", NULL),
 	B("Tyan",	"S5397 (Tempest i5400PW)", OK, "http://www.tyan.com/product_board_detail.aspx?pid=560", NULL),
+	B("VIA",	"EITX-3000",		OK, "http://www.viaembedded.com/en/products/boards/810/1/EITX-3000.html", NULL),
 	B("VIA",	"EPIA M/MII/...",	OK, "http://www.via.com.tw/en/products/embedded/ProductDetail.jsp?productLine=1&motherboard_id=202", NULL), /* EPIA-MII link for now */
 	B("VIA",	"EPIA SP",		OK, "http://www.via.com.tw/en/products/embedded/ProductDetail.jsp?productLine=1&motherboard_id=261", NULL),
 	B("VIA",	"EPIA-CN",		OK, "http://www.via.com.tw/en/products/mainboards/motherboards.jsp?motherboard_id=400", NULL),
@@ -1029,6 +1043,7 @@
 	B("VIA",	"VB700X",		OK, "http://www.via.com.tw/en/products/mainboards/motherboards.jsp?motherboard_id=490", NULL),
 	B("ZOTAC",	"Fusion-ITX WiFi (FUSION350-A-E)", OK, NULL, NULL),
 	B("ZOTAC",	"GeForce 8200",		OK, NULL, NULL),
+	B("ZOTAC",	"H61-ITX WiFi (H61ITX-A-E)", BAD, NULL, "Probing works (Winbond W25Q32, 4096 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked."),
 	B("ZOTAC",	"H67-ITX WiFi (H67ITX-C-E)", BAD, NULL, "Probing works (Winbond W25Q32, 4096 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked."),
 	B("ZOTAC",	"nForce 630i Supreme (N73U-Supreme)", OK, NULL, NULL),
 	B("ZOTAC",	"ZBOX AD02 (PLUS)",	OK, NULL, NULL),
diff --git a/spi.c b/spi.c
index 732f4c5..94a76a7 100644
--- a/spi.c
+++ b/spi.c
@@ -152,6 +152,7 @@
 #if CONFIG_INTERNAL == 1
 #if defined(__i386__) || defined(__x86_64__)
 	case SPI_CONTROLLER_ICH7:
+	case SPI_CONTROLLER_ICH9:
 		/* Return BBAR for ICH chipsets. */
 		return ichspi_bbar;
 #endif