From f6604627ff71d42bb63a3d81c2986a9d296d55cb Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 6 May 2015 16:38:28 +0100 Subject: [usb] Detect missed disconnections The USB core will currently fail to detect disconnections if a new device has attached by the time the port is examined in usb_hotplug(). Fix by recording the fact that a disconnection has taken place whenever the "connection status changed" (CSC) bit is observed to be set. (Whether the change represents a disconnection or a reconnection, it indicates that the port has experienced some time of being disconnected.) Note that the time at which a disconnection can be detected varies by hub type. In particular: root hubs can observe the CSC bit when polling, and so will record the disconnection before calling usb_port_changed(), but USB hubs read the port status (and hence the CSC bit) only during the call to hub_speed(), long after the call to usb_port_changed(). Signed-off-by: Michael Brown --- src/drivers/bus/usb.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/drivers/bus') diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c index 2191867ae..2b9efa454 100644 --- a/src/drivers/bus/usb.c +++ b/src/drivers/bus/usb.c @@ -1589,18 +1589,20 @@ static int usb_hotplug ( struct usb_port *port ) { return rc; } - /* Handle attached/detached device as applicable */ - if ( port->speed && ! port->attached ) { - /* Newly attached device */ - return usb_attached ( port ); - } else if ( port->attached && ! port->speed ) { - /* Newly detached device */ + /* Detach device, if applicable */ + if ( port->attached && ( port->disconnected || ! port->speed ) ) usb_detached ( port ); - return 0; - } else { - /* Ignore */ - return 0; + + /* Attach device, if applicable */ + if ( port->speed && ! port->attached ) { + if ( ( rc = usb_attached ( port ) ) != 0 ) + return rc; } + + /* Clear any recorded disconnections */ + port->disconnected = 0; + + return 0; } /****************************************************************************** -- cgit v1.2.3-55-g7522