diff --git a/flash.h b/flash.h
index a843b9d1e66d62f116ff93626436fe2d6d40d899..bf52a56e415170d2047ad9edad9d54a8f84d4927 100644
--- a/flash.h
+++ b/flash.h
@@ -654,6 +654,7 @@ int spi_disable_blockprotect(void);
 void spi_byte_program(int address, uint8_t byte);
 int spi_nbyte_read(int address, uint8_t *bytes, int len);
 int spi_aai_write(struct flashchip *flash, uint8_t *buf);
+uint32_t spi_get_valid_read_addr(void);
 
 /* 82802ab.c */
 int probe_82802ab(struct flashchip *flash);
diff --git a/ichspi.c b/ichspi.c
index ea8079531d6c94d3399b02138f148907f2276c4a..a3bb18479069f08bf1751d742fe3554585bf4c3a 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -767,7 +767,7 @@ int ich_spi_command(unsigned int writecnt, unsigned int readcnt,
 	/* unknown / not programmed command */
 	if (opcode_index == -1) {
 		printf_debug("Invalid OPCODE 0x%02x\n", cmd);
-		return 1;
+		return SPI_INVALID_OPCODE;
 	}
 
 	opcode = &(curopcodes->opcode[opcode_index]);
diff --git a/spi.c b/spi.c
index 0bc7ee72b3f3ba2c38ab89c30868ff277ecaff18..b61f4331694749472c37f677a85a74cf1138ff6c 100644
--- a/spi.c
+++ b/spi.c
@@ -57,9 +57,11 @@ int spi_command(unsigned int writecnt, unsigned int readcnt,
 static int spi_rdid(unsigned char *readarr, int bytes)
 {
 	const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID };
+	int ret;
 
-	if (spi_command(sizeof(cmd), bytes, cmd, readarr))
-		return 1;
+	ret = spi_command(sizeof(cmd), bytes, cmd, readarr);
+	if (ret)
+		return ret;
 	printf_debug("RDID returned %02x %02x %02x.\n", readarr[0], readarr[1],
 		     readarr[2]);
 	return 0;
@@ -67,20 +69,42 @@ static int spi_rdid(unsigned char *readarr, int bytes)
 
 static int spi_rems(unsigned char *readarr)
 {
-	const unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, 0, 0, 0 };
-
-	if (spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr))
-		return 1;
+	unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, 0, 0, 0 };
+	uint32_t readaddr;
+	int ret;
+
+	ret = spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
+	if (ret == SPI_INVALID_ADDRESS) {
+		/* Find the lowest even address allowed for reads. */
+		readaddr = (spi_get_valid_read_addr() + 1) & ~1;
+		cmd[1] = (readaddr >> 16) & 0xff,
+		cmd[2] = (readaddr >> 8) & 0xff,
+		cmd[3] = (readaddr >> 0) & 0xff,
+		ret = spi_command(sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
+	}
+	if (ret)
+		return ret;
 	printf_debug("REMS returned %02x %02x.\n", readarr[0], readarr[1]);
 	return 0;
 }
 
 static int spi_res(unsigned char *readarr)
 {
-	const unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
-
-	if (spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr))
-		return 1;
+	unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0, 0, 0 };
+	uint32_t readaddr;
+	int ret;
+
+	ret = spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr);
+	if (ret == SPI_INVALID_ADDRESS) {
+		/* Find the lowest even address allowed for reads. */
+		readaddr = (spi_get_valid_read_addr() + 1) & ~1;
+		cmd[1] = (readaddr >> 16) & 0xff,
+		cmd[2] = (readaddr >> 8) & 0xff,
+		cmd[3] = (readaddr >> 0) & 0xff,
+		ret = spi_command(sizeof(cmd), JEDEC_RES_INSIZE, cmd, readarr);
+	}
+	if (ret)
+		return ret;
 	printf_debug("RES returned %02x.\n", readarr[0]);
 	return 0;
 }
@@ -248,13 +272,16 @@ uint8_t spi_read_status_register(void)
 {
 	const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR };
 	unsigned char readarr[2]; /* JEDEC_RDSR_INSIZE=1 but wbsio needs 2 */
+	int ret;
 
 	/* Read Status Register */
 	if (flashbus == BUS_TYPE_SB600_SPI) {
 		/* SB600 uses a different way to read status register. */
 		return sb600_read_status_register();
 	} else {
-		spi_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
+		ret = spi_command(sizeof(cmd), sizeof(readarr), cmd, readarr);
+		if (ret)
+			printf_debug("RDSR failed!\n");
 	}
 
 	return readarr[0];
@@ -666,6 +693,12 @@ int spi_chip_write_256(struct flashchip *flash, uint8_t *buf)
 	return 1;
 }
 
+uint32_t spi_get_valid_read_addr(void)
+{
+	/* Need to return BBAR for ICH chipsets. */
+	return 0;
+}
+
 int spi_aai_write(struct flashchip *flash, uint8_t *buf)
 {
 	uint32_t pos = 2, size = flash->total_size * 1024;
diff --git a/spi.h b/spi.h
index d3d98057758e5a6d3c3b2cc7179c0724ba286e8e..aa80c43eafc7c5907efe0471ca2fe337f2c69386 100644
--- a/spi.h
+++ b/spi.h
@@ -105,4 +105,8 @@
 #define JEDEC_BYTE_PROGRAM_OUTSIZE	0x05
 #define JEDEC_BYTE_PROGRAM_INSIZE	0x00
 
+/* Error codes */
+#define SPI_INVALID_OPCODE	-2
+#define SPI_INVALID_ADDRESS	-3
+
 #endif		/* !__SPI_H__ */