Skip to content
Snippets Groups Projects
Forked from Reform / reform-boundary-uboot
Source project has a limited visibility.
  • Bin Meng's avatar
    d4efefe3
    dm: usb: Fix broken usb_stop() · d4efefe3
    Bin Meng authored
    
    At present we only do device_remove() during usb stop. The DM API
    device_remove() only marks the device state as inactivated, but
    still keeps its USB topology (eg: parent, children, etc) in the DM
    device structure. There is no issue if we only start USB subsystem
    once and never stop it. But a big issue occurs when we do 'usb stop'
    and 'usb start' multiple times.
    
    Strange things may be observed with current implementation, like:
    - the enumeration may report only 1 mass storage device is detected,
      but the total number of USB devices is correct.
    - USB keyboard does not work anymore after a bunch of 'usb reset'
      even if 'usb tree' shows it is correctly identified.
    - read/write flash drive via 'fatload usb' may complain "Bad device"
    
    In fact, every time when USB host controller starts the enumeration
    process, it takes random time for each USB port to show up online,
    hence each USB device may appear in a different order from previous
    enumeration, and gets assigned to a totally different USB address.
    As a result, we end up using a stale USB topology in the DM device
    structure which still reflects the previous enumeration result, and
    it may create an exact same DM device name like generic_bus_0_dev_7
    that is already in the DM device structure. And since the DM device
    structure is there, there is no device_bind() call to bind driver to
    the device during current enumeration process, eventually creating
    an inconsistent software representation of the hardware topology, a
    non-working USB subsystem.
    
    The fix is to clear the unused USB topology in the usb_stop(), by
    calling device_unbind() on each controller's root hub device, and
    the unbinding will unbind all of its children automatically.
    
    For Sandbox, we need scan the device tree each time when we start
    the USB stack, in order to re-create the emulated USB devices and
    bind drivers for them before we actually do the driver probe.
    
    Signed-off-by: default avatarBin Meng <bmeng.cn@gmail.com>
    d4efefe3
    History
    dm: usb: Fix broken usb_stop()
    Bin Meng authored
    
    At present we only do device_remove() during usb stop. The DM API
    device_remove() only marks the device state as inactivated, but
    still keeps its USB topology (eg: parent, children, etc) in the DM
    device structure. There is no issue if we only start USB subsystem
    once and never stop it. But a big issue occurs when we do 'usb stop'
    and 'usb start' multiple times.
    
    Strange things may be observed with current implementation, like:
    - the enumeration may report only 1 mass storage device is detected,
      but the total number of USB devices is correct.
    - USB keyboard does not work anymore after a bunch of 'usb reset'
      even if 'usb tree' shows it is correctly identified.
    - read/write flash drive via 'fatload usb' may complain "Bad device"
    
    In fact, every time when USB host controller starts the enumeration
    process, it takes random time for each USB port to show up online,
    hence each USB device may appear in a different order from previous
    enumeration, and gets assigned to a totally different USB address.
    As a result, we end up using a stale USB topology in the DM device
    structure which still reflects the previous enumeration result, and
    it may create an exact same DM device name like generic_bus_0_dev_7
    that is already in the DM device structure. And since the DM device
    structure is there, there is no device_bind() call to bind driver to
    the device during current enumeration process, eventually creating
    an inconsistent software representation of the hardware topology, a
    non-working USB subsystem.
    
    The fix is to clear the unused USB topology in the usb_stop(), by
    calling device_unbind() on each controller's root hub device, and
    the unbinding will unbind all of its children automatically.
    
    For Sandbox, we need scan the device tree each time when we start
    the USB stack, in order to re-create the emulated USB devices and
    bind drivers for them before we actually do the driver probe.
    
    Signed-off-by: default avatarBin Meng <bmeng.cn@gmail.com>