summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm/xscale/pxa2x0_ohci.c42
-rw-r--r--sys/arch/loongson/dev/ohci_voyager.c4
-rw-r--r--sys/dev/cardbus/ohci_cardbus.c4
-rw-r--r--sys/dev/pci/ohci_pci.c4
-rw-r--r--sys/dev/usb/ehci.c59
-rw-r--r--sys/dev/usb/ohci.c126
-rw-r--r--sys/dev/usb/ohcivar.h4
-rw-r--r--sys/dev/usb/uhci.c135
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