Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Apr 2000 17:01:09 -0400 (EDT)
From:      mike+fbsd@medianstrip.net
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/18261: resume from suspend breaks usb
Message-ID:  <20000427210109.594E0BA4C@vapre.mobile.medianstrip.net>

next in thread | raw e-mail | index | archive | help

>Number:         18261
>Category:       kern
>Synopsis:       resume from suspend breaks usb
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 27 14:40:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     mike ryan
>Release:        FreeBSD 4.0-STABLE i386
>Organization:
>Environment:

	sony vaio z505hs laptop.  a kernel built from GENERIC with only two
	additions:

		DEVICE uhci
		DEVICE usb

>Description:

	after resuming from suspend, the following errors appear on the console:  

		usb0: host controller process error
		usb0: host controller halted

	and all usb devices stop working.

>How-To-Repeat:

	install a kernel with usb support, suspend, and resume.

>Fix:

	this patch (borrowed from netbsd) makes it work for me:

--- sys/dev/usb/uhcivar.orig	Thu Jan 20 17:24:34 2000
+++ sys/dev/usb/uhcivar.h	Thu Apr 27 16:24:51 2000
@@ -148,6 +148,9 @@
 	u_int8_t sc_addr;		/* device address */
 	u_int8_t sc_conf;		/* device configuration */
 
+	u_int8_t sc_saved_sof;
+	u_int16_t sc_saved_frnum;
+
 	char sc_isreset;
 	char sc_suspend;
 
--- sys/dev/usb/uhci.orig	Thu Feb 10 13:50:17 2000
+++ sys/dev/usb/uhci.c	Thu Apr 27 16:29:42 2000
@@ -254,6 +254,7 @@
 static void		uhci_dump_td __P((uhci_soft_td_t *));
 #endif
 
+#define UWRITE1(sc, r, x) bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x))
 #define UWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x))
 #define UWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
 #define UREAD1(sc, r) bus_space_read_1((sc)->iot, (sc)->ioh, (r))
@@ -584,17 +585,17 @@
 				      sc->sc_has_timo->timo_handle);
 		sc->sc_bus.use_polling++;
 		uhci_run(sc, 0); /* stop the controller */
+
+		/* save some state if BIOS doesn't */
+		sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
+		sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
+
 		UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */
 		usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
 		sc->sc_suspend = why;
 		sc->sc_bus.use_polling--;
 		DPRINTF(("uhci_power: cmd=0x%x\n", UREAD2(sc, UHCI_CMD)));
 	} else {
-		/*
-		 * XXX We should really do much more here in case the
-		 * controller registers have been lost and BIOS has
-		 * not restored them.
-		 */
 #ifdef DIAGNOSTIC
 		if (sc->sc_suspend == PWR_RESUME)
 			printf("uhci_power: weird, resume without suspend.\n");
@@ -603,6 +604,12 @@
 		sc->sc_suspend = why;
 		if (cmd & UHCI_CMD_RS)
 			uhci_run(sc, 0); /* in case BIOS has started it */
+
+		/* restore saved state */
+		UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0));
+		UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
+		UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
+
 		UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force global resume */
 		usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
 		UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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