bootstd: Add a new pre-scan priority for bootdevs

We need extensions to be set up before we start trying to boot any of the
bootdevs. Add a new priority before all the others for tht sort of thing.
Also add a 'none' option, so that the first one is not 0.

While we are here, comment enum bootdev_prio_t fully and expand the test
for the 'bootdev hunt' command.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index e868615..5ed310c 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -630,6 +630,7 @@
 int bootdev_setup_iter_order(struct bootflow_iter *iter, struct udevice **devp)
 {
 	struct udevice *bootstd, *dev = *devp, **order;
+	bool show = iter->flags & BOOTFLOWF_SHOW;
 	struct uclass *uc;
 	int count, upto;
 	int ret;
@@ -640,6 +641,13 @@
 		return log_msg_ret("std", ret);
 	}
 
+	/* hunt for any pre-scan devices */
+	if (iter->flags & BOOTFLOWF_HUNT) {
+		ret = bootdev_hunt_prio(BOOTDEVP_1_PRE_SCAN, show);
+		if (ret)
+			return log_msg_ret("pre", ret);
+	}
+
 	/* Handle scanning a single device */
 	if (dev) {
 		iter->flags |= BOOTFLOWF_SINGLE_DEV;
diff --git a/doc/develop/bootstd.rst b/doc/develop/bootstd.rst
index 1ccc494..bfa8cbd 100644
--- a/doc/develop/bootstd.rst
+++ b/doc/develop/bootstd.rst
@@ -211,7 +211,7 @@
     {
         struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-        ucp->prio = BOOTDEVP_0_INTERNAL_FAST;
+        ucp->prio = BOOTDEVP_2_INTERNAL_FAST;
 
         return 0;
     }
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index 80c8b64..1ad9b6c 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -1060,7 +1060,7 @@
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_3_SCAN_SLOW;
+	ucp->prio = BOOTDEVP_5_SCAN_SLOW;
 
 	return 0;
 }
@@ -1089,7 +1089,7 @@
 };
 
 BOOTDEV_HUNTER(ide_bootdev_hunter) = {
-	.prio		= BOOTDEVP_3_SCAN_SLOW,
+	.prio		= BOOTDEVP_5_SCAN_SLOW,
 	.uclass		= UCLASS_IDE,
 	.hunt		= ide_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(ide_bootdev),
diff --git a/drivers/mmc/mmc_bootdev.c b/drivers/mmc/mmc_bootdev.c
index 300208f..b57b8a6 100644
--- a/drivers/mmc/mmc_bootdev.c
+++ b/drivers/mmc/mmc_bootdev.c
@@ -15,7 +15,7 @@
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_0_INTERNAL_FAST;
+	ucp->prio = BOOTDEVP_2_INTERNAL_FAST;
 
 	return 0;
 }
@@ -37,7 +37,7 @@
 };
 
 BOOTDEV_HUNTER(mmc_bootdev_hunter) = {
-	.prio		= BOOTDEVP_0_INTERNAL_FAST,
+	.prio		= BOOTDEVP_2_INTERNAL_FAST,
 	.uclass		= UCLASS_MMC,
 	.drv		= DM_DRIVER_REF(mmc_bootdev),
 };
diff --git a/drivers/mtd/spi/sf_bootdev.c b/drivers/mtd/spi/sf_bootdev.c
index 2272e85..d6b47b1 100644
--- a/drivers/mtd/spi/sf_bootdev.c
+++ b/drivers/mtd/spi/sf_bootdev.c
@@ -53,7 +53,7 @@
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+	ucp->prio = BOOTDEVP_4_SCAN_FAST;
 
 	return 0;
 }
@@ -76,7 +76,7 @@
 };
 
 BOOTDEV_HUNTER(sf_bootdev_hunter) = {
-	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.prio		= BOOTDEVP_4_SCAN_FAST,
 	.uclass		= UCLASS_SPI_FLASH,
 	.drv		= DM_DRIVER_REF(sf_bootdev),
 };
diff --git a/drivers/nvme/nvme-uclass.c b/drivers/nvme/nvme-uclass.c
index 7a8ff06..f3af6a2 100644
--- a/drivers/nvme/nvme-uclass.c
+++ b/drivers/nvme/nvme-uclass.c
@@ -17,7 +17,7 @@
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+	ucp->prio = BOOTDEVP_4_SCAN_FAST;
 
 	return 0;
 }
@@ -62,7 +62,7 @@
 };
 
 BOOTDEV_HUNTER(nvme_bootdev_hunter) = {
-	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.prio		= BOOTDEVP_4_SCAN_FAST,
 	.uclass		= UCLASS_NVME,
 	.hunt		= nvme_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(nvme_bootdev),
diff --git a/drivers/scsi/scsi_bootdev.c b/drivers/scsi/scsi_bootdev.c
index 2367b33..991013f 100644
--- a/drivers/scsi/scsi_bootdev.c
+++ b/drivers/scsi/scsi_bootdev.c
@@ -16,7 +16,7 @@
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+	ucp->prio = BOOTDEVP_4_SCAN_FAST;
 
 	return 0;
 }
@@ -55,7 +55,7 @@
 };
 
 BOOTDEV_HUNTER(scsi_bootdev_hunter) = {
-	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.prio		= BOOTDEVP_4_SCAN_FAST,
 	.uclass		= UCLASS_SCSI,
 	.hunt		= scsi_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(scsi_bootdev),
diff --git a/drivers/usb/host/usb_bootdev.c b/drivers/usb/host/usb_bootdev.c
index 66d0b6a..32919f9 100644
--- a/drivers/usb/host/usb_bootdev.c
+++ b/drivers/usb/host/usb_bootdev.c
@@ -15,7 +15,7 @@
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_3_SCAN_SLOW;
+	ucp->prio = BOOTDEVP_5_SCAN_SLOW;
 
 	return 0;
 }
@@ -42,7 +42,7 @@
 };
 
 BOOTDEV_HUNTER(usb_bootdev_hunter) = {
-	.prio		= BOOTDEVP_3_SCAN_SLOW,
+	.prio		= BOOTDEVP_5_SCAN_SLOW,
 	.uclass		= UCLASS_USB,
 	.hunt		= usb_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(usb_bootdev),
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index 27efac0..91af412 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -360,7 +360,7 @@
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_2_SCAN_FAST;
+	ucp->prio = BOOTDEVP_4_SCAN_FAST;
 
 	return 0;
 }
@@ -405,7 +405,7 @@
 };
 
 BOOTDEV_HUNTER(virtio_bootdev_hunter) = {
-	.prio		= BOOTDEVP_2_SCAN_FAST,
+	.prio		= BOOTDEVP_4_SCAN_FAST,
 	.uclass		= UCLASS_VIRTIO,
 	.hunt		= virtio_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(virtio_bootdev),
diff --git a/include/bootdev.h b/include/bootdev.h
index b7973fa..65d14f2 100644
--- a/include/bootdev.h
+++ b/include/bootdev.h
@@ -21,15 +21,36 @@
  *
  * Smallest value is the highest priority. By default, bootdevs are scanned from
  * highest to lowest priority
+ *
+ * BOOTDEVP_0_NONE: Invalid value, do not use
+ * @BOOTDEVP_6_PRE_SCAN: Scan bootdevs with this priority always, before
+ * starting any bootflow scan
+ * @BOOTDEVP_2_INTERNAL_FAST: Internal devices which don't need scanning and
+ * generally very quick to access, e.g. less than 100ms
+ * @BOOTDEVP_3_INTERNAL_SLOW: Internal devices which don't need scanning but
+ * take a significant fraction of a second to access
+ * @BOOTDEVP_4_SCAN_FAST: Extenal devices which need scanning or bus
+ * enumeration to find, but this enumeration happens quickly, typically under
+ * 100ms
+ * @BOOTDEVP_5_SCAN_SLOW: Extenal devices which need scanning or bus
+ * enumeration to find. The enumeration takes significant fraction of a second
+ * to complete
+ * @BOOTDEVP_6_NET_BASE: Basic network devices which are quickly and easily
+ * available. Typically used for an internal Ethernet device
+ * @BOOTDEVP_7_NET_FALLBACK: Secondary network devices which require extra time
+ * to start up, or are less desirable. Typically used for secondary Ethernet
+ * devices. Note that USB ethernet devices are found during USB enumeration,
+ * so do not use this priority
  */
 enum bootdev_prio_t {
-	BOOTDEVP_0_INTERNAL_FAST	= 10,
-	BOOTDEVP_1_INTERNAL_SLOW	= 20,
-	BOOTDEVP_2_SCAN_FAST		= 30,
-	BOOTDEVP_3_SCAN_SLOW		= 40,
-	BOOTDEVP_4_NET_BASE		= 50,
-	BOOTDEVP_5_NET_FALLBACK		= 60,
-	BOOTDEVP_6_SYSTEM		= 70,
+	BOOTDEVP_0_NONE,
+	BOOTDEVP_1_PRE_SCAN,
+	BOOTDEVP_2_INTERNAL_FAST,
+	BOOTDEVP_3_INTERNAL_SLOW,
+	BOOTDEVP_4_SCAN_FAST,
+	BOOTDEVP_5_SCAN_SLOW,
+	BOOTDEVP_6_NET_BASE,
+	BOOTDEVP_7_NET_FALLBACK,
 
 	BOOTDEVP_COUNT,
 };
diff --git a/net/eth_bootdev.c b/net/eth_bootdev.c
index bcbb35a..13e5fcd 100644
--- a/net/eth_bootdev.c
+++ b/net/eth_bootdev.c
@@ -60,7 +60,7 @@
 {
 	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
 
-	ucp->prio = BOOTDEVP_4_NET_BASE;
+	ucp->prio = BOOTDEVP_6_NET_BASE;
 
 	return 0;
 }
@@ -112,7 +112,7 @@
 };
 
 BOOTDEV_HUNTER(eth_bootdev_hunt) = {
-	.prio		= BOOTDEVP_4_NET_BASE,
+	.prio		= BOOTDEVP_6_NET_BASE,
 	.uclass		= UCLASS_ETH,
 	.hunt		= eth_bootdev_hunt,
 	.drv		= DM_DRIVER_REF(eth_bootdev),
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index f965363..86607f7 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -247,14 +247,14 @@
 	bootdev_list_hunters(std);
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
-	ut_assert_nextline("  50        ethernet         eth_bootdev");
-	ut_assert_nextline("  40        ide              ide_bootdev");
-	ut_assert_nextline("  10        mmc              mmc_bootdev");
-	ut_assert_nextline("  30        nvme             nvme_bootdev");
-	ut_assert_nextline("  30        scsi             scsi_bootdev");
-	ut_assert_nextline("  30        spi_flash        sf_bootdev");
-	ut_assert_nextline("  40        usb              usb_bootdev");
-	ut_assert_nextline("  30        virtio           virtio_bootdev");
+	ut_assert_nextline("   6        ethernet         eth_bootdev");
+	ut_assert_nextline("   5        ide              ide_bootdev");
+	ut_assert_nextline("   2        mmc              mmc_bootdev");
+	ut_assert_nextline("   4        nvme             nvme_bootdev");
+	ut_assert_nextline("   4        scsi             scsi_bootdev");
+	ut_assert_nextline("   4        spi_flash        sf_bootdev");
+	ut_assert_nextline("   5        usb              usb_bootdev");
+	ut_assert_nextline("   4        virtio           virtio_bootdev");
 	ut_assert_nextline("(total hunters: 8)");
 	ut_assert_console_end();
 
@@ -284,17 +284,28 @@
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextline("Prio  Used  Uclass           Hunter");
 	ut_assert_nextlinen("----");
+	ut_assert_nextline("   6        ethernet         eth_bootdev");
+	ut_assert_skip_to_line("(total hunters: 8)");
+	ut_assert_console_end();
+
+	/* Use the MMC hunter and see that it updates */
+	ut_assertok(run_command("bootdev hunt mmc", 0));
+	ut_assertok(run_command("bootdev hunt -l", 0));
+	ut_assert_skip_to_line("   5        ide              ide_bootdev");
+	ut_assert_nextline("   2     *  mmc              mmc_bootdev");
 	ut_assert_skip_to_line("(total hunters: 8)");
 	ut_assert_console_end();
 
 	/* Scan all hunters */
 	sandbox_set_eth_enable(false);
-
+	test_set_skip_delays(true);
 	ut_assertok(run_command("bootdev hunt", 0));
 	ut_assert_nextline("Hunting with: ethernet");
 	ut_assert_nextline("Hunting with: ide");
 	ut_assert_nextline("Bus 0: not available  ");
-	ut_assert_nextline("Hunting with: mmc");
+
+	/* mmc hunter has already been used so should not run again */
+
 	ut_assert_nextline("Hunting with: nvme");
 	ut_assert_nextline("Hunting with: scsi");
 	ut_assert_nextline("scanning bus for devices...");
@@ -309,14 +320,14 @@
 	ut_assertok(run_command("bootdev hunt -l", 0));
 	ut_assert_nextlinen("Prio");
 	ut_assert_nextlinen("----");
-	ut_assert_nextline("  50     *  ethernet         eth_bootdev");
-	ut_assert_nextline("  40     *  ide              ide_bootdev");
-	ut_assert_nextline("  10     *  mmc              mmc_bootdev");
-	ut_assert_nextline("  30     *  nvme             nvme_bootdev");
-	ut_assert_nextline("  30     *  scsi             scsi_bootdev");
-	ut_assert_nextline("  30     *  spi_flash        sf_bootdev");
-	ut_assert_nextline("  40     *  usb              usb_bootdev");
-	ut_assert_nextline("  30     *  virtio           virtio_bootdev");
+	ut_assert_nextline("   6     *  ethernet         eth_bootdev");
+	ut_assert_nextline("   5     *  ide              ide_bootdev");
+	ut_assert_nextline("   2     *  mmc              mmc_bootdev");
+	ut_assert_nextline("   4     *  nvme             nvme_bootdev");
+	ut_assert_nextline("   4     *  scsi             scsi_bootdev");
+	ut_assert_nextline("   4     *  spi_flash        sf_bootdev");
+	ut_assert_nextline("   5     *  usb              usb_bootdev");
+	ut_assert_nextline("   4     *  virtio           virtio_bootdev");
 	ut_assert_nextline("(total hunters: 8)");
 	ut_assert_console_end();
 
@@ -370,14 +381,14 @@
 	test_set_skip_delays(true);
 
 	console_record_reset_enable();
-	ut_assertok(bootdev_hunt_prio(BOOTDEVP_2_SCAN_FAST, false));
+	ut_assertok(bootdev_hunt_prio(BOOTDEVP_4_SCAN_FAST, false));
 	ut_assert_nextline("scanning bus for devices...");
 	ut_assert_skip_to_line("            Type: Hard Disk");
 	ut_assert_nextlinen("            Capacity:");
 	ut_assert_console_end();
 
 	/* now try a different priority, verbosely */
-	ut_assertok(bootdev_hunt_prio(BOOTDEVP_3_SCAN_SLOW, true));
+	ut_assertok(bootdev_hunt_prio(BOOTDEVP_5_SCAN_SLOW, true));
 	ut_assert_nextline("Hunting with: ide");
 	ut_assert_nextline("Bus 0: not available  ");
 	ut_assert_nextline("Hunting with: usb");