kern/73000: UHCI driver fails to detect (certain) interrupts on boot
Daan Vreeken [PA4DAN]
Danovitsch at Vitsch.net
Fri Oct 22 05:50:27 PDT 2004
>Number: 73000
>Category: kern
>Synopsis: UHCI driver fails to detect (certain) interrupts on boot
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Oct 22 12:50:27 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Daan Vreeken [PA4DAN]
>Release: FreeBSD 5.1-RELEASE i386
>Organization:
>Environment:
System: FreeBSD Racebeest.Danovitsch.LAN 5.1-RELEASE FreeBSD 5.1-RELEASE #18: Thu Oct 7 11:39:42 CEST 2004 root at Racebeest.Danovitsch.LAN:/usr/src.5.1/sys/i386/compile/Laptop i386
>Description:
During boot the UHCI driver uses the routine uhci_waitintr() to
detect interrupts (since interrupts are disabled at that point). The routine
checks the UHCI interrupt status register and if it detects an interrupt
condition it manually calls uhci_intr1() to handle the interrupt. The fault
is that uhci_waitintr() only checks for UHCI_STS_USBINTR and not all other
interrupt flags (like UHCI_STS_USBEI).
This causes interrupts to be ignored (if UHCI_STS_USBINTR isn't
set). Having an axe(4) USB ethernet adapter plugged in during boot causes
the system to freeze (for a very long period of time) during initialisation
of the device. Eventually uhci_waitintr() will timeout, but that can take up
to minutes per request. When using a USB WLAN device with my own driver (
http://vitsch.net/bsd/atuwi ) causes the system to stall for hours at boot,
since the driver does about 100 USB requests during attach.
>How-To-Repeat:
Plugin an axe(4) or atuwi device into a system with a UHCI
controller (not sure if all UHCI controllers exhibit the same behaviour) and
boot the system. Booting should take minutes up to hours.
>Fix:
Apply the following patch (to -current). The patch makes
uhci_waitintr() and uhci_poll() aware of all interrupt flags in the
interrupt status register instead of just UHCI_STS_USBINT.
--- uhci-waitintr-2004-10-22.diff begins here ---
--- uhci.c.org Fri Oct 22 12:16:29 2004
+++ uhci.c Fri Oct 22 12:21:11 2004
@@ -1552,7 +1552,7 @@
for (; timo >= 0; timo--) {
usb_delay_ms(&sc->sc_bus, 1);
DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
- if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
+ if (UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS)
uhci_intr1(sc);
if (xfer->status != USBD_IN_PROGRESS)
return;
@@ -1576,7 +1576,7 @@
{
uhci_softc_t *sc = (uhci_softc_t *)bus;
- if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
+ if (UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS)
uhci_intr1(sc);
}
--- uhci-waitintr-2004-10-22.diff ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list