]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
dm: uclass: don't assign aliased seq numbers
authorMichael Walle <michael@walle.cc>
Mon, 1 Jun 2020 23:47:09 +0000 (01:47 +0200)
committerSimon Glass <sjg@chromium.org>
Fri, 12 Jun 2020 02:52:11 +0000 (20:52 -0600)
If there are aliases for an uclass, set the base for the "dynamically"
allocated numbers next to the highest alias.

Please note, that this might lead to holes in the sequences, depending
on the device tree. For example if there is only an alias "ethernet1",
the next device seq number would be 2.

In particular this fixes a problem with boards which are using ethernet
aliases but also might have network add-in cards like the E1000. If the
board is started with the add-in card and depending on the order of the
drivers, the E1000 might occupy the first ethernet device and mess up
all the hardware addresses, because the devices are now shifted by one.

Also adapt the test cases to the new handling and add test cases
checking the holes in the seq numbers.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Alex Marginean <alexandru.marginean@nxp.com>
Tested-by: Alex Marginean <alexandru.marginean@nxp.com>
Acked-by: Vladimir Oltean <olteanv@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Michal Simek <michal.simek@xilinx.com> [on zcu102-revA]
arch/sandbox/dts/test.dts
drivers/core/uclass.c
include/configs/sandbox.h
test/dm/eth.c
test/dm/test-fdt.c

index b9255e4593eb1b5d375d9d7499add9ae00dd1574..a6e2bfd082f63211801dff6baa3685f404610216 100644 (file)
@@ -23,8 +23,8 @@
                pci0 = &pci0;
                pci1 = &pci1;
                pci2 = &pci2;
-               remoteproc1 = &rproc_1;
-               remoteproc2 = &rproc_2;
+               remoteproc0 = &rproc_1;
+               remoteproc1 = &rproc_2;
                rtc0 = &rtc_0;
                rtc1 = &rtc_1;
                spi0 = "/spi@0";
index 2ab419cfe4da0171aee21d14d69a79d21d5d0f38..c3f1b73cd6b4c3b751bd81fadf977ccea5163f4a 100644 (file)
@@ -689,13 +689,14 @@ int uclass_unbind_device(struct udevice *dev)
 
 int uclass_resolve_seq(struct udevice *dev)
 {
+       struct uclass *uc = dev->uclass;
+       struct uclass_driver *uc_drv = uc->uc_drv;
        struct udevice *dup;
-       int seq;
+       int seq = 0;
        int ret;
 
        assert(dev->seq == -1);
-       ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, dev->req_seq,
-                                       false, &dup);
+       ret = uclass_find_device_by_seq(uc_drv->id, dev->req_seq, false, &dup);
        if (!ret) {
                dm_warn("Device '%s': seq %d is in use by '%s'\n",
                        dev->name, dev->req_seq, dup->name);
@@ -707,9 +708,17 @@ int uclass_resolve_seq(struct udevice *dev)
                return ret;
        }
 
-       for (seq = 0; seq < DM_MAX_SEQ; seq++) {
-               ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, seq,
-                                               false, &dup);
+       if (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS) &&
+           (uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) {
+               /*
+                * dev_read_alias_highest_id() will return -1 if there no
+                * alias. Thus we can always add one.
+                */
+               seq = dev_read_alias_highest_id(uc_drv->name) + 1;
+       }
+
+       for (; seq < DM_MAX_SEQ; seq++) {
+               ret = uclass_find_device_by_seq(uc_drv->id, seq, false, &dup);
                if (ret == -ENODEV)
                        break;
                if (ret)
index 2a81f3a9bc02e5024cd1b107918e42f119556256..528187e1a68ac19983436949848da6241e06ce2d 100644 (file)
@@ -94,9 +94,9 @@
 #endif
 
 #define SANDBOX_ETH_SETTINGS           "ethaddr=00:00:11:22:33:44\0" \
-                                       "eth1addr=00:00:11:22:33:45\0" \
-                                       "eth3addr=00:00:11:22:33:46\0" \
-                                       "eth5addr=00:00:11:22:33:47\0" \
+                                       "eth3addr=00:00:11:22:33:45\0" \
+                                       "eth5addr=00:00:11:22:33:46\0" \
+                                       "eth6addr=00:00:11:22:33:47\0" \
                                        "ipaddr=1.2.3.4\0"
 
 #define MEM_LAYOUT_ENV_SETTINGS \
index 1fddcaabb093258bcf752879b1009ea2975f8646..b58c9640a277618ac994c756ab701ef9f5a24ab5 100644 (file)
@@ -48,7 +48,7 @@ static int dm_test_eth_alias(struct unit_test_state *uts)
        ut_assertok(net_loop(PING));
        ut_asserteq_str("eth@10002000", env_get("ethact"));
 
-       env_set("ethact", "eth1");
+       env_set("ethact", "eth6");
        ut_assertok(net_loop(PING));
        ut_asserteq_str("eth@10004000", env_get("ethact"));
 
@@ -105,7 +105,7 @@ static int dm_test_eth_act(struct unit_test_state *uts)
        const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
                                                "sbe5", "eth@10004000"};
        const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
-                                                "eth3addr", "eth1addr"};
+                                                "eth3addr", "eth6addr"};
        char ethaddr[DM_TEST_ETH_NUM][18];
        int i;
 
@@ -188,15 +188,15 @@ static int dm_test_eth_rotate(struct unit_test_state *uts)
 
        /* Invalidate eth1's MAC address */
        memset(ethaddr, '\0', sizeof(ethaddr));
-       strncpy(ethaddr, env_get("eth1addr"), 17);
-       /* Must disable access protection for eth1addr before clearing */
-       env_set(".flags", "eth1addr");
-       env_set("eth1addr", NULL);
+       strncpy(ethaddr, env_get("eth6addr"), 17);
+       /* Must disable access protection for eth6addr before clearing */
+       env_set(".flags", "eth6addr");
+       env_set("eth6addr", NULL);
 
        retval = _dm_test_eth_rotate1(uts);
 
        /* Restore the env */
-       env_set("eth1addr", ethaddr);
+       env_set("eth6addr", ethaddr);
        env_set("ethrotate", NULL);
 
        if (!retval) {
index 4fcae03dc5b26aa1506a86905c6728ff868e57fd..51f25474094ae962084b8d08e126a7f76bf2f971 100644 (file)
@@ -361,20 +361,32 @@ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts)
        ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 2, &dev));
        ut_asserteq_str("d-test", dev->name);
 
-       /* d-test actually gets 0 */
-       ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 0, &dev));
+       /*
+        * d-test actually gets 9, because thats the next free one after the
+        * aliases.
+        */
+       ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 9, &dev));
        ut_asserteq_str("d-test", dev->name);
 
-       /* initially no one wants seq 1 */
-       ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 1,
+       /* initially no one wants seq 10 */
+       ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 10,
                                                      &dev));
        ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
        ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 4, &dev));
 
        /* But now that it is probed, we can find it */
-       ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev));
+       ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 10, &dev));
        ut_asserteq_str("f-test", dev->name);
 
+       /*
+        * And we should still have holes in our sequence numbers, that is 2
+        * and 4 should not be used.
+        */
+       ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 2,
+                                                      true, &dev));
+       ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 4,
+                                                      true, &dev));
+
        return 0;
 }
 DM_TEST(dm_test_fdt_uclass_seq, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);