bootstd: Allow scanning a single bootdev label

We want to support scanning a single label, like 'mmc' or 'usb0'. Add
this feature by plumbing the label through to the iterator, setting a
flag to indicate that only siblings of the initial device should be used.

This means that scanning a bootdev by its name is not supported anymore.
That feature doesn't seem very useful in practice, so it is no great loss.

Add a test for bootdev_find_by_any() while we are here.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/boot/bootflow.c b/boot/bootflow.c
index 32e2aad..50d9c2e 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -215,7 +215,37 @@
 		dev = iter->dev;
 		log_debug("inc_dev=%d\n", inc_dev);
 		if (!inc_dev) {
-			ret = bootdev_setup_iter(iter, &dev, &method_flags);
+			ret = bootdev_setup_iter(iter, NULL, &dev,
+						 &method_flags);
+		} else if (IS_ENABLED(CONFIG_BOOTSTD_FULL) &&
+			   (iter->flags & BOOTFLOWF_SINGLE_UCLASS)) {
+			/* Move to the next bootdev in this uclass */
+			uclass_find_next_device(&dev);
+			if (!dev) {
+				log_debug("finished uclass %s\n",
+					  dev_get_uclass_name(dev));
+				ret = -ENODEV;
+			}
+		} else if (IS_ENABLED(CONFIG_BOOTSTD_FULL) &&
+			   iter->flags & BOOTFLOWF_SINGLE_MEDIA) {
+			log_debug("next in single\n");
+			method_flags = 0;
+			do {
+				/*
+				 * Move to the next bootdev child of this media
+				 * device. This ensures that we cover all the
+				 * available SCSI IDs and LUNs.
+				 */
+				device_find_next_child(&dev);
+				log_debug("- next %s\n",
+					dev ? dev->name : "(none)");
+			} while (dev && device_get_uclass_id(dev) !=
+				UCLASS_BOOTDEV);
+			if (!dev) {
+				log_debug("finished uclass %s\n",
+					  dev_get_uclass_name(dev));
+				ret = -ENODEV;
+			}
 		} else {
 			log_debug("labels %p\n", iter->labels);
 			if (iter->labels) {
@@ -294,12 +324,13 @@
 	return 0;
 }
 
-int bootflow_scan_bootdev(struct udevice *dev, struct bootflow_iter *iter,
-			  int flags, struct bootflow *bflow)
+int bootflow_scan_bootdev(struct udevice *dev, const char *label,
+			  struct bootflow_iter *iter, int flags,
+			  struct bootflow *bflow)
 {
 	int ret;
 
-	if (dev)
+	if (dev || label)
 		flags |= BOOTFLOWF_SKIP_GLOBAL;
 	bootflow_iter_init(iter, flags);
 
@@ -318,7 +349,7 @@
 		struct udevice *dev = NULL;
 		int method_flags;
 
-		ret = bootdev_setup_iter(iter, &dev, &method_flags);
+		ret = bootdev_setup_iter(iter, label, &dev, &method_flags);
 		if (ret)
 			return log_msg_ret("obdev", -ENODEV);
 
@@ -345,7 +376,7 @@
 {
 	int ret;
 
-	ret = bootflow_scan_bootdev(NULL, iter, flags, bflow);
+	ret = bootflow_scan_bootdev(NULL, NULL, iter, flags, bflow);
 	if (ret)
 		return log_msg_ret("start", ret);