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