diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_ohci.c | 42 | ||||
-rw-r--r-- | sys/arch/loongson/dev/ohci_voyager.c | 4 | ||||
-rw-r--r-- | sys/dev/cardbus/ohci_cardbus.c | 4 | ||||
-rw-r--r-- | sys/dev/pci/ohci_pci.c | 4 | ||||
-rw-r--r-- | sys/dev/usb/ehci.c | 59 | ||||
-rw-r--r-- | sys/dev/usb/ohci.c | 126 | ||||
-rw-r--r-- | sys/dev/usb/ohcivar.h | 4 | ||||
-rw-r--r-- | sys/dev/usb/uhci.c | 135 |
8 files changed, 157 insertions, 221 deletions
diff --git a/sys/arch/arm/xscale/pxa2x0_ohci.c b/sys/arch/arm/xscale/pxa2x0_ohci.c index 94b05953f83..1ca904c5bab 100644 --- a/sys/arch/arm/xscale/pxa2x0_ohci.c +++ b/sys/arch/arm/xscale/pxa2x0_ohci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pxa2x0_ohci.c,v 1.22 2010/08/27 05:04:06 deraadt Exp $ */ +/* $OpenBSD: pxa2x0_ohci.c,v 1.23 2010/08/30 21:30:15 deraadt Exp $ */ /* * Copyright (c) 2005 David Gwynne <dlg@openbsd.org> @@ -40,7 +40,8 @@ int pxaohci_match(struct device *, void *, void *); void pxaohci_attach(struct device *, struct device *, void *); int pxaohci_detach(struct device *, int); -void pxaohci_power(int, void *); +int pxaohci_activate(struct device *, int); +void pxaohci_powerhook(int, void *); struct pxaohci_softc { ohci_softc_t sc; @@ -126,7 +127,7 @@ unsupported: return; } - sc->sc.sc_powerhook = powerhook_establish(pxaohci_power, sc); + sc->sc.sc_powerhook = powerhook_establish(pxaohci_powerhook, sc); if (sc->sc.sc_powerhook == NULL) printf("%s: cannot establish powerhook\n", sc->sc.sc_bus.bdev.dv_xname); @@ -169,28 +170,33 @@ pxaohci_detach(struct device *self, int flags) } -void -pxaohci_power(int why, void *arg) +int +pxaohci_activate(struct device *self, int act) { - struct pxaohci_softc *sc = (struct pxaohci_softc *)arg; - int s; - - s = splhardusb(); - sc->sc.sc_bus.use_polling++; - switch (why) { - case PWR_SUSPEND: - ohci_power(why, &sc->sc); + struct pxaohci_softc *sc = (struct pxaohci_softc *)self; + + switch (act) { + case DVACT_SUSPEND: + sc->sc.sc_bus.use_polling++; + ohci_powerhook(act, &sc->sc); pxa2x0_clkman_config(CKEN_USBHC, 0); + sc->sc.sc_bus.use_polling--; break; - - case PWR_RESUME: + case DVACT_RESUME: + sc->sc.sc_bus.use_polling++; pxa2x0_clkman_config(CKEN_USBHC, 1); pxaohci_enable(sc); - ohci_power(why, &sc->sc); + ohci_powerhook(act, &sc->sc); + sc->sc.sc_bus.use_polling--; break; } - sc->sc.sc_bus.use_polling--; - splx(s); + return 0; +} + +void +pxaohci_powerhook(int why, void *arg) +{ + pxaohci_activate(arg, why); } void diff --git a/sys/arch/loongson/dev/ohci_voyager.c b/sys/arch/loongson/dev/ohci_voyager.c index ca37ca57503..9bac45f83cd 100644 --- a/sys/arch/loongson/dev/ohci_voyager.c +++ b/sys/arch/loongson/dev/ohci_voyager.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ohci_voyager.c,v 1.1 2010/02/26 14:53:11 miod Exp $ */ +/* $OpenBSD: ohci_voyager.c,v 1.2 2010/08/30 21:30:17 deraadt Exp $ */ /* OpenBSD: ohci_pci.c,v 1.33 2008/06/26 05:42:17 ray Exp */ /* $NetBSD: ohci_pci.c,v 1.23 2002/10/02 16:51:47 thorpej Exp $ */ @@ -176,7 +176,7 @@ ohci_voyager_attach_deferred(struct device *self) return; } - sc->sc.sc_powerhook = powerhook_establish(ohci_power, &sc->sc); + sc->sc.sc_powerhook = powerhook_establish(ohci_powerhook, &sc->sc); if (sc->sc.sc_powerhook == NULL) printf("%s: unable to establish powerhook\n", sc->sc.sc_bus.bdev.dv_xname); diff --git a/sys/dev/cardbus/ohci_cardbus.c b/sys/dev/cardbus/ohci_cardbus.c index d5274cd52e8..3aec5eb7b9c 100644 --- a/sys/dev/cardbus/ohci_cardbus.c +++ b/sys/dev/cardbus/ohci_cardbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ohci_cardbus.c,v 1.15 2010/03/27 21:40:13 jsg Exp $ */ +/* $OpenBSD: ohci_cardbus.c,v 1.16 2010/08/30 21:30:14 deraadt Exp $ */ /* $NetBSD: ohci_cardbus.c,v 1.19 2004/08/02 19:14:28 mycroft Exp $ */ /* @@ -167,7 +167,7 @@ ohci_cardbus_attach(struct device *parent, struct device *self, void *aux) return; } - sc->sc.sc_powerhook = powerhook_establish(ohci_power, &sc->sc); + sc->sc.sc_powerhook = powerhook_establish(ohci_powerhook, &sc->sc); /* Attach usb device. */ sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus, diff --git a/sys/dev/pci/ohci_pci.c b/sys/dev/pci/ohci_pci.c index 3fbf5054bd1..396beae47f6 100644 --- a/sys/dev/pci/ohci_pci.c +++ b/sys/dev/pci/ohci_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ohci_pci.c,v 1.34 2010/04/08 00:23:53 tedu Exp $ */ +/* $OpenBSD: ohci_pci.c,v 1.35 2010/08/30 21:30:15 deraadt Exp $ */ /* $NetBSD: ohci_pci.c,v 1.23 2002/10/02 16:51:47 thorpej Exp $ */ /* @@ -190,7 +190,7 @@ ohci_pci_attach_deferred(struct device *self) return; } - sc->sc.sc_powerhook = powerhook_establish(ohci_power, &sc->sc); + sc->sc.sc_powerhook = powerhook_establish(ohci_powerhook, &sc->sc); if (sc->sc.sc_powerhook == NULL) printf("%s: unable to establish powerhook\n", sc->sc.sc_bus.bdev.dv_xname); diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c index c64ada9f4ca..adedd16a391 100644 --- a/sys/dev/usb/ehci.c +++ b/sys/dev/usb/ehci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ehci.c,v 1.107 2010/08/27 04:09:20 deraadt Exp $ */ +/* $OpenBSD: ehci.c,v 1.108 2010/08/30 21:30:15 deraadt Exp $ */ /* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */ /* @@ -123,7 +123,7 @@ struct ehci_pipe { u_int8_t ehci_reverse_bits(u_int8_t, int); -void ehci_power(int, void *); +void ehci_powerhook(int, void *); usbd_status ehci_open(usbd_pipe_handle); void ehci_poll(struct usbd_bus *); @@ -419,7 +419,7 @@ ehci_init(ehci_softc_t *sc) sc->sc_bus.methods = &ehci_bus_methods; sc->sc_bus.pipe_size = sizeof(struct ehci_pipe); - sc->sc_powerhook = powerhook_establish(ehci_power, sc); + sc->sc_powerhook = powerhook_establish(ehci_powerhook, sc); sc->sc_eintrs = EHCI_NORMAL_INTRS; @@ -1029,51 +1029,18 @@ int ehci_activate(struct device *self, int act) { struct ehci_softc *sc = (struct ehci_softc *)self; - int rv = 0; + u_int32_t cmd, hcr; + int i, rv = 0; switch (act) { case DVACT_ACTIVATE: break; - case DVACT_DEACTIVATE: if (sc->sc_child != NULL) rv = config_deactivate(sc->sc_child); sc->sc_dying = 1; break; case DVACT_SUSPEND: - ehci_power(PWR_SUSPEND, sc); - break; - case DVACT_RESUME: - ehci_power(PWR_RESUME, sc); - rv = config_activate_children(self, act); - break; - } - return (rv); -} - -/* - * Handle suspend/resume. - * - * We need to switch to polling mode here, because this routine is - * called from an interrupt context. This is all right since we - * are almost suspended anyway. - */ -void -ehci_power(int why, void *v) -{ - ehci_softc_t *sc = v; - u_int32_t cmd, hcr; - int s, i; - -#ifdef EHCI_DEBUG - DPRINTF(("ehci_power: sc=%p, why=%d\n", sc, why)); - if (ehcidebug > 0) - ehci_dump_regs(sc); -#endif - - s = splhardusb(); - switch (why) { - case PWR_SUSPEND: sc->sc_bus.use_polling++; for (i = 1; i <= sc->sc_noport; i++) { @@ -1115,8 +1082,7 @@ ehci_power(int why, void *v) sc->sc_bus.use_polling--; break; - - case PWR_RESUME: + case DVACT_RESUME: sc->sc_bus.use_polling++; /* restore things in case the bios sucks */ @@ -1166,15 +1132,16 @@ ehci_power(int why, void *v) usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); sc->sc_bus.use_polling--; + rv = config_activate_children(self, act); break; } - splx(s); + return (rv); +} -#ifdef EHCI_DEBUG - DPRINTF(("ehci_power: sc=%p\n", sc)); - if (ehcidebug > 0) - ehci_dump_regs(sc); -#endif +void +ehci_powerhook(int why, void *v) +{ + ehci_activate(v, why); } /* diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index 713b5a9344d..38263538f73 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ohci.c,v 1.96 2010/08/27 04:09:20 deraadt Exp $ */ +/* $OpenBSD: ohci.c,v 1.97 2010/08/30 21:30:16 deraadt Exp $ */ /* $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ @@ -327,22 +327,70 @@ int ohci_activate(struct device *self, int act) { struct ohci_softc *sc = (struct ohci_softc *)self; + u_int32_t reg; int rv = 0; switch (act) { case DVACT_ACTIVATE: break; - case DVACT_DEACTIVATE: if (sc->sc_child != NULL) rv = config_deactivate(sc->sc_child); sc->sc_dying = 1; break; case DVACT_SUSPEND: - ohci_power(PWR_SUSPEND, sc); + sc->sc_bus.use_polling++; + reg = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK; + if (sc->sc_control == 0) { + /* + * Preserve register values, in case that APM BIOS + * does not recover them. + */ + sc->sc_control = reg; + sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE); + sc->sc_ival = OHCI_GET_IVAL(OREAD4(sc, + OHCI_FM_INTERVAL)); + } + reg |= OHCI_HCFS_SUSPEND; + OWRITE4(sc, OHCI_CONTROL, reg); + usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); + sc->sc_bus.use_polling--; break; case DVACT_RESUME: - ohci_power(PWR_RESUME, sc); + sc->sc_bus.use_polling++; + + /* Some broken BIOSes do not recover these values */ + OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0)); + OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr); + OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr); + if (sc->sc_intre) + OWRITE4(sc, OHCI_INTERRUPT_ENABLE, + sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE)); + if (sc->sc_control) + reg = sc->sc_control; + else + reg = OREAD4(sc, OHCI_CONTROL); + reg |= OHCI_HCFS_RESUME; + OWRITE4(sc, OHCI_CONTROL, reg); + usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); + reg = (reg & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL; + OWRITE4(sc, OHCI_CONTROL, reg); + + reg = (OREAD4(sc, OHCI_FM_REMAINING) & OHCI_FIT) ^ OHCI_FIT; + reg |= OHCI_FSMPS(sc->sc_ival) | sc->sc_ival; + OWRITE4(sc, OHCI_FM_INTERVAL, reg); + OWRITE4(sc, OHCI_PERIODIC_START, OHCI_PERIODIC(sc->sc_ival)); + + /* Fiddle the No OverCurrent Protection to avoid a chip bug */ + reg = OREAD4(sc, OHCI_RH_DESCRIPTOR_A); + OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, reg | OHCI_NOCP); + OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */ + usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY); + OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, reg); + + usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); + sc->sc_control = sc->sc_intre = sc->sc_ival = 0; + sc->sc_bus.use_polling--; break; } return (rv); @@ -983,75 +1031,9 @@ ohci_shutdown(void *v) * are almost suspended anyway. */ void -ohci_power(int why, void *v) +ohci_powerhook(int why, void *v) { - ohci_softc_t *sc = v; - u_int32_t reg; - int s; - -#ifdef OHCI_DEBUG - DPRINTF(("ohci_power: sc=%p, why=%d\n", sc, why)); - ohci_dumpregs(sc); -#endif - - s = splhardusb(); - switch (why) { - case PWR_SUSPEND: - sc->sc_bus.use_polling++; - reg = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK; - if (sc->sc_control == 0) { - /* - * Preserve register values, in case that APM BIOS - * does not recover them. - */ - sc->sc_control = reg; - sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE); - sc->sc_ival = OHCI_GET_IVAL(OREAD4(sc, - OHCI_FM_INTERVAL)); - } - reg |= OHCI_HCFS_SUSPEND; - OWRITE4(sc, OHCI_CONTROL, reg); - usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); - sc->sc_bus.use_polling--; - break; - case PWR_RESUME: - sc->sc_bus.use_polling++; - - /* Some broken BIOSes do not recover these values */ - OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0)); - OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr); - OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr); - if (sc->sc_intre) - OWRITE4(sc, OHCI_INTERRUPT_ENABLE, - sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE)); - if (sc->sc_control) - reg = sc->sc_control; - else - reg = OREAD4(sc, OHCI_CONTROL); - reg |= OHCI_HCFS_RESUME; - OWRITE4(sc, OHCI_CONTROL, reg); - usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); - reg = (reg & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL; - OWRITE4(sc, OHCI_CONTROL, reg); - - reg = (OREAD4(sc, OHCI_FM_REMAINING) & OHCI_FIT) ^ OHCI_FIT; - reg |= OHCI_FSMPS(sc->sc_ival) | sc->sc_ival; - OWRITE4(sc, OHCI_FM_INTERVAL, reg); - OWRITE4(sc, OHCI_PERIODIC_START, OHCI_PERIODIC(sc->sc_ival)); - - /* Fiddle the No OverCurrent Protection to avoid a chip bug */ - reg = OREAD4(sc, OHCI_RH_DESCRIPTOR_A); - OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, reg | OHCI_NOCP); - OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */ - usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY); - OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, reg); - - usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); - sc->sc_control = sc->sc_intre = sc->sc_ival = 0; - sc->sc_bus.use_polling--; - break; - } - splx(s); + ohci_activate(v, why); } #ifdef OHCI_DEBUG diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h index 27b2a6fb596..5e98b4962fe 100644 --- a/sys/dev/usb/ohcivar.h +++ b/sys/dev/usb/ohcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ohcivar.h,v 1.28 2009/11/04 19:14:10 kettenis Exp $ */ +/* $OpenBSD: ohcivar.h,v 1.29 2010/08/30 21:30:17 deraadt Exp $ */ /* $NetBSD: ohcivar.h,v 1.32 2003/02/22 05:24:17 tsutsui Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */ @@ -144,4 +144,4 @@ usbd_status ohci_init(ohci_softc_t *); int ohci_intr(void *); int ohci_detach(ohci_softc_t *, int); int ohci_activate(struct device *, int); -void ohci_power(int, void *); +void ohci_powerhook(int, void *); diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index a179b25c21c..ee39cf7cf25 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uhci.c,v 1.76 2010/08/27 04:09:21 deraadt Exp $ */ +/* $OpenBSD: uhci.c,v 1.77 2010/08/30 21:30:17 deraadt Exp $ */ /* $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ @@ -129,7 +129,7 @@ void uhci_globalreset(uhci_softc_t *); usbd_status uhci_portreset(uhci_softc_t*, int); void uhci_reset(uhci_softc_t *); void uhci_shutdown(void *v); -void uhci_power(int, void *); +void uhci_powerhook(int, void *); usbd_status uhci_run(uhci_softc_t *, int run); uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *); void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *); @@ -508,7 +508,7 @@ uhci_init(uhci_softc_t *sc) sc->sc_bus.pipe_size = sizeof(struct uhci_pipe); sc->sc_suspend = PWR_RESUME; - sc->sc_powerhook = powerhook_establish(uhci_power, sc); + sc->sc_powerhook = powerhook_establish(uhci_powerhook, sc); sc->sc_shutdownhook = shutdownhook_establish(uhci_shutdown, sc); UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */ @@ -524,21 +524,70 @@ int uhci_activate(struct device *self, int act) { struct uhci_softc *sc = (struct uhci_softc *)self; - int rv = 0; + int cmd, rv = 0; switch (act) { case DVACT_ACTIVATE: break; - case DVACT_DEACTIVATE: if (sc->sc_child != NULL) rv = config_deactivate(sc->sc_child); break; case DVACT_SUSPEND: - uhci_power(PWR_SUSPEND, sc); +#ifdef UHCI_DEBUG + if (uhcidebug > 2) + uhci_dumpregs(sc); +#endif + if (sc->sc_intr_xfer != NULL) + timeout_del(&sc->sc_poll_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); + + UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */ + + UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */ + usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); + sc->sc_suspend = act; + sc->sc_bus.use_polling--; + DPRINTF(("uhci_powerhook: cmd=0x%x\n", UREAD2(sc, UHCI_CMD))); break; case DVACT_RESUME: - uhci_power(PWR_RESUME, sc); +#ifdef DIAGNOSTIC + if (sc->sc_suspend == PWR_RESUME) + printf("uhci_powerhook: weird, resume without suspend.\n"); +#endif + sc->sc_bus.use_polling++; + sc->sc_suspend = act; + 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 */ + UHCICMD(sc, UHCI_CMD_MAXP); + UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | + UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */ + uhci_run(sc, 1); /* and start traffic again */ + usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); + sc->sc_bus.use_polling--; + if (sc->sc_intr_xfer != NULL) { + timeout_del(&sc->sc_poll_handle); + timeout_set(&sc->sc_poll_handle, uhci_poll_hub, + sc->sc_intr_xfer); + timeout_add(&sc->sc_poll_handle, sc->sc_ival); + } +#ifdef UHCI_DEBUG + if (uhcidebug > 2) + uhci_dumpregs(sc); +#endif break; } return (rv); @@ -683,77 +732,9 @@ uhci_shutdown(void *v) * are almost suspended anyway. */ void -uhci_power(int why, void *v) +uhci_powerhook(int why, void *v) { - uhci_softc_t *sc = v; - int cmd; - int s; - - s = splhardusb(); - cmd = UREAD2(sc, UHCI_CMD); - - DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n", - sc, why, sc->sc_suspend, cmd)); - - switch (why) { - case PWR_SUSPEND: -#ifdef UHCI_DEBUG - if (uhcidebug > 2) - uhci_dumpregs(sc); -#endif - if (sc->sc_intr_xfer != NULL) - timeout_del(&sc->sc_poll_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); - - UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */ - - 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))); - break; - case PWR_RESUME: -#ifdef DIAGNOSTIC - if (sc->sc_suspend == PWR_RESUME) - printf("uhci_power: weird, resume without suspend.\n"); -#endif - sc->sc_bus.use_polling++; - 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 */ - UHCICMD(sc, UHCI_CMD_MAXP); - UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | - UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */ - uhci_run(sc, 1); /* and start traffic again */ - usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); - sc->sc_bus.use_polling--; - if (sc->sc_intr_xfer != NULL) { - timeout_del(&sc->sc_poll_handle); - timeout_set(&sc->sc_poll_handle, uhci_poll_hub, - sc->sc_intr_xfer); - timeout_add(&sc->sc_poll_handle, sc->sc_ival); - } -#ifdef UHCI_DEBUG - if (uhcidebug > 2) - uhci_dumpregs(sc); -#endif - break; - } - splx(s); + uhci_activate(v, why); } #ifdef UHCI_DEBUG |