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>
