[coreboot-gerrit] Patch set updated for coreboot: ac24401 libpayload: Handle multifunction bridge devices better.

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Fri Apr 5 21:56:57 CEST 2013


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2517

-gerrit

commit ac24401af7c73862bf5a9b499c22a8d31c7ae9d0
Author: Gabe Black <gabeblack at google.com>
Date:   Thu Nov 8 19:31:23 2012 -0800

    libpayload: Handle multifunction bridge devices better.
    
    This change modifies the code in libpayload that scans the PCI hierarchy for
    USB controllers. Previously, if a devices primary function (function 0) was a
    bridge, then none of the other functions, if any, would be looked at. If one
    of the other functions was a bridge, that wouldn't be handled either. The new
    version looks at each function that's present no matter what, and if it
    discovers that it's a bridge it scans the other side.
    
    Change-Id: I37f269a4fe505fd32d9594e2daf17ddd78609c15
    Signed-off-by: Gabe Black <gabeblack at google.com>
---
 payloads/libpayload/drivers/usb/usbinit.c | 56 +++++++++++++++++--------------
 1 file changed, 31 insertions(+), 25 deletions(-)

diff --git a/payloads/libpayload/drivers/usb/usbinit.c b/payloads/libpayload/drivers/usb/usbinit.c
index 74358bb..76653ff 100644
--- a/payloads/libpayload/drivers/usb/usbinit.c
+++ b/payloads/libpayload/drivers/usb/usbinit.c
@@ -47,12 +47,12 @@ static int usb_controller_initialize(int bus, int dev, int func)
 	u32 class;
 	u32 devclass;
 	u32 prog_if;
-	pcidev_t addr;
+	pcidev_t pci_device;
 	u32 pciid;
 
-	addr = PCI_DEV (bus, dev, func);
-	class = pci_read_config32(addr, 8);
-	pciid = pci_read_config32(addr, 0);
+	pci_device = PCI_DEV (bus, dev, func);
+	class = pci_read_config32(pci_device, 8);
+	pciid = pci_read_config32(pci_device, 0);
 
 	devclass = class >> 16;
 	prog_if = (class >> 8) & 0xff;
@@ -63,9 +63,9 @@ static int usb_controller_initialize(int bus, int dev, int func)
 	if (devclass == 0xc03) {
 		u32 pci_command;
 
-		pci_command = pci_read_config32(addr, PCI_COMMAND);
+		pci_command = pci_read_config32(pci_device, PCI_COMMAND);
 		pci_command |= PCI_COMMAND_MASTER;
-		pci_write_config32(addr, PCI_COMMAND, pci_command);
+		pci_write_config32(pci_device, PCI_COMMAND, pci_command);
 
 		usb_debug("%02x:%02x.%x %04x:%04x.%d ", bus, dev, func,
 			pciid >> 16, pciid & 0xFFFF, func);
@@ -73,7 +73,7 @@ static int usb_controller_initialize(int bus, int dev, int func)
 		case 0x00:
 #ifdef CONFIG_USB_UHCI
 			usb_debug("UHCI controller\n");
-			uhci_init (addr);
+			uhci_init (pci_device);
 #else
 			usb_debug("UHCI controller (not supported)\n");
 #endif
@@ -82,7 +82,7 @@ static int usb_controller_initialize(int bus, int dev, int func)
 		case 0x10:
 #ifdef CONFIG_USB_OHCI
 			usb_debug("OHCI controller\n");
-			ohci_init(addr);
+			ohci_init(pci_device);
 #else
 			usb_debug("OHCI controller (not supported)\n");
 #endif
@@ -91,7 +91,7 @@ static int usb_controller_initialize(int bus, int dev, int func)
 		case 0x20:
 #ifdef CONFIG_USB_EHCI
 			usb_debug("EHCI controller\n");
-			ehci_init(addr);
+			ehci_init(pci_device);
 #else
 			usb_debug("EHCI controller (not supported)\n");
 #endif
@@ -100,7 +100,7 @@ static int usb_controller_initialize(int bus, int dev, int func)
 		case 0x30:
 #ifdef CONFIG_USB_XHCI
 			usb_debug("xHCI controller\n");
-			xhci_init(addr);
+			xhci_init(pci_device);
 #else
 			usb_debug("xHCI controller (not supported)\n");
 #endif
@@ -121,31 +121,37 @@ static void usb_scan_pci_bus(int bus)
 	int dev, func;
 	for (dev = 0; dev < 32; dev++) {
 		u8 header_type;
-		pcidev_t addr = PCI_DEV(bus, dev, 0);
+		pcidev_t pci_device = PCI_DEV(bus, dev, 0);
+
 		/* Check if there's a device here at all. */
-		if (pci_read_config32(addr, REG_VENDOR_ID) == 0xffffffff)
-			continue;
-		header_type = pci_read_config8(addr, REG_HEADER_TYPE);
-		/* If this is a bridge, scan the bus on the other side. */
-		if ((header_type & ~HEADER_TYPE_MULTIFUNCTION) ==
-				HEADER_TYPE_BRIDGE) {
-			int sub_bus =
-				pci_read_config8(addr, REG_SECONDARY_BUS);
-			usb_scan_pci_bus(sub_bus);
+		if (pci_read_config32(pci_device, REG_VENDOR_ID) == 0xffffffff)
 			continue;
-		}
+
 		/*
 		 * EHCI is defined by standards to be at a higher function
 		 * than the USB1 controllers. We don't want to init USB1 +
 		 * devices just to "steal" those for USB2, so make sure USB2
-		 * comes first.
+		 * comes first by scanning multifunction devices from 7 to 0.
 		 */
+
 		/* Check for a multifunction device. */
+		header_type = pci_read_config8(pci_device, REG_HEADER_TYPE);
 		if (header_type & HEADER_TYPE_MULTIFUNCTION)
-			for (func = 7; func > 0; func--)
+			func = 7;
+		else
+			func = 0;
+
+		for (; func >= 0; func--) {
+			pci_device = PCI_DEV(bus, dev, func);
+			header_type = pci_read_config8(pci_device, REG_HEADER_TYPE);
+			/* If this is a bridge, scan the other side. */
+			if ((header_type & ~HEADER_TYPE_MULTIFUNCTION) ==
+					HEADER_TYPE_BRIDGE)
+				usb_scan_pci_bus(pci_read_config8(pci_device,
+							REG_SECONDARY_BUS));
+			else
 				usb_controller_initialize(bus, dev, func);
-		/* Initialize function 0. */
-		usb_controller_initialize(bus, dev, 0);
+		}
 	}
 }
 



More information about the coreboot-gerrit mailing list