Save and restore the registers SOF and FRAMENUMBER on suspend. In some

cases the registers are not correctly set on resume.

This solves the problem of USB failing after resuming a machine.

Submitted by:	mike+fbsd@medianstrip.net
PR:		18261
This commit is contained in:
Nick Hibma 2000-08-07 00:04:53 +00:00
parent 2a46959d8e
commit 9bd863570a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64315
2 changed files with 15 additions and 5 deletions

View File

@ -250,6 +250,7 @@ Static void uhci_dump_tds(uhci_soft_td_t *);
Static void uhci_dump_td(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))
@ -565,17 +566,17 @@ uhci_power(int why, void *v)
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");
@ -584,6 +585,12 @@ uhci_power(int why, void *v)
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 */

View File

@ -154,6 +154,9 @@ typedef struct uhci_softc {
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;