diff options
author | Michael Brown | 2015-12-07 00:22:37 +0100 |
---|---|---|
committer | Michael Brown | 2015-12-07 14:08:22 +0100 |
commit | 15ce7ce355b3cfb5ec8bc2d51528b08f02f4648b (patch) | |
tree | 0c8628f693944e02af6db1ea17ef5d5fb5f46427 /src/drivers/bus | |
parent | [efi] Add %.usb target for building EFI-bootable USB (or other) disk images (diff) | |
download | ipxe-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')
-rw-r--r-- | src/drivers/bus/usb.c | 19 |
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; } /****************************************************************************** |