Use bus probing for 82802AB

We probe for chip sizes from 256KiB to 2MiB, with and without shifted
addresses (for x16 chips).  That makes 8 probing calls that currently
cover 28 chips in our database.

Change-Id: I3dd753efb3152a8a103ca88b941802b815a8180a
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/442
diff --git a/82802ab.c b/82802ab.c
index e53e788..c958f04 100644
--- a/82802ab.c
+++ b/82802ab.c
@@ -23,7 +23,10 @@
  */
 
 #include <stdbool.h>
+#include <stdlib.h>
+
 #include "flash.h"
+#include "programmer.h"
 #include "chipdrivers/memory_bus.h"
 
 void print_status_82802ab(uint8_t status)
@@ -37,50 +40,94 @@
 	msg_cdbg("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:");
 }
 
-int probe_82802ab(struct flashctx *flash)
+static struct found_id *probe_82802ab_generic(
+		const struct par_master *par,
+		chipsize_t chip_size, feature_bits_t chip_features)
 {
-	chipaddr bios = flash->virtual_memory;
-	uint8_t id1, id2, flashcontent1, flashcontent2;
-	int shifted = (flash->chip->feature_bits & FEATURE_ADDR_SHIFTED) ? 1 : 0;
+	const unsigned int addr_shift = chip_features & FEATURE_ADDR_SHIFTED ? 1 : 0;
+	uint8_t raw[2], flashcontent1, flashcontent2;
+
+	const chipaddr bios = (chipaddr)programmer_map_flash_data(par, chip_size, "");
+	if (bios == (chipaddr)ERROR_PTR)
+		return NULL;
 
 	/* Reset to get a clean state */
-	chip_writeb(flash, 0xFF, bios);
+	par->chip_writeb(par, 0xFF, bios);
 	programmer_delay(10);
 
 	/* Enter ID mode */
-	chip_writeb(flash, 0x90, bios);
+	par->chip_writeb(par, 0x90, bios);
 	programmer_delay(10);
 
-	id1 = chip_readb(flash, bios + (0x00 << shifted));
-	id2 = chip_readb(flash, bios + (0x01 << shifted));
+	raw[0] = par->chip_readb(par, bios + (0x00 << addr_shift));
+	raw[1] = par->chip_readb(par, bios + (0x01 << addr_shift));
 
 	/* Leave ID mode */
-	chip_writeb(flash, 0xFF, bios);
+	par->chip_writeb(par, 0xFF, bios);
 
 	programmer_delay(10);
 
-	msg_cdbg("%s: id1 0x%02x, id2 0x%02x", __func__, id1, id2);
-
-	if (!oddparity(id1))
-		msg_cdbg(", id1 parity violation");
-
 	/*
 	 * Read the product ID location again. We should now see normal
 	 * flash contents.
 	 */
-	flashcontent1 = chip_readb(flash, bios + (0x00 << shifted));
-	flashcontent2 = chip_readb(flash, bios + (0x01 << shifted));
+	flashcontent1 = par->chip_readb(par, bios + (0x00 << addr_shift));
+	flashcontent2 = par->chip_readb(par, bios + (0x01 << addr_shift));
 
-	if (id1 == flashcontent1)
+	programmer_unmap_flash_region(par, (void *)bios, chip_size);
+
+	if (flashprog_no_data(raw, sizeof(raw)))
+		return NULL;
+
+	msg_cdbg("%s (%uKiB, features: 0x%02x): id1 0x%02x, id2 0x%02x",
+		 __func__, chip_size / KiB, chip_features, raw[0], raw[1]);
+
+	if (!oddparity(raw[0]))
+		msg_cdbg(", id1 parity violation");
+
+	if (raw[0] == flashcontent1)
 		msg_cdbg(", id1 is normal flash content");
-	if (id2 == flashcontent2)
+	if (raw[1] == flashcontent2)
 		msg_cdbg(", id2 is normal flash content");
-
 	msg_cdbg("\n");
-	if (id1 != flash->chip->id.manufacture || id2 != flash->chip->id.model)
-		return 0;
 
-	return 1;
+	struct memory_found_id *const found = alloc_memory_found_id();
+	if (!found) {
+		msg_cerr("Out of memory!\n");
+		return NULL;
+	}
+
+	found->generic.info.id.manufacture	= raw[0];
+	found->generic.info.id.model		= raw[1];
+	found->generic.info.id.type		= ID_82802AB;
+	found->memory_info.chip_size		= chip_size;
+	found->memory_info.chip_features	= chip_features;
+
+	return &found->generic;
+}
+
+struct found_id *probe_82802ab(const struct bus_probe *probe,
+			       const struct master_common *mst,
+			       const struct flashchip *chip)
+{
+	const struct par_master *const par = (const struct par_master *)mst;
+	struct found_id *ids = NULL, **next_ptr = &ids;
+	chipsize_t chip_size;
+
+	if (chip)
+		return probe_82802ab_generic(par, chip->total_size * KiB, chip->feature_bits);
+
+	for (chip_size = 256*KiB; chip_size <= 2*MiB; chip_size *= 2) {
+		*next_ptr = probe_82802ab_generic(par, chip_size, 0);
+		if (*next_ptr)
+			next_ptr = &(*next_ptr)->next;
+
+		*next_ptr = probe_82802ab_generic(par, chip_size, FEATURE_ADDR_SHIFTED);
+		if (*next_ptr)
+			next_ptr = &(*next_ptr)->next;
+	}
+
+	return ids;
 }
 
 /* FIXME: needs timeout */
diff --git a/flashchips.c b/flashchips.c
index dd48f69..0c7fa95 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -3550,7 +3550,7 @@
 		.total_size	= 256,
 		.page_size	= 0, /* unused */
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -3588,7 +3588,7 @@
 		.total_size	= 512,
 		.page_size	= 0, /* unused */
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -3626,7 +3626,7 @@
 		.total_size	= 512,
 		.page_size	= 0, /* unused */
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -11128,7 +11128,7 @@
 		.total_size	= 256,
 		.page_size	= 256 * 1024,
 		.tested		= TEST_OK_PRE,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO, /* Datasheet has no timing info specified */
 		.block_erasers	=
 		{
@@ -11158,7 +11158,7 @@
 		.total_size	= 512,
 		.page_size	= 128 * 1024, /* maximal block size */
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
 		{
@@ -11188,7 +11188,7 @@
 		.total_size	= 512,
 		.page_size	= 128 * 1024, /* maximal block size */
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
 		{
@@ -11218,7 +11218,7 @@
 		.total_size	= 512,
 		.page_size	= 256,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
 		{
@@ -11245,7 +11245,7 @@
 		.page_size	= 128 * 1024, /* maximal block size */
 		.feature_bits	= FEATURE_ADDR_SHIFTED,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
 		{
@@ -11276,7 +11276,7 @@
 		.page_size	= 128 * 1024, /* maximal block size */
 		.feature_bits	= FEATURE_ADDR_SHIFTED,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
 		{
@@ -11306,7 +11306,7 @@
 		.total_size	= 512,
 		.page_size	= 64 * 1024,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
 		.block_erasers	=
 		{
@@ -11333,7 +11333,7 @@
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
 		.block_erasers	=
 		{
@@ -19839,7 +19839,7 @@
 		.page_size	= 256,
 		.feature_bits	= 0,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine doesn't use probe_timing (sst28sf040.c) */
 		.block_erasers	=
 		{
@@ -20358,7 +20358,7 @@
 		.total_size	= 512,
 		.page_size	= 4 * 1024,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
 		.block_erasers	=
 		{
@@ -20429,7 +20429,7 @@
 		.total_size	= 1024,
 		.page_size	= 4 * 1024,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
 		.block_erasers	=
 		{
@@ -20465,7 +20465,7 @@
 		.total_size	= 2048,
 		.page_size	= 4 * 1024,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
 		.block_erasers	=
 		{
@@ -20667,7 +20667,7 @@
 		.total_size	= 2048,
 		.page_size	= 4 * 1024,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
 		.block_erasers	=
 		{
@@ -20962,7 +20962,7 @@
 		.total_size	= 512,
 		.page_size	= 0,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_FIXME,
 		.block_erasers	=
 		{
@@ -20997,7 +20997,7 @@
 		.total_size	= 512,
 		.page_size	= 0,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_FIXME,
 		.block_erasers	=
 		{
@@ -21032,7 +21032,7 @@
 		.total_size	= 1024,
 		.page_size	= 0,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_FIXME,
 		.block_erasers	=
 		{
@@ -21068,7 +21068,7 @@
 		.total_size	= 1024,
 		.page_size	= 0,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_FIXME,
 		.block_erasers	=
 		{
@@ -21104,7 +21104,7 @@
 		.total_size	= 256,
 		.page_size	= 0,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
 		.block_erasers	=
 		{
@@ -21140,7 +21140,7 @@
 		.total_size	= 2048,
 		.page_size	= 0,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
 		.block_erasers	=
 		{
@@ -21167,7 +21167,7 @@
 		.total_size	= 512,
 		.page_size	= 0,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
 		.block_erasers	=
 		{
@@ -21194,7 +21194,7 @@
 		.total_size	= 1024,
 		.page_size	= 0,
 		.tested		= TEST_OK_PR,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
 		.block_erasers	=
 		{
@@ -21221,7 +21221,7 @@
 		.total_size	= 1024,
 		.page_size	= 0,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
 		{
@@ -21248,7 +21248,7 @@
 		.total_size	= 2048,
 		.page_size	= 0,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,	/* Datasheet has no timing info specified */
 		.block_erasers	=
 		{
@@ -21721,7 +21721,7 @@
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
 		.tested		= TEST_OK_PREW,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
@@ -21755,7 +21755,7 @@
 		.page_size	= 64 * 1024,
 		.feature_bits	= FEATURE_EITHER_RESET,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_82802ab,
+		.probe		= probe_buses,
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
diff --git a/include/chipdrivers/memory_bus.h b/include/chipdrivers/memory_bus.h
index 75501da..c0c13ab 100644
--- a/include/chipdrivers/memory_bus.h
+++ b/include/chipdrivers/memory_bus.h
@@ -19,10 +19,13 @@
 #include <stdint.h>
 
 struct flashprog_flashctx;
+struct master_common;
+struct bus_probe;
+struct flashchip;
 
 /* 82802ab.c */
+struct found_id *probe_82802ab(const struct bus_probe *, const struct master_common *, const struct flashchip *);
 uint8_t wait_82802ab(struct flashprog_flashctx *);
-int probe_82802ab(struct flashprog_flashctx *);
 int erase_block_82802ab(struct flashprog_flashctx *, unsigned int page, unsigned int pagesize);
 int write_82802ab(struct flashprog_flashctx *, const uint8_t *buf, unsigned int start, unsigned int len);
 void print_status_82802ab(uint8_t status);
diff --git a/parallel.c b/parallel.c
index 5446e1a..e5c39a7 100644
--- a/parallel.c
+++ b/parallel.c
@@ -78,6 +78,7 @@
 
 static const struct bus_probe memory_probes[] = {
     /* prio. type		function		function argument */
+	{ 0, ID_82802AB,	probe_82802ab,		NULL },
 };
 
 static bool memory_probe_match(const struct flashchip *chip, const struct id_info_ext *found)