[PATCH v6 01/20] dm: core: Fix uclass_probe_all to really probe all devices

Michal Suchanek msuchanek at suse.de
Wed Oct 12 21:57:50 CEST 2022


uclass_probe_all uses uclass_first_device/uclass_next_device assigning
the return value.

The interface for getting meaningful error is
uclass_first_device_check/uclass_next_device_check, use it.

Also do not stop iteration when an error is encountered. Probing all
devices includes those that happen to be after a failing device in the
uclass order.

Fixes: a59153dfeb ("dm: core: add function uclass_probe_all() to probe all devices")
Signed-off-by: Michal Suchanek <msuchanek at suse.de>
---
v6: add test
---
 drivers/core/uclass.c | 12 +++++-------
 test/dm/test-fdt.c    | 19 +++++++++++++++----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 08d9ed82de..a591e22403 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -799,20 +799,18 @@ int uclass_pre_remove_device(struct udevice *dev)
 int uclass_probe_all(enum uclass_id id)
 {
 	struct udevice *dev;
-	int ret;
+	int ret, err;
 
-	ret = uclass_first_device(id, &dev);
-	if (ret || !dev)
-		return ret;
+	err = uclass_first_device_check(id, &dev);
 
 	/* Scanning uclass to probe all devices */
 	while (dev) {
-		ret = uclass_next_device(&dev);
+		ret = uclass_next_device_check(&dev);
 		if (ret)
-			return ret;
+			err = ret;
 	}
 
-	return 0;
+	return err;
 }
 
 int uclass_id_count(enum uclass_id id)
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 012f2f455f..1f14513d9f 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -392,10 +392,10 @@ DM_TEST(dm_test_fdt_offset,
 	UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_FLAT_TREE);
 
 /**
- * Test various error conditions with uclass_first_device() and
- * uclass_next_device()
+ * Test various error conditions with uclass_first_device(),
+ * uclass_next_device(), and uclass_probe_all()
  */
-static int dm_test_first_next_device(struct unit_test_state *uts)
+static int dm_test_first_next_device_probeall(struct unit_test_state *uts)
 {
 	struct dm_testprobe_pdata *pdata;
 	struct udevice *dev, *parent = NULL;
@@ -428,9 +428,20 @@ static int dm_test_first_next_device(struct unit_test_state *uts)
 	device_remove(parent, DM_REMOVE_NORMAL);
 	ut_asserteq(-ENOENT, uclass_first_device(UCLASS_TEST_PROBE, &dev));
 
+	/* Now that broken devices are set up test probe_all */
+	device_remove(parent, DM_REMOVE_NORMAL);
+	/* There are broken devices so an error should be returned */
+	ut_assert(uclass_probe_all(UCLASS_TEST_PROBE) < 0);
+	/* but non-error device should be probed nonetheless */
+	ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 2, &dev));
+	ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
+	ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 3, &dev));
+	ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
+
 	return 0;
 }
-DM_TEST(dm_test_first_next_device, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+DM_TEST(dm_test_first_next_device_probeall,
+	UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 
 /* Test iteration through devices in a uclass */
 static int dm_test_uclass_foreach(struct unit_test_state *uts)
-- 
2.37.3



More information about the U-Boot mailing list