From mryan01@vapre.mobile.medianstrip.net  Thu Apr 27 14:31:08 2000
Return-Path: <mryan01@vapre.mobile.medianstrip.net>
Received: from vapre.mobile.medianstrip.net (host251-12.infonet.tufts.edu [130.64.251.12])
	by hub.freebsd.org (Postfix) with ESMTP id F3B8637B52F
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 27 Apr 2000 14:31:02 -0700 (PDT)
	(envelope-from mryan01@vapre.mobile.medianstrip.net)
Received: by vapre.mobile.medianstrip.net (Postfix, from userid 1000)
	id 594E0BA4C; Thu, 27 Apr 2000 17:01:09 -0400 (EDT)
Message-Id: <20000427210109.594E0BA4C@vapre.mobile.medianstrip.net>
Date: Thu, 27 Apr 2000 17:01:09 -0400 (EDT)
From: mike+fbsd@medianstrip.net
Sender: mryan01@vapre.mobile.medianstrip.net
To: FreeBSD-gnats-submit@freebsd.org
Subject: resume from suspend breaks usb
X-Send-Pr-Version: 3.2

>Number:         18261
>Category:       kern
>Synopsis:       resume from suspend breaks usb
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    n_hibma
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 27 14:40:01 PDT 2000
>Closed-Date:    Sun Aug 13 12:43:54 PDT 2000
>Last-Modified:  Sun Aug 13 12:45:26 PDT 2000
>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:
Responsible-Changed-From-To: freebsd-bugs->n_hibma 
Responsible-Changed-By: nra 
Responsible-Changed-When: Thu Jul 20 19:54:43 PDT 2000 
Responsible-Changed-Why:  
Nick takes care of the usb bits.  He might be interested in these 
patches.  Thanks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=18261 
State-Changed-From-To: open->analyzed 
State-Changed-By: n_hibma 
State-Changed-When: Sun Aug 6 16:36:38 PDT 2000 
State-Changed-Why:  
The patch is corrected. Thatnks for picking the diff between Free and 
NetBSD apart. I will commit this as soon as I had time to test it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=18261 
State-Changed-From-To: analyzed->open 
State-Changed-By: n_hibma 
State-Changed-When: Sun Aug 6 17:07:29 PDT 2000 
State-Changed-Why:  
Committed. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=18261 
State-Changed-From-To: open->closed 
State-Changed-By: n_hibma 
State-Changed-When: Sun Aug 13 12:43:54 PDT 2000 
State-Changed-Why:  
Patch committed to both current and stable. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=18261 
>Unformatted:
