mirror of https://github.com/ipxe/ipxe.git
[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
parent
7f65a08f3e
commit
15ce7ce355
|
@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue