mirror of https://github.com/ipxe/ipxe.git
[ehci] Poll child companion controllers after disowning port
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/36/head
parent
e4783add79
commit
b3de9664c7
|
@ -292,6 +292,51 @@ static void ehci_legacy_release ( struct ehci_device *ehci,
|
|||
DBGC ( ehci, "EHCI %p released ownership to BIOS\n", ehci );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Companion controllers
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Poll child companion controllers
|
||||
*
|
||||
* @v ehci EHCI device
|
||||
*/
|
||||
static void ehci_poll_companions ( struct ehci_device *ehci ) {
|
||||
struct usb_bus *bus;
|
||||
struct device_description *desc;
|
||||
|
||||
/* Poll any USB buses belonging to child companion controllers */
|
||||
for_each_usb_bus ( bus ) {
|
||||
|
||||
/* Get underlying devices description */
|
||||
desc = &bus->dev->desc;
|
||||
|
||||
/* Skip buses that are not PCI devices */
|
||||
if ( desc->bus_type != BUS_TYPE_PCI )
|
||||
continue;
|
||||
|
||||
/* Skip buses that are not part of the same PCI device */
|
||||
if ( PCI_FIRST_FUNC ( desc->location ) !=
|
||||
PCI_FIRST_FUNC ( ehci->bus->dev->desc.location ) )
|
||||
continue;
|
||||
|
||||
/* Skip buses that are not UHCI or OHCI PCI devices */
|
||||
if ( ( desc->class != PCI_CLASS ( PCI_CLASS_SERIAL,
|
||||
PCI_CLASS_SERIAL_USB,
|
||||
PCI_CLASS_SERIAL_USB_UHCI ))&&
|
||||
( desc->class != PCI_CLASS ( PCI_CLASS_SERIAL,
|
||||
PCI_CLASS_SERIAL_USB,
|
||||
PCI_CLASS_SERIAL_USB_OHCI ) ))
|
||||
continue;
|
||||
|
||||
/* Poll child companion controller bus */
|
||||
usb_poll ( bus );
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Run / stop / reset
|
||||
|
@ -1460,9 +1505,17 @@ static int ehci_root_enable ( struct usb_hub *hub, struct usb_port *port ) {
|
|||
return -ETIMEDOUT;
|
||||
|
||||
disown:
|
||||
/* Disown port */
|
||||
portsc &= ~EHCI_PORTSC_CHANGE;
|
||||
portsc |= EHCI_PORTSC_OWNER;
|
||||
writel ( portsc, ehci->op + EHCI_OP_PORTSC ( port->address ) );
|
||||
|
||||
/* Delay to allow child companion controllers to settle */
|
||||
mdelay ( EHCI_DISOWN_DELAY_MS );
|
||||
|
||||
/* Poll child companion controllers */
|
||||
ehci_poll_companions ( ehci );
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
|
@ -424,6 +424,12 @@ ehci_ring_remaining ( struct ehci_ring *ring ) {
|
|||
*/
|
||||
#define EHCI_PORT_POWER_DELAY_MS 20
|
||||
|
||||
/** Time to delay after releasing ownership of a port
|
||||
*
|
||||
* This is a policy decision.
|
||||
*/
|
||||
#define EHCI_DISOWN_DELAY_MS 100
|
||||
|
||||
/** Maximum time to wait for BIOS to release ownership
|
||||
*
|
||||
* This is a policy decision.
|
||||
|
|
Loading…
Reference in New Issue