|
@@ -292,6 +292,51 @@ static void ehci_legacy_release ( struct ehci_device *ehci,
|
292
|
292
|
DBGC ( ehci, "EHCI %p released ownership to BIOS\n", ehci );
|
293
|
293
|
}
|
294
|
294
|
|
|
295
|
+/******************************************************************************
|
|
296
|
+ *
|
|
297
|
+ * Companion controllers
|
|
298
|
+ *
|
|
299
|
+ ******************************************************************************
|
|
300
|
+ */
|
|
301
|
+
|
|
302
|
+/**
|
|
303
|
+ * Poll child companion controllers
|
|
304
|
+ *
|
|
305
|
+ * @v ehci EHCI device
|
|
306
|
+ */
|
|
307
|
+static void ehci_poll_companions ( struct ehci_device *ehci ) {
|
|
308
|
+ struct usb_bus *bus;
|
|
309
|
+ struct device_description *desc;
|
|
310
|
+
|
|
311
|
+ /* Poll any USB buses belonging to child companion controllers */
|
|
312
|
+ for_each_usb_bus ( bus ) {
|
|
313
|
+
|
|
314
|
+ /* Get underlying devices description */
|
|
315
|
+ desc = &bus->dev->desc;
|
|
316
|
+
|
|
317
|
+ /* Skip buses that are not PCI devices */
|
|
318
|
+ if ( desc->bus_type != BUS_TYPE_PCI )
|
|
319
|
+ continue;
|
|
320
|
+
|
|
321
|
+ /* Skip buses that are not part of the same PCI device */
|
|
322
|
+ if ( PCI_FIRST_FUNC ( desc->location ) !=
|
|
323
|
+ PCI_FIRST_FUNC ( ehci->bus->dev->desc.location ) )
|
|
324
|
+ continue;
|
|
325
|
+
|
|
326
|
+ /* Skip buses that are not UHCI or OHCI PCI devices */
|
|
327
|
+ if ( ( desc->class != PCI_CLASS ( PCI_CLASS_SERIAL,
|
|
328
|
+ PCI_CLASS_SERIAL_USB,
|
|
329
|
+ PCI_CLASS_SERIAL_USB_UHCI ))&&
|
|
330
|
+ ( desc->class != PCI_CLASS ( PCI_CLASS_SERIAL,
|
|
331
|
+ PCI_CLASS_SERIAL_USB,
|
|
332
|
+ PCI_CLASS_SERIAL_USB_OHCI ) ))
|
|
333
|
+ continue;
|
|
334
|
+
|
|
335
|
+ /* Poll child companion controller bus */
|
|
336
|
+ usb_poll ( bus );
|
|
337
|
+ }
|
|
338
|
+}
|
|
339
|
+
|
295
|
340
|
/******************************************************************************
|
296
|
341
|
*
|
297
|
342
|
* Run / stop / reset
|
|
@@ -1460,9 +1505,17 @@ static int ehci_root_enable ( struct usb_hub *hub, struct usb_port *port ) {
|
1460
|
1505
|
return -ETIMEDOUT;
|
1461
|
1506
|
|
1462
|
1507
|
disown:
|
|
1508
|
+ /* Disown port */
|
1463
|
1509
|
portsc &= ~EHCI_PORTSC_CHANGE;
|
1464
|
1510
|
portsc |= EHCI_PORTSC_OWNER;
|
1465
|
1511
|
writel ( portsc, ehci->op + EHCI_OP_PORTSC ( port->address ) );
|
|
1512
|
+
|
|
1513
|
+ /* Delay to allow child companion controllers to settle */
|
|
1514
|
+ mdelay ( EHCI_DISOWN_DELAY_MS );
|
|
1515
|
+
|
|
1516
|
+ /* Poll child companion controllers */
|
|
1517
|
+ ehci_poll_companions ( ehci );
|
|
1518
|
+
|
1466
|
1519
|
return -ENODEV;
|
1467
|
1520
|
}
|
1468
|
1521
|
|