Browse Source

[ehci] Poll child companion controllers after disowning port

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
b3de9664c7
2 changed files with 59 additions and 0 deletions
  1. 53
    0
      src/drivers/usb/ehci.c
  2. 6
    0
      src/drivers/usb/ehci.h

+ 53
- 0
src/drivers/usb/ehci.c View File

@@ -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
 

+ 6
- 0
src/drivers/usb/ehci.h View File

@@ -424,6 +424,12 @@ ehci_ring_remaining ( struct ehci_ring *ring ) {
424 424
  */
425 425
 #define EHCI_PORT_POWER_DELAY_MS 20
426 426
 
427
+/** Time to delay after releasing ownership of a port
428
+ *
429
+ * This is a policy decision.
430
+ */
431
+#define EHCI_DISOWN_DELAY_MS 100
432
+
427 433
 /** Maximum time to wait for BIOS to release ownership
428 434
  *
429 435
  * This is a policy decision.

Loading…
Cancel
Save