]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
bootstd: Correct logic for single uclass
authorSimon Glass <sjg@chromium.org>
Mon, 23 Oct 2023 07:02:12 +0000 (00:02 -0700)
committerTom Rini <trini@konsulko.com>
Mon, 23 Oct 2023 17:05:13 +0000 (13:05 -0400)
The current logic for "bootflow mmc" is flawed since it checks the
uclass of the bootdev instead of its parent, the media device. Correct
this and add a test that covers this scenario.

Signed-off-by: Simon Glass <sjg@chromium.org>
Tested-by: Ivan T.Ivanov <iivanov@suse.de>
boot/bootflow.c
test/boot/bootdev.c

index 6ef62e1d1896637d1feaf127e0def36c7a341e3d..7f5b0e9420789eb59bf2fa376e11296516f0537d 100644 (file)
@@ -155,6 +155,27 @@ static void bootflow_iter_set_dev(struct bootflow_iter *iter,
        }
 }
 
+/**
+ * scan_next_in_uclass() - Scan for the next bootdev in the same media uclass
+ *
+ * Move through the following bootdevs until we find another in this media
+ * uclass, or run out
+ *
+ * @devp: On entry, the device to check, on exit the new device, or NULL if
+ * there is none
+ */
+static void scan_next_in_uclass(struct udevice **devp)
+{
+       struct udevice *dev = *devp;
+       enum uclass_id cur_id = device_get_uclass_id(dev->parent);
+
+       do {
+               uclass_find_next_device(&dev);
+       } while (dev && cur_id != device_get_uclass_id(dev->parent));
+
+       *devp = dev;
+}
+
 /**
  * iter_incr() - Move to the next item (method, part, bootdev)
  *
@@ -230,8 +251,7 @@ static int iter_incr(struct bootflow_iter *iter)
                                                 &method_flags);
                } else if (IS_ENABLED(CONFIG_BOOTSTD_FULL) &&
                           (iter->flags & BOOTFLOWIF_SINGLE_UCLASS)) {
-                       /* Move to the next bootdev in this uclass */
-                       uclass_find_next_device(&dev);
+                       scan_next_in_uclass(&dev);
                        if (!dev) {
                                log_debug("finished uclass %s\n",
                                          dev_get_uclass_name(dev));
index 7228f545e9e648a76b1cee6e03032297ada27a57..63786174805749233d1f39dbfc1c64116601388e 100644 (file)
@@ -232,6 +232,19 @@ static int bootdev_test_order(struct unit_test_state *uts)
                        iter.dev_used[2]->name);
        bootflow_iter_uninit(&iter);
 
+       /* Try a single uclass */
+       ut_assertok(env_set("boot_targets", NULL));
+       ut_assertok(bootflow_scan_first(NULL, "mmc", &iter, 0, &bflow));
+       ut_asserteq(2, iter.num_devs);
+
+       /* Now scan pass mmc1 and make sure that only mmc0 shows up */
+       ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
+       ut_asserteq(3, iter.num_devs);
+       ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name);
+       ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name);
+       ut_asserteq_str("mmc0.bootdev", iter.dev_used[2]->name);
+       bootflow_iter_uninit(&iter);
+
        return 0;
 }
 BOOTSTD_TEST(bootdev_test_order, UT_TESTF_DM | UT_TESTF_SCAN_FDT);