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 ) );
|
assert ( iob_headroom ( iobuf ) >= sizeof ( *packet ) );
|
||||||
|
|
||||||
/* Fail immediately if device has been unplugged */
|
/* Fail immediately if device has been unplugged */
|
||||||
if ( port->speed == USB_SPEED_NONE )
|
if ( port->disconnected )
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* Reset endpoint if required */
|
/* Reset endpoint if required */
|
||||||
|
@ -534,7 +534,7 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Fail immediately if device has been unplugged */
|
/* Fail immediately if device has been unplugged */
|
||||||
if ( port->speed == USB_SPEED_NONE )
|
if ( port->disconnected )
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* Reset endpoint if required */
|
/* Reset endpoint if required */
|
||||||
|
@ -1717,23 +1717,24 @@ static int usb_hotplugged ( struct usb_port *port ) {
|
||||||
if ( ( rc = hub->driver->speed ( hub, port ) ) != 0 ) {
|
if ( ( rc = hub->driver->speed ( hub, port ) ) != 0 ) {
|
||||||
DBGC ( hub, "USB hub %s port %d could not get speed: %s\n",
|
DBGC ( hub, "USB hub %s port %d could not get speed: %s\n",
|
||||||
hub->name, port->address, strerror ( rc ) );
|
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 */
|
/* Detach device, if applicable */
|
||||||
if ( port->attached && ( port->disconnected || ! port->speed ) )
|
if ( port->attached && ( port->disconnected || ! port->speed ) )
|
||||||
usb_detached ( port );
|
usb_detached ( port );
|
||||||
|
|
||||||
|
/* Clear any recorded disconnections */
|
||||||
|
port->disconnected = 0;
|
||||||
|
|
||||||
/* Attach device, if applicable */
|
/* Attach device, if applicable */
|
||||||
if ( port->speed && ( ! port->attached ) &&
|
if ( port->speed && ( ! port->attached ) &&
|
||||||
( ( rc = usb_attached ( port ) ) != 0 ) )
|
( ( rc = usb_attached ( port ) ) != 0 ) )
|
||||||
goto err_attached;
|
|
||||||
|
|
||||||
err_attached:
|
|
||||||
err_speed:
|
|
||||||
/* Clear any recorded disconnections */
|
|
||||||
port->disconnected = 0;
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
@ -496,9 +496,10 @@ static void hub_remove ( struct usb_function *func ) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* If hub has been unplugged, mark all ports as unplugged */
|
/* 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++ ) {
|
for ( i = 1 ; i <= hub->ports ; i++ ) {
|
||||||
port = usb_port ( hub, i );
|
port = usb_port ( hub, i );
|
||||||
|
port->disconnected = 1;
|
||||||
port->speed = USB_SPEED_NONE;
|
port->speed = USB_SPEED_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue