Introduce a priority for bus-probing functions

We want to stop probing once anything was detected by specific,
high-priority probing functions. This can benefit, for example,
the probing of non-flash chips on the SPI bus. So far we didn't
probe for these automatically, because the probing commands can
be misunderstood by SPI flashes.

We'll invoke the probing functions in order of their priority,
starting with priority `0'. Once any of them returns something
that doesn't look like continuous 0 or 1 bits,  we'll skip all
probing functions with less priority.

Change-Id: Ibde3c348a2fb84b71c325a6c2719e9f2c8b5e784
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/418
diff --git a/flashprog.c b/flashprog.c
index 423ca38..2726298 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -625,22 +625,39 @@
 
 static void probe_bus(struct registered_master *const mst, const enum id_type type)
 {
+	unsigned int least_priority, priority, i;
 	struct found_id **next_ptr;
-	unsigned int i;
 
 	if (mst->probed)
 		return;
 
+	for (i = 0, least_priority = 0; i < mst->probing.probe_count; ++i) {
+		if (least_priority < mst->probing.probes[i].priority)
+			least_priority = mst->probing.probes[i].priority;
+	}
+
 	next_ptr = &mst->found_ids;
-	for (i = 0; i < mst->probing.probe_count; ++i) {
-		if (type && type != mst->probing.probes[i].type)
-			continue;
+	for (priority = 0; priority <= least_priority; ++priority) {
+		bool found = false;
 
-		*next_ptr = mst->probing.probes[i].run(&mst->probing.probes[i], &mst->common);
+		for (i = 0; i < mst->probing.probe_count; ++i) {
+			if (mst->probing.probes[i].priority != priority)
+				continue;
 
-		/* walk to end in case multiple IDs were found in a single call */
-		while (*next_ptr)
-			next_ptr = &(*next_ptr)->next;
+			if (type && type != mst->probing.probes[i].type)
+				continue;
+
+			*next_ptr = mst->probing.probes[i].run(&mst->probing.probes[i], &mst->common);
+			found |= !!*next_ptr;
+
+			/* walk to end in case multiple IDs were found in a single call */
+			while (*next_ptr)
+				next_ptr = &(*next_ptr)->next;
+		}
+
+		/* Skip lower-priority probing if anything was found. */
+		if (found)
+			break;
 	}
 
 	mst->probed = true;