On Friday 22 July 2011 01:38:33 Mike Tancsa wrote:
More for the archives in case anyone else runs into this.
We got a new desktop board in that we were testing out netbooting and
noticed that without xhci loaded in the kernel the box hangs with the
last thing being initialized em0 (full dmesg etc at
http://www.tancsa.com/xhci.txt)
Its an Intel DQ67SW
ata2: [ITHREAD]
ata3: ATA channel 1 on atapci0
ata3: [ITHREAD]
pci0: simple comms, UART at device 22.3 (no driver attached)
em0: Intel(R) PRO/1000 Network Connection 7.2.3 port 0xf080-0xf09f mem
0xfe60-0xfe61,0xfe628000-0xfe628fff irq 20 at device 25.0 on pci0
em0: Using an MSI interrupt
em0: [FILTER]
em0: Ethernet address: 00:22:4d:52:04:46
with usb 3 disabled in the BIOS, or with xhci loaded, all boots fine as
shown below.
Please try the attached patch for /sys/dev/pci:
--HPS
=== pci.c
==
--- pci.c (revision 224243)
+++ pci.c (local)
@@ -62,6 +62,7 @@
#include dev/pci/pcivar.h
#include dev/pci/pci_private.h
+#include dev/usb/controller/xhcireg.h
#include dev/usb/controller/ehcireg.h
#include dev/usb/controller/ohcireg.h
#include dev/usb/controller/uhcireg.h
@@ -2956,6 +2957,63 @@
bus_release_resource(self, SYS_RES_MEMORY, rid, res);
}
+/* Perform early XHCI takeover from SMM. */
+static void
+xhci_early_takeover(device_t self)
+{
+ struct resource *res;
+ uint32_t cparams;
+ uint32_t eec;
+ uint8_t eecp;
+ uint8_t bios_sem;
+ int rid;
+ int i;
+
+ rid = PCIR_BAR(0);
+ res = bus_alloc_resource_any(self, SYS_RES_MEMORY, rid, RF_ACTIVE);
+ if (res == NULL)
+ return;
+
+ cparams = bus_read_4(res, XHCI_HCSPARAMS0);
+
+ eec = -1;
+
+ /* Synchronise with the BIOS if it owns the controller. */
+ for (eecp = XHCI_HCS0_XECP(cparams) 2; eecp != 0 XHCI_XECP_NEXT(eec);
+ eecp += XHCI_XECP_NEXT(eec) 2) {
+ eec = bus_read_4(res, eecp);
+
+ if (XHCI_XECP_ID(eec) != XHCI_ID_USB_LEGACY)
+ continue;
+
+ bios_sem = bus_read_1(res, eecp + XHCI_XECP_BIOS_SEM);
+ if (bios_sem == 0)
+ continue;
+
+ if (bootverbose)
+ printf(xhci early:
+ SMM active, request owner change\n);
+
+ bus_write_1(res, eecp + XHCI_XECP_OS_SEM, 1);
+
+ /* wait a maximum of 5 second */
+
+ for (i = 0; (i 5000) (bios_sem != 0); i++) {
+ DELAY(1000);
+ bios_sem = bus_read_1(res, eecp +
+ XHCI_XECP_BIOS_SEM);
+ }
+
+ if (bios_sem != 0) {
+ if (bootverbose)
+printf(xhci early:
+SMM does not respond\n);
+ }
+
+ }
+ bus_release_resource(self, SYS_RES_MEMORY, rid, res);
+}
+
void
pci_add_resources(device_t bus, device_t dev, int force, uint32_t prefetchmask)
{
@@ -3002,7 +3060,9 @@
if (pci_usb_takeover pci_get_class(dev) == PCIC_SERIALBUS
pci_get_subclass(dev) == PCIS_SERIALBUS_USB) {
- if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_EHCI)
+ if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_XHCI)
+ xhci_early_takeover(dev);
+ else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_EHCI)
ehci_early_takeover(dev);
else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_OHCI)
ohci_early_takeover(dev);
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to freebsd-usb-unsubscr...@freebsd.org