[flashrom] [PATCH 1/4] Improve SPI status register pretty printing.

Stefan Tauner stefan.tauner at student.tuwien.ac.at
Sun Sep 23 16:54:54 CEST 2012


 - Move all functions related to SPI status registers to a new file
   spi25_status_register.c. This includes the generic as well as the
   SST-specificfunctions from spi25.c and the chip-specific functions
   from a25.c and at25.c.
 - introduce
    * spi_prettyprint_status_register_hex()
    * spi_prettyprint_status_register_bpl()
    * spi_prettyprint_status_register_plain()
   Use the latter on every compatible flash chip that has no better printlock
   function set and get rid of the implicit pretty printing in the SPI probing
   functions.
 - remove
    * spi_prettyprint_status_register_common()
    * spi_prettyprint_status_register_amic_a25lq032() because it can be fully
      substituted with spi_prettyprint_status_register_amic_a25l032().
    * spi_prettyprint_status_register() (old switch, no longer needed)
 - promote and export spi_prettyprint_status_register_st_m25p() as
   spi_prettyprint_status_register_default_bp3().
 - add #define TEST_BAD_REW and use it for a number of Atmel chips which
   had only TEST_BAD_READ set even though they dont have erasers or a write
   function set.

Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
---
 Makefile          |    4 +-
 a25.c             |  100 ---------
 at25.c            |  281 --------------------------
 chipdrivers.h     |   41 ++--
 flash.h           |    1 +
 flashchips.c      |  140 +++++++++++--
 spi25.c           |  294 +--------------------------
 spi25_statusreg.c |  584 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 733 insertions(+), 712 deletions(-)
 delete mode 100644 a25.c
 delete mode 100644 at25.c
 create mode 100644 spi25_statusreg.c

diff --git a/Makefile b/Makefile
index 9309ce5..de7ad84 100644
--- a/Makefile
+++ b/Makefile
@@ -284,8 +284,8 @@ endif
 
 CHIP_OBJS = jedec.o stm50flw0x0x.o w39.o w29ee011.o \
 	sst28sf040.o m29f400bt.o 82802ab.o pm49fl00x.o \
-	sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o \
-	a25.o at25.o opaque.o sfdp.o en29lv640b.o
+	sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o spi25_statusreg.o \
+	opaque.o sfdp.o en29lv640b.o
 
 ###############################################################################
 # Library code.
diff --git a/a25.c b/a25.c
deleted file mode 100644
index 2264157..0000000
--- a/a25.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * This file is part of the flashrom project.
- *
- * Copyright (C) 2010 Carl-Daniel Hailfinger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include "flash.h"
-#include "chipdrivers.h"
-#include "spi.h"
-
-/* Prettyprint the status register. Works for AMIC A25L series. */
-
-int spi_prettyprint_status_register_amic_a25l05p(struct flashctx *flash)
-{
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-
-	spi_prettyprint_status_register_srwd(status);
-	spi_prettyprint_status_register_bit(status, 6);
-	spi_prettyprint_status_register_bit(status, 5);
-	spi_prettyprint_status_register_bit(status, 4);
-	spi_prettyprint_status_register_bp(status, 1);
-	spi_prettyprint_status_register_welwip(status);
-	return 0;
-}
-
-int spi_prettyprint_status_register_amic_a25l40p(struct flashctx *flash)
-{
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-
-	spi_prettyprint_status_register_srwd(status);
-	spi_prettyprint_status_register_bit(status, 6);
-	spi_prettyprint_status_register_bit(status, 5);
-	spi_prettyprint_status_register_bp(status, 2);
-	spi_prettyprint_status_register_welwip(status);
-	return 0;
-}
-
-int spi_prettyprint_status_register_amic_a25l032(struct flashctx *flash)
-{
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-
-	spi_prettyprint_status_register_srwd(status);
-	msg_cdbg("Chip status register: Sector Protect Size (SEC) "
-		 "is %i KB\n", (status & (1 << 6)) ? 4 : 64);
-	msg_cdbg("Chip status register: Top/Bottom (TB) "
-		 "is %s\n", (status & (1 << 5)) ? "bottom" : "top");
-	spi_prettyprint_status_register_bp(status, 2);
-	spi_prettyprint_status_register_welwip(status);
-	msg_cdbg("Chip status register 2 is NOT decoded!\n");
-	return 0;
-}
-
-int spi_prettyprint_status_register_amic_a25lq032(struct flashctx *flash)
-{
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-
-	spi_prettyprint_status_register_srwd(status);
-	msg_cdbg("Chip status register: Sector Protect Size (SEC) "
-		 "is %i KB\n", (status & (1 << 6)) ? 4 : 64);
-	msg_cdbg("Chip status register: Top/Bottom (TB) "
-		 "is %s\n", (status & (1 << 5)) ? "bottom" : "top");
-	spi_prettyprint_status_register_bp(status, 2);
-	spi_prettyprint_status_register_welwip(status);
-	msg_cdbg("Chip status register 2 is NOT decoded!\n");
-	return 0;
-}
-
-/* FIXME: spi_disable_blockprotect is incorrect but works fine for chips using
- * spi_prettyprint_status_register_amic_a25l05p or
- * spi_prettyprint_status_register_amic_a25l40p.
- * FIXME: spi_disable_blockprotect is incorrect and will fail for chips using
- * spi_prettyprint_status_register_amic_a25l032 or
- * spi_prettyprint_status_register_amic_a25lq032 if those have locks controlled
- * by the second status register.
- */
diff --git a/at25.c b/at25.c
deleted file mode 100644
index 803e7e4..0000000
--- a/at25.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * This file is part of the flashrom project.
- *
- * Copyright (C) 2010 Carl-Daniel Hailfinger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include "flash.h"
-#include "chipdrivers.h"
-#include "spi.h"
-
-/* Prettyprint the status register. Works for Atmel A25/A26 series. */
-
-static void spi_prettyprint_status_register_atmel_at25_wpen(uint8_t status)
-{
-	msg_cdbg("Chip status register: Write Protect Enable (WPEN) "
-		 "is %sset\n", (status & (1 << 7)) ? "" : "not ");
-}
-
-static void spi_prettyprint_status_register_atmel_at25_srpl(uint8_t status)
-{
-	msg_cdbg("Chip status register: Sector Protection Register Lock (SRPL) "
-		 "is %sset\n", (status & (1 << 7)) ? "" : "not ");
-}
-
-static void spi_prettyprint_status_register_atmel_at25_epewpp(uint8_t status)
-{
-	msg_cdbg("Chip status register: Erase/Program Error (EPE) "
-		 "is %sset\n", (status & (1 << 5)) ? "" : "not ");
-	msg_cdbg("Chip status register: WP# pin (WPP) "
-		 "is %sasserted\n", (status & (1 << 4)) ? "not " : "");
-}
-
-static void spi_prettyprint_status_register_atmel_at25_swp(uint8_t status)
-{
-	msg_cdbg("Chip status register: Software Protection Status (SWP): ");
-	switch (status & (3 << 2)) {
-	case 0x0 << 2:
-		msg_cdbg("no sectors are protected\n");
-		break;
-	case 0x1 << 2:
-		msg_cdbg("some sectors are protected\n");
-		/* FIXME: Read individual Sector Protection Registers. */
-		break;
-	case 0x3 << 2:
-		msg_cdbg("all sectors are protected\n");
-		break;
-	default:
-		msg_cdbg("reserved for future use\n");
-		break;
-	}
-}
-
-int spi_prettyprint_status_register_at25df(struct flashctx *flash)
-{
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-
-	spi_prettyprint_status_register_atmel_at25_srpl(status);
-	spi_prettyprint_status_register_bit(status, 6);
-	spi_prettyprint_status_register_atmel_at25_epewpp(status);
-	spi_prettyprint_status_register_atmel_at25_swp(status);
-	spi_prettyprint_status_register_welwip(status);
-	return 0;
-}
-
-int spi_prettyprint_status_register_at25df_sec(struct flashctx *flash)
-{
-	/* FIXME: We should check the security lockdown. */
-	msg_cdbg("Ignoring security lockdown (if present)\n");
-	msg_cdbg("Ignoring status register byte 2\n");
-	return spi_prettyprint_status_register_at25df(flash);
-}
-
-int spi_prettyprint_status_register_at25f512b(struct flashctx *flash)
-{
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-
-	spi_prettyprint_status_register_atmel_at25_srpl(status);
-	spi_prettyprint_status_register_bit(status, 6);
-	spi_prettyprint_status_register_atmel_at25_epewpp(status);
-	spi_prettyprint_status_register_bit(status, 3);
-	spi_prettyprint_status_register_bp(status, 0);
-	spi_prettyprint_status_register_welwip(status);
-	return 0;
-}
-
-int spi_prettyprint_status_register_at25fs010(struct flashctx *flash)
-{
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-
-	spi_prettyprint_status_register_atmel_at25_wpen(status);
-	msg_cdbg("Chip status register: Bit 6 / Block Protect 4 (BP4) is "
-		 "%sset\n", (status & (1 << 6)) ? "" : "not ");
-	msg_cdbg("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
-		 "%sset\n", (status & (1 << 5)) ? "" : "not ");
-	spi_prettyprint_status_register_bit(status, 4);
-	msg_cdbg("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
-		 "%sset\n", (status & (1 << 3)) ? "" : "not ");
-	msg_cdbg("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
-		 "%sset\n", (status & (1 << 2)) ? "" : "not ");
-	/* FIXME: Pretty-print detailed sector protection status. */
-	spi_prettyprint_status_register_welwip(status);
-	return 0;
-}
-
-int spi_prettyprint_status_register_at25fs040(struct flashctx *flash)
-{
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-
-	spi_prettyprint_status_register_atmel_at25_wpen(status);
-	spi_prettyprint_status_register_bp(status, 4);
-	/* FIXME: Pretty-print detailed sector protection status. */
-	spi_prettyprint_status_register_welwip(status);
-	return 0;
-}
-
-int spi_prettyprint_status_register_atmel_at26df081a(struct flashctx *flash)
-{
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-
-	spi_prettyprint_status_register_atmel_at25_srpl(status);
-	msg_cdbg("Chip status register: Sequential Program Mode Status (SPM) "
-		 "is %sset\n", (status & (1 << 6)) ? "" : "not ");
-	spi_prettyprint_status_register_atmel_at25_epewpp(status);
-	spi_prettyprint_status_register_atmel_at25_swp(status);
-	spi_prettyprint_status_register_welwip(status);
-	return 0;
-}
-
-int spi_disable_blockprotect_at25df(struct flashctx *flash)
-{
-	uint8_t status;
-	int result;
-
-	status = spi_read_status_register(flash);
-	/* If block protection is disabled, stop here. */
-	if ((status & (3 << 2)) == 0)
-		return 0;
-
-	msg_cdbg("Some block protection in effect, disabling... ");
-	if (status & (1 << 7)) {
-		msg_cdbg("Need to disable Sector Protection Register Lock\n");
-		if ((status & (1 << 4)) == 0) {
-			msg_cerr("WP# pin is active, disabling "
-				 "write protection is impossible.\n");
-			return 1;
-		}
-		/* All bits except bit 7 (SPRL) are readonly. */
-		result = spi_write_status_register(flash, status & ~(1 << 7));
-		if (result) {
-			msg_cerr("spi_write_status_register failed.\n");
-			return result;
-		}
-		
-	}
-	/* Global unprotect. Make sure to mask SPRL as well. */
-	result = spi_write_status_register(flash, status & ~0xbc);
-	if (result) {
-		msg_cerr("spi_write_status_register failed.\n");
-		return result;
-	}
-	status = spi_read_status_register(flash);
-	if ((status & (3 << 2)) != 0) {
-		msg_cerr("Block protection could not be disabled!\n");
-		return 1;
-	}
-	msg_cdbg("done.\n");
-	return 0;
-}
-
-int spi_disable_blockprotect_at25df_sec(struct flashctx *flash)
-{
-	/* FIXME: We should check the security lockdown. */
-	msg_cinfo("Ignoring security lockdown (if present)\n");
-	return spi_disable_blockprotect_at25df(flash);
-}
-
-int spi_disable_blockprotect_at25f512b(struct flashctx *flash)
-{
-	/* spi_disable_blockprotect_at25df is not really the right way to do
-	 * this, but the side effects of said function work here as well.
-	 */
-	return spi_disable_blockprotect_at25df(flash);
-}
-
-int spi_disable_blockprotect_at25fs010(struct flashctx *flash)
-{
-	uint8_t status;
-	int result;
-
-	status = spi_read_status_register(flash);
-	/* If block protection is disabled, stop here. */
-	if ((status & 0x6c) == 0)
-		return 0;
-
-	msg_cdbg("Some block protection in effect, disabling... ");
-	if (status & (1 << 7)) {
-		msg_cdbg("Need to disable Status Register Write Protect\n");
-		/* Clear bit 7 (WPEN). */
-		result = spi_write_status_register(flash, status & ~(1 << 7));
-		if (result) {
-			msg_cerr("spi_write_status_register failed.\n");
-			return result;
-		}
-	}
-	/* Global unprotect. Make sure to mask WPEN as well. */
-	result = spi_write_status_register(flash, status & ~0xec);
-	if (result) {
-		msg_cerr("spi_write_status_register failed.\n");
-		return result;
-	}
-	status = spi_read_status_register(flash);
-	if ((status & 0x6c) != 0) {
-		msg_cerr("Block protection could not be disabled!\n");
-		return 1;
-	}
-	msg_cdbg("done.\n");
-	return 0;
-}
-
-int spi_disable_blockprotect_at25fs040(struct flashctx *flash)
-{
-	uint8_t status;
-	int result;
-
-	status = spi_read_status_register(flash);
-	/* If block protection is disabled, stop here. */
-	if ((status & 0x7c) == 0)
-		return 0;
-
-	msg_cdbg("Some block protection in effect, disabling... ");
-	if (status & (1 << 7)) {
-		msg_cdbg("Need to disable Status Register Write Protect\n");
-		/* Clear bit 7 (WPEN). */
-		result = spi_write_status_register(flash, status & ~(1 << 7));
-		if (result) {
-			msg_cerr("spi_write_status_register failed.\n");
-			return result;
-		}
-	}
-	/* Global unprotect. Make sure to mask WPEN as well. */
-	result = spi_write_status_register(flash, status & ~0xfc);
-	if (result) {
-		msg_cerr("spi_write_status_register failed.\n");
-		return result;
-	}
-	status = spi_read_status_register(flash);
-	if ((status & 0x7c) != 0) {
-		msg_cerr("Block protection could not be disabled!\n");
-		return 1;
-	}
-	msg_cdbg("done.\n");
-	return 0;
-}
diff --git a/chipdrivers.h b/chipdrivers.h
index 1ef4959..d5cd2ea 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -49,47 +49,44 @@ int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int b
 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);
-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);
-void spi_prettyprint_status_register_bp(uint8_t status, int bp);
-void spi_prettyprint_status_register_srwd(uint8_t status);
-void spi_prettyprint_status_register_welwip(uint8_t status);
-int spi_prettyprint_status_register(struct flashctx *flash);
-int spi_disable_blockprotect(struct flashctx *flash);
 int spi_byte_program(struct flashctx *flash, unsigned int addr, uint8_t databyte);
 int spi_nbyte_program(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len);
 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);
 
-/* sfdp.c */
-int probe_spi_sfdp(struct flashctx *flash);
-
-/* opaque.c */
-int probe_opaque(struct flashctx *flash);
-int read_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
-int write_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
-int erase_opaque(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen);
-
-/* a25.c */
+/* spi25_sr.c */
+uint8_t spi_read_status_register(struct flashctx *flash);
+int spi_write_status_register(struct flashctx *flash, int status);
+int spi_prettyprint_status_register_plain(struct flashctx *flash);
+int spi_prettyprint_status_register_default_bp3(struct flashctx *flash);
+int spi_disable_blockprotect(struct flashctx *flash);
 int spi_prettyprint_status_register_amic_a25l05p(struct flashctx *flash);
 int spi_prettyprint_status_register_amic_a25l40p(struct flashctx *flash);
 int spi_prettyprint_status_register_amic_a25l032(struct flashctx *flash);
-int spi_prettyprint_status_register_amic_a25lq032(struct flashctx *flash);
-
-/* at25.c */
 int spi_prettyprint_status_register_at25df(struct flashctx *flash);
 int spi_prettyprint_status_register_at25df_sec(struct flashctx *flash);
 int spi_prettyprint_status_register_at25f512b(struct flashctx *flash);
 int spi_prettyprint_status_register_at25fs010(struct flashctx *flash);
 int spi_prettyprint_status_register_at25fs040(struct flashctx *flash);
-int spi_prettyprint_status_register_atmel_at26df081a(struct flashctx *flash);
+int spi_prettyprint_status_register_at26df081a(struct flashctx *flash);
 int spi_disable_blockprotect_at25df(struct flashctx *flash);
 int spi_disable_blockprotect_at25df_sec(struct flashctx *flash);
 int spi_disable_blockprotect_at25f512b(struct flashctx *flash);
 int spi_disable_blockprotect_at25fs010(struct flashctx *flash);
 int spi_disable_blockprotect_at25fs040(struct flashctx *flash);
+int spi_prettyprint_status_register_sst25(struct flashctx *flash);
+int spi_prettyprint_status_register_sst25vf016(struct flashctx *flash);
+int spi_prettyprint_status_register_sst25vf040b(struct flashctx *flash);
+
+/* sfdp.c */
+int probe_spi_sfdp(struct flashctx *flash);
+
+/* opaque.c */
+int probe_opaque(struct flashctx *flash);
+int read_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
+int write_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
+int erase_opaque(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen);
 
 /* 82802ab.c */
 uint8_t wait_82802ab(struct flashctx *flash);
diff --git a/flash.h b/flash.h
index 4913536..baa6251 100644
--- a/flash.h
+++ b/flash.h
@@ -188,6 +188,7 @@ struct flashctx {
 #define TEST_BAD_READ	(1 << 5)
 #define TEST_BAD_ERASE	(1 << 6)
 #define TEST_BAD_WRITE	(1 << 7)
+#define TEST_BAD_REW	(TEST_BAD_READ | TEST_BAD_ERASE | TEST_BAD_WRITE)
 #define TEST_BAD_PREW	(TEST_BAD_PROBE | TEST_BAD_READ | TEST_BAD_ERASE | TEST_BAD_WRITE)
 #define TEST_BAD_MASK	0xf0
 
diff --git a/flashchips.c b/flashchips.c
index a6c2004..c28a6c2 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -1194,7 +1194,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}			
 		},
-		.printlock	= spi_prettyprint_status_register_amic_a25lq032,
+		.printlock	= spi_prettyprint_status_register_amic_a25l032,
 		.unlock		= NULL, /* Two status reg bytes (read with 0x35 and 0x05) */
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -1795,7 +1795,7 @@ const struct flashchip flashchips[] = {
 		.total_size	= 512,
 		.page_size	= 256,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_BAD_WRITE,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
@@ -1805,6 +1805,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_20,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.write		= NULL /* Incompatible Page write */,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600}, /* 3.0-3.6V for higher speed, 2.7-3.6V normal */
@@ -1841,7 +1842,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
-		.printlock	= spi_prettyprint_status_register_atmel_at26df081a,
+		.printlock	= spi_prettyprint_status_register_at26df081a,
 		.unlock		= spi_disable_blockprotect_at25df,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -1917,7 +1918,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
-		.printlock	= spi_prettyprint_status_register_atmel_at26df081a,
+		.printlock	= spi_prettyprint_status_register_at26df081a,
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -1937,7 +1938,7 @@ const struct flashchip flashchips[] = {
 		.tested		= TEST_UNTESTED,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
-		.printlock	= spi_prettyprint_status_register_atmel_at26df081a,
+		.printlock	= spi_prettyprint_status_register_at26df081a,
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -1951,7 +1952,7 @@ const struct flashchip flashchips[] = {
 		.model_id	= ATMEL_AT26F004,
 		.total_size	= 512,
 		.page_size	= 256,
-		.tested		= TEST_UNTESTED,
+		.tested		= TEST_BAD_WRITE,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
@@ -1974,6 +1975,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.write		= NULL /* Incompatible Page write */,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
@@ -2084,7 +2086,7 @@ const struct flashchip flashchips[] = {
 		.total_size	= 16896 /* No power of two sizes */,
 		.page_size	= 1056 /* No power of two sizes */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
+		.tested		= TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL /* Incompatible Page write */,
@@ -2101,7 +2103,7 @@ const struct flashchip flashchips[] = {
 		.total_size	= 128 /* Size can only be determined from status register */,
 		.page_size	= 256 /* Size can only be determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
+		.tested		= TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
@@ -2118,7 +2120,7 @@ const struct flashchip flashchips[] = {
 		.total_size	= 256 /* Size can only be determined from status register */,
 		.page_size	= 256 /* Size can only be determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
+		.tested		= TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
@@ -2135,7 +2137,7 @@ const struct flashchip flashchips[] = {
 		.total_size	= 512 /* Size can only be determined from status register */,
 		.page_size	= 256 /* Size can only be determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
+		.tested		= TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
@@ -2152,7 +2154,7 @@ const struct flashchip flashchips[] = {
 		.total_size	= 1024 /* Size can only be determined from status register */,
 		.page_size	= 256 /* Size can only be determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
+		.tested		= TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
@@ -2169,7 +2171,7 @@ const struct flashchip flashchips[] = {
 		.total_size	= 2048 /* Size can only be determined from status register */,
 		.page_size	= 512 /* Size can only be determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
+		.tested		= TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
@@ -2186,7 +2188,7 @@ const struct flashchip flashchips[] = {
 		.total_size	= 4224 /* No power of two sizes */,
 		.page_size	= 528 /* No power of two sizes */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
+		.tested		= TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
@@ -2205,7 +2207,7 @@ const struct flashchip flashchips[] = {
 		/* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
 		.feature_bits	= FEATURE_OTP,
-		.tested		= TEST_BAD_READ,
+		.tested		= TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
@@ -2222,7 +2224,7 @@ const struct flashchip flashchips[] = {
 		.total_size	= 8192 /* Size can only be determined from status register */,
 		.page_size	= 1024 /* Size can only be determined from status register */,
 		/* does not support EWSR nor WREN and has no writable status register bits whatsoever */
-		.tested		= TEST_BAD_READ,
+		.tested		= TEST_BAD_REW,
 		.probe		= probe_spi_rdid,
 		.probe_timing	= TIMING_ZERO,
 		.write		= NULL,
@@ -2615,6 +2617,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_1,
 		.read		= spi_chip_read,
@@ -2648,6 +2651,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2681,6 +2685,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2714,6 +2719,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2747,6 +2753,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2781,6 +2788,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2815,6 +2823,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2849,6 +2858,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2883,6 +2893,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2917,6 +2928,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2951,6 +2963,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -2985,6 +2998,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3019,6 +3033,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3053,6 +3068,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3087,6 +3103,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3121,6 +3138,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3155,6 +3173,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3192,6 +3211,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3229,6 +3249,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3266,6 +3287,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3300,6 +3322,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3334,6 +3357,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3368,6 +3392,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3402,6 +3427,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3436,6 +3462,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3471,6 +3498,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3506,6 +3534,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3547,6 +3576,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3582,6 +3612,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3617,6 +3648,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3652,6 +3684,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3687,6 +3720,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -3723,6 +3757,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4011,6 +4046,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4048,6 +4084,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4086,6 +4123,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4124,6 +4162,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4162,6 +4201,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4200,6 +4240,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4237,6 +4278,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4273,6 +4315,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4665,6 +4708,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4699,6 +4743,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4736,6 +4781,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4773,6 +4819,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4810,6 +4857,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4847,6 +4895,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4881,6 +4930,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4915,6 +4965,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4949,6 +5000,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -4983,6 +5035,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5017,6 +5070,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5051,6 +5105,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5455,6 +5510,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5486,6 +5542,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5517,6 +5574,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5548,6 +5606,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5579,6 +5638,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5609,6 +5669,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5639,6 +5700,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5676,6 +5738,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5707,6 +5770,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5738,6 +5802,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5775,6 +5840,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -5806,6 +5872,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -6079,6 +6146,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -6169,6 +6237,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -6197,6 +6266,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -6225,6 +6295,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -6253,6 +6324,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -6281,6 +6353,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -6312,6 +6385,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_60,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
 		.read		= spi_chip_read,
@@ -6343,6 +6417,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_60,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
 		.read		= spi_chip_read,
@@ -6374,6 +6449,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_60,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_1,
 		.read		= spi_chip_read,
@@ -6411,6 +6487,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25vf016,
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_aai_write,
 		.read		= spi_chip_read,
@@ -6448,6 +6525,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_aai_write,
 		.read		= spi_chip_read,
@@ -6485,6 +6563,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -6516,6 +6595,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_60,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
 		.read		= spi_chip_read,
@@ -6553,6 +6633,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25vf040b,
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_aai_write,
 		.read		= spi_chip_read,
@@ -6590,6 +6671,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25vf040b,
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_aai_write,
 		.read		= spi_chip_read,
@@ -6627,6 +6709,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			},
 		},
+		.printlock	= spi_prettyprint_status_register_sst25, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_aai_write,
 		.read		= spi_chip_read,
@@ -7439,6 +7522,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7472,6 +7556,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_1, /* 128 */
 		.read		= spi_chip_read,
@@ -7500,6 +7585,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7529,6 +7615,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_1, /* 128 */
 		.read		= spi_chip_read,
@@ -7557,6 +7644,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7585,6 +7673,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7613,6 +7702,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7640,6 +7730,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7668,6 +7759,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7696,6 +7788,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7724,6 +7817,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7752,6 +7846,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_default_bp3, /* TODO: check */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7784,6 +7879,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7814,6 +7910,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -7845,6 +7942,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8662,6 +8760,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8700,6 +8799,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8738,6 +8838,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8776,6 +8877,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8813,6 +8915,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8843,6 +8946,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8874,6 +8978,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8905,6 +9010,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8936,6 +9042,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -8973,6 +9080,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -9010,6 +9118,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
@@ -9047,6 +9156,7 @@ const struct flashchip flashchips[] = {
 				.block_erase = spi_block_erase_c7,
 			}
 		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
 		.unlock		= spi_disable_blockprotect,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
diff --git a/spi25.c b/spi25.c
index a65f548..38f9b2b 100644
--- a/spi25.c
+++ b/spi25.c
@@ -148,14 +148,8 @@ static int probe_spi_rdid_generic(struct flashctx *flash, int bytes)
 
 	msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
 
-	if (id1 == chip->manufacture_id && id2 == chip->model_id) {
-		/* Print the status register to tell the
-		 * user about possible write protection.
-		 */
-		spi_prettyprint_status_register(flash);
-
+	if (id1 == chip->manufacture_id && id2 == chip->model_id)
 		return 1;
-	}
 
 	/* Test if this is a pure vendor match. */
 	if (id1 == chip->manufacture_id && GENERIC_DEVICE_ID == chip->model_id)
@@ -210,14 +204,8 @@ int probe_spi_rems(struct flashctx *flash)
 
 	msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
 
-	if (id1 == chip->manufacture_id && id2 == chip->model_id) {
-		/* Print the status register to tell the
-		 * user about possible write protection.
-		 */
-		spi_prettyprint_status_register(flash);
-
+	if (id1 == chip->manufacture_id && id2 == chip->model_id)
 		return 1;
-	}
 
 	/* Test if this is a pure vendor match. */
 	if (id1 == chip->manufacture_id && GENERIC_DEVICE_ID == chip->model_id)
@@ -268,10 +256,6 @@ int probe_spi_res1(struct flashctx *flash)
 	if (id2 != flash->chip->model_id)
 		return 0;
 
-	/* Print the status register to tell the
-	 * user about possible write protection.
-	 */
-	spi_prettyprint_status_register(flash);
 	return 1;
 }
 
@@ -292,168 +276,9 @@ int probe_spi_res2(struct flashctx *flash)
 	if (id1 != flash->chip->manufacture_id || id2 != flash->chip->model_id)
 		return 0;
 
-	/* Print the status register to tell the
-	 * user about possible write protection.
-	 */
-	spi_prettyprint_status_register(flash);
 	return 1;
 }
 
-uint8_t spi_read_status_register(struct flashctx *flash)
-{
-	static const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
-	/* FIXME: No workarounds for driver/hardware bugs in generic code. */
-	unsigned char readarr[2]; /* JEDEC_RDSR_INSIZE=1 but wbsio needs 2 */
-	int ret;
-
-	/* Read Status Register */
-	ret = spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd,
-			       readarr);
-	if (ret)
-		msg_cerr("RDSR failed!\n");
-
-	return readarr[0];
-}
-
-/* Common highest bit: Status Register Write Disable (SRWD). */
-void spi_prettyprint_status_register_srwd(uint8_t status)
-{
-	msg_cdbg("Chip status register: Status Register Write Disable (SRWD) is %sset\n",
-		 (status & (1 << 7)) ? "" : "not ");
-}
-
-void spi_prettyprint_status_register_welwip(uint8_t status)
-{
-	msg_cdbg("Chip status register: Write Enable Latch (WEL) is "
-		     "%sset\n", (status & (1 << 1)) ? "" : "not ");
-	msg_cdbg("Chip status register: Write In Progress (WIP/BUSY) is "
-		     "%sset\n", (status & (1 << 0)) ? "" : "not ");
-}
-
-/* Prettyprint the status register. Common definitions. */
-void spi_prettyprint_status_register_bp(uint8_t status, int bp)
-{
-	switch (bp) {
-	/* Fall through. */
-	case 4:
-		msg_cdbg("Chip status register: Block Protect 4 (BP4) "
-			     "is %sset\n", (status & (1 << 5)) ? "" : "not ");
-	case 3:
-		msg_cdbg("Chip status register: Block Protect 3 (BP3) "
-			     "is %sset\n", (status & (1 << 5)) ? "" : "not ");
-	case 2:
-		msg_cdbg("Chip status register: Block Protect 2 (BP2) "
-			     "is %sset\n", (status & (1 << 4)) ? "" : "not ");
-	case 1:
-		msg_cdbg("Chip status register: Block Protect 1 (BP1) "
-			     "is %sset\n", (status & (1 << 3)) ? "" : "not ");
-	case 0:
-		msg_cdbg("Chip status register: Block Protect 0 (BP0) "
-			     "is %sset\n", (status & (1 << 2)) ? "" : "not ");
-	}
-}
-
-/* Prettyprint the status register. Unnamed bits. */
-void spi_prettyprint_status_register_bit(uint8_t status, int bit)
-{
-	msg_cdbg("Chip status register: Bit %i "
-		 "is %sset\n", bit, (status & (1 << bit)) ? "" : "not ");
-}
-
-static void spi_prettyprint_status_register_common(uint8_t status)
-{
-	spi_prettyprint_status_register_bp(status, 3);
-	spi_prettyprint_status_register_welwip(status);
-}
-
-/* Prettyprint the status register. Works for
- * ST M25P series
- * MX MX25L series
- */
-void spi_prettyprint_status_register_st_m25p(uint8_t status)
-{
-	spi_prettyprint_status_register_srwd(status);
-	spi_prettyprint_status_register_bit(status, 6);
-	spi_prettyprint_status_register_common(status);
-}
-
-void spi_prettyprint_status_register_sst25(uint8_t status)
-{
-	msg_cdbg("Chip status register: Block Protect Write Disable "
-		     "(BPL) is %sset\n", (status & (1 << 7)) ? "" : "not ");
-	msg_cdbg("Chip status register: Auto Address Increment Programming "
-		     "(AAI) is %sset\n", (status & (1 << 6)) ? "" : "not ");
-	spi_prettyprint_status_register_common(status);
-}
-
-/* Prettyprint the status register. Works for
- * SST 25VF016
- */
-void spi_prettyprint_status_register_sst25vf016(uint8_t status)
-{
-	static const char *const bpt[] = {
-		"none",
-		"1F0000H-1FFFFFH",
-		"1E0000H-1FFFFFH",
-		"1C0000H-1FFFFFH",
-		"180000H-1FFFFFH",
-		"100000H-1FFFFFH",
-		"all", "all"
-	};
-	spi_prettyprint_status_register_sst25(status);
-	msg_cdbg("Resulting block protection : %s\n",
-		     bpt[(status & 0x1c) >> 2]);
-}
-
-void spi_prettyprint_status_register_sst25vf040b(uint8_t status)
-{
-	static const char *const bpt[] = {
-		"none",
-		"0x70000-0x7ffff",
-		"0x60000-0x7ffff",
-		"0x40000-0x7ffff",
-		"all blocks", "all blocks", "all blocks", "all blocks"
-	};
-	spi_prettyprint_status_register_sst25(status);
-	msg_cdbg("Resulting block protection : %s\n",
-		bpt[(status & 0x1c) >> 2]);
-}
-
-int spi_prettyprint_status_register(struct flashctx *flash)
-{
-	const struct flashchip *chip = flash->chip;
-	uint8_t status;
-
-	status = spi_read_status_register(flash);
-	msg_cdbg("Chip status register is %02x\n", status);
-	switch (chip->manufacture_id) {
-	case ST_ID:
-		if (((chip->model_id & 0xff00) == 0x2000) ||
-		    ((chip->model_id & 0xff00) == 0x2500))
-			spi_prettyprint_status_register_st_m25p(status);
-		break;
-	case MACRONIX_ID:
-		if ((chip->model_id & 0xff00) == 0x2000)
-			spi_prettyprint_status_register_st_m25p(status);
-		break;
-	case SST_ID:
-		switch (chip->model_id) {
-		case 0x2541:
-			spi_prettyprint_status_register_sst25vf016(status);
-			break;
-		case 0x8d:
-		case 0x258d:
-			spi_prettyprint_status_register_sst25vf040b(status);
-			break;
-		default:
-			spi_prettyprint_status_register_sst25(status);
-			break;
-		}
-		break;
-	}
-	return 0;
-}
-
 int spi_chip_erase_60(struct flashctx *flash)
 {
 	int result;
@@ -799,92 +624,6 @@ erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode)
 	}
 }
 
-int spi_write_status_enable(struct flashctx *flash)
-{
-	static const unsigned char cmd[JEDEC_EWSR_OUTSIZE] = { JEDEC_EWSR };
-	int result;
-
-	/* Send EWSR (Enable Write Status Register). */
-	result = spi_send_command(flash, sizeof(cmd), JEDEC_EWSR_INSIZE, cmd, NULL);
-
-	if (result)
-		msg_cerr("%s failed\n", __func__);
-
-	return result;
-}
-
-/*
- * This is according the SST25VF016 datasheet, who knows it is more
- * generic that this...
- */
-static int spi_write_status_register_flag(struct flashctx *flash, int status, const unsigned char enable_opcode)
-{
-	int result;
-	int i = 0;
-	/*
-	 * WRSR requires either EWSR or WREN depending on chip type.
-	 * The code below relies on the fact hat EWSR and WREN have the same
-	 * INSIZE and OUTSIZE.
-	 */
-	struct spi_command cmds[] = {
-	{
-		.writecnt	= JEDEC_WREN_OUTSIZE,
-		.writearr	= (const unsigned char[]){ enable_opcode },
-		.readcnt	= 0,
-		.readarr	= NULL,
-	}, {
-		.writecnt	= JEDEC_WRSR_OUTSIZE,
-		.writearr	= (const unsigned char[]){ JEDEC_WRSR, (unsigned char) status },
-		.readcnt	= 0,
-		.readarr	= NULL,
-	}, {
-		.writecnt	= 0,
-		.writearr	= NULL,
-		.readcnt	= 0,
-		.readarr	= NULL,
-	}};
-
-	result = spi_send_multicommand(flash, cmds);
-	if (result) {
-		msg_cerr("%s failed during command execution\n", __func__);
-		/* No point in waiting for the command to complete if execution
-		 * failed.
-		 */
-		return result;
-	}
-	/* WRSR performs a self-timed erase before the changes take effect.
-	 * This may take 50-85 ms in most cases, and some chips apparently
-	 * allow running RDSR only once. Therefore pick an initial delay of
-	 * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed.
-	 */
-	programmer_delay(100 * 1000);
-	while (spi_read_status_register(flash) & SPI_SR_WIP) {
-		if (++i > 490) {
-			msg_cerr("Error: WIP bit after WRSR never cleared\n");
-			return TIMEOUT_ERROR;
-		}
-		programmer_delay(10 * 1000);
-	}
-	return 0;
-}
-
-int spi_write_status_register(struct flashctx *flash, int status)
-{
-	int feature_bits = flash->chip->feature_bits;
-	int ret = 1;
-
-	if (!(feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) {
-		msg_cdbg("Missing status register write definition, assuming "
-			 "EWSR is needed\n");
-		feature_bits |= FEATURE_WRSR_EWSR;
-	}
-	if (feature_bits & FEATURE_WRSR_WREN)
-		ret = spi_write_status_register_flag(flash, status, JEDEC_WREN);
-	if (ret && (feature_bits & FEATURE_WRSR_EWSR))
-		ret = spi_write_status_register_flag(flash, status, JEDEC_EWSR);
-	return ret;
-}
-
 int spi_byte_program(struct flashctx *flash, unsigned int addr,
 		     uint8_t databyte)
 {
@@ -969,35 +708,6 @@ int spi_nbyte_program(struct flashctx *flash, unsigned int addr, uint8_t *bytes,
 	return result;
 }
 
-/* A generic brute-force block protection disable works like this:
- * Write 0x00 to the status register. Check if any locks are still set (that
- * part is chip specific). Repeat once.
- */
-int spi_disable_blockprotect(struct flashctx *flash)
-{
-	uint8_t status;
-	int result;
-
-	status = spi_read_status_register(flash);
-	/* If block protection is disabled, stop here. */
-	if ((status & 0x3c) == 0)
-		return 0;
-
-	msg_cdbg("Some block protection in effect, disabling... ");
-	result = spi_write_status_register(flash, status & ~0x3c);
-	if (result) {
-		msg_cerr("spi_write_status_register failed.\n");
-		return result;
-	}
-	status = spi_read_status_register(flash);
-	if ((status & 0x3c) != 0) {
-		msg_cerr("Block protection could not be disabled!\n");
-		return 1;
-	}
-	msg_cdbg("done.\n");
-	return 0;
-}
-
 int spi_nbyte_read(struct flashctx *flash, unsigned int address, uint8_t *bytes,
 		   unsigned int len)
 {
diff --git a/spi25_statusreg.c b/spi25_statusreg.c
new file mode 100644
index 0000000..ce66c3b
--- /dev/null
+++ b/spi25_statusreg.c
@@ -0,0 +1,584 @@
+/*
+ * This file is part of the flashrom project.
+ * It handles everything related to status registers of the JEDEC family 25.
+ *
+ * Copyright (C) 2007, 2008, 2009, 2010 Carl-Daniel Hailfinger
+ * Copyright (C) 2008 coresystems GmbH
+ * Copyright (C) 2008 Ronald Hoogenboom <ronald at zonnet.nl>
+ * Copyright (C) 2012 Stefan Tauner
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include "flash.h"
+#include "chipdrivers.h"
+#include "spi.h"
+
+/* === Generic functions === */
+int spi_write_status_enable(struct flashctx *flash)
+{
+	static const unsigned char cmd[JEDEC_EWSR_OUTSIZE] = { JEDEC_EWSR };
+	int result;
+
+	/* Send EWSR (Enable Write Status Register). */
+	result = spi_send_command(flash, sizeof(cmd), JEDEC_EWSR_INSIZE, cmd, NULL);
+
+	if (result)
+		msg_cerr("%s failed\n", __func__);
+
+	return result;
+}
+
+static int spi_write_status_register_flag(struct flashctx *flash, int status, const unsigned char enable_opcode)
+{
+	int result;
+	int i = 0;
+	/*
+	 * WRSR requires either EWSR or WREN depending on chip type.
+	 * The code below relies on the fact hat EWSR and WREN have the same
+	 * INSIZE and OUTSIZE.
+	 */
+	struct spi_command cmds[] = {
+	{
+		.writecnt	= JEDEC_WREN_OUTSIZE,
+		.writearr	= (const unsigned char[]){ enable_opcode },
+		.readcnt	= 0,
+		.readarr	= NULL,
+	}, {
+		.writecnt	= JEDEC_WRSR_OUTSIZE,
+		.writearr	= (const unsigned char[]){ JEDEC_WRSR, (unsigned char) status },
+		.readcnt	= 0,
+		.readarr	= NULL,
+	}, {
+		.writecnt	= 0,
+		.writearr	= NULL,
+		.readcnt	= 0,
+		.readarr	= NULL,
+	}};
+
+	result = spi_send_multicommand(flash, cmds);
+	if (result) {
+		msg_cerr("%s failed during command execution\n", __func__);
+		/* No point in waiting for the command to complete if execution
+		 * failed.
+		 */
+		return result;
+	}
+	/* WRSR performs a self-timed erase before the changes take effect.
+	 * This may take 50-85 ms in most cases, and some chips apparently
+	 * allow running RDSR only once. Therefore pick an initial delay of
+	 * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed.
+	 */
+	programmer_delay(100 * 1000);
+	while (spi_read_status_register(flash) & SPI_SR_WIP) {
+		if (++i > 490) {
+			msg_cerr("Error: WIP bit after WRSR never cleared\n");
+			return TIMEOUT_ERROR;
+		}
+		programmer_delay(10 * 1000);
+	}
+	return 0;
+}
+
+int spi_write_status_register(struct flashctx *flash, int status)
+{
+	int feature_bits = flash->chip->feature_bits;
+	int ret = 1;
+
+	if (!(feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) {
+		msg_cdbg("Missing status register write definition, assuming "
+			 "EWSR is needed\n");
+		feature_bits |= FEATURE_WRSR_EWSR;
+	}
+	if (feature_bits & FEATURE_WRSR_WREN)
+		ret = spi_write_status_register_flag(flash, status, JEDEC_WREN);
+	if (ret && (feature_bits & FEATURE_WRSR_EWSR))
+		ret = spi_write_status_register_flag(flash, status, JEDEC_EWSR);
+	return ret;
+}
+
+uint8_t spi_read_status_register(struct flashctx *flash)
+{
+	static const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
+	/* FIXME: No workarounds for driver/hardware bugs in generic code. */
+	unsigned char readarr[2]; /* JEDEC_RDSR_INSIZE=1 but wbsio needs 2 */
+	int ret;
+
+	/* Read Status Register */
+	ret = spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd, readarr);
+	if (ret)
+		msg_cerr("RDSR failed!\n");
+
+	return readarr[0];
+}
+
+/* A generic brute-force block protection disable works like this:
+ * Write 0x00 to the status register. Check if any locks are still set (that
+ * part is chip specific). Repeat once.
+ */
+int spi_disable_blockprotect(struct flashctx *flash)
+{
+	uint8_t status;
+	int result;
+
+	status = spi_read_status_register(flash);
+	/* If block protection is disabled, stop here. */
+	if ((status & 0x3c) == 0)
+		return 0;
+
+	msg_cdbg("Some block protection in effect, disabling... ");
+	result = spi_write_status_register(flash, status & ~0x3c);
+	if (result) {
+		msg_cerr("spi_write_status_register failed.\n");
+		return result;
+	}
+	status = spi_read_status_register(flash);
+	if ((status & 0x3c) != 0) {
+		msg_cerr("Block protection could not be disabled!\n");
+		return 1;
+	}
+	msg_cdbg("done.\n");
+	return 0;
+}
+
+static void spi_prettyprint_status_register_hex(uint8_t status)
+{
+	msg_cdbg("Chip status register is 0x%02x.\n", status);
+}
+
+/* Common highest bit: Status Register Write Disable (SRWD). */
+static void spi_prettyprint_status_register_srwd(uint8_t status)
+{
+	msg_cdbg("Chip status register: Status Register Write Disable (SRWD) is %sset\n",
+		 (status & (1 << 7)) ? "" : "not ");
+}
+
+/* Common highest bit: Block Protect Write Disable (BPL). */
+static void spi_prettyprint_status_register_bpl(uint8_t status)
+{
+	msg_cdbg("Chip status register: Block Protect Write Disable (BPL) is %sset\n",
+		 (status & (1 << 7)) ? "" : "not ");
+}
+
+/* Common lowest 2 bits: WEL and WIP. */
+static void spi_prettyprint_status_register_welwip(uint8_t status)
+{
+	msg_cdbg("Chip status register: Write Enable Latch (WEL) is %sset\n",
+		 (status & (1 << 1)) ? "" : "not ");
+	msg_cdbg("Chip status register: Write In Progress (WIP/BUSY) is %sset\n",
+		 (status & (1 << 0)) ? "" : "not ");
+}
+
+/* Common block protection (BP) bits. */
+static void spi_prettyprint_status_register_bp(uint8_t status, int bp)
+{
+	switch (bp) {
+	/* Fall through. */
+	case 4:
+		msg_cdbg("Chip status register: Block Protect 4 (BP4) is %sset\n",
+			 (status & (1 << 5)) ? "" : "not ");
+	case 3:
+		msg_cdbg("Chip status register: Block Protect 3 (BP3) is %sset\n",
+			 (status & (1 << 5)) ? "" : "not ");
+	case 2:
+		msg_cdbg("Chip status register: Block Protect 2 (BP2) is %sset\n",
+			 (status & (1 << 4)) ? "" : "not ");
+	case 1:
+		msg_cdbg("Chip status register: Block Protect 1 (BP1) is %sset\n",
+			 (status & (1 << 3)) ? "" : "not ");
+	case 0:
+		msg_cdbg("Chip status register: Block Protect 0 (BP0) is %sset\n",
+			 (status & (1 << 2)) ? "" : "not ");
+	}
+}
+
+/* Unnamed bits. */
+static void spi_prettyprint_status_register_bit(uint8_t status, int bit)
+{
+	msg_cdbg("Chip status register: Bit %i is %sset\n", bit, (status & (1 << bit)) ? "" : "not ");
+}
+
+int spi_prettyprint_status_register_plain(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+	return 0;
+}
+
+/* Works for many chips of the
+ * ST M25P series
+ * MX MX25L series
+ */
+int spi_prettyprint_status_register_default_bp3(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_srwd(status);
+	spi_prettyprint_status_register_bit(status, 6);
+	spi_prettyprint_status_register_bp(status, 3);
+	spi_prettyprint_status_register_welwip(status);
+	return 0;
+}
+
+/* === Amic ===
+ * FIXME: spi_disable_blockprotect is incorrect but works fine for chips using
+ * spi_prettyprint_status_register_amic_a25l05p or
+ * spi_prettyprint_status_register_amic_a25l40p.
+ * FIXME: spi_disable_blockprotect is incorrect and will fail for chips using
+ * spi_prettyprint_status_register_amic_a25l032 if those have locks controlled
+ * by the second status register.
+ */
+
+int spi_prettyprint_status_register_amic_a25l05p(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_srwd(status);
+	spi_prettyprint_status_register_bit(status, 6);
+	spi_prettyprint_status_register_bit(status, 5);
+	spi_prettyprint_status_register_bit(status, 4);
+	spi_prettyprint_status_register_bp(status, 1);
+	spi_prettyprint_status_register_welwip(status);
+	return 0;
+}
+
+int spi_prettyprint_status_register_amic_a25l40p(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_srwd(status);
+	spi_prettyprint_status_register_bit(status, 6);
+	spi_prettyprint_status_register_bit(status, 5);
+	spi_prettyprint_status_register_bp(status, 2);
+	spi_prettyprint_status_register_welwip(status);
+	return 0;
+}
+
+int spi_prettyprint_status_register_amic_a25l032(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_srwd(status);
+	msg_cdbg("Chip status register: Sector Protect Size (SEC) is %i KB\n", (status & (1 << 6)) ? 4 : 64);
+	msg_cdbg("Chip status register: Top/Bottom (TB) is %s\n", (status & (1 << 5)) ? "bottom" : "top");
+	spi_prettyprint_status_register_bp(status, 2);
+	spi_prettyprint_status_register_welwip(status);
+	msg_cdbg("Chip status register 2 is NOT decoded!\n");
+	return 0;
+}
+
+/* === Atmel === */
+
+static void spi_prettyprint_status_register_atmel_at25_wpen(uint8_t status)
+{
+	msg_cdbg("Chip status register: Write Protect Enable (WPEN) is %sset\n",
+		 (status & (1 << 7)) ? "" : "not ");
+}
+
+static void spi_prettyprint_status_register_atmel_at25_srpl(uint8_t status)
+{
+	msg_cdbg("Chip status register: Sector Protection Register Lock (SRPL) is %sset\n",
+		 (status & (1 << 7)) ? "" : "not ");
+}
+
+static void spi_prettyprint_status_register_atmel_at25_epewpp(uint8_t status)
+{
+	msg_cdbg("Chip status register: Erase/Program Error (EPE) is %sset\n",
+		 (status & (1 << 5)) ? "" : "not ");
+	msg_cdbg("Chip status register: WP# pin (WPP) is %sasserted\n",
+		 (status & (1 << 4)) ? "not " : "");
+}
+
+static void spi_prettyprint_status_register_atmel_at25_swp(uint8_t status)
+{
+	msg_cdbg("Chip status register: Software Protection Status (SWP): ");
+	switch (status & (3 << 2)) {
+	case 0x0 << 2:
+		msg_cdbg("no sectors are protected\n");
+		break;
+	case 0x1 << 2:
+		msg_cdbg("some sectors are protected\n");
+		/* FIXME: Read individual Sector Protection Registers. */
+		break;
+	case 0x3 << 2:
+		msg_cdbg("all sectors are protected\n");
+		break;
+	default:
+		msg_cdbg("reserved for future use\n");
+		break;
+	}
+}
+
+int spi_prettyprint_status_register_at25df(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_atmel_at25_srpl(status);
+	spi_prettyprint_status_register_bit(status, 6);
+	spi_prettyprint_status_register_atmel_at25_epewpp(status);
+	spi_prettyprint_status_register_atmel_at25_swp(status);
+	spi_prettyprint_status_register_welwip(status);
+	return 0;
+}
+
+int spi_prettyprint_status_register_at25df_sec(struct flashctx *flash)
+{
+	/* FIXME: We should check the security lockdown. */
+	msg_cdbg("Ignoring security lockdown (if present)\n");
+	msg_cdbg("Ignoring status register byte 2\n");
+	return spi_prettyprint_status_register_at25df(flash);
+}
+
+int spi_prettyprint_status_register_at25f512b(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_atmel_at25_srpl(status);
+	spi_prettyprint_status_register_bit(status, 6);
+	spi_prettyprint_status_register_atmel_at25_epewpp(status);
+	spi_prettyprint_status_register_bit(status, 3);
+	spi_prettyprint_status_register_bp(status, 0);
+	spi_prettyprint_status_register_welwip(status);
+	return 0;
+}
+
+int spi_prettyprint_status_register_at25fs010(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_atmel_at25_wpen(status);
+	msg_cdbg("Chip status register: Bit 6 / Block Protect 4 (BP4) is "
+		 "%sset\n", (status & (1 << 6)) ? "" : "not ");
+	msg_cdbg("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
+		 "%sset\n", (status & (1 << 5)) ? "" : "not ");
+	spi_prettyprint_status_register_bit(status, 4);
+	msg_cdbg("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
+		 "%sset\n", (status & (1 << 3)) ? "" : "not ");
+	msg_cdbg("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
+		 "%sset\n", (status & (1 << 2)) ? "" : "not ");
+	/* FIXME: Pretty-print detailed sector protection status. */
+	spi_prettyprint_status_register_welwip(status);
+	return 0;
+}
+
+int spi_prettyprint_status_register_at25fs040(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_atmel_at25_wpen(status);
+	spi_prettyprint_status_register_bp(status, 4);
+	/* FIXME: Pretty-print detailed sector protection status. */
+	spi_prettyprint_status_register_welwip(status);
+	return 0;
+}
+
+int spi_prettyprint_status_register_at26df081a(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_atmel_at25_srpl(status);
+	msg_cdbg("Chip status register: Sequential Program Mode Status (SPM) is %sset\n",
+		 (status & (1 << 6)) ? "" : "not ");
+	spi_prettyprint_status_register_atmel_at25_epewpp(status);
+	spi_prettyprint_status_register_atmel_at25_swp(status);
+	spi_prettyprint_status_register_welwip(status);
+	return 0;
+}
+
+int spi_disable_blockprotect_at25df(struct flashctx *flash)
+{
+	uint8_t status;
+	int result;
+
+	status = spi_read_status_register(flash);
+	/* If block protection is disabled, stop here. */
+	if ((status & (3 << 2)) == 0)
+		return 0;
+
+	msg_cdbg("Some block protection in effect, disabling... ");
+	if (status & (1 << 7)) {
+		msg_cdbg("Need to disable Sector Protection Register Lock\n");
+		if ((status & (1 << 4)) == 0) {
+			msg_cerr("WP# pin is active, disabling "
+				 "write protection is impossible.\n");
+			return 1;
+		}
+		/* All bits except bit 7 (SPRL) are readonly. */
+		result = spi_write_status_register(flash, status & ~(1 << 7));
+		if (result) {
+			msg_cerr("spi_write_status_register failed.\n");
+			return result;
+		}
+		
+	}
+	/* Global unprotect. Make sure to mask SPRL as well. */
+	result = spi_write_status_register(flash, status & ~0xbc);
+	if (result) {
+		msg_cerr("spi_write_status_register failed.\n");
+		return result;
+	}
+	status = spi_read_status_register(flash);
+	if ((status & (3 << 2)) != 0) {
+		msg_cerr("Block protection could not be disabled!\n");
+		return 1;
+	}
+	msg_cdbg("done.\n");
+	return 0;
+}
+
+int spi_disable_blockprotect_at25df_sec(struct flashctx *flash)
+{
+	/* FIXME: We should check the security lockdown. */
+	msg_cinfo("Ignoring security lockdown (if present)\n");
+	return spi_disable_blockprotect_at25df(flash);
+}
+
+int spi_disable_blockprotect_at25f512b(struct flashctx *flash)
+{
+	/* spi_disable_blockprotect_at25df is not really the right way to do
+	 * this, but the side effects of said function work here as well.
+	 */
+	return spi_disable_blockprotect_at25df(flash);
+}
+
+int spi_disable_blockprotect_at25fs010(struct flashctx *flash)
+{
+	uint8_t status;
+	int result;
+
+	status = spi_read_status_register(flash);
+	/* If block protection is disabled, stop here. */
+	if ((status & 0x6c) == 0)
+		return 0;
+
+	msg_cdbg("Some block protection in effect, disabling... ");
+	if (status & (1 << 7)) {
+		msg_cdbg("Need to disable Status Register Write Protect\n");
+		/* Clear bit 7 (WPEN). */
+		result = spi_write_status_register(flash, status & ~(1 << 7));
+		if (result) {
+			msg_cerr("spi_write_status_register failed.\n");
+			return result;
+		}
+	}
+	/* Global unprotect. Make sure to mask WPEN as well. */
+	result = spi_write_status_register(flash, status & ~0xec);
+	if (result) {
+		msg_cerr("spi_write_status_register failed.\n");
+		return result;
+	}
+	status = spi_read_status_register(flash);
+	if ((status & 0x6c) != 0) {
+		msg_cerr("Block protection could not be disabled!\n");
+		return 1;
+	}
+	msg_cdbg("done.\n");
+	return 0;
+}
+
+int spi_disable_blockprotect_at25fs040(struct flashctx *flash)
+{
+	uint8_t status;
+	int result;
+
+	status = spi_read_status_register(flash);
+	/* If block protection is disabled, stop here. */
+	if ((status & 0x7c) == 0)
+		return 0;
+
+	msg_cdbg("Some block protection in effect, disabling... ");
+	if (status & (1 << 7)) {
+		msg_cdbg("Need to disable Status Register Write Protect\n");
+		/* Clear bit 7 (WPEN). */
+		result = spi_write_status_register(flash, status & ~(1 << 7));
+		if (result) {
+			msg_cerr("spi_write_status_register failed.\n");
+			return result;
+		}
+	}
+	/* Global unprotect. Make sure to mask WPEN as well. */
+	result = spi_write_status_register(flash, status & ~0xfc);
+	if (result) {
+		msg_cerr("spi_write_status_register failed.\n");
+		return result;
+	}
+	status = spi_read_status_register(flash);
+	if ((status & 0x7c) != 0) {
+		msg_cerr("Block protection could not be disabled!\n");
+		return 1;
+	}
+	msg_cdbg("done.\n");
+	return 0;
+}
+
+/* === SST === */
+
+static void spi_prettyprint_status_register_sst25_common(uint8_t status)
+{
+	spi_prettyprint_status_register_hex(status);
+
+	spi_prettyprint_status_register_bpl(status);
+	msg_cdbg("Chip status register: Auto Address Increment Programming (AAI) is %sset\n",
+		 (status & (1 << 6)) ? "" : "not ");
+	spi_prettyprint_status_register_bp(status, 3);
+	spi_prettyprint_status_register_welwip(status);
+}
+
+int spi_prettyprint_status_register_sst25(struct flashctx *flash)
+{
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_sst25_common(status);
+	return 0;
+}
+
+int spi_prettyprint_status_register_sst25vf016(struct flashctx *flash)
+{
+	static const char *const bpt[] = {
+		"none",
+		"1F0000H-1FFFFFH",
+		"1E0000H-1FFFFFH",
+		"1C0000H-1FFFFFH",
+		"180000H-1FFFFFH",
+		"100000H-1FFFFFH",
+		"all", "all"
+	};
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_sst25_common(status);
+	msg_cdbg("Resulting block protection : %s\n", bpt[(status & 0x1c) >> 2]);
+	return 0;
+}
+
+int spi_prettyprint_status_register_sst25vf040b(struct flashctx *flash)
+{
+	static const char *const bpt[] = {
+		"none",
+		"0x70000-0x7ffff",
+		"0x60000-0x7ffff",
+		"0x40000-0x7ffff",
+		"all blocks", "all blocks", "all blocks", "all blocks"
+	};
+	uint8_t status = spi_read_status_register(flash);
+	spi_prettyprint_status_register_sst25_common(status);
+	msg_cdbg("Resulting block protection : %s\n", bpt[(status & 0x1c) >> 2]);
+	return 0;
+}
-- 
Kind regards, Stefan Tauner





More information about the flashrom mailing list