summaryrefslogtreecommitdiffstats
path: root/src/drivers/bus/usb.c
diff options
context:
space:
mode:
authorMichael Brown2015-12-07 00:22:37 +0100
committerMichael Brown2015-12-07 14:08:22 +0100
commit15ce7ce355b3cfb5ec8bc2d51528b08f02f4648b (patch)
tree0c8628f693944e02af6db1ea17ef5d5fb5f46427 /src/drivers/bus/usb.c
parent[efi] Add %.usb target for building EFI-bootable USB (or other) disk images (diff)
downloadipxe-15ce7ce355b3cfb5ec8bc2d51528b08f02f4648b.tar.gz
ipxe-15ce7ce355b3cfb5ec8bc2d51528b08f02f4648b.tar.xz
ipxe-15ce7ce355b3cfb5ec8bc2d51528b08f02f4648b.zip
[usb] Use port->disconnected to check for disconnected devices
The usb_message() and usb_stream() functions currently check for port->speed==USB_SPEED_NONE to determine whether or not a device has been unplugged. This test will give a false negative result if a new device has been plugged in before the hotplug mechanism has finished handling the removal of the old device. Fix by checking instead the port->disconnected flag, which is now cleared only after completing the removal of the old device. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/bus/usb.c')
-rw-r--r--src/drivers/bus/usb.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c
index 63a7e46a..53501b46 100644
--- a/src/drivers/bus/usb.c
+++ b/src/drivers/bus/usb.c
@@ -485,7 +485,7 @@ int usb_message ( struct usb_endpoint *ep, unsigned int request,
assert ( iob_headroom ( iobuf ) >= sizeof ( *packet ) );
/* Fail immediately if device has been unplugged */
- if ( port->speed == USB_SPEED_NONE )
+ if ( port->disconnected )
return -ENODEV;
/* Reset endpoint if required */
@@ -534,7 +534,7 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
int rc;
/* Fail immediately if device has been unplugged */
- if ( port->speed == USB_SPEED_NONE )
+ if ( port->disconnected )
return -ENODEV;
/* Reset endpoint if required */
@@ -1717,23 +1717,24 @@ static int usb_hotplugged ( struct usb_port *port ) {
if ( ( rc = hub->driver->speed ( hub, port ) ) != 0 ) {
DBGC ( hub, "USB hub %s port %d could not get speed: %s\n",
hub->name, port->address, strerror ( rc ) );
- goto err_speed;
+ /* Treat as a disconnection */
+ port->disconnected = 1;
+ port->speed = USB_SPEED_NONE;
}
/* Detach device, if applicable */
if ( port->attached && ( port->disconnected || ! port->speed ) )
usb_detached ( port );
+ /* Clear any recorded disconnections */
+ port->disconnected = 0;
+
/* Attach device, if applicable */
if ( port->speed && ( ! port->attached ) &&
( ( rc = usb_attached ( port ) ) != 0 ) )
- goto err_attached;
+ return rc;
- err_attached:
- err_speed:
- /* Clear any recorded disconnections */
- port->disconnected = 0;
- return rc;
+ return 0;
}
/******************************************************************************