Ignore RES (1 byte) if chip replied to REMS (2 bytes)
SPI RES is the most unreliable way to identify chips because it only
returns a 1-byte ID for most chips.
For every given ID out there, probably a dozen incompatible flash
chips match it. We already refuse to identify a chip with RES if that
chip responds to RDID (3 bytes, good match), and with this patch we
additionally refuse RES if the chip responds to REMS (2 bytes, still a
good match). This increases matching accuracy a lot.
Besides that, the RDID/REMS response checking has been cleaned up for
better readability.
Corresponding to flashrom svn r899.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Sean Nelson <audiohacked@gmail.com>
diff --git a/spi.c b/spi.c
index e1ab2ea..66f1db8 100644
--- a/spi.c
+++ b/spi.c
@@ -385,17 +385,30 @@
{
unsigned char readarr[3];
uint32_t id2;
+ const unsigned char allff[] = {0xff, 0xff, 0xff};
+ const unsigned char all00[] = {0x00, 0x00, 0x00};
- /* Check if RDID was successful and did not return 0xff 0xff 0xff.
- * In that case, RES is pointless.
+ /* Check if RDID is usable and does not return 0xff 0xff 0xff or
+ * 0x00 0x00 0x00. In that case, RES is pointless.
*/
- if (!spi_rdid(readarr, 3) && ((readarr[0] != 0xff) ||
- (readarr[1] != 0xff) || (readarr[2] != 0xff)))
+ if (!spi_rdid(readarr, 3) && memcmp(readarr, allff, 3) &&
+ memcmp(readarr, all00, 3)) {
+ msg_cdbg("Ignoring RES in favour of RDID.\n");
return 0;
+ }
+ /* Check if REMS is usable and does not return 0xff 0xff or
+ * 0x00 0x00. In that case, RES is pointless.
+ */
+ if (!spi_rems(readarr) && memcmp(readarr, allff, JEDEC_REMS_INSIZE) &&
+ memcmp(readarr, all00, JEDEC_REMS_INSIZE)) {
+ msg_cdbg("Ignoring RES in favour of REMS.\n");
+ return 0;
+ }
if (spi_res(readarr))
return 0;
+ /* FIXME: Handle the case where RES gives a 2-byte response. */
id2 = readarr[0];
printf_debug("%s: id 0x%x\n", __func__, id2);
if (id2 != flash->model_id)