fix uhci suspend

Andrea Bittau a.bittau at cs.ucl.ac.uk
Tue Mar 27 10:03:50 UTC 2007


To suspend, you need to:
1) stop the controller
2) set the global suspend bit

The current code does:
cmd = UREAD2(sc, UHCI_CMD);
...
uhci_run(sc, 0); /* stop the controller */
...
UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */

The problem is that cmd is not re-read after stopping the controller, so cmd
will still have the run bit set to 1 instead of 0.  Thus, when entering suspend,
the controller's run bit will be put back to 1 and the controller will freak
out.  The attached patch fixes this.  I don't know if the resume branch of the
code suffers from this problem too---I'm working on suspend for now.  With my
patch, I can get ICH7 82801G to suspend, otherwise, suspend would just hang the
box.

---

Index: uhci.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/uhci.c,v
retrieving revision 1.172
diff -u -p -r1.172 uhci.c
--- uhci.c	19 Oct 2006 01:15:58 -0000	1.172
+++ uhci.c	27 Mar 2007 09:33:48 -0000
@@ -723,6 +723,7 @@ uhci_power(int why, void *v)
 			    sc->sc_intr_xfer);
 		sc->sc_bus.use_polling++;
 		uhci_run(sc, 0); /* stop the controller */
+		cmd &= ~UHCI_CMD_RS;
 
 		/* save some state if BIOS doesn't */
 		sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);


More information about the freebsd-usb mailing list