Browse Source

[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>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
15ce7ce355
2 changed files with 12 additions and 10 deletions
  1. 10
    9
      src/drivers/bus/usb.c
  2. 2
    1
      src/drivers/usb/usbhub.c

+ 10
- 9
src/drivers/bus/usb.c View File

485
 	assert ( iob_headroom ( iobuf ) >= sizeof ( *packet ) );
485
 	assert ( iob_headroom ( iobuf ) >= sizeof ( *packet ) );
486
 
486
 
487
 	/* Fail immediately if device has been unplugged */
487
 	/* Fail immediately if device has been unplugged */
488
-	if ( port->speed == USB_SPEED_NONE )
488
+	if ( port->disconnected )
489
 		return -ENODEV;
489
 		return -ENODEV;
490
 
490
 
491
 	/* Reset endpoint if required */
491
 	/* Reset endpoint if required */
534
 	int rc;
534
 	int rc;
535
 
535
 
536
 	/* Fail immediately if device has been unplugged */
536
 	/* Fail immediately if device has been unplugged */
537
-	if ( port->speed == USB_SPEED_NONE )
537
+	if ( port->disconnected )
538
 		return -ENODEV;
538
 		return -ENODEV;
539
 
539
 
540
 	/* Reset endpoint if required */
540
 	/* Reset endpoint if required */
1717
 	if ( ( rc = hub->driver->speed ( hub, port ) ) != 0 ) {
1717
 	if ( ( rc = hub->driver->speed ( hub, port ) ) != 0 ) {
1718
 		DBGC ( hub, "USB hub %s port %d could not get speed: %s\n",
1718
 		DBGC ( hub, "USB hub %s port %d could not get speed: %s\n",
1719
 		       hub->name, port->address, strerror ( rc ) );
1719
 		       hub->name, port->address, strerror ( rc ) );
1720
-		goto err_speed;
1720
+		/* Treat as a disconnection */
1721
+		port->disconnected = 1;
1722
+		port->speed = USB_SPEED_NONE;
1721
 	}
1723
 	}
1722
 
1724
 
1723
 	/* Detach device, if applicable */
1725
 	/* Detach device, if applicable */
1724
 	if ( port->attached && ( port->disconnected || ! port->speed ) )
1726
 	if ( port->attached && ( port->disconnected || ! port->speed ) )
1725
 		usb_detached ( port );
1727
 		usb_detached ( port );
1726
 
1728
 
1729
+	/* Clear any recorded disconnections */
1730
+	port->disconnected = 0;
1731
+
1727
 	/* Attach device, if applicable */
1732
 	/* Attach device, if applicable */
1728
 	if ( port->speed && ( ! port->attached ) &&
1733
 	if ( port->speed && ( ! port->attached ) &&
1729
 	     ( ( rc = usb_attached ( port ) ) != 0 ) )
1734
 	     ( ( rc = usb_attached ( port ) ) != 0 ) )
1730
-		goto err_attached;
1735
+		return rc;
1731
 
1736
 
1732
- err_attached:
1733
- err_speed:
1734
-	/* Clear any recorded disconnections */
1735
-	port->disconnected = 0;
1736
-	return rc;
1737
+	return 0;
1737
 }
1738
 }
1738
 
1739
 
1739
 /******************************************************************************
1740
 /******************************************************************************

+ 2
- 1
src/drivers/usb/usbhub.c View File

496
 	unsigned int i;
496
 	unsigned int i;
497
 
497
 
498
 	/* If hub has been unplugged, mark all ports as unplugged */
498
 	/* If hub has been unplugged, mark all ports as unplugged */
499
-	if ( usb->port->speed == USB_SPEED_NONE ) {
499
+	if ( usb->port->disconnected ) {
500
 		for ( i = 1 ; i <= hub->ports ; i++ ) {
500
 		for ( i = 1 ; i <= hub->ports ; i++ ) {
501
 			port = usb_port ( hub, i );
501
 			port = usb_port ( hub, i );
502
+			port->disconnected = 1;
502
 			port->speed = USB_SPEED_NONE;
503
 			port->speed = USB_SPEED_NONE;
503
 		}
504
 		}
504
 	}
505
 	}

Loading…
Cancel
Save