spi: Use bus probing for REMS, RES and AT25F

Change-Id: Ic5d2a5283c5fb5e52c58c0b5937922371f56249f
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/417
diff --git a/flashchips.c b/flashchips.c
index aed54e6..1722bc3 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -2072,7 +2072,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_at25f,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -2102,7 +2102,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_at25f,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -2132,7 +2132,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_at25f,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -2163,7 +2163,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_at25f,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -2193,7 +2193,7 @@
 		.page_size	= 128,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_at25f,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -13727,7 +13727,7 @@
 
 	/* The ST M25P05 is a bit of a problem. It has the same ID as the
 	 * ST M25P05-A in RES mode, but supports only 128 byte writes instead
-	 * of 256 byte writes. We rely heavily on the fact that probe_spi_res1
+	 * of 256 byte writes. We rely heavily on the fact that probe_spi_res(1)
 	 * only is successful if RDID does not work.
 	 */
 	{
@@ -13741,7 +13741,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_res1,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -13802,7 +13802,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_res1,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -13952,7 +13952,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_res1,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -14042,7 +14042,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_res1,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -16441,7 +16441,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_res2, /* The continuation code is transferred as the 3rd byte m( */
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -16651,7 +16651,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_res2, /* The continuation code is transferred as the 3rd byte m( */
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -18786,7 +18786,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EWSR,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_rems,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -18819,7 +18819,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EWSR,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -18852,7 +18852,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EITHER,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -18885,7 +18885,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EWSR,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_rems,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -18963,7 +18963,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EWSR,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_rems,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -19074,7 +19074,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EWSR,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_spi_rems,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -19146,7 +19146,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EWSR,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_rems,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -19263,7 +19263,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_EWSR,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_rems,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -21306,7 +21306,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -21341,7 +21341,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -21412,7 +21412,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -21484,7 +21484,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -21581,7 +21581,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -21614,7 +21614,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -21647,7 +21647,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -21683,7 +21683,7 @@
 		.page_size	= 256,
 		.feature_bits	= FEATURE_WRSR_WREN,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_spi_res2,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -27534,7 +27534,7 @@
 		.total_size	= 0,
 		.page_size	= 256,
 		.tested		= TEST_BAD_PREW,
-		.probe		= probe_spi_rems,
+		.probe		= probe_buses,
 		.write		= NULL,
 	},
 
diff --git a/include/chipdrivers/spi.h b/include/chipdrivers/spi.h
index 9b14342..1646561 100644
--- a/include/chipdrivers/spi.h
+++ b/include/chipdrivers/spi.h
@@ -29,13 +29,11 @@
 
 /* spi25.c */
 struct found_id *probe_spi_rdid(const struct bus_probe *, const struct master_common *);
+struct found_id *probe_spi_rems(const struct bus_probe *, const struct master_common *);
+struct found_id *probe_spi_res(const struct bus_probe *, const struct master_common *);
+struct found_id *probe_spi_at25f(const struct bus_probe *, const struct master_common *);
 
 int spi_simple_write_cmd(struct flashprog_flashctx *, uint8_t op, unsigned int poll_delay);
-int probe_spi_rems(struct flashprog_flashctx *);
-int probe_spi_res1(struct flashprog_flashctx *);
-int probe_spi_res2(struct flashprog_flashctx *);
-int probe_spi_res3(struct flashprog_flashctx *);
-int probe_spi_at25f(struct flashprog_flashctx *);
 int spi_write_enable(struct flashprog_flashctx *);
 int spi_write_disable(struct flashprog_flashctx *);
 int spi_block_erase_20(struct flashprog_flashctx *, unsigned int addr, unsigned int blocklen);
diff --git a/spi.c b/spi.c
index fee3aee..8d07ed1 100644
--- a/spi.c
+++ b/spi.c
@@ -165,6 +165,11 @@
 static const struct bus_probe spi_probes[] = {
        /* type		function		function argument */
 	{ ID_SPI_RDID,	probe_spi_rdid,		NULL },
+	{ ID_SPI_AT25F,	probe_spi_at25f,	NULL },
+	{ ID_SPI_REMS,	probe_spi_rems,		NULL },
+	{ ID_SPI_RES3,	probe_spi_res,		NULL },
+	{ ID_SPI_RES2,	probe_spi_res,		NULL },
+	{ ID_SPI_RES1,	probe_spi_res,		NULL },
 };
 
 static bool spi_probe_match(const struct flashchip *chip, const struct id_info_ext *found)
diff --git a/spi25.c b/spi25.c
index b22c8a8..d1ce38e 100644
--- a/spi25.c
+++ b/spi25.c
@@ -46,25 +46,25 @@
 	return 0;
 }
 
-static int spi_rems(struct flashctx *flash, unsigned char *readarr)
+static int spi_rems(const struct spi_master *spi, unsigned char *readarr)
 {
 	static const unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, };
 	int ret;
 
-	ret = spi_send_command(flash, sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
+	ret = spi->command(spi, sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
 	if (ret)
 		return ret;
 	msg_cspew("REMS returned 0x%02x 0x%02x. ", readarr[0], readarr[1]);
 	return 0;
 }
 
-static int spi_res(struct flashctx *flash, unsigned char *readarr, int bytes)
+static int spi_res(const struct spi_master *spi, unsigned char *readarr, int bytes)
 {
 	static const unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, };
 	int ret;
 	int i;
 
-	ret = spi_send_command(flash, sizeof(cmd), bytes, cmd, readarr);
+	ret = spi->command(spi, sizeof(cmd), bytes, cmd, readarr);
 	if (ret)
 		return ret;
 	msg_cspew("RES returned");
@@ -147,136 +147,114 @@
 	return found;
 }
 
-int probe_spi_rems(struct flashctx *flash)
+struct found_id *probe_spi_rems(const struct bus_probe *probe, const struct master_common *mst)
 {
-	const struct flashchip *chip = flash->chip;
+	const struct spi_master *const spi = (const struct spi_master *)mst;
 	unsigned char readarr[JEDEC_REMS_INSIZE];
-	uint32_t id1, id2;
 
-	if (spi_rems(flash, readarr)) {
-		return 0;
+	if (spi_rems(spi, readarr) || flashprog_no_data(readarr, sizeof(readarr))) {
+		return NULL;
 	}
 
-	id1 = readarr[0];
-	id2 = readarr[1];
+	struct found_id *const found = calloc(1, sizeof(*found));
+	if (!found) {
+		msg_cerr("Out of memory!\n");
+		return NULL;
+	}
 
-	msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
+	struct id_info *const id = &found->info.id;
 
-	if (id1 == chip->id.manufacture && id2 == chip->id.model)
-		return 1;
+	id->manufacture	= readarr[0];
+	id->model	= readarr[1];
+	id->type	= ID_SPI_REMS;
 
-	/* Test if this is a pure vendor match. */
-	if (id1 == chip->id.manufacture && GENERIC_DEVICE_ID == chip->id.model)
-		return 1;
+	msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id->id1, id->id2);
 
-	/* Test if there is any vendor ID. */
-	if (GENERIC_MANUF_ID == chip->id.manufacture && id1 != 0xff && id1 != 0x00)
-		return 1;
-
-	return 0;
+	return found;
 }
 
-int probe_spi_res1(struct flashctx *flash)
+struct found_id *probe_spi_res(const struct bus_probe *probe, const struct master_common *mst)
 {
-	static const unsigned char allff[] = {0xff, 0xff, 0xff};
-	static const unsigned char all00[] = {0x00, 0x00, 0x00};
+	const struct spi_master *const spi = (const struct spi_master *)mst;
+	const unsigned int res_len = probe->type == ID_SPI_RES3 ? 3 :
+				    (probe->type == ID_SPI_RES2 ? 2 : 1);
 	unsigned char readarr[3];
-	uint32_t id2;
 
-	/* We only want one-byte RES if RDID and REMS are unusable. */
+	if (res_len == 1) {
+		/* We only want one-byte RES if RDID and REMS are unusable. */
 
-	/* 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(flash->mst.spi, 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(flash, 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_rdid(spi, readarr, 3) && !flashprog_no_data(readarr, 3)) {
+			msg_cdbg("Ignoring RES in favour of RDID.\n");
+			return NULL;
+		}
+
+		if (!spi_rems(spi, readarr) && !flashprog_no_data(readarr, JEDEC_REMS_INSIZE)) {
+			msg_cdbg("Ignoring RES in favour of REMS.\n");
+			return NULL;
+		}
 	}
 
-	if (spi_res(flash, readarr, 1)) {
-		return 0;
+	if (spi_res(spi, readarr, res_len) || flashprog_no_data(readarr, res_len)) {
+		return NULL;
 	}
 
-	id2 = readarr[0];
-
-	msg_cdbg("%s: id 0x%x\n", __func__, id2);
-
-	if (id2 != flash->chip->id.model)
-		return 0;
-
-	return 1;
-}
-
-int probe_spi_res2(struct flashctx *flash)
-{
-	unsigned char readarr[2];
-	uint32_t id1, id2;
-
-	if (spi_res(flash, readarr, 2)) {
-		return 0;
+	struct found_id *const found = calloc(1, sizeof(*found));
+	if (!found) {
+		msg_cerr("Out of memory!\n");
+		return NULL;
 	}
 
-	id1 = readarr[0];
-	id2 = readarr[1];
+	struct id_info *const id = &found->info.id;
 
-	msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
-
-	if (id1 != flash->chip->id.manufacture || id2 != flash->chip->id.model)
-		return 0;
-
-	return 1;
-}
-
-int probe_spi_res3(struct flashctx *flash)
-{
-	unsigned char readarr[3];
-	uint32_t id1, id2;
-
-	if (spi_res(flash, readarr, 3)) {
-		return 0;
+	switch (res_len) {
+	case 1:
+		id->manufacture	= 0;
+		id->model	= readarr[0];
+		msg_cdbg("%s: id 0x%02x\n", __func__, id->model);
+		break;
+	case 2:
+		id->manufacture	= readarr[0];
+		id->model	= readarr[1];
+		msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id->id1, id->id2);
+		break;
+	case 3:
+		id->manufacture	= (readarr[0] << 8) | readarr[1];
+		id->model	= readarr[2];
+		msg_cdbg("%s: id1 0x%04x, id2 0x%02x\n", __func__, id->id1, id->id2);
+		break;
 	}
+	id->type = probe->type;
 
-	id1 = (readarr[0] << 8) | readarr[1];
-	id2 = readarr[2];
-
-	msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
-
-	if (id1 != flash->chip->id.manufacture || id2 != flash->chip->id.model)
-		return 0;
-
-	return 1;
+	return found;
 }
 
 /* Only used for some Atmel chips. */
-int probe_spi_at25f(struct flashctx *flash)
+struct found_id *probe_spi_at25f(const struct bus_probe *probe, const struct master_common *mst)
 {
 	static const unsigned char cmd[AT25F_RDID_OUTSIZE] = { AT25F_RDID };
+	const struct spi_master *const spi = (const struct spi_master *)mst;
 	unsigned char readarr[AT25F_RDID_INSIZE];
-	uint32_t id1;
-	uint32_t id2;
 
-	if (spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd, readarr))
-		return 0;
+	if (spi->command(spi, sizeof(cmd), sizeof(readarr), cmd, readarr))
+		return NULL;
+	if (flashprog_no_data(readarr, sizeof(readarr)))
+		return NULL;
 
-	id1 = readarr[0];
-	id2 = readarr[1];
+	struct found_id *const found = calloc(1, sizeof(*found));
+	if (!found) {
+		msg_cerr("Out of memory!\n");
+		return NULL;
+	}
 
-	msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
+	struct id_info *const id = &found->info.id;
 
-	if (id1 == flash->chip->id.manufacture && id2 == flash->chip->id.model)
-		return 1;
+	id->manufacture	= readarr[0];
+	id->model	= readarr[1];
+	id->type	= ID_SPI_AT25F;
 
-	return 0;
+	msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id->id1, id->id2);
+
+	return found;
 }
 
 static int spi_poll_wip(struct flashctx *const flash, const unsigned int poll_delay)