aboutsummaryrefslogtreecommitdiffstats
path: root/src/drivers/usb/usbhub.c
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2015-05-06 16:38:28 +0100
committerMichael Brown <mcb30@ipxe.org>2015-05-08 14:57:14 +0100
commitf6604627ff71d42bb63a3d81c2986a9d296d55cb (patch)
tree8eb038959b4e3429c4c15e9a1a7a5bd73e68c2b2 /src/drivers/usb/usbhub.c
parentb88ab14ba38d0eb2123975ed78c8eb04ba13cf72 (diff)
downloadipxe-f6604627ff71d42bb63a3d81c2986a9d296d55cb.tar.gz
[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>
Diffstat (limited to 'src/drivers/usb/usbhub.c')
-rw-r--r--src/drivers/usb/usbhub.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/src/drivers/usb/usbhub.c b/src/drivers/usb/usbhub.c
index 6d0cdba45..8b5fa9c4d 100644
--- a/src/drivers/usb/usbhub.c
+++ b/src/drivers/usb/usbhub.c
@@ -331,6 +331,9 @@ static int hub_speed ( struct usb_hub *hub, struct usb_port *port ) {
port->speed = USB_SPEED_NONE;
}
+ /* Record disconnections */
+ port->disconnected |= ( changed & ( 1 << USB_HUB_PORT_CONNECTION ) );
+
/* Clear port status change bits */
if ( ( rc = hub_clear_changes ( hubdev, port->address, changed ) ) != 0)
return rc;