Date: Fri, 22 Jul 2011 10:22:09 +0200 From: Hans Petter Selasky <hselasky@c2i.net> To: freebsd-usb@freebsd.org Subject: Re: boot hang without xhci [updated patch] Message-ID: <201107221022.09811.hselasky@c2i.net>
next in thread | raw e-mail | index | archive | help
--Boundary-00=_xMTKOKq+mHA7yQN Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit 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 > 0xfe600000-0xfe61ffff,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 --Boundary-00=_xMTKOKq+mHA7yQN Content-Type: text/x-patch; charset="iso-8859-1"; name="xhci_early_takeover.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="xhci_early_takeover.patch" === 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,68 @@ 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; + uint8_t offs; + 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"); + } + + /* Disable interrupts */ + offs = bus_read_1(res, XHCI_CAPLENGTH); + bus_write_4(res, offs + XHCI_USBCMD, 0); + bus_read_4(res, offs + XHCI_USBSTS); + } + 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 +3065,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); --Boundary-00=_xMTKOKq+mHA7yQN--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107221022.09811.hselasky>