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
 	DBGC ( ehci, "EHCI %p released ownership to BIOS\n", ehci );
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
  * Run / stop / reset
342
  * Run / stop / reset
1460
 	return -ETIMEDOUT;
1505
 	return -ETIMEDOUT;
1461
 
1506
 
1462
  disown:
1507
  disown:
1508
+	/* Disown port */
1463
 	portsc &= ~EHCI_PORTSC_CHANGE;
1509
 	portsc &= ~EHCI_PORTSC_CHANGE;
1464
 	portsc |= EHCI_PORTSC_OWNER;
1510
 	portsc |= EHCI_PORTSC_OWNER;
1465
 	writel ( portsc, ehci->op + EHCI_OP_PORTSC ( port->address ) );
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
 	return -ENODEV;
1519
 	return -ENODEV;
1467
 }
1520
 }
1468
 
1521
 

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

424
  */
424
  */
425
 #define EHCI_PORT_POWER_DELAY_MS 20
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
 /** Maximum time to wait for BIOS to release ownership
433
 /** Maximum time to wait for BIOS to release ownership
428
  *
434
  *
429
  * This is a policy decision.
435
  * This is a policy decision.

Loading…
Cancel
Save