]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[usb] Do not call usb_hotplug() when registering a new hub
authorMichael Brown <mcb30@ipxe.org>
Wed, 13 May 2015 13:13:09 +0000 (14:13 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 13 May 2015 13:13:09 +0000 (14:13 +0100)
The action of registering a new hub can itself happen in only two
ways: either a new USB hub has been created (in which case we are
already inside a call to usb_hotplug()), or a new root hub has been
created.

In the former case, we do not need to issue a further call to
usb_hotplug(), since the hub's ports will all be marked as changed and
so will be handled after the return from register_usb_hub() anyway.
Calling usb_hotplug() within register_usb_hub() leads to a confusing
order of events, such as:

- root hub port 1 detects a change
- root hub port 2 detects a change
- usb_hotplug() is called
  - root hub port 1 finds a USB hub
    - usb_hotplug() is called
      - this inner call to usb_hotplug() handles root hub port 2

Fix by calling usb_hotplug() only from usb_step() and from
register_usb_bus().  This avoids recursive calls to usb_hotplug() and
ensures that devices are enumerated in the order of detection.

Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/bus/usb.c

index 085caf23b9aec334afba80eb6a6576e70192aa21..7574aaa1da28648dd7c0996ab63a1dd317d1f7fc 100644 (file)
@@ -1779,9 +1779,6 @@ int register_usb_hub ( struct usb_hub *hub ) {
         */
        usb_poll ( bus );
 
-       /* Attach any devices already present */
-       usb_hotplug();
-
        return 0;
 
        hub->driver->close ( hub );
@@ -1915,6 +1912,9 @@ int register_usb_bus ( struct usb_bus *bus ) {
        if ( ( rc = register_usb_hub ( bus->hub ) ) != 0 )
                goto err_register_hub;
 
+       /* Attach any devices already present */
+       usb_hotplug();
+
        return 0;
 
        unregister_usb_hub ( bus->hub );