Add infrastructure to probe per bus
Add some infrastructure around per-bus probing functions. Each function
is provided a private parameter, e.g. the expected length of an ID. This
will allow us to implement probing functions that are only called as of-
ten as necessary. The results will be stored in the `registered_master`
structure, to be compared to database entries later.
The probe_buses() wrapper can be used for chip entries, and allows us to
transition the existing probing functions one by one. Once all functions
have been ported, probe_flash() can be adapted as well and the wrapper
will become obsolete.
Change-Id: I6e82b6d61df50234096ac39acab58a4014203933
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/74899
diff --git a/flashprog.c b/flashprog.c
index 0ab20cb..cf697fb 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -180,6 +180,15 @@
int i = --shutdown_fn_count;
ret |= shutdown_fn[i].func(shutdown_fn[i].data);
}
+
+ int i;
+ for (i = 0; i < registered_master_count; ++i) {
+ struct found_id *found_id, *next;
+ for (found_id = registered_masters[i].found_ids; found_id; found_id = next) {
+ next = found_id->next;
+ free(found_id);
+ }
+ }
registered_master_count = 0;
return ret;
@@ -619,6 +628,88 @@
return 0;
}
+static void probe_bus(struct registered_master *const mst, const enum id_type type)
+{
+ struct found_id **next_ptr;
+ unsigned int i;
+
+ if (mst->probed)
+ return;
+
+ next_ptr = &mst->found_ids;
+ for (i = 0; i < mst->probing.probe_count; ++i) {
+ if (type && type != mst->probing.probes[i].type)
+ continue;
+
+ *next_ptr = mst->probing.probes[i].run(&mst->probing.probes[i], &mst->common);
+
+ /* walk to end in case multiple IDs were found in a single call */
+ while (*next_ptr)
+ next_ptr = &(*next_ptr)->next;
+ }
+
+ mst->probed = true;
+}
+
+static bool chip_on_bus(struct registered_master *const mst, const struct flashprog_chip *const chip)
+{
+ static const char *const id_names[] = {
+ [ID_82802AB] = "82802AB",
+ [ID_EN29LV640B] = "EN29LV640B",
+ [ID_JEDEC] = "JEDEC",
+ [ID_JEDEC_29GL] = "JEDEC_29GL",
+ [ID_OPAQUE] = "OPAQUE",
+ [ID_SPI_AT25F] = "SPI_AT25F",
+ [ID_SPI_RDID] = "SPI_RDID",
+ [ID_SPI_RDID4] = "SPI_RDID4",
+ [ID_SPI_REMS] = "SPI_REMS",
+ [ID_SPI_RES1] = "SPI_RES1",
+ [ID_SPI_RES2] = "SPI_RES2",
+ [ID_SPI_RES3] = "SPI_RES3",
+ [ID_SPI_SFDP] = "SPI_SFDP",
+ [ID_SPI_ST95] = "SPI_ST95",
+ [ID_W29EE011] = "W29EE011",
+ [ID_EDI] = "EDI",
+ };
+
+ if (chip_to_probe) {
+ /* If we are looking for a particular chip,
+ limit the probing functions to its type. */
+ probe_bus(mst, chip->id.type);
+ } else {
+ probe_bus(mst, 0);
+ }
+
+ struct found_id *found_id;
+ for (found_id = mst->found_ids; found_id; found_id = found_id->next) {
+ if (found_id->info.id.type != chip->id.type)
+ continue;
+
+ if (found_id->info.id.type < ARRAY_SIZE(id_names))
+ msg_cdbg("%s: id1 0x%02x, id2 0x%02x ",
+ id_names[found_id->info.id.type],
+ found_id->info.id.id1, found_id->info.id.id2);
+
+ if (mst->probing.match(chip, &found_id->info))
+ break;
+ }
+
+ msg_cdbg("\n");
+ return !!found_id;
+}
+
+/* wrapper that's used until all probing functions are ported to per-bus probing */
+int probe_buses(struct flashctx *const flash)
+{
+ int i;
+ for (i = 0; i < registered_master_count; ++i) {
+ if (flash->mst.common == ®istered_masters[i].common &&
+ chip_on_bus(®istered_masters[i], flash->chip))
+ return 1;
+ }
+ return 0;
+}
+
int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
{
const struct flashchip *chip;