• Luben Tuikov's avatar
    USB: Reset USB 3.0 devices on (re)discovery · 07194ab7
    Luben Tuikov authored
    If the device isn't reset, the XHCI HCD sends
    SET ADDRESS to address 0 while the device is
    already in Addressed state, and the request is
    dropped on the floor as it is addressed to the
    default address. This sequence of events, which this
    patch fixes looks like this:
    
    usb_reset_and_verify_device()
    	hub_port_init()
    		hub_set_address()
    			SET_ADDRESS to 0 with 1
    		usb_get_device_descriptor(udev, 8)
    		usb_get_device_descriptor(udev, 18)
    	descriptors_changed() --> goto re_enumerate:
    		hub_port_logical_disconnect()
    			kick_khubd()
    
    And then:
    
    hub_events()
    	hub_port_connect_change()
    		usb_disconnect()
    			usb_disable_device()
    		new device struct
    		sets device state to Powered
    		choose_address()
    		hub_port_init() <-- no reset, but SET ADDRESS to 0 with 1, timeout!
    
    The solution is to always reset the device in
    hub_port_init() to put it in a known state.
    
    Note from Sarah Sharp:
    
    This patch should be queued for stable trees all the way back to 2.6.34,
    since that was the first kernel that supported configured device reset.
    The code this patch touches has been there since 2.6.32, but the bug
    would never be hit before 2.6.34 because the xHCI driver would
    completely reject an attempt to reset a configured device under xHCI.
    Signed-off-by: default avatarLuben Tuikov <ltuikov@yahoo.com>
    Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
    Cc: stable@kernel.org
    07194ab7
hub.c 110 KB