[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>
pull/43/head
Michael Brown 2015-12-06 23:22:37 +00:00
parent 7f65a08f3e
commit 15ce7ce355
2 changed files with 12 additions and 10 deletions

View File

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

View File

@ -496,9 +496,10 @@ static void hub_remove ( struct usb_function *func ) {
unsigned int i;
/* If hub has been unplugged, mark all ports as unplugged */
if ( usb->port->speed == USB_SPEED_NONE ) {
if ( usb->port->disconnected ) {
for ( i = 1 ; i <= hub->ports ; i++ ) {
port = usb_port ( hub, i );
port->disconnected = 1;
port->speed = USB_SPEED_NONE;
}
}