summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/serprog-protocol.txt2
-rw-r--r--atavia.c2
-rw-r--r--board_enable.c13
-rw-r--r--chipdrivers.h1
-rw-r--r--chipset_enable.c2
-rw-r--r--dmi.c2
-rw-r--r--flash.h2
-rw-r--r--flashchips.c70
-rw-r--r--flashchips.h55
-rw-r--r--flashrom.8.tmpl14
-rw-r--r--flashrom.c2
-rw-r--r--ft2232_spi.c2
-rw-r--r--it8212.c2
-rw-r--r--print.c24
-rw-r--r--sb600spi.c2
15 files changed, 111 insertions, 84 deletions
diff --git a/Documentation/serprog-protocol.txt b/Documentation/serprog-protocol.txt
index 58f441716..6b7e7e330 100644
--- a/Documentation/serprog-protocol.txt
+++ b/Documentation/serprog-protocol.txt
@@ -74,7 +74,7 @@ Additional information of the above commands:
Send and receive bytes via SPI.
Maximum slen is Q_WRNMAXLEN in case Q_BUSTYPE returns SPI only or S_BUSTYPE was used
to set SPI exclusively before. Same for rlen and Q_RDNMAXLEN.
- This operation is immediate, meaning it doesnt use the operation buffer.
+ This operation is immediate, meaning it doesn't use the operation buffer.
0x14 (S_SPI_FREQ):
Set the SPI clock frequency. The 32-bit value indicates the
requested frequency in Hertz. Value 0 is reserved and should
diff --git a/atavia.c b/atavia.c
index 72ec20989..db29eeabf 100644
--- a/atavia.c
+++ b/atavia.c
@@ -113,7 +113,7 @@ static bool atavia_ready(struct pci_dev *pcidev_dev)
}
msg_pdbg2("\n%s: %s after %d tries (access=0x%02x, status=0x%02x)\n",
- __func__, ready ? "suceeded" : "failed", try, access, status);
+ __func__, ready ? "succeeded" : "failed", try, access, status);
atavia_prettyprint_access(access);
return ready;
}
diff --git a/board_enable.c b/board_enable.c
index ea6e7a173..1235bb83f 100644
--- a/board_enable.c
+++ b/board_enable.c
@@ -2374,7 +2374,7 @@ const struct board_match board_matches[] = {
{0x8086, 0x266a, 0x1043, 0x80a6, 0x8086, 0x2668, 0x1043, 0x813d, NULL, NULL, NULL, P3, "ASUS", "P5GD2/C variants", 0, NT, intel_ich_gpio21_raise},
{0x8086, 0x27b8, 0x103c, 0x2a22, 0x8086, 0x2770, 0x103c, 0x2a22, "^LITHIUM$", NULL, NULL, P3, "ASUS", "P5LP-LE (Lithium-UL8E)",0, OK, intel_ich_gpio34_raise},
{0x8086, 0x27b8, 0x1043, 0x2a22, 0x8086, 0x2770, 0x1043, 0x2a22, "^P5LP-LE$", NULL, NULL, P3, "ASUS", "P5LP-LE (Epson OEM)", 0, OK, intel_ich_gpio34_raise},
- {0x8086, 0x27da, 0x1043, 0x8179, 0x8086, 0x27b8, 0x1043, 0x8179, "^P5LD2$", NULL, NULL, P3, "ASUS", "P5LD2", 0, NT, intel_ich_gpio16_raise},
+ {0x8086, 0x27da, 0x1043, 0x8179, 0x8086, 0x27b8, 0x1043, 0x8179, "^P5LD2$", NULL, NULL, P3, "ASUS", "P5LD2", 0, OK, intel_ich_gpio16_raise},
{0x8086, 0x27da, 0x1043, 0x8179, 0x8086, 0x27b0, 0x1043, 0x8179, "^P5LD2-MQ$", NULL, NULL, P3, "ASUS", "P5LD2-MQ", 0, OK, intel_ich_gpio16_raise},
{0x8086, 0x27da, 0x1043, 0x8179, 0x8086, 0x27b8, 0x1043, 0x8179, "^P5LD2-VM$", NULL, NULL, P3, "ASUS", "P5LD2-VM", 0, NT, intel_ich_gpio16_raise},
{0x8086, 0x27b0, 0x1043, 0x8179, 0x8086, 0x2770, 0x1043, 0x817a, "^P5LD2-VM DH$", NULL, NULL, P3, "ASUS", "P5LD2-VM DH", 0, OK, intel_ich_gpio16_raise},
@@ -2422,11 +2422,12 @@ const struct board_match board_matches[] = {
{0x8086, 0x7190, 0, 0, 0x8086, 0x7110, 0, 0, "^SE440BX-2$", NULL, NULL, P3, "Intel", "SE440BX-2", 0, NT, intel_piix4_gpo27_lower},
{0x1022, 0x7468, 0, 0, 0x1022, 0x7460, 0, 0, NULL, "iwill", "dk8_htx", P3, "IWILL", "DK8-HTX", 0, OK, w83627hf_gpio24_raise_2e},
{0x8086, 0x27A0, 0x8086, 0x27a0, 0x8086, 0x27b8, 0x8086, 0x27b8, NULL, "kontron", "986lcd-m", P3, "Kontron", "986LCD-M", 0, OK, board_kontron_986lcd_m},
- {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, 0x1E22, 0x17AA, 0x21FA, 0x8086, 0x1E55, 0x17AA, 0x21FA, "^ThinkPad X230", NULL, NULL, P2, "Lenovo", "X230", 0, OK, p2_whitelist_laptop},
+ {0x8086, 0x1E22, 0x17AA, 0x21F6, 0x8086, 0x1E55, 0x17AA, 0x21F6, "^ThinkPad T530", NULL, NULL, P2, "IBM/Lenovo", "ThinkPad T530", 0, OK, p2_whitelist_laptop},
+ {0x8086, 0x27a0, 0x17aa, 0x2015, 0x8086, 0x27b9, 0x17aa, 0x2009, "^ThinkPad T60", NULL, NULL, P2, "IBM/Lenovo", "ThinkPad T60", 0, OK, p2_whitelist_laptop},
+ {0x8086, 0x27a0, 0x17aa, 0x2017, 0x8086, 0x27b9, 0x17aa, 0x2009, "^ThinkPad T60", NULL, NULL, P2, "IBM/Lenovo", "ThinkPad T60(s)", 0, OK, p2_whitelist_laptop},
+ {0x8086, 0x3B07, 0x17AA, 0x2166, 0x8086, 0x3B30, 0x17AA, 0x2167, "^Lenovo X201", NULL, NULL, P2, "IBM/Lenovo", "ThinkPad X201", 0, OK, p2_whitelist_laptop},
+ {0x8086, 0x1E22, 0x17AA, 0x21FA, 0x8086, 0x1E55, 0x17AA, 0x21FA, "^ThinkPad X230", NULL, NULL, P2, "IBM/Lenovo", "ThinkPad X230", 0, OK, p2_whitelist_laptop},
+ {0x8086, 0x27A0, 0x17AA, 0x2017, 0x8086, 0x27B9, 0x17AA, 0x2009, "^ThinkPad X60", NULL, NULL, P2, "IBM/Lenovo", "ThinkPad X60(s)", 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},
{0x8086, 0x7190, 0, 0, 0x8086, 0x7110, 0, 0, "^MS-6163 (i440BX)$", NULL, NULL, P3, "MSI", "MS-6163 (MS-6163 Pro)", 0, OK, intel_piix4_gpo14_raise},
diff --git a/chipdrivers.h b/chipdrivers.h
index 4ece42e3b..dbe45b812 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -158,7 +158,6 @@ int printlock_regspace2_block_eraser_1(struct flashctx *flash);
/* m29f400bt.c */
int probe_m29f400bt(struct flashctx *flash);
int write_m29f400bt(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len);
-void protect_m29f400bt(struct flashctx *flash, chipaddr bios);
/* sst28sf040.c */
int erase_chip_28sf040(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
diff --git a/chipset_enable.c b/chipset_enable.c
index 37a718f19..79ae0983c 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -608,7 +608,7 @@ static int enable_flash_ich_spi(struct pci_dev *dev, enum ich_chipset ich_genera
if (ich_generation != CHIPSET_TUNNEL_CREEK && ich_generation != CHIPSET_CENTERTON) {
uint8_t buc = mmio_readb(rcrb + 0x3414);
- msg_pdbg("Top Swap : %s\n", (buc & 1) ? "enabled (A16(+) inverted)" : "not enabled");
+ msg_pdbg("Top Swap: %s\n", (buc & 1) ? "enabled (A16(+) inverted)" : "not enabled");
}
/* Handle FWH-related parameters and initialization */
diff --git a/dmi.c b/dmi.c
index f329fab64..1b120966a 100644
--- a/dmi.c
+++ b/dmi.c
@@ -188,7 +188,7 @@ static void dmi_table(uint32_t base, uint16_t len, uint16_t num)
/* - If a short entry is found (less than 4 bytes), not only it
* is invalid, but we cannot reliably locate the next entry.
* - If the length value indicates that this structure spreads
- * accross the table border, something is fishy too.
+ * across the table border, something is fishy too.
* Better stop at this point, and let the user know his/her
* table is broken.
*/
diff --git a/flash.h b/flash.h
index aa01ccf6f..8271da9d1 100644
--- a/flash.h
+++ b/flash.h
@@ -187,7 +187,7 @@ struct flashchip {
* elements or set the function pointer to NULL.
*/
struct block_eraser {
- struct eraseblock{
+ struct eraseblock {
unsigned int size; /* Eraseblock size in bytes */
unsigned int count; /* Number of contiguous blocks with that size */
} eraseblocks[NUM_ERASEREGIONS];
diff --git a/flashchips.c b/flashchips.c
index a973ddda5..68b5dcf76 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -1994,7 +1994,7 @@ const struct flashchip flashchips[] = {
.total_size = 512,
.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 =
@@ -2477,7 +2477,7 @@ const struct flashchip flashchips[] = {
/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
/* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
.feature_bits = FEATURE_OTP,
- .tested = TEST_UNTESTED,
+ .tested = TEST_OK_PREW,
.probe = probe_spi_at45db,
.probe_timing = TIMING_ZERO,
.block_erasers =
@@ -3158,7 +3158,7 @@ const struct flashchip flashchips[] = {
.total_size = 64,
.page_size = 0, /* unused */
.feature_bits = 0,
- .tested = TEST_OK_PR,
+ .tested = {.probe = OK, .read = OK, .erase = BAD, .write = BAD },
.probe = probe_jedec, /* FIXME! */
.probe_timing = TIMING_ZERO,
.block_erasers =
@@ -5433,7 +5433,7 @@ const struct flashchip flashchips[] = {
.page_size = 256,
/* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (B version only) */
.feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
- .tested = TEST_UNTESTED,
+ .tested = TEST_OK_PREW,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
@@ -6627,7 +6627,7 @@ const struct flashchip flashchips[] = {
.block_erase = spi_block_erase_c7,
},
},
- .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6: Continously Program (CP) mode */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6: Continuously Program (CP) mode */
.unlock = spi_disable_blockprotect,
.write = spi_chip_write_256,
.read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
@@ -7641,7 +7641,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {64 * 1024, 8}, },
+ .eraseblocks = { {64 * 1024, 8} },
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {512 * 1024, 1} },
@@ -10242,9 +10242,9 @@ const struct flashchip flashchips[] = {
}
},
.printlock = spi_prettyprint_status_register_bp3_srwd,
- .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
.write = spi_chip_write_256,
- .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O (0x3B) supported */
.voltage = {2700, 3600},
},
@@ -10276,15 +10276,15 @@ const struct flashchip flashchips[] = {
}
},
.printlock = spi_prettyprint_status_register_bp3_srwd,
- .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
.write = spi_chip_write_256,
- .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O (0x3B) supported */
.voltage = {2700, 3600},
},
{
.vendor = "Spansion",
- .name = "S25FL116K/S25FL216K",
+ .name = "S25FL116K/S25FL216K", /* FIXME: separate them */
.bustype = BUS_SPI,
.manufacture_id = SPANSION_ID,
.model_id = SPANSION_S25FL216,
@@ -10311,9 +10311,9 @@ const struct flashchip flashchips[] = {
}
},
.printlock = spi_prettyprint_status_register_bp3_srwd,
- .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
.write = spi_chip_write_256,
- .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O (0x3B) supported */
.voltage = {2700, 3600},
},
@@ -10702,10 +10702,10 @@ const struct flashchip flashchips[] = {
{
.vendor = "SST",
- .name = "SST25VF512A",
+ .name = "SST25VF512(A)",
.bustype = BUS_SPI,
.manufacture_id = SST_ID,
- .model_id = SST_SST25VF512A_REMS,
+ .model_id = SST_SST25VF512_REMS,
.total_size = 64,
.page_size = 256,
.feature_bits = FEATURE_WRSR_EWSR,
@@ -10722,25 +10722,25 @@ const struct flashchip flashchips[] = {
.block_erase = spi_block_erase_52,
}, {
.eraseblocks = { {32 * 1024, 2} },
- .block_erase = spi_block_erase_d8,
+ .block_erase = spi_block_erase_d8, /* Supported by SST25VF512A only */
}, {
.eraseblocks = { {64 * 1024, 1} },
.block_erase = spi_block_erase_60,
}, {
.eraseblocks = { {64 * 1024, 1} },
- .block_erase = spi_block_erase_c7,
+ .block_erase = spi_block_erase_c7, /* Supported by SST25VF512A only */
},
},
.printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
.unlock = spi_disable_blockprotect,
.write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
- .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .read = spi_chip_read, /* Fast read (0x0B) supported by SST25VF512A only */
.voltage = {2700, 3600},
},
{
.vendor = "SST",
- .name = "SST25VF010",
+ .name = "SST25VF010(A)",
.bustype = BUS_SPI,
.manufacture_id = SST_ID,
.model_id = SST_SST25VF010_REMS,
@@ -10760,19 +10760,19 @@ const struct flashchip flashchips[] = {
.block_erase = spi_block_erase_52,
}, {
.eraseblocks = { {32 * 1024, 4} },
- .block_erase = spi_block_erase_d8,
+ .block_erase = spi_block_erase_d8, /* Supported by SST25VF010A only */
}, {
.eraseblocks = { {128 * 1024, 1} },
.block_erase = spi_block_erase_60,
}, {
.eraseblocks = { {128 * 1024, 1} },
- .block_erase = spi_block_erase_c7,
+ .block_erase = spi_block_erase_c7, /* Supported by SST25VF010A only */
},
},
.printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
.unlock = spi_disable_blockprotect,
.write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
- .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .read = spi_chip_read, /* Fast read (0x0B) supported by SST25VF010A only */
.voltage = {2700, 3600},
},
@@ -12157,7 +12157,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {64 * 1024, 8}, },
+ .eraseblocks = { {64 * 1024, 8} },
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {512 * 1024, 1} },
@@ -12249,7 +12249,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {16 * 1024, 8}, },
+ .eraseblocks = { {16 * 1024, 8} },
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {128 * 1024, 1} },
@@ -12276,7 +12276,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {64 * 1024, 8}, },
+ .eraseblocks = { {64 * 1024, 8} },
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {512 * 1024, 1} },
@@ -12335,7 +12335,7 @@ const struct flashchip flashchips[] = {
},
.block_erase = erase_sector_stm50,
}, {
- .eraseblocks = { {64 * 1024, 8}, },
+ .eraseblocks = { {64 * 1024, 8} },
.block_erase = erase_block_82802ab,
}
},
@@ -12368,7 +12368,7 @@ const struct flashchip flashchips[] = {
},
.block_erase = erase_sector_stm50,
}, {
- .eraseblocks = { {64 * 1024, 8}, },
+ .eraseblocks = { {64 * 1024, 8} },
.block_erase = erase_block_82802ab,
}
},
@@ -12401,7 +12401,7 @@ const struct flashchip flashchips[] = {
},
.block_erase = erase_sector_stm50,
}, {
- .eraseblocks = { {64 * 1024, 16}, },
+ .eraseblocks = { {64 * 1024, 16} },
.block_erase = erase_block_82802ab,
}
},
@@ -12435,7 +12435,7 @@ const struct flashchip flashchips[] = {
},
.block_erase = erase_sector_stm50,
}, {
- .eraseblocks = { {64 * 1024, 16}, },
+ .eraseblocks = { {64 * 1024, 16} },
.block_erase = erase_block_82802ab,
}
},
@@ -12495,7 +12495,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {64 * 1024, 32}, },
+ .eraseblocks = { {64 * 1024, 32} },
.block_erase = erase_block_82802ab,
}
},
@@ -12520,7 +12520,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {64 * 1024, 8}, },
+ .eraseblocks = { {64 * 1024, 8} },
.block_erase = erase_block_82802ab,
}
},
@@ -12545,7 +12545,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {64 * 1024, 16}, },
+ .eraseblocks = { {64 * 1024, 16} },
.block_erase = erase_block_82802ab,
}
},
@@ -12570,7 +12570,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {64 * 1024, 16}, },
+ .eraseblocks = { {64 * 1024, 16} },
.block_erase = erase_block_82802ab,
}
},
@@ -14318,7 +14318,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {64 * 1024, 16}, },
+ .eraseblocks = { {64 * 1024, 16} },
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {1024 * 1024, 1} },
@@ -14347,7 +14347,7 @@ const struct flashchip flashchips[] = {
.block_erasers =
{
{
- .eraseblocks = { {64 * 1024, 8}, },
+ .eraseblocks = { {64 * 1024, 8} },
.block_erase = erase_sector_jedec,
}, {
.eraseblocks = { {512 * 1024, 1} },
diff --git a/flashchips.h b/flashchips.h
index b2c1d4d15..f0fbf4b25 100644
--- a/flashchips.h
+++ b/flashchips.h
@@ -75,6 +75,7 @@
#define AMD_AM29F800BT 0xD6
#define AMD_AM29LV001BB 0x6D
#define AMD_AM29LV001BT 0xED
+#define AMD_AM29LV010B 0x6E /* 1Mb, uniform */
#define AMD_AM29LV002BB 0xC2
#define AMD_AM29LV002BT 0x40
#define AMD_AM29LV004BB 0xB6
@@ -156,6 +157,10 @@
#define ATMEL_AT26DF161A 0x4601
#define ATMEL_AT26DF321 0x4700 /* Same as 25DF321 */
#define ATMEL_AT26F004 0x0400
+#define ATMEL_AT29LV512 0x3D
+#define ATMEL_AT29LV010A 0x35 /* Same as AT29BV010A, the latter works down to 2.7V */
+#define ATMEL_AT29LV020 0xBA
+#define ATMEL_AT29BV040A 0xC4
#define ATMEL_AT29C040A 0xA4
#define ATMEL_AT29C010A 0xD5
#define ATMEL_AT29C020 0xDA
@@ -187,13 +192,15 @@
#define ATMEL_AT45DB321D 0x2701 /* Buggy data sheet */
#define ATMEL_AT45DB642 /* No ID (opcode) available for AT45DB642 */
#define ATMEL_AT45DB642D 0x2800
-#define ATMEL_AT49BV512 0x03
+#define ATMEL_AT49BV512 0x03 /* Same as AT49F512 */
+#define ATMEL_AT49F001N 0x05 /* Same as AT49F001 */
+#define ATMEL_AT49F001NT 0x04 /* Same as AT49F001T */
#define ATMEL_AT49F002N 0x07 /* for AT49F002(N) */
#define ATMEL_AT49LH002 0xE9
#define ATMEL_AT49LH00B4 0xED
#define ATMEL_AT49LH004 0xEE
#define ATMEL_AT49F002NT 0x08 /* for AT49F002(N)T */
-#define ATMEL_AT49F010 0x17 /* Same as AT49HF010 */
+#define ATMEL_AT49F010 0x17 /* Same as AT49HF010 (some erroneous datasheets say 0x87), AT49BV010, AT49HBV010, AT49HLV010 */
#define ATMEL_AT49F020 0x0B
#define ATMEL_AT49F040 0x13
#define ATMEL_AT49F080 0x23
@@ -261,7 +268,7 @@
#define EON_EN25F80 0x3114
#define EON_EN25F16 0x3115
#define EON_EN25F32 0x3116
-#define EON_EN25F64 0x3117 /* guessed */
+#define EON_EN25F64 0x3117
#define EON_EN25Q40 0x3013
#define EON_EN25Q80 0x3014
#define EON_EN25Q16 0x3015 /* Same as EN25D16 */
@@ -561,7 +568,7 @@
* second byte is the device code,
* third byte is a dummy byte.
*/
-#define SANYO_ID 0x62 /* Sanyo */
+#define SANYO_ID 0x62 /* Sanyo */
#define SANYO_LE25FW203A 0x1600
#define SANYO_LE25FW403A 0x1100
#define SANYO_LE25FW106 0x15
@@ -644,8 +651,13 @@
#define SST_SST25WF020 0x2503
#define SST_SST25WF040 0x2504
#define SST_SST25WF080 0x2505
-#define SST_SST25VF512A_REMS 0x48 /* REMS or RES opcode */
-#define SST_SST25VF010_REMS 0x49 /* REMS or RES opcode */
+/* There exist some successors to members of the SST25WF family with alphabetic suffixes. They have very weird
+ * IDs and were not spotted in the wild yet. Their datasheets show a 4 byte long response w/o a vendor ID. */
+#define SST_SST25WF020A /* 0x62 0x16 0x12 0x00 */
+#define SST_SST25WF040B /* 0x62 0x16 0x13 0x00 */
+#define SST_SST25WF080B /* 0x62 0x16 0x14 0x00 */
+#define SST_SST25VF512_REMS 0x48 /* REMS or RES opcode, same as SST25VF512A */
+#define SST_SST25VF010_REMS 0x49 /* REMS or RES opcode, same as SST25VF010A */
#define SST_SST25VF020_REMS 0x43 /* REMS or RES opcode, same as SST25LF020A */
#define SST_SST25VF020B 0x258C
#define SST_SST25VF040_REMS 0x44 /* REMS or RES opcode, same as SST25LF040A */
@@ -667,6 +679,7 @@
#define SST_SST27VF010 0xA9
#define SST_SST27VF020 0xAA
#define SST_SST28SF040 0x04
+#define SST_SST29LE512 0x3D /* Same as SST29VE512 */
#define SST_SST29EE512 0x5D
#define SST_SST29EE010 0x07
#define SST_SST29LE010 0x08 /* Same as SST29VE010 */
@@ -685,6 +698,10 @@
#define SST_SST39VF020 0xD6 /* Same as 39LF020 */
#define SST_SST39VF040 0xD7 /* Same as 39LF040 */
#define SST_SST39VF080 0xD8 /* Same as 39LF080/39VF080/39VF088 */
+#define SST_SST45VF512 0x41 /* REMS, read opcode 0xFF */
+#define SST_SST45LF010 0x42 /* REMS, read opcode 0xFF, 'funny' other opcodes */
+#define SST_SST45VF010 0x45 /* REMS, read opcode 0xFF */
+#define SST_SST45VF020 0x43 /* REMS, read opcode 0xFF */
#define SST_SST49LF040B 0x50
#define SST_SST49LF040 0x51
#define SST_SST49LF020 0x61
@@ -785,6 +802,10 @@
#define SM_MVC_29C51002B 0xA2 /* Identical chips: {F,S,V}29C51002B */
#define SM_MVC_29C51004B 0xA3 /* Identical chips: {F,S,V}29C51004B */
+#define TENX_ID 0x7F7F5E /* Tenx Technologies */
+#define TENX_ID_NOPREFIX 0x5E
+#define TENX_ICE25P05 0x01 /* Maybe? */
+
#define TI_ID 0x97 /* Texas Instruments */
#define TI_OLD_ID 0x01 /* TI chips from last century */
#define TI_TMS29F002RT 0xB0
@@ -820,18 +841,18 @@
#define WINBOND_ID 0xDA /* Winbond */
#define WINBOND_W19B160BB 0x49
#define WINBOND_W19B160BT 0xC4
-#define WINBOND_W19B320SB 0x2A /* Same as W19L320SB */
-#define WINBOND_W19B320ST 0xBA /* Same as W19L320ST */
+#define WINBOND_W19B320SB 0x2A /* Same as W19L320SB */
+#define WINBOND_W19B320ST 0xBA /* Same as W19L320ST */
#define WINBOND_W19B322MB 0x92
#define WINBOND_W19B322MT 0x10
#define WINBOND_W19B323MB 0x94
#define WINBOND_W19B323MT 0x13
#define WINBOND_W19B324MB 0x97
#define WINBOND_W19B324MT 0x16
-#define WINBOND_W29C010 0xC1 /* Same as W29C010M, W29C011A, W29EE011, W29EE012, and ASD AE29F1008 */
-#define WINBOND_W29C020 0x45 /* Same as W29C020C, W29C022 and ASD AE29F2008 */
-#define WINBOND_W29C040 0x46 /* Same as W29C040P */
-#define WINBOND_W29C512A 0xC8 /* Same as W29EE512 */
+#define WINBOND_W29C010 0xC1 /* Same as W29C010M, W29C011A, W29EE011, W29EE012, and ASD AE29F1008 */
+#define WINBOND_W29C020 0x45 /* Same as W29C020C, W29C022 and ASD AE29F2008 */
+#define WINBOND_W29C040 0x46 /* Same as W29C040P */
+#define WINBOND_W29C512A 0xC8 /* Same as W29EE512 */
#define WINBOND_W29GL032CHL 0x7E1D01 /* Uniform Sectors, WP protects Top OR Bottom sector */
#define WINBOND_W29GL032CB 0x7E1A00 /* Top Boot Sector, WP protects Top 2 sectors */
#define WINBOND_W29GL032CT 0x7E1A01 /* Bottom Boot Sector, WP protects Bottom 2 sectors */
@@ -848,13 +869,13 @@
#define WINBOND_W39L512 0x38
#define WINBOND_W39V040A 0x3D
#define WINBOND_W39V040FA 0x34
-#define WINBOND_W39V040B 0x54 /* Same as W39V040FB */
-#define WINBOND_W39V040C 0x50 /* Same as W39V040FC */
+#define WINBOND_W39V040B 0x54 /* Same as W39V040FB */
+#define WINBOND_W39V040C 0x50 /* Same as W39V040FC */
#define WINBOND_W39V080A 0xD0
#define WINBOND_W39V080FA 0xD3
-#define WINBOND_W39V080FA_DM 0x93 /* W39V080FA dual mode */
-#define WINBOND_W49F002 0x25 /* Same as W49F002B */
-#define WINBOND_W49F002U 0x0B /* Same as W49F002N and ASD AE49F2008 */
+#define WINBOND_W39V080FA_DM 0x93 /* W39V080FA dual mode */
+#define WINBOND_W49F002 0x25 /* Same as W49F002B */
+#define WINBOND_W49F002U 0x0B /* Same as W49F002N and ASD AE49F2008 */
#define WINBOND_W49F020 0x8C
#define WINBOND_W49V002A 0xB0
#define WINBOND_W49V002FA 0x32
diff --git a/flashrom.8.tmpl b/flashrom.8.tmpl
index 153591abb..81eceaa7d 100644
--- a/flashrom.8.tmpl
+++ b/flashrom.8.tmpl
@@ -229,7 +229,7 @@ bitbanging adapter)
.sp
Some programmers have optional or mandatory parameters which are described
in detail in the
-.B PROGRAMMER SPECIFIC INFO
+.B PROGRAMMER-SPECIFIC INFORMATION
section. Support for some programmers can be disabled at compile time.
.B "flashrom \-h"
lists all supported programmers.
@@ -242,11 +242,11 @@ Save the full debug log to
.BR <logfile> .
If the file already exists, it will be overwritten. This is the recommended
way to gather logs from flashrom because they will be verbose even if the
-on-screen messages are not verbose.
+on-screen messages are not verbose and don't require output redirection.
.TP
.B "\-R, \-\-version"
Show version information and exit.
-.SH PROGRAMMER SPECIFIC INFO
+.SH PROGRAMMER-SPECIFIC INFORMATION
Some programmer drivers accept further parameters to set programmer-specific
parameters. These parameters are separated from the programmer name by a
colon. While some programmers take arguments at fixed positions, other
@@ -474,7 +474,7 @@ like above. In this case you can use
.sp
.B " flashrom \-p internal:laptop=this_is_not_a_laptop"
.sp
-to tell flashrom (at your own risk) that it does not running on a laptop.
+to tell flashrom (at your own risk) that it is not running on a laptop.
.SS
.BR "dummy " programmer
The dummy programmer operates on a buffer in memory only. It provides a safe
@@ -595,7 +595,7 @@ is an 8-bit hexadecimal value.
.SS
.BR "nic3com" , " nicrealtek" , " nicnatsemi" , " nicintel", " nicintel_eeprom"\
, " nicintel_spi" , " gfxnvidia" , " ogp_spi" , " drkaiser" , " satasii"\
-, " satamv" , " atahpt" ", " atavia " and " it8212 " programmers
+, " satamv" , " atahpt", " atavia " and " it8212 " programmers
These programmers have an option to specify the PCI address of the card
your want to use, which must be specified if more than one card supported
by the selected programmer is installed in your system. The syntax is
@@ -782,7 +782,7 @@ where
.B value
can be
.BR 1 " or " 2
-to select target chip 1 or 2 repectively. The default is target chip 1.
+to select target chip 1 or 2 respectively. The default is target chip 1.
.SS
.BR "rayer_spi " programmer
The default I/O base address used for the parallel port is 0x378 and you can use
@@ -998,7 +998,7 @@ and associated flashrom options in the
paragraph in the
.B internal programmer
subsection of the
-.B PROGRAMMER SPECIFIC INFO
+.B PROGRAMMER-SPECIFIC INFORMATION
section and the information in our wiki at
.BR "http://www.flashrom.org/Laptops " .
.SS
diff --git a/flashrom.c b/flashrom.c
index fc8b073c4..3f29e6db9 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -1757,7 +1757,7 @@ int selfcheck(void)
* depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
* For 'flashchips' we export the size explicitly to work around this and to be able to implement the
* checks below. */
- if (flashchips_size <= 1 || flashchips[flashchips_size-1].name != NULL) {
+ if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
msg_gerr("Flashchips table miscompilation!\n");
ret = 1;
} else {
diff --git a/ft2232_spi.c b/ft2232_spi.c
index f74deb4f9..7e7e2b188 100644
--- a/ft2232_spi.c
+++ b/ft2232_spi.c
@@ -69,7 +69,7 @@ const struct dev_entry devs_ft2232spi[] = {
{FIC_VID, OPENMOKO_DBGBOARD_PID, OK, "FIC", "OpenMoko Neo1973 Debug board (V2+)"},
{OLIMEX_VID, OLIMEX_ARM_OCD_PID, NT, "Olimex", "ARM-USB-OCD"},
{OLIMEX_VID, OLIMEX_ARM_TINY_PID, OK, "Olimex", "ARM-USB-TINY"},
- {OLIMEX_VID, OLIMEX_ARM_OCD_H_PID, NT, "Olimex", "ARM-USB-OCD-H"},
+ {OLIMEX_VID, OLIMEX_ARM_OCD_H_PID, OK, "Olimex", "ARM-USB-OCD-H"},
{OLIMEX_VID, OLIMEX_ARM_TINY_H_PID, OK, "Olimex", "ARM-USB-TINY-H"},
{0},
diff --git a/it8212.c b/it8212.c
index c63be8e61..460e820fc 100644
--- a/it8212.c
+++ b/it8212.c
@@ -28,7 +28,7 @@ static uint8_t *it8212_bar = NULL;
#define PCI_VENDOR_ID_ITE 0x1283
const struct dev_entry devs_it8212[] = {
- {PCI_VENDOR_ID_ITE, 0x8212, OK, "ITE", "8212F PATA RAID"},
+ {PCI_VENDOR_ID_ITE, 0x8212, NT, "ITE", "8212F PATA RAID"},
{},
};
diff --git a/print.c b/print.c
index 85eefdc68..b1faea7a9 100644
--- a/print.c
+++ b/print.c
@@ -662,6 +662,7 @@ const struct board_info boards_known[] = {
B("ASUS", "DSAN-DX", NT, "http://www.asus.com/Server_Workstation/Server_Motherboards/DSANDX/", NULL),
B("ASUS", "E35M1-I DELUXE", OK, "http://www.asus.com/Motherboards/AMD_CPU_on_Board/E35M1I_DELUXE/", NULL),
B("ASUS", "F1A75-V PRO", OK, "http://www.asus.com/Motherboard/F1A75V_PRO/", NULL),
+ B("ASUS", "F2A85-M", DEP, "https://www.asus.com/Motherboards/F2A85M/", "UEFI builds v6404 and above disable access to some parts of the flash, cf. http://www.coreboot.org/ASUS_F2A85-M#UEFI_builds_that_allow_flash_chip_access"),
B("ASUS", "K8N", OK, "http://www.asus.com/Motherboards/AMD_Socket_754/K8N/", NULL),
B("ASUS", "K8V", OK, "http://www.asus.com/Motherboards/AMD_Socket_754/K8V/", NULL),
B("ASUS", "K8V SE Deluxe", OK, "http://www.asus.com/Motherboards/AMD_Socket_754/K8V_SE_Deluxe/", NULL),
@@ -675,6 +676,7 @@ const struct board_info boards_known[] = {
B("ASUS", "M2NBP-VM CSM", OK, "http://www.asus.com/Motherboards/AMD_AM2/M2NBPVM_CSM/", NULL),
B("ASUS", "M2N-E", OK, "http://www.asus.com/Motherboards/AMD_AM2/M2NE/", "If the machine doesn't come up again after flashing, try resetting the NVRAM(CMOS). The MAC address of the onboard network card will change to the value stored in the new image, so backup the old address first. See http://www.flashrom.org/pipermail/flashrom/2009-November/000879.html"),
B("ASUS", "M2N-E SLI", OK, "http://www.asus.com/Motherboards/AMD_AM2/M2NE_SLI/", NULL),
+ B("ASUS", "M2N-MX SE Plus", OK, "http://www.asus.com/Motherboards/M2NMX_SE_Plus/", NULL),
B("ASUS", "M2NPV-VM", OK, "http://www.asus.com/Motherboards/AMD_AM2/M2NPVVM/", NULL),
B("ASUS", "M2N-SLI Deluxe", OK, "http://www.asus.com/Motherboards/AMD_AM2/M2NSLI_Deluxe/", NULL),
B("ASUS", "M2V", OK, "http://www.asus.com/Motherboards/AMD_AM2/M2V/", NULL),
@@ -748,7 +750,7 @@ const struct board_info boards_known[] = {
B("ASUS", "P5KPL-CM", OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5KPLCM/", NULL),
B("ASUS", "P5L-MX", OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5LMX/", NULL),
B("ASUS", "P5L-VM 1394", OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5LVM_1394/", NULL),
- B("ASUS", "P5LD2", NT, NULL, "Untested board enable."),
+ B("ASUS", "P5LD2", OK, NULL, NULL),
B("ASUS", "P5LD2-MQ", OK, "http://support.asus.com/download.aspx?SLanguage=en&p=8&s=12&m=Vintage-PH2&os=&hashedid=n/a", "Found in ASUS Vintage-PH2 barebones."),
B("ASUS", "P5LD2-VM", NT, "http://www.asus.com/Motherboards/Intel_Socket_775/P5LD2VM/", "Untested board enable."),
B("ASUS", "P5LD2-VM DH", OK, "http://www.asus.com/Motherboards/Intel_Socket_775/P5LD2VM_DH/", NULL),
@@ -1005,6 +1007,7 @@ const struct board_info boards_known[] = {
B("MSI", "MS-7376 (K9A2 Platinum V1)", OK, "http://www.msi.com/product/mb/K9A2-Platinum.html", NULL),
B("MSI", "MS-7379 (G31M)", OK, "http://www.msi.com/product/mb/G31M.html", NULL),
B("MSI", "MS-7399 1.1 (Persian)", OK, "http://acersupport.com/acerpanam/desktop/0000/Acer/AspireM5640/AspireM5640sp2.shtml", "This is an OEM board used by Acer in e.g. Aspire M5640/M3640."),
+ B("MSI", "MS-7502", OK, NULL, "This is an OEM board used by Medion in e.g. Medion MD8833."),
B("MSI", "MS-7522 (MSI X58 Pro-E)", OK, "http://www.msi.com/product/mb/X58_ProE.html", NULL),
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),
@@ -1046,6 +1049,7 @@ const struct board_info boards_known[] = {
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", "AB61", OK, "http://www.shuttle.eu/_archive/older/de/ab61.htm", 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),
@@ -1149,7 +1153,8 @@ const struct board_info boards_known[] = {
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", "IONITX-A", OK, NULL, NULL),
+ B("ZOTAC", "IONITX-A-E", OK, NULL, NULL),
+ B("ZOTAC", "IONITX-F-E", OK, NULL, NULL),
B("ZOTAC", "nForce 630i Supreme (N73U-Supreme)", OK, NULL, NULL),
B("ZOTAC", "ZBOX AD02 (PLUS)", OK, NULL, NULL),
B("ZOTAC", "ZBOX HD-ID11", OK, NULL, NULL),
@@ -1171,16 +1176,17 @@ const struct board_info laptops_known[] = {
B("Dell", "Latitude CPi A366XT", BAD, "http://www.coreboot.org/Dell_Latitude_CPi_A366XT", "The laptop immediately powers off if you try to hot-swap the chip. It's not yet tested if write/erase would work on this laptop."),
B("Dell", "Vostro 3700", BAD, NULL, "Locked ME, see http://www.flashrom.org/pipermail/flashrom/2012-May/009197.html."),
B("Dell", "Latitude E6520", BAD, NULL, "Locked ME, see http://www.flashrom.org/pipermail/flashrom/2012-June/009420.html."),
- B("Elitegroup", "A928", OK, NULL, "Bootsector is locked and needs to be skipped with a layout file (writeable address range is 00000000:0003bfff"),
+ B("Elitegroup", "A928", OK, NULL, "Bootsector is locked and needs to be skipped with a layout file (writeable address range is 00000000:0003bfff)."),
B("HP/Compaq", "EliteBook 8560p", BAD, NULL, "SPI lock down, SMM protection, PR in BIOS region, read-only descriptor, locked ME region."),
B("HP/Compaq", "nx9005", BAD, "http://h18000.www1.hp.com/products/quickspecs/11602_na/11602_na.HTML", "Shuts down when probing for a chip. http://www.flashrom.org/pipermail/flashrom/2010-May/003321.html"),
B("HP/Compaq", "nx9010", BAD, "http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&objectID=c00348514", "Hangs upon '''flashrom -V''' (needs hard power-cycle then)."),
- B("IBM/Lenovo", "Thinkpad T40p", BAD, "http://www.thinkwiki.org/wiki/Category:T40p", NULL),
- B("IBM/Lenovo", "Thinkpad T420", BAD, "http://www.thinkwiki.org/wiki/Category:T420", "Probing works (Macronix MX25L6405, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs) and ME is locked. Also, a Protected Range is locking the top range of the BIOS region (presumably the boot block)."),
- B("IBM/Lenovo", "Thinkpad T410s", BAD, "http://www.thinkwiki.org/wiki/Category:T410s", "Probing works (Winbond W25X64, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs) and ME is locked. Also, a Protected Range is locking the top range of the BIOS region (presumably the boot block)."),
- B("IBM/Lenovo", "Thinkpad X1", BAD, "http://www.thinkwiki.org/wiki/Category:X1", "Probing works (ST M25PX64, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs) and ME is locked. Also, a Protected Range is locking the top range of the BIOS region (presumably the boot block)."),
- B("IBM/Lenovo", "240", BAD, "http://www.stanford.edu/~bresnan//tp240.html", "Seems to (partially) work at first, but one block/sector cannot be written which then leaves you with a bricked laptop. Maybe this can be investigated and fixed in software later."),
- B("Lenovo", "3000 V100 TF05Cxx", OK, "http://www5.pc.ibm.com/europe/products.nsf/products?openagent&brand=Lenovo3000Notebook&series=Lenovo+3000+V+Series#viewallmodelstop", NULL),
+ B("IBM/Lenovo", "ThinkPad T40p", BAD, "http://www.thinkwiki.org/wiki/Category:T40p", NULL),
+ B("IBM/Lenovo", "ThinkPad T420", BAD, "http://www.thinkwiki.org/wiki/Category:T420", "Probing works (Macronix MX25L6405, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs) and ME is locked. Also, a Protected Range is locking the top range of the BIOS region (presumably the boot block)."),
+ B("IBM/Lenovo", "ThinkPad T410s", BAD, "http://www.thinkwiki.org/wiki/Category:T410s", "Probing works (Winbond W25X64, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs) and ME is locked. Also, a Protected Range is locking the top range of the BIOS region (presumably the boot block)."),
+ B("IBM/Lenovo", "ThinkPad X1", BAD, "http://www.thinkwiki.org/wiki/Category:X1", "Probing works (ST M25PX64, 8192 kB, SPI), but parts of the flash are problematic: descriptor is r/o (conforming to ICH reqs) and ME is locked. Also, a Protected Range is locking the top range of the BIOS region (presumably the boot block)."),
+ B("IBM/Lenovo", "ThinkPad T530", OK, "http://www.thinkwiki.org/wiki/Category:T530", "Works fine but only with coreboot (due to locked regions and additional PR restrictions)."),
+ B("IBM/Lenovo", "ThinkPad 240", BAD, "http://www.stanford.edu/~bresnan//tp240.html", "Seems to (partially) work at first, but one block/sector cannot be written which then leaves you with a bricked laptop. Maybe this can be investigated and fixed in software later."),
+ B("IBM/Lenovo", "3000 V100 TF05Cxx", OK, "http://www5.pc.ibm.com/europe/products.nsf/products?openagent&brand=Lenovo3000Notebook&series=Lenovo+3000+V+Series#viewallmodelstop", NULL),
//B("MSI", "GT60-2OD", OK, "http://www.msi.com/product/nb/GT60_2OD.html", NULL), requires layout patches
#endif
diff --git a/sb600spi.c b/sb600spi.c
index 5710fb27e..69fad65ce 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -191,7 +191,7 @@ static int check_readwritecnt(struct flashctx *flash, unsigned int writecnt, uns
return SPI_INVALID_LENGTH;
}
- unsigned int maxreadcnt = flash->mst->spi.max_data_read + 3;
+ unsigned int maxreadcnt = flash->mst->spi.max_data_read;
if (readcnt > maxreadcnt) {
msg_pinfo("%s: SPI controller can not receive %d bytes, it is limited to %d bytes\n",
__func__, readcnt, maxreadcnt);