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

Tested mainboards:
OK:
 - ASUS C60M1-I
   http://www.flashrom.org/pipermail/flashrom/2013-February/010578.html
 - ASUS P8H77-I
   http://www.flashrom.org/pipermail/flashrom/2013-March/010607.html
 - ASUS P8H77-M
   http://www.flashrom.org/pipermail/flashrom/2013-May/010994.html
 - ASUS P8P67 LE (B2)
   http://www.flashrom.org/pipermail/flashrom/2013-May/010972.html
 - Elitegroup GeForce6100PM-M2 (V3.0)
   http://www.flashrom.org/pipermail/flashrom/2013-July/011177.html
 - GIGABYTE GA-P55A-UD7
   http://www.flashrom.org/pipermail/flashrom/2013-July/011302.html
 - MSI B75MA-E33 (MS-7808)
   http://www.flashrom.org/pipermail/flashrom/2013-March/010659.html
 - MSI H77MA-G43 (MS-7756)
   http://www.flashrom.org/pipermail/flashrom/2013-April/010853.html
 - MSI KA780G (MS-7551)
   http://paste.flashrom.org/view.php?id=1617
 - SAPPHIRE IPC-E350M1
   Reported by xvilka on IRC
 - Supermicro X8DTG-D
   http://www.flashrom.org/pipermail/flashrom/2013-July/011305.html
NOT OK:
 - ASRock Fatal1ty Z77 Performance
   http://www.flashrom.org/pipermail/flashrom/2013-January/010467.html
 - ASRock Z68 Extreme4
   http://www.flashrom.org/pipermail/flashrom/2013-May/010984.html
 - ASUS P8B75-M LE
   http://www.flashrom.org/pipermail/flashrom/2013-April/010867.html
 - ASUS P8P67-M PRO
   http://www.flashrom.org/pipermail/flashrom/2013-February/010541.html
 - ASUS P8Z68-V LE
   http://www.flashrom.org/pipermail/flashrom/2013-February/010582.html
 - Intel DQ77MK
   http://paste.flashrom.org/view.php?id=1603
 - Supermicro X9DRD-7LN4F
   http://paste.flashrom.org/view.php?id=1582
 - Supermicro X9SCE-F
   http://www.flashrom.org/pipermail/flashrom/2013-February/010588.html
 - Supermicro X9SCM-F
   http://www.flashrom.org/pipermail/flashrom/2013-February/010527.html
 - Tyan S7066
   http://www.flashrom.org/pipermail/flashrom/2013-March/010630.html

Chipsets:
 - Marked Intel B75 as tested
   http://www.flashrom.org/pipermail/flashrom/2013-March/010659.html
 - Marked Intel H77 as tested
   http://www.flashrom.org/pipermail/flashrom/2013-March/010607.html
 - Removed 10de:03e2 because it is apparently the MCP61 host bridge.
   It was reclassified to Host Bridge in the PCI device ID database and there
   is at least one report suggesting this configuration too:
   http://www.flashrom.org/pipermail/flashrom/2012-August/009716.html
 - Added MCP89 which hopefully works with the code for previous versions.
   Thanks to James Laird for submitting this change.

Tested flash chips:
 - Atmel AT25DF641(A) to PREW (+PREW)
   http://www.flashrom.org/pipermail/flashrom/2013-June/011113.html
 - Atmel AT25F512 to PREW (+PREW)
   http://www.flashrom.org/pipermail/flashrom/2013-April/010904.html
   Also, change its ID according to Modification of PCN SC040401A:
   "There has been a change in the returned value of the Product Identification
   (RDID) command, the AT25F512A RDID code is 65h compared to 60h from
   the AT25F512 product."
   It seems to be quite likely that all AT25F512 are fully functional relabeled
   AT25F1024 chips. There are even some hints in the datasheet:
   in table 6 they stress that address pin 16 needs to be low under all circum-
   stances; while continuous reads can wrap around on the AT25F1024 the DS
   notes "For the AT25F512, the read command must be terminated when the
   highest address (00FFFF) is reached." OTOH the lock bit semantics are
   different, but this has not been tested thoroughly
 - Atmel AT25F512A to PREW (+PREW)
   http://paste.flashrom.org/view.php?id=1569
 - Eon EN25F05 to PREW (+PREW)
   http://paste.flashrom.org/view.php?id=1571
 - Macronix MX25L12805(D) to PREW (+REW)
   http://www.flashrom.org/pipermail/flashrom/2013-April/010913.html
 - Spansion S25FL256S......0 and S25FL512S to P/!R!E!W (+P)
   Tested by Stefan Tauner
 - Micron/Numonyx/ST M25PX80 to PREW (+PREW)
   Tested by Stefan Tauner
 - Micron/Numonyx/ST N25Q032..3E and N25Q128..3E to PREW (+PREW)
   Tested by Stefan Tauner
 - Micron/Numonyx/ST N25Q256..3E and N25Q512..3G to P/!R!E!W (+P)
   Tested by Stefan Tauner
 - SST SST25VF040B to PREW (+PREW)
   http://paste.flashrom.org/view.php?id=1574
 - SST SST25VF040B.REMS to PREW (+EW)
   http://paste.flashrom.org/view.php?id=1575
 - ST M25P05-A to PREW (+PREW)
   http://paste.flashrom.org/view.php?id=1576
 - ST M29W512B to PREW (+W)
   http://www.flashrom.org/pipermail/flashrom/2013-March/010635.html
 - Winbond W25Q64.W to PREW (+PREW)
   Tested by the chromiumos guys.
 - Winbond W25Q128.V to PREW (+REW)
   http://www.flashrom.org/pipermail/flashrom/2013-June/011108.html
 - Winbond W25X20 to PREW (+PREW)
   http://www.flashrom.org/pipermail/flashrom/2013-May/010990.html

Miscellaneous:
 - Add Lenovo X201 to the laptop whitelist.
 - Add chip IDs for the ESMT F25L..QA family.
 - Add chip IDs for a few Macronix MX25 models.
 - The list of flashchips is not sorted strictly alphabetically and should not be
   either. Refine the comment explaining the scheme on top of the list.
 - Support -L output of chip sizes with up to 6 decimal places (up to 4 Gb).
 - Use z length modifier in (more) prints for size_t types.
 - Remove chips >16MB again because our current implementation of memory mapping
   the flash chip violates common rules by mapping a window as large as the chip.
   This leads to failing mmaps as can be seen here:
   http://paste.flashrom.org/view.php?id=1695
 - Document spispeed parameter of linux_spi (and fix some leaks).
 - Rephrase the "multiple chips detected" message because it was confusing.
 - Skip verification step if the image is equal to the flash contents.
 - Tiny other stuff.

Corresponding to flashrom svn r1702.

Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
diff --git a/board_enable.c b/board_enable.c
index a4de790..a565c15 100644
--- a/board_enable.c
+++ b/board_enable.c
@@ -2415,6 +2415,7 @@
 	{0x8086, 0x27a0, 0x17aa, 0x2015,  0x8086, 0x27b9, 0x17aa, 0x2009, "^ThinkPad T60", NULL, NULL,        P2, "Lenovo",      "T60",                   0,   OK, p2_whitelist_laptop},
 	{0x8086, 0x27a0, 0x17aa, 0x2017,  0x8086, 0x27b9, 0x17aa, 0x2009, "^ThinkPad T60", NULL, NULL,        P2, "Lenovo",      "T60(s)",                0,   OK, p2_whitelist_laptop},
 	{0x8086, 0x27a0, 0x17aa, 0x2017,  0x8086, 0x27b9, 0x17aa, 0x2009, "^ThinkPad X60", NULL, NULL,        P2, "Lenovo",      "X60(s)",                0,   OK, p2_whitelist_laptop},
+	{0x8086, 0x3B07, 0x17AA, 0x2166,  0x8086, 0x3B30, 0x17AA, 0x2167, "^Lenovo X201", NULL, NULL,         P2, "Lenovo",      "X201",                  0,   OK, p2_whitelist_laptop},
 	{0x8086, 0x2411, 0x8086, 0x2411,  0x8086, 0x7125, 0x0e11, 0xb165, NULL,         NULL, NULL,           P3, "Mitac",       "6513WU",                0,   OK, board_mitac_6513wu},
 	{0x8086, 0x8186, 0x8086, 0x8186,  0x8086, 0x8800,      0,      0, "^MSC Vertriebs GmbH$", NULL, NULL, P2, "MSC",         "Q7-TCTC",               0,   OK, p2_not_a_laptop},
 	{0x10DE, 0x005E, 0x1462, 0x7125,  0x10DE, 0x0052, 0x1462, 0x7125, NULL,         NULL, NULL,           P3, "MSI",         "K8N Neo4-F",            0,   OK, nvidia_mcp_gpio2_raise}, /* TODO: Should probably be K8N Neo4 Platinum, see http://www.coreboot.org/pipermail/flashrom/2010-August/004362.html. */
diff --git a/chipset_enable.c b/chipset_enable.c
index 3979347..b52a5b4 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -1366,7 +1366,6 @@
 	{0x10de, 0x0367, OK, "NVIDIA", "MCP55",		enable_flash_mcp55}, /* Pro */
 	{0x10de, 0x03e0, OK, "NVIDIA", "MCP61",		enable_flash_mcp6x_7x},
 	{0x10de, 0x03e1, OK, "NVIDIA", "MCP61",		enable_flash_mcp6x_7x},
-	{0x10de, 0x03e2, NT, "NVIDIA", "MCP61",		enable_flash_mcp6x_7x},
 	{0x10de, 0x03e3, NT, "NVIDIA", "MCP61",		enable_flash_mcp6x_7x},
 	{0x10de, 0x0440, NT, "NVIDIA", "MCP65",		enable_flash_mcp6x_7x},
 	{0x10de, 0x0441, NT, "NVIDIA", "MCP65",		enable_flash_mcp6x_7x},
@@ -1380,6 +1379,7 @@
 	{0x10de, 0x0aad, NT, "NVIDIA", "MCP79",		enable_flash_mcp6x_7x},
 	{0x10de, 0x0aae, NT, "NVIDIA", "MCP79",		enable_flash_mcp6x_7x},
 	{0x10de, 0x0aaf, NT, "NVIDIA", "MCP79",		enable_flash_mcp6x_7x},
+	{0x10de, 0x0d80, NT, "NVIDIA", "MCP89",		enable_flash_mcp6x_7x},
 	/* VIA northbridges */
 	{0x1106, 0x0585, NT, "VIA", "VT82C585VPX",	via_no_byte_merge},
 	{0x1106, 0x0595, NT, "VIA", "VT82C595",		via_no_byte_merge},
@@ -1428,8 +1428,8 @@
 	{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, 0x1e49, OK, "Intel", "B75",		enable_flash_pch7},
+	{0x8086, 0x1e4a, OK, "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},
diff --git a/cli_classic.c b/cli_classic.c
index 14fb825..089cf03 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -435,10 +435,11 @@
 	}
 
 	if (chipcount > 1) {
-		msg_cinfo("Multiple flash chips were detected: \"%s\"", flashes[0].chip->name);
+		msg_cinfo("Multiple flash chip definitions match the detected chip(s): \"%s\"",
+			  flashes[0].chip->name);
 		for (i = 1; i < chipcount; i++)
 			msg_cinfo(", \"%s\"", flashes[i].chip->name);
-		msg_cinfo("\nPlease specify which chip to use with the -c <chipname> option.\n");
+		msg_cinfo("\nPlease specify which chip definition to use with the -c <chipname> option.\n");
 		ret = 1;
 		goto out_shutdown;
 	} else if (!chipcount) {
diff --git a/cli_output.c b/cli_output.c
index 476b2bf..c9cce73 100644
--- a/cli_output.c
+++ b/cli_output.c
@@ -46,7 +46,7 @@
 int open_logfile(const char * const filename)
 {
 	if (!filename) {
-		msg_gerr("No filename specified.\n");
+		msg_gerr("No logfile name specified.\n");
 		return 1;
 	}
 	if ((logfile = fopen(filename, "w")) == NULL) {
diff --git a/dummyflasher.c b/dummyflasher.c
index cc15b00..9c0d868 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -414,15 +414,14 @@
 
 void *dummy_map(const char *descr, uintptr_t phys_addr, size_t len)
 {
-	msg_pspew("%s: Mapping %s, 0x%lx bytes at 0x%*" PRIxPTR "\n",
-		  __func__, descr, (unsigned long)len, PRIxPTR_WIDTH, phys_addr);
+	msg_pspew("%s: Mapping %s, 0x%zx bytes at 0x%*" PRIxPTR "\n",
+		  __func__, descr, len, PRIxPTR_WIDTH, phys_addr);
 	return (void *)phys_addr;
 }
 
 void dummy_unmap(void *virt_addr, size_t len)
 {
-	msg_pspew("%s: Unmapping 0x%lx bytes at %p\n",
-		  __func__, (unsigned long)len, virt_addr);
+	msg_pspew("%s: Unmapping 0x%zx bytes at %p\n", __func__, len, virt_addr);
 }
 
 static void dummy_chip_writeb(const struct flashctx *flash, uint8_t val,
@@ -447,8 +446,7 @@
 			      chipaddr addr, size_t len)
 {
 	size_t i;
-	msg_pspew("%s: addr=0x%" PRIxPTR ", len=0x%08lx, writing data (hex):",
-		  __func__, addr, (unsigned long)len);
+	msg_pspew("%s: addr=0x%" PRIxPTR ", len=0x%zx, writing data (hex):", __func__, addr, len);
 	for (i = 0; i < len; i++) {
 		if ((i % 16) == 0)
 			msg_pspew("\n");
@@ -480,8 +478,7 @@
 static void dummy_chip_readn(const struct flashctx *flash, uint8_t *buf,
 			     const chipaddr addr, size_t len)
 {
-	msg_pspew("%s:  addr=0x%" PRIxPTR ", len=0x%lx, returning array of 0xff\n",
-		  __func__, addr, (unsigned long)len);
+	msg_pspew("%s:  addr=0x%" PRIxPTR ", len=0x%zx, returning array of 0xff\n", __func__, addr, len);
 	memset(buf, 0xff, len);
 	return;
 }
diff --git a/flash.h b/flash.h
index cba7bd8..63701ed 100644
--- a/flash.h
+++ b/flash.h
@@ -93,6 +93,7 @@
  */
 #define NUM_ERASEFUNCTIONS 6
 
+/* Feature bits used for non-SPI only */
 #define FEATURE_REGISTERMAP	(1 << 0)
 #define FEATURE_BYTEWRITES	(1 << 1)
 #define FEATURE_LONG_RESET	(0 << 4)
@@ -104,11 +105,12 @@
 #define FEATURE_ADDR_2AA	(1 << 2)
 #define FEATURE_ADDR_AAA	(2 << 2)
 #define FEATURE_ADDR_SHIFTED	(1 << 5)
+/* Feature bits used for SPI only */
 #define FEATURE_WRSR_EWSR	(1 << 6)
 #define FEATURE_WRSR_WREN	(1 << 7)
+#define FEATURE_WRSR_EITHER	(FEATURE_WRSR_EWSR | FEATURE_WRSR_WREN)
 #define FEATURE_OTP		(1 << 8)
 #define FEATURE_QPI		(1 << 9)
-#define FEATURE_WRSR_EITHER	(FEATURE_WRSR_EWSR | FEATURE_WRSR_WREN)
 
 struct flashctx;
 typedef int (erasefunc_t)(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
diff --git a/flashchips.c b/flashchips.c
index a3d4345..1b6a22e 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -29,8 +29,8 @@
 /**
  * List of supported flash chips.
  *
- * Please keep the list sorted by vendor name and chip name, so that
- * the output of 'flashrom -L' is alphabetically sorted.
+ * Please keep the list sorted by vendor name and chip family, so that the output of 'flashrom -L' is roughly
+ * alphabetically sorted. Within families keep them in order of density.
  */
 const struct flashchip flashchips[] = {
 
@@ -1297,7 +1297,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{16 * 1024, 1},
 					{8 * 1024, 2},
 					{32 * 1024, 1},
@@ -1329,7 +1329,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{64 * 1024, 3},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
@@ -1678,7 +1678,7 @@
 		.total_size	= 8192,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -1755,7 +1755,7 @@
 		.total_size	= 64,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_at25f,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -1784,7 +1784,7 @@
 		.total_size	= 64,
 		.page_size	= 128,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_at25f,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -2809,7 +2809,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{128 * 1024, 1},
 					{96 * 1024, 1},
 					{8 * 1024, 2},
@@ -3426,7 +3426,7 @@
 		.total_size	= 64,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -4503,7 +4503,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{16 * 1024, 1},
 					{8 * 1024, 2},
 					{32 * 1024, 1},
@@ -4535,7 +4535,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{64 * 1024, 7},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
@@ -4568,7 +4568,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{16 * 1024, 1},
 					{8 * 1024, 2},
 					{32 * 1024, 1},
@@ -4600,7 +4600,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{64 * 1024, 7},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
@@ -5375,7 +5375,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{8 * 1024, 1},
 					{4 * 1024, 2},
 					{112 * 1024, 1},
@@ -5479,7 +5479,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{16 * 1024, 1},
 					{8 * 1024, 2},
 					{96 * 1024, 1},
@@ -5506,7 +5506,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{128 * 1024, 3},
 					{96 * 1024, 1},
 					{8 * 1024, 2},
@@ -5534,7 +5534,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{16 * 1024, 1},
 					{8 * 1024, 2},
 					{96 * 1024, 1},
@@ -5562,7 +5562,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{128 * 1024, 3},
 					{96 * 1024, 1},
 					{8 * 1024, 2},
@@ -6263,7 +6263,7 @@
 		.page_size	= 256,
 		/* MX25L12805D has 64B of OTP; enter 0xB1, exit 0xC1 */
 		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
-		.tested		= TEST_OK_PROBE,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -6429,7 +6429,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{8 * 1024, 1},
 					{4 * 1024, 2},
 					{8 * 1024, 2},
@@ -6462,7 +6462,7 @@
 		.block_erasers	=
 		{
 			{
-				.eraseblocks = { 
+				.eraseblocks = {
 					{64 * 1024, 1},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
@@ -7360,7 +7360,7 @@
 		/* supports SFDP */
 		/* OTP: 64B total; read 0x4B, 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	=
@@ -7495,7 +7495,7 @@
 		/* supports SFDP */
 		/* OTP: 64B total; read 0x4B, 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	= {
@@ -7561,7 +7561,7 @@
 		/* supports SFDP */
 		/* OTP: 64B total; read 0x4B, write 0x42 */
 		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
-		.tested		= TEST_BAD_REW,
+		.tested		= TEST_OK_PROBE | TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	= {
@@ -7621,7 +7621,7 @@
 
 	{
 		.vendor		= "Numonyx",
-		.name		= "N25Q512..3E", /* ..3E = 3V, uniform 64KB/4KB blocks/sectors */
+		.name		= "N25Q512..3G", /* ..3G = 3V, uniform 64KB/4KB blocks/sectors */
 		.bustype	= BUS_SPI,
 		.manufacture_id = ST_ID,
 		.model_id	= ST_N25Q512__3E,
@@ -7630,7 +7630,7 @@
 		/* supports SFDP */
 		/* OTP: 64B total; read 0x4B, write 0x42 */
 		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
-		.tested		= TEST_BAD_REW,
+		.tested		= TEST_OK_PROBE | TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	= {
@@ -8874,7 +8874,7 @@
 		/* supports 4B addressing */
 		/* OTP: 1024B total, 32B reserved; read 0x4B; write 0x42 */
 		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
-		.tested		= TEST_BAD_REW,
+		.tested		= TEST_OK_PROBE | TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	= {
@@ -8911,7 +8911,7 @@
 		/* supports SFDP */
 		/* OTP: 1024B total, 32B reserved; read 0x4B; write 0x42 */
 		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
-		.tested		= TEST_BAD_REW,
+		.tested		= TEST_OK_PROBE | TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	= {
@@ -9184,7 +9184,7 @@
 		.total_size	= 512,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EWSR,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -9222,7 +9222,7 @@
 		.total_size	= 512,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EWSR,
-		.tested		= TEST_OK_PR,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rems,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -9470,7 +9470,7 @@
 		.feature_bits	= FEATURE_LONG_RESET,
 		.tested		= TEST_OK_PR,
 		.probe		= probe_jedec,
-		.probe_timing	= 10, 
+		.probe_timing	= 10,
 		.block_erasers	=
 		{
 			{
@@ -9494,7 +9494,7 @@
 		.feature_bits	= FEATURE_LONG_RESET,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
-		.probe_timing	= 10, 
+		.probe_timing	= 10,
 		.block_erasers	=
 		{
 			{
@@ -9542,7 +9542,7 @@
 		.feature_bits	= FEATURE_LONG_RESET,
 		.tested		= TEST_OK_PRE,
 		.probe		= probe_jedec,
-		.probe_timing	= 10, 
+		.probe_timing	= 10,
 		.block_erasers	=
 		{
 			{
@@ -9918,7 +9918,7 @@
 				.eraseblocks = { {4 * 1024, 128} },
 				.block_erase = erase_sector_49lfxxxc,
 			}, {
-				.eraseblocks = { 
+				.eraseblocks = {
 					{64 * 1024, 7},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
@@ -9983,7 +9983,7 @@
 				.eraseblocks = { {4 * 1024, 256} },
 				.block_erase = erase_sector_49lfxxxc,
 			}, {
-				.eraseblocks = { 
+				.eraseblocks = {
 					{64 * 1024, 15},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
@@ -10016,7 +10016,7 @@
 				.eraseblocks = { {4 * 1024, 512} },
 				.block_erase = erase_sector_49lfxxxc,
 			}, {
-				.eraseblocks = { 
+				.eraseblocks = {
 					{64 * 1024, 31},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
@@ -10163,7 +10163,7 @@
 		.feature_bits	= FEATURE_EITHER_RESET,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_jedec,
-		.probe_timing	= TIMING_FIXME, 
+		.probe_timing	= TIMING_FIXME,
 		.block_erasers	=
 		{
 			{
@@ -10200,7 +10200,7 @@
 				.eraseblocks = { {4 * 1024, 512} },
 				.block_erase = erase_sector_49lfxxxc,
 			}, {
-				.eraseblocks = { 
+				.eraseblocks = {
 					{64 * 1024, 31},
 					{32 * 1024, 1},
 					{8 * 1024, 2},
@@ -10224,7 +10224,7 @@
 		.total_size	= 64,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -10607,7 +10607,7 @@
 		.page_size	= 256,
 		/* OTP: 64B total; read 0x4B, 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	= {
@@ -10945,7 +10945,7 @@
 		.total_size	= 64,
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
-		.tested		= TEST_OK_PRE,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_jedec,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -11677,7 +11677,7 @@
 		/* supports SFDP */
 		/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
 		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
-		.tested		= TEST_OK_PROBE,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -11914,7 +11914,7 @@
 		/* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
 		/* QPI enable 0x38, disable 0xFF */
 		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -11984,7 +11984,7 @@
 		.total_size	= 256,
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_OK_PREW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -12266,7 +12266,7 @@
 		.feature_bits	= FEATURE_LONG_RESET,
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_jedec,
-		.probe_timing	= 10, 
+		.probe_timing	= 10,
 		.block_erasers	=
 		{
 			{
@@ -12524,7 +12524,7 @@
 		.feature_bits	= FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
 		.tested		= TEST_OK_PREW,
 		.probe		= probe_jedec,
-		.probe_timing	= 10, 
+		.probe_timing	= 10,
 		.block_erasers	=
 		{
 			{
diff --git a/flashchips.h b/flashchips.h
index bf22986..e19d200 100644
--- a/flashchips.h
+++ b/flashchips.h
@@ -141,7 +141,7 @@
 #define ATMEL_AT25DL161		0x4603	/* EDI 0x0100 */
 #define ATMEL_AT25DQ161		0x8600	/* EDI 0x0100 */
 #define ATMEL_AT25DQ321		0x8700	/* EDI 0x0100 */
-#define ATMEL_AT25F512		0x65	/* guessed, no device ID in datasheet. Needs AT25F_RDID */
+#define ATMEL_AT25F512		0x60	/* Needs AT25F_RDID. ID from PCN and actual HW. Seems to be a relabeled AT25F1024. */
 #define ATMEL_AT25F512A		0x65	/* Needs AT25F_RDID */
 #define ATMEL_AT25F512B		0x6500
 #define ATMEL_AT25F1024		0x60	/* Needs AT25F_RDID */
@@ -208,6 +208,11 @@
 #define ESMT_ID			0x8C	/* Elite Semiconductor Memory Technology (ESMT) / EFST Elite Flash Storage */
 #define ESMT_F25L008A		0x2014
 #define ESMT_F25D08QA		0x2534
+#define ESMT_F25L16QA2S		0x4015
+#define ESMT_F25L32QA		0x4016
+#define ESMT_F25L32QA2S		0x4116
+#define ESMT_F25L64QA		0x4117
+#define ESMT_F25L128QA		0x4118
 #define ESMT_F49B002UA		0x00
 
 /*
@@ -271,6 +276,8 @@
 #define EON_EN25S16		0x3815
 #define EON_EN25S32		0x3816
 #define EON_EN25S64		0x3817
+#define EON_EN25T80		0x5114
+#define EON_EN25T16		0x5115
 #define EON_EN29F512		0x7F21
 #define EON_EN29F010		0x20
 #define EON_EN29F040A		0x7F04
@@ -280,6 +287,12 @@
 #define EON_EN29F002T		0x7F92	/* Same as EN29F002A */
 #define EON_EN29F002B		0x7F97	/* Same as EN29F002AN */
 
+#define EXCEL_ID		0x7F7F7F7F4A	/* Excel Semiconductor Inc. (ESI) resides in bank 5 */
+#define EXCEL_ID_NOPREFIX	0x4A	/* ESI, missing 0x7F prefix */
+#define EXCEL_ES25P40		0x2013
+#define EXCEL_ES25P80		0x2014
+#define EXCEL_ES25P16		0x2015
+
 #define FIDELIX_ID		0xF8	/* Fidelix */
 #define FIDELIX_FM25M16		0x4215
 #define FIDELIX_FM25M32		0x4216
@@ -423,11 +436,14 @@
 #define MACRONIX_MX25L3205	0x2016	/* MX25L3205, MX25L3205A (64k 0x20); MX25L3205D/MX25L3208D (4k 0x20); MX25L3206E (4k 0x20, 64k 0x52) */
 #define MACRONIX_MX25L6405	0x2017	/* MX25L6405, MX25L6405D (64k 0x20); MX25L6406E/MX25L6436E (4k 0x20); MX25L6445E (4k 0x20, 64k 0x52) */
 #define MACRONIX_MX25L12805	0x2018	/* Same as MX25L12805D */
+#define MACRONIX_MX25L25635F	0x2019	/* Same as MX25L25639F, but the latter seems to not support REMS */
 #define MACRONIX_MX25L1635D	0x2415
 #define MACRONIX_MX25L1635E	0x2515	/* MX25L1635{E} */
 #define MACRONIX_MX25U1635E	0x2535
 #define MACRONIX_MX25U3235E	0x2536	/* Same as MX25U6435F */
 #define MACRONIX_MX25U6435E	0x2537	/* Same as MX25U6435F */
+#define MACRONIX_MX25U12835E	0x2538	/* Same as MX25U12835F */
+#define MACRONIX_MX25U25635F	0x2539
 #define MACRONIX_MX25L3235D	0x5E16	/* MX25L3225D/MX25L3235D/MX25L3237D */
 #define MACRONIX_MX29F001B	0x19
 #define MACRONIX_MX29F001T	0x18
diff --git a/flashrom.8 b/flashrom.8
index 4e6ab55..b8fd391 100644
--- a/flashrom.8
+++ b/flashrom.8
@@ -1,4 +1,4 @@
-.TH FLASHROM 8 "Dec, 2012"
+.TH FLASHROM 8 "Jul, 2013"
 .SH NAME
 flashrom \- detect, read, write, verify and erase flash chips
 .SH SYNOPSIS
@@ -590,7 +590,9 @@
 is the serial number of the device (which can be found for example in the output of lsusb -v).
 .sp
 All models supported by the ft2232_spi driver can configure the SPI clock rate by setting a divisor. The
-expressible divisors are all even numbers between 2 and 2^17 (=131072) resulting in SPI clock frequencies of
+expressible divisors are all
+.B even
+numbers between 2 and 2^17 (=131072) resulting in SPI clock frequencies of
 6 MHz down to about 92 Hz for 12 MHz inputs. The default divisor is set to 2, but you can use another one by
 specifying the optional
 .B divisor
@@ -615,12 +617,12 @@
 instead. In case the device supports it, you can set the SPI clock frequency
 with the optional
 .B spispeed
-parameter. The frequency is parsed as Hertz, unless an
+parameter. The frequency is parsed as hertz, unless an
 .BR M ", or " k
 suffix is given, then megahertz or kilohertz are used respectively.
 Example that sets the frequency to 2 MHz:
 .sp
-.B "flashrom \-p serprog:dev=/dev/device:baud,spispeed=2M"
+.B "  flashrom \-p serprog:dev=/dev/device:baud,spispeed=2M"
 .sp
 More information about serprog is available in
 .B serprog-protocol.txt
@@ -797,6 +799,13 @@
 .B /dev/spidevX.Y
 is the Linux device node for your SPI controller.
 .sp
+In case the device supports it, you can set the SPI clock frequency with the optional
+.B spispeed
+parameter. The frequency is parsed as kilohertz.
+Example that sets the frequency to 8 MHz:
+.sp
+.B "  flashrom \-p linux_spi:dev=/dev/spidevX.Y,spispeed=8000"
+.sp
 Please note that the linux_spi driver only works on Linux.
 .SH EXAMPLES
 To back up and update your BIOS, run
diff --git a/flashrom.c b/flashrom.c
index b05faf3..db5b1c7 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -1995,7 +1995,7 @@
 		}
 	}
 
-	if (verify_it) {
+	if (verify_it && !all_skipped) {
 		msg_cinfo("Verifying flash... ");
 
 		if (write_it) {
diff --git a/hwaccess.h b/hwaccess.h
index 714a660..fd6eb12 100644
--- a/hwaccess.h
+++ b/hwaccess.h
@@ -240,19 +240,19 @@
   #if defined(__i386__) || defined(__x86_64__)
     #include <sys/types.h>
     #include <machine/sysarch.h>
-#if defined(__NetBSD__)
-    #if defined(__i386__)
-      #define iopl i386_iopl
-    #elif defined(__x86_64__)
-      #define iopl x86_64_iopl
+    #if defined(__NetBSD__)
+      #if defined(__i386__)
+        #define iopl i386_iopl
+      #elif defined(__x86_64__)
+        #define iopl x86_64_iopl
+      #endif
+    #elif defined (__OpenBSD__)
+      #if defined(__i386__)
+        #define iopl i386_iopl
+      #elif defined(__amd64__)
+        #define iopl amd64_iopl
+      #endif
     #endif
-#elif defined (__OpenBSD__)
-    #if defined(__i386__)
-      #define iopl i386_iopl
-    #elif defined(__amd64__)
-      #define iopl amd64_iopl
-    #endif
-#endif
 
 static inline void outb(uint8_t value, uint16_t port)
 {
diff --git a/ich_descriptors.c b/ich_descriptors.c
index e5ca87a..528717b 100644
--- a/ich_descriptors.c
+++ b/ich_descriptors.c
@@ -188,12 +188,12 @@
 			 nr);
 		return;
 	}
-	for (i = 0; i <= nr; i++)
+	for (i = 0; i < 5; i++)
 		msg_pdbg2("FLREG%d   0x%08x\n", i, desc->region.FLREGs[i]);
 	msg_pdbg2("\n");
 
 	msg_pdbg2("--- Details ---\n");
-	for (i = 0; i <= nr; i++)
+	for (i = 0; i < 5; i++)
 		pprint_freg(&desc->region, i);
 	msg_pdbg2("\n");
 }
@@ -805,7 +805,7 @@
 			  __func__, nr);
 		return ICH_RET_ERR;
 	}
-	for (i = 0; i <= nr; i++)
+	for (i = 0; i < 5; i++)
 		desc->region.FLREGs[i] = read_descriptor_reg(2, i, spibar);
 
 	/* master section */
diff --git a/jedec.c b/jedec.c
index 0894c2b..10f5db9 100644
--- a/jedec.c
+++ b/jedec.c
@@ -381,8 +381,8 @@
 	return failed;
 }
 
-int write_page_write_jedec_common(struct flashctx *flash, uint8_t *src,
-				  unsigned int start, unsigned int page_size)
+static int write_page_write_jedec_common(struct flashctx *flash, uint8_t *src,
+					 unsigned int start, unsigned int page_size)
 {
 	int i, tried = 0, failed;
 	uint8_t *s = src;
diff --git a/linux_spi.c b/linux_spi.c
index 2f46463..d12fceb 100644
--- a/linux_spi.c
+++ b/linux_spi.c
@@ -66,28 +66,33 @@
 	const uint8_t mode = SPI_MODE_0;
 	const uint8_t bits = 8;
 
-	dev = extract_programmer_param("dev");
-	if (!dev || !strlen(dev)) {
-		msg_perr("No SPI device given. Use flashrom -p "
-			 "linux_spi:dev=/dev/spidevX.Y\n");
-		return 1;
-	}
-
-	p = extract_programmer_param("speed");
+	p = extract_programmer_param("spispeed");
 	if (p && strlen(p)) {
 		speed = (uint32_t)strtoul(p, &endp, 10) * 1024;
 		if (p == endp) {
 			msg_perr("%s: invalid clock: %s kHz\n", __func__, p);
+			free(p);
 			return 1;
 		}
 	}
+	free(p);
+
+	dev = extract_programmer_param("dev");
+	if (!dev || !strlen(dev)) {
+		msg_perr("No SPI device given. Use flashrom -p "
+			 "linux_spi:dev=/dev/spidevX.Y\n");
+		free(dev);
+		return 1;
+	}
 
 	msg_pdbg("Using device %s\n", dev);
 	if ((fd = open(dev, O_RDWR)) == -1) {
 		msg_perr("%s: failed to open %s: %s\n", __func__,
 			 dev, strerror(errno));
+		free(dev);
 		return 1;
 	}
+	free(dev);
 
 	if (register_shutdown(linux_spi_shutdown, NULL))
 		return 1;
diff --git a/physmap.c b/physmap.c
index 5e22883..932fe75 100644
--- a/physmap.c
+++ b/physmap.c
@@ -220,13 +220,13 @@
 	}
 
 	if ((getpagesize() - 1) & len) {
-		msg_perr("Mapping %s at 0x%0*" PRIxPTR ", unaligned size 0x%lx.\n",
-			 descr, PRIxPTR_WIDTH, phys_addr, (unsigned long)len);
+		msg_perr("Mapping %s at 0x%0*" PRIxPTR ", unaligned size 0x%zx.\n",
+			 descr, PRIxPTR_WIDTH, phys_addr, len);
 	}
 
 	if ((getpagesize() - 1) & phys_addr) {
-		msg_perr("Mapping %s, 0x%lx bytes at unaligned 0x%0*" PRIxPTR ".\n",
-			 descr, (unsigned long)len, PRIxPTR_WIDTH, phys_addr);
+		msg_perr("Mapping %s, 0x%zx bytes at unaligned 0x%0*" PRIxPTR ".\n",
+			 descr, len, PRIxPTR_WIDTH, phys_addr);
 	}
 
 	if (readonly)
@@ -237,8 +237,8 @@
 	if (ERROR_PTR == virt_addr) {
 		if (NULL == descr)
 			descr = "memory";
-		msg_perr("Error accessing %s, 0x%lx bytes at 0x%0*" PRIxPTR "\n",
-			 descr, (unsigned long)len, PRIxPTR_WIDTH, phys_addr);
+		msg_perr("Error accessing %s, 0x%zx bytes at 0x%0*" PRIxPTR "\n",
+			 descr, len, PRIxPTR_WIDTH, phys_addr);
 		msg_perr(MEM_DEV " mmap failed: %s\n", strerror(errno));
 #ifdef __linux__
 		if (EINVAL == errno) {
diff --git a/print.c b/print.c
index bee7e79..0d209c1 100644
--- a/print.c
+++ b/print.c
@@ -160,7 +160,7 @@
 	msg_ginfo("Known");
 	for (i = 0; i < border; i++)
 		msg_ginfo(" ");
-	msg_ginfo(" Size");
+	msg_ginfo(" Size ");
 	for (i = 0; i < border; i++)
 		msg_ginfo(" ");
 
@@ -178,7 +178,7 @@
 	msg_ginfo("Broken");
 	for (i = 0; i < border; i++)
 		msg_ginfo(" ");
-	msg_ginfo("[kB]");
+	msg_ginfo("[kB] ");
 	for (i = 0; i < border + maxtypelen; i++)
 		msg_ginfo(" ");
 	msg_gdbg("range [V]");
@@ -287,7 +287,7 @@
 		for (i = 0; i < border + 1; i++)
 			msg_ginfo(" ");
 
-		msg_ginfo("%5d", chip->total_size);
+		msg_ginfo("%6d", chip->total_size);
 		for (i = 0; i < border; i++)
 			msg_ginfo(" ");
 
@@ -565,9 +565,10 @@
 	B("ASRock",	"A780FullHD",		OK, "http://www.asrock.com/mb/overview.asp?Model=A780FullHD", "While flashrom is working correctly, there might be problems with the firmware images themselves. Please see http://www.flashrom.org/pipermail/flashrom/2012-July/009600.html for details."),
 	B("ASRock",	"ALiveNF6G-DVI",	OK, "http://www.asrock.com/mb/overview.asp?Model=ALiveNF6G-DVI", NULL),
 	B("ASRock",	"AM2NF6G-VSTA",		OK, "http://www.asrock.com/mb/overview.asp?Model=AM2NF6G-VSTA", NULL),
-	B("ASRock",	"E350M1/USB3",		OK, "http://www.asrock.com/mb/overview.asp?model=e350m1/usb3", NULL),
-	B("ASRock",	"G31M-S rev 2.0",	OK, "http://www.asrock.com/mb/overview.asp?model=G31M-S", NULL),
 	B("ASRock",	"ConRoeXFire-eSATA2",	OK, "http://www.asrock.com/mb/overview.asp?model=conroexfire-esata2", NULL),
+	B("ASRock",	"E350M1/USB3",		OK, "http://www.asrock.com/mb/overview.asp?model=e350m1/usb3", NULL),
+	B("ASRock",	"Fatal1ty Z77 Performance", BAD, "http://www.asrock.com/mb/overview.asp?Model=Fatal1ty%20Z77%20Performance", "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("ASRock",	"G31M-S rev 2.0",	OK, "http://www.asrock.com/mb/overview.asp?model=G31M-S", NULL),
 	B("ASRock",	"H61M-ITX",		BAD, "http://www.asrock.com/mb/overview.asp?Model=H61M-ITX", "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("ASRock",	"H67M",			BAD, "http://www.asrock.com/mb/overview.asp?Model=H67M", "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("ASRock",	"K7S41",		OK, "http://www.asrock.com/mb/overview.asp?Model=K7S41", NULL),
@@ -577,6 +578,7 @@
 	B("ASRock",	"M3A790GXH/128M",	OK, "http://www.asrock.com/mb/overview.asp?Model=M3A790GXH/128M", NULL),
 	B("ASRock",	"N61P-S",		OK, "http://www.asrock.com/mb/overview.asp?Model=N61P-S", NULL),
 	B("ASRock",	"P4i65GV",		OK, "http://www.asrock.com/mb/overview.asp?Model=P4i65GV", NULL),
+	B("ASRock",	"Z68 Extreme4",		BAD, "http://www.asrock.com/mb/overview.asp?Model=Z68%20Extreme4", "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",	"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),
@@ -600,6 +602,7 @@
 	B("ASUS",	"A8V Deluxe",		OK, "http://www.asus.com/Motherboards/AMD_Socket_939/A8V_Deluxe/", NULL),
 	B("ASUS",	"A8V-E Deluxe",		OK, "http://www.asus.com/Motherboards/AMD_Socket_939/A8VE_Deluxe/", NULL),
 	B("ASUS",	"A8V-E SE",		OK, "http://www.asus.com/Motherboards/AMD_Socket_939/A8VE_SE/", "See http://www.coreboot.org/pipermail/coreboot/2007-October/026496.html"),
+	B("ASUS",	"C60M1-I",		OK, "http://www.asus.com/Motherboards/C60M1I/", "The MAC address of the onboard network card is stored in flash."),
 	B("ASUS",	"Crosshair II Formula",	OK, "http://www.asus.com/Motherboards/AMD_AM2Plus/Crosshair_II_Formula/", NULL),
 	B("ASUS",	"Crosshair IV Extreme",	OK, "http://www.asus.com/Motherboards/AMD_AM3/Crosshair_IV_Extreme/", NULL),
 	B("ASUS",	"DSAN-DX",		NT, "http://www.asus.com/Server_Workstation/Server_Motherboards/DSANDX/", NULL),
@@ -711,13 +714,19 @@
 	B("ASUS",	"P7H55-M LX",		BAD, NULL, "flashrom works correctly, but GbE LAN is nonworking (probably due to a missing/bogus MAC address; see http://www.flashrom.org/pipermail/flashrom/2011-July/007432.html and http://ubuntuforums.org/showthread.php?t=1534389 for a possible workaround)"),
 	B("ASUS",	"P8B-E/4L",		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",	"P8B WS",		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("ASUS",	"P8B75-M LE",		BAD, NULL, "Probing works (2x 8192 kB via hwseq), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs), ME region is locked."),
 	B("ASUS",	"P8H61 PRO",		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("ASUS",	"P8H61-M LE/USB3",	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("ASUS",	"P8H67-M PRO",		BAD, NULL, "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",	"P8H77-I",		OK, "http://www.asus.com/Motherboards/P8H77I/", NULL),
+	B("ASUS",	"P8H77-M",		OK, "http://www.asus.com/Motherboards/P8H77M/", NULL),
 	B("ASUS",	"P8P67 (rev. 3.1)",	BAD, NULL, "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",	"P8P67 LE",		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("ASUS",	"P8P67 LE (B2)",	OK, NULL, NULL),
+	B("ASUS",	"P8P67 LE (B3)",	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("ASUS",	"P8P67 PRO (rev. 3.0)",	OK, "http://www.asus.com/Motherboards/Intel_Socket_1155/P8P67_PRO/", NULL),
+	B("ASUS",	"P8P67-M PRO",		BAD, NULL, "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",	"P8Z68-V",		OK, "http://www.asus.com/Motherboards/Intel_Socket_1155/P8Z68V/", "Warning: MAC address of LOM is stored at 0x1000 - 0x1005 of the image."),
+	B("ASUS",	"P8Z68-V LE",		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",		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),
@@ -751,6 +760,7 @@
 	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",	"848P-A7",		OK, NULL, NULL),
+	B("Elitegroup",	"GeForce6100PM-M2 (V3.0)", 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),
@@ -830,6 +840,7 @@
 	B("GIGABYTE",	"GA-MA790GP-DS4H",	OK, "http://www.gigabyte.com/products/product-page.aspx?pid=2887", NULL),
 	B("GIGABYTE",	"GA-MA790XT-UD4P (rev. 1.0)", OK, "http://www.gigabyte.com/products/product-page.aspx?pid=3010", NULL),
 	B("GIGABYTE",	"GA-P55A-UD4 (rev. 1.0)", OK, "http://www.gigabyte.com/products/product-page.aspx?pid=3436", NULL),
+	B("GIGABYTE",	"GA-P55A-UD7"		, OK, "http://www.gigabyte.com/products/product-page.aspx?pid=3324", NULL),
 	B("GIGABYTE",	"GA-P67A-UD3P",		OK, "http://www.gigabyte.com/products/product-page.aspx?pid=3649", NULL),
 	B("GIGABYTE",	"GA-X58A-UD3R (rev. 2.0)", OK, NULL, NULL),
 	B("GIGABYTE",	"GA-X58A-UD7 (rev. 2.0)", OK, NULL, NULL),
@@ -865,6 +876,7 @@
 	B("Intel",	"DH67CF",		BAD, NULL, "H67 with BIOS lock enable and locked ME region, see http://www.flashrom.org/pipermail/flashrom/2011-September/007789.html"),
 	B("Intel",	"DH67CL",		BAD, NULL, "H67 with BIOS lock enable and locked ME region, see http://www.flashrom.org/pipermail/flashrom/2012-November/010112.html"),
 	B("Intel",	"DN2800MT (Marshalltown)", BAD, NULL, "BIOS locked via BIOS_CNTL."),
+	B("Intel",	"DQ77MK",		BAD, NULL, "Q77 with BIOS lock enable and locked ME region, see http://paste.flashrom.org/view.php?id=1603"),
 	B("Intel",	"EP80759",		OK, NULL, NULL),
 	B("Intel",	"Foxhollow",		OK, NULL, "Intel reference board."),
 	B("Intel",	"Greencity",		OK, NULL, "Intel reference board."),
@@ -918,6 +930,7 @@
 	B("MSI",	"MS-7529 (G31M3-L(S) V2)", OK, "http://www.msi.com/product/mb/G31M3-L-V2---G31M3-LS-V2.html", NULL),
 	B("MSI",	"MS-7529 (G31TM-P21)",  OK, "http://www.msi.com/product/mb/G31TM-P21.html", NULL),
 	B("MSI",	"MS-7548 (Aspen-GL8E)", OK, "http://h10025.www1.hp.com/ewfrf/wc/document?docname=c01635688&lc=en&cc=us&dlc=en", NULL),
+	B("MSI",	"MS-7551 (KA780G)",	OK, "http://www.msi.com/product/mb/KA780G.html", NULL),
 	B("MSI",	"MS-7596 (785GM-E51)",  OK, "http://www.msi.com/product/mb/785GM-E51.html", NULL),
 	B("MSI",	"MS-7597 (GF615M-P33)",	BAD, NULL, "Missing board enable/SIO support (Fintek F71889), see http://www.flashrom.org/pipermail/flashrom/2012-March/008956.html"),
 	B("MSI",	"MS-7599 (870-C45)",	OK, "http://www.msi.com/product/mb/870-C45.html", NULL),
@@ -929,7 +942,9 @@
 	B("MSI",	"MS-7676 (Z68MA-G45 (B3))", OK, "http://www.msi.com/product/mb/Z68MA-G45--B3-.html", NULL),
 	B("MSI",	"MS-7696 (A75MA-G55)",	OK, "http://www.msi.com/product/mb/A75MA-G55.html", NULL),
 	B("MSI",	"MS-7698 (E350IA-E45)",	OK, "http://www.msi.com/product/mb/E350IA-E45.html", NULL),
-	B("MSI",	"MS-7740 (H61MA-E35(B3))",	OK, "http://www.msi.com/product/mb/H61MA-E35--B3-.html", NULL),
+	B("MSI",	"MS-7740 (H61MA-E35(B3))", OK, "http://www.msi.com/product/mb/H61MA-E35--B3-.html", NULL),
+	B("MSI",	"MS-7756 (H77MA-G43)",	OK, "http://www.msi.com/product/mb/H77MA-G43.html", NULL),
+	B("MSI",	"MS-7808 (B75MA-E33)",	OK, "http://www.msi.com/product/mb/B75MA-E33.html", NULL),
 	B("NEC",	"PowerMate 2000",	OK, "http://support.necam.com/mobilesolutions/hardware/Desktops/pm2000/celeron/", NULL),
 	B("Nokia",	"IP530",		OK, NULL, NULL),
 	B("Palit",	"N61S",			OK, NULL, NULL),
@@ -946,6 +961,7 @@
 	B("Portwell",	"PEB-4700VLA",		OK, "http://www.portwell.com/products/detail.asp?CUSTCHAR1=PEB-4700VLA", NULL),
 	B("RCA",	"RM4100",		OK, "http://www.settoplinux.org/index.php?title=RCA_RM4100", NULL),
 	B("Samsung",	"Polaris 32",		OK, NULL, NULL),
+	B("SAPPHIRE",	"IPC-E350M1",		OK, "http://www.sapphiretech.com/presentation/product/?pid=1034&lid=1", NULL),
 	B("Shuttle",	"AK31",			OK, "http://www.motherboard.cz/mb/shuttle/AK31.htm", NULL),
 	B("Shuttle",	"AK38N",		OK, "http://eu.shuttle.com/en/desktopdefault.aspx/tabid-36/558_read-9889/", NULL),
 	B("Shuttle",	"AV11V30",		OK, NULL, NULL),
@@ -971,6 +987,7 @@
 	B("Supermicro", "X7SPA-HF",		OK, "http://www.supermicro.com/products/motherboard/ATOM/ICH9/X7SPA.cfm?typ=H&IPMI=Y", NULL),
 	B("Supermicro", "X8DT3",		OK, "http://www.supermicro.com/products/motherboard/QPI/5500/X8DT3.cfm", NULL),
 	B("Supermicro", "X8DTE-F",		OK, "http://www.supermicro.com/products/motherboard/QPI/5500/X8DT6-F.cfm?IPMI=Y&SAS=N", NULL),
+	B("Supermicro", "X8DTG-D",		OK, "http://www.supermicro.com/products/motherboard/qpi/5500/x8dtg-df.cfm", NULL),
 	B("Supermicro", "X8DTH-6F",		OK, "http://www.supermicro.com/products/motherboard/QPI/5500/X8DTH-6F.cfm", NULL),
 	B("Supermicro",	"X8DTT-F",		OK, "http://www.supermicro.com/products/motherboard/QPI/5500/X8DTT-F.cfm", NULL),
 	B("Supermicro",	"X8DTT-HIBQF",		OK, "http://www.supermicro.com/products/motherboard/QPI/5500/X8DTT-H.cfm", NULL),
@@ -979,11 +996,14 @@
 	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",	"X9DRD-7LN4F",		BAD, "http://www.supermicro.com/products/motherboard/xeon/c600/x9drd-7ln4f.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",	"X9DRT-HF+",		BAD, NULL, "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; SMM protection enabled."),
 	B("Supermicro",	"X9DRW",		BAD, NULL, "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",	"X9SCE-F",		BAD, "http://www.supermicro.com/products/motherboard/Xeon/C202_C204/X9SCE-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("Supermicro",	"X9SCM-F",		BAD, "http://www.supermicro.com/products/motherboard/Xeon/C202_C204/X9SCM-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("T-Online",	"S-100",		OK, "http://wiki.freifunk-hannover.de/T-Online_S_100", NULL),
 	B("Tekram",	"P6Pro-A5",		OK, "http://www.motherboard.cz/mb/tekram/P6Pro-A5.htm", NULL),
 	B("Termtek",	"TK-3370 (Rev:2.5B)",	OK, NULL, NULL),
@@ -1020,6 +1040,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("Tyan",	"S7066 (S7066WGM3NR)",	BAD, "http://www.tyan.com/product_SKU_spec.aspx?ProductType=MB&pid=790&SKU=600000330", "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("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),
diff --git a/serprog.c b/serprog.c
index 26b580c..3476315 100644
--- a/serprog.c
+++ b/serprog.c
@@ -797,7 +797,7 @@
 static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
 {
 	unsigned char sbuf[6];
-	msg_pspew("%s: addr=0x%" PRIxPTR " len=%lu\n", __func__, addr, (unsigned long)len);
+	msg_pspew("%s: addr=0x%" PRIxPTR " len=%zu\n", __func__, addr, len);
 	/* Stream the read-n -- as above. */
 	if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
 		sp_execute_opbuf_noflush();
diff --git a/spi25_statusreg.c b/spi25_statusreg.c
index 107bacd..8fb7f2d 100644
--- a/spi25_statusreg.c
+++ b/spi25_statusreg.c
@@ -640,7 +640,7 @@
 int spi_prettyprint_status_register_bp2_ep_srwd(struct flashctx *flash)
 {
 	uint8_t status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
+	msg_cdbg("Chip status register is 0x%02x\n", status);
 
 	spi_prettyprint_status_register_srwd(status);
 	msg_cdbg("Chip status register: Program Fail Flag (P_FAIL) is %sset\n",