fix/workaround for usb probe lockups on nForce2 mbs
Ian Dowse
iedowse at maths.tcd.ie
Thu Sep 25 10:50:03 PDT 2003
In message <3F72659E.8090809 at nortelnetworks.com>, Andrew Atrens writes:
>
>The attached patch fixes the boot lockups I've been experiencing on my
>nForce2 (A7N8X-Deluxe) motherboards when usb devices are on the bus at
>boot time.
>
>Looks like something in usb_explore is (inadvertently?) enabling
>interrupts if it detects a device on a port. The fix is, during hub
>attach, to not assume that interrupts are off when we access the hub in
>'polling' mode.
Great, thanks for tracking it down! It sounds very similar to a
problem people were having before with FAST_IPSEC where interrupts
were being enabled and confusing the USB code. You have a "uhci"
rather than an "ohci" controller I assume? If so, coould you try
the following patch instead? Unfortunately I don't have anything
to test this on, but it in theory it should work around this class
of problems by backporting from -CURRENT some logic for avoiding
interrupts in polling mode.
Ian
Index: uhci.c
===================================================================
RCS file: /home/iedowse/CVS/src/sys/dev/usb/uhci.c,v
retrieving revision 1.40.2.11
diff -u -r1.40.2.11 uhci.c
--- uhci.c 22 Aug 2003 06:59:11 -0000 1.40.2.11
+++ uhci.c 25 Sep 2003 17:34:03 -0000
@@ -908,10 +908,26 @@
sc->sc_bulk_end = pqh;
}
+Static int uhci_intr1(uhci_softc_t *);
+
int
uhci_intr(void *arg)
{
uhci_softc_t *sc = arg;
+
+ DPRINTFN(15,("uhci_intr: real interrupt\n"));
+ if (sc->sc_bus.use_polling) {
+#ifdef DIAGNOSTIC
+ printf("uhci_intr: ignored interrupt while polling\n");
+#endif
+ return (0);
+ }
+ return (uhci_intr1(sc));
+}
+
+int
+uhci_intr1(uhci_softc_t *sc)
+{
int status;
int ack;
uhci_intr_info_t *ii;
@@ -934,7 +950,7 @@
#ifdef USB_DEBUG
if (uhcidebug > 15) {
- DPRINTF(("%s: uhci_intr\n", USBDEVNAME(sc->sc_bus.bdev)));
+ DPRINTF(("%s: uhci_intr1\n", USBDEVNAME(sc->sc_bus.bdev)));
uhci_dumpregs(sc);
}
#endif
@@ -1203,7 +1219,7 @@
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)
- uhci_intr(sc);
+ uhci_intr1(sc);
if (xfer->status != USBD_IN_PROGRESS)
return;
}
@@ -1227,7 +1243,7 @@
uhci_softc_t *sc = (uhci_softc_t *)bus;
if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
- uhci_intr(sc);
+ uhci_intr1(sc);
}
#if 0
More information about the freebsd-stable
mailing list