[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 <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2015-05-06 16:38:28 +01:00
parent b88ab14ba3
commit f6604627ff
5 changed files with 78 additions and 51 deletions

View File

@@ -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;
}
/******************************************************************************