Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Sep 2003 23:48:46 -0400
From:      Andrew Atrens <atrens@nortelnetworks.com>
To:        stable@freebsd.org
Subject:   fix/workaround for usb probe lockups on nForce2 mbs
Message-ID:  <3F72659E.8090809@nortelnetworks.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------030403060902050201080906
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit


All,

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.

Not sure if this is a fix or a workaround. I'll leave that to the usb 
gods to decide ...

At any rate, I'd appreciate some feedback ... nForce2 users, does this 
work for you ?


Cheers,

Andrew.


--------------030403060902050201080906
Content-Type: text/plain;
 name="usb.c.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="usb.c.patch"

--- ../usb.good/usb.c	Mon Aug 25 21:22:33 2003
+++ usb.c	Wed Sep 24 23:22:56 2003
@@ -243,11 +243,24 @@
 		 * Turning this code off will delay attachment of USB devices
 		 * until the USB event thread is running, which means that
 		 * the keyboard will not work until after cold boot.
+		 *
+		 * On nForce2/ohci interrupts get enabled while use_polling
+		 * is set to true. When this happens the cpu spins servicing
+		 * the interrupt routine repeatedly and the restart locks
+		 * solid. This appears to be a race condition as it only
+		 * happens when devices are connected prior to boot - indeed
+		 * with no devices attached the lockup doesn't happen.
+		 *
+		 * Don't take any chances and use splusb() to make sure we
+		 * don't start receiving interrupts before we are ready for
+		 * them ...
 		 */
 		if (cold) {
+	                int s = splusb();
 			sc->sc_bus->use_polling++;
 			dev->hub->explore(sc->sc_bus->root_hub);
 			sc->sc_bus->use_polling--;
+			splx( s );
 		}
 #endif
 	} else {

--------------030403060902050201080906--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3F72659E.8090809>