summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/acpi/acpi.c431
-rw-r--r--sys/dev/acpi/acpivar.h16
-rw-r--r--sys/dev/ata/wd.c26
-rw-r--r--sys/dev/cardbus/ehci_cardbus.c7
-rw-r--r--sys/dev/pci/ahci.c5
-rw-r--r--sys/dev/pci/ehci_pci.c33
-rw-r--r--sys/dev/pci/glxpcib.c5
-rw-r--r--sys/dev/pci/pccbb.c8
-rw-r--r--sys/dev/pci/pci.c30
-rw-r--r--sys/dev/pci/pciide.c5
-rw-r--r--sys/dev/pci/ppb.c7
-rw-r--r--sys/dev/pci/sdhc_pci.c7
-rw-r--r--sys/dev/pci/sili_pci.c5
-rw-r--r--sys/dev/pci/vga_pci.c5
-rw-r--r--sys/dev/pcmcia/pcmcia.c3
-rw-r--r--sys/dev/pcmcia/wdc_pcmcia.c5
-rw-r--r--sys/dev/sdmmc/sdhc.c6
-rw-r--r--sys/dev/usb/ehci.c8
-rw-r--r--sys/dev/usb/ehcivar.h3
19 files changed, 280 insertions, 335 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index b3468d22cb6..5bd1162cf6a 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.240 2012/10/04 08:32:20 ehrhardt Exp $ */
+/* $OpenBSD: acpi.c,v 1.241 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -102,7 +102,6 @@ void acpi_pbtn_task(void *, int);
int acpi_thinkpad_enabled;
int acpi_toshiba_enabled;
int acpi_asus_enabled;
-int acpi_saved_spl;
int acpi_saved_boothowto;
int acpi_enabled;
@@ -112,9 +111,8 @@ int acpi_matchhids(struct acpi_attach_args *aa, const char *hids[],
void acpi_thread(void *);
void acpi_create_thread(void *);
void acpi_init_pm(struct acpi_softc *);
-
-void acpi_handle_suspend_failure(struct acpi_softc *);
void acpi_init_gpes(struct acpi_softc *);
+void acpi_indicator(struct acpi_softc *, int);
int acpi_founddock(struct aml_node *, void *);
int acpi_foundpss(struct aml_node *, void *);
@@ -140,7 +138,6 @@ struct idechnl {
int64_t sta;
};
-void acpi_resume(struct acpi_softc *, int);
int acpi_add_device(struct aml_node *node, void *arg);
struct gpe_block *acpi_find_gpe(struct acpi_softc *, int);
@@ -579,20 +576,21 @@ acpi_pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
{
struct acpi_pci *pdev;
int bus, dev, fun;
- int state;
+ int state = -1, defaultstate = pci_get_powerstate(pc, tag);
pci_decompose_tag(pc, tag, &bus, &dev, &fun);
TAILQ_FOREACH(pdev, &acpi_pcidevs, next) {
if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun) {
- switch (acpi_softc->sc_nextstate) {
+ switch (acpi_softc->sc_state) {
case ACPI_STATE_S3:
+ defaultstate = PCI_PMCSR_STATE_D3;
state = MAX(pdev->_s3d, pdev->_s3w);
break;
case ACPI_STATE_S4:
state = MAX(pdev->_s4d, pdev->_s4w);
break;
+ case ACPI_STATE_S5:
default:
- state = -1;
break;
}
@@ -602,7 +600,7 @@ acpi_pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
}
}
- return PCI_PMCSR_STATE_D3;
+ return defaultstate;
}
void
@@ -637,6 +635,7 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
struct device *dev;
struct acpi_ac *ac;
struct acpi_bat *bat;
+ int s;
#endif /* SMALL_KERNEL */
paddr_t facspa;
@@ -761,7 +760,9 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
#ifndef SMALL_KERNEL
/* Initialize GPE handlers */
+ s = spltty();
acpi_init_gpes(sc);
+ splx(s);
/* some devices require periodic polling */
timeout_set(&sc->sc_dev_timeout, acpi_poll, sc);
@@ -1456,6 +1457,9 @@ acpi_reset(void)
struct acpi_softc *sc = acpi_softc;
struct acpi_fadt *fadt = sc->sc_fadt;
+ if (acpi_enabled == 0)
+ return;
+
/*
* RESET_REG_SUP is not properly set in some implementations,
* but not testing against it breaks more machines than it fixes
@@ -1695,43 +1699,36 @@ void
acpi_enable_onegpe(struct acpi_softc *sc, int gpe)
{
uint8_t mask, en;
- int s;
/* Read enabled register */
- s = spltty();
mask = (1L << (gpe & 7));
en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3);
dnprintf(50, "enabling GPE %.2x (current: %sabled) %.2x\n",
gpe, (en & mask) ? "en" : "dis", en);
acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask);
- splx(s);
}
/* Clear all GPEs */
void
acpi_disable_allgpes(struct acpi_softc *sc)
{
- int idx, s;
+ int idx;
- s = spltty();
for (idx = 0; idx < sc->sc_lastgpe; idx += 8) {
acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx >> 3, 0);
acpi_write_pmreg(sc, ACPIREG_GPE_STS, idx >> 3, -1);
}
- splx(s);
}
/* Enable runtime GPEs */
void
acpi_enable_rungpes(struct acpi_softc *sc)
{
- int s, idx;
+ int idx;
- s = spltty();
for (idx = 0; idx < sc->sc_lastgpe; idx++)
if (sc->gpe_table[idx].handler)
acpi_enable_onegpe(sc, idx);
- splx(s);
}
/* Enable wakeup GPEs */
@@ -1739,9 +1736,7 @@ void
acpi_enable_wakegpes(struct acpi_softc *sc, int state)
{
struct acpi_wakeq *wentry;
- int s;
- s = spltty();
SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) {
dnprintf(10, "%.4s(S%d) gpe %.2x\n", wentry->q_node->name,
wentry->q_state,
@@ -1749,7 +1744,6 @@ acpi_enable_wakegpes(struct acpi_softc *sc, int state)
if (state <= wentry->q_state)
acpi_enable_onegpe(sc, wentry->q_gpe);
}
- splx(s);
}
int
@@ -1778,19 +1772,15 @@ acpi_gpe(struct acpi_softc *sc, int gpe, void *arg)
{
struct aml_node *node = arg;
uint8_t mask, en;
- int s;
dnprintf(10, "handling GPE %.2x\n", gpe);
aml_evalnode(sc, node, 0, NULL, NULL);
- s = spltty();
mask = (1L << (gpe & 7));
if (!sc->gpe_table[gpe].edge)
acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask);
en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3);
acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask);
- splx(s);
-
return (0);
}
@@ -1894,45 +1884,21 @@ acpi_init_pm(struct acpi_softc *sc)
sc->sc_sst = aml_searchname(&aml_root, "_SI_._SST");
}
-int
-acpi_sleep_state(struct acpi_softc *sc, int state)
+void
+acpi_sleep_pm(struct acpi_softc *sc, int state)
{
- int ret;
-
- switch (state) {
- case ACPI_STATE_S0:
- case ACPI_STATE_S1:
- case ACPI_STATE_S2:
- case ACPI_STATE_S5:
- return (0);
- }
+ uint16_t rega, regb, regra, regrb;
+ int retry = 0;
- if (sc->sc_sleeptype[state].slp_typa == -1 ||
- sc->sc_sleeptype[state].slp_typb == -1)
- return (EOPNOTSUPP);
-
- if ((ret = acpi_prepare_sleep_state(sc, state)) != 0)
- return (ret);
-
- ret = acpi_sleep_machdep(sc, state);
-
-#ifndef SMALL_KERNEL
- acpi_resume(sc, state);
-#endif /* !SMALL_KERNEL */
- return (ret);
-}
-
-int
-acpi_enter_sleep_state(struct acpi_softc *sc, int state)
-{
- uint16_t rega, regb;
- int retries;
+ disable_intr();
/* Clear WAK_STS bit */
acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS);
- /* Disable BM arbitration */
- acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, ACPI_PM2_ARB_DIS);
+ /* Disable BM arbitration at deep sleep and beyond */
+ if (state >= ACPI_STATE_S3 &&
+ sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len)
+ acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, ACPI_PM2_ARB_DIS);
/* Write SLP_TYPx values */
rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0);
@@ -1944,259 +1910,194 @@ acpi_enter_sleep_state(struct acpi_softc *sc, int state)
acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
- /* Set SLP_EN bit */
+ /* Loop on WAK_STS, setting the SLP_EN bits once in a while */
rega |= ACPI_PM1_SLP_EN;
regb |= ACPI_PM1_SLP_EN;
+ while (1) {
+ if (retry == 0) {
+ acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
+ acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
+ }
+ retry = (retry + 1) % 100000;
- /*
- * Let the machdep code flush caches and do any other necessary
- * tasks before going away.
- */
- acpi_cpu_flush(sc, state);
-
- /*
- * XXX The following sequence is probably not right.
- */
- acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
- acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
-
- /* Loop on WAK_STS */
- for (retries = 1000; retries > 0; retries--) {
- rega = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0);
- regb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0);
- if ((rega & ACPI_PM1_WAK_STS) ||
- (regb & ACPI_PM1_WAK_STS))
+ regra = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0);
+ regrb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0);
+ if ((regra & ACPI_PM1_WAK_STS) ||
+ (regrb & ACPI_PM1_WAK_STS))
break;
- DELAY(1000);
}
-
- return (-1);
}
void
-acpi_resume(struct acpi_softc *sc, int state)
+acpi_resume_pm(struct acpi_softc *sc, int fromstate)
{
- struct aml_value env;
+ uint16_t rega, regb, en;
- memset(&env, 0, sizeof(env));
- env.type = AML_OBJTYPE_INTEGER;
- env.v_integer = sc->sc_state;
+ /* Write SLP_TYPx values */
+ rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0);
+ regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0);
+ rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
+ regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
+ rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typa);
+ regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typb);
+ acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
+ acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
/* Force SCI_EN on resume to fix horribly broken machines */
acpi_write_pmreg(sc, ACPIREG_PM1_CNT, 0, ACPI_PM1_SCI_EN);
/* Clear fixed event status */
- acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0,
- ACPI_PM1_ALL_STS);
+ acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
- if (sc->sc_bfs)
- if (aml_evalnode(sc, sc->sc_bfs, 1, &env, NULL) != 0) {
- dnprintf(10, "%s evaluating method _BFS failed.\n",
- DEVNAME(sc));
- }
-
- if (sc->sc_wak)
- if (aml_evalnode(sc, sc->sc_wak, 1, &env, NULL) != 0) {
- dnprintf(10, "%s evaluating method _WAK failed.\n",
- DEVNAME(sc));
- }
-
- /* Reset the indicator lights to "waking" */
- if (sc->sc_sst) {
- env.v_integer = ACPI_SST_WAKING;
- aml_evalnode(sc, sc->sc_sst, 1, &env, NULL);
- }
+ /* acpica-reference.pdf page 148 says do not call _BFS */
+ /* 1st resume AML step: _BFS(fromstate) */
+ aml_node_setval(sc, sc->sc_bfs, fromstate);
/* Enable runtime GPEs */
acpi_disable_allgpes(sc);
acpi_enable_rungpes(sc);
- if (state == ACPI_STATE_S4)
- boothowto = acpi_saved_boothowto;
-
- config_suspend(TAILQ_FIRST(&alldevs), DVACT_RESUME);
-
- cold = 0;
- enable_intr();
- splx(acpi_saved_spl);
+ acpi_indicator(sc, ACPI_SST_WAKING);
- acpi_resume_machdep();
+ /* 2nd resume AML step: _WAK(fromstate) */
+ aml_node_setval(sc, sc->sc_wak, fromstate);
- sc->sc_state = ACPI_STATE_S0;
- if (sc->sc_tts) {
- env.v_integer = sc->sc_state;
- if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) {
- dnprintf(10, "%s evaluating method _TTS failed.\n",
- DEVNAME(sc));
- }
- }
+ /* Clear WAK_STS bit */
+ acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS);
- /* disable _LID for wakeup */
- acpibtn_disable_psw();
+ en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
+ if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON))
+ en |= ACPI_PM1_PWRBTN_EN;
+ if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON))
+ en |= ACPI_PM1_SLPBTN_EN;
+ acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
- /* Reset the indicator lights to "working" */
- if (sc->sc_sst) {
- env.v_integer = ACPI_SST_WORKING;
- aml_evalnode(sc, sc->sc_sst, 1, &env, NULL);
+ /*
+ * If PM2 exists, re-enable BM arbitration (reportedly some
+ * BIOS forget to)
+ */
+ if (sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len) {
+ rega = acpi_read_pmreg(sc, ACPIREG_PM2_CNT, 0);
+ rega &= ~ACPI_PM2_ARB_DIS;
+ acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, rega);
}
-
-#ifdef MULTIPROCESSOR
- sched_start_secondary_cpus();
-#endif
-
- acpi_record_event(sc, APM_NORMAL_RESUME);
-
- bufq_restart();
-
-#if NWSDISPLAY > 0
- wsdisplay_resume();
-#endif /* NWSDISPLAY > 0 */
}
+/* Set the indicator light to some state */
void
-acpi_handle_suspend_failure(struct acpi_softc *sc)
+acpi_indicator(struct acpi_softc *sc, int led_state)
{
- struct aml_value env;
+ static int save_led_state = -1;
- /* Undo a partial suspend. Devices will have already been resumed */
- cold = 0;
- enable_intr();
- splx(acpi_saved_spl);
-
- /* Tell ACPI to go back to S0 */
- memset(&env, 0, sizeof(env));
- env.type = AML_OBJTYPE_INTEGER;
- sc->sc_state = ACPI_STATE_S0;
- if (sc->sc_tts) {
- env.v_integer = sc->sc_state;
- if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) {
- dnprintf(10, "%s evaluating method _TTS failed.\n",
- DEVNAME(sc));
- }
+ if (save_led_state != led_state) {
+ aml_node_setval(sc, sc->sc_sst, led_state);
+ save_led_state = led_state;
}
-
- /* disable _LID for wakeup */
- acpibtn_disable_psw();
-
- /* Reset the indicator lights to "working" */
- if (sc->sc_sst) {
- env.v_integer = ACPI_SST_WORKING;
- aml_evalnode(sc, sc->sc_sst, 1, &env, NULL);
- }
-
-#ifdef MULTIPROCESSOR
- sched_start_secondary_cpus();
-#endif
}
int
-acpi_prepare_sleep_state(struct acpi_softc *sc, int state)
+acpi_sleep_state(struct acpi_softc *sc, int state)
{
- struct aml_value env;
- int error = 0;
+ int error = ENXIO;
+ int s;
- if (sc == NULL || state == ACPI_STATE_S0)
- return(0);
+ switch (state) {
+ case ACPI_STATE_S0:
+ return (0);
+ case ACPI_STATE_S1:
+ return (EOPNOTSUPP);
+ case ACPI_STATE_S5: /* only sleep states handled here */
+ return (EOPNOTSUPP);
+ }
if (sc->sc_sleeptype[state].slp_typa == -1 ||
sc->sc_sleeptype[state].slp_typb == -1) {
printf("%s: state S%d unavailable\n",
sc->sc_dev.dv_xname, state);
- return (ENXIO);
+ return (EOPNOTSUPP);
}
-#ifdef MULTIPROCESSOR
- sched_stop_secondary_cpus();
- KASSERT(CPU_IS_PRIMARY(curcpu()));
-#endif
-
- sc->sc_nextstate = state;
-
- memset(&env, 0, sizeof(env));
- env.type = AML_OBJTYPE_INTEGER;
- env.v_integer = state;
- /* _TTS(state) */
- if (sc->sc_tts)
- if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) {
- dnprintf(10, "%s evaluating method _TTS failed.\n",
- DEVNAME(sc));
- return (ENXIO);
- }
-
- if (state == ACPI_STATE_S4)
- printf("%s: hibernating to disk ...\n", DEVNAME(sc));
+ /* 1st suspend AML step: _TTS(tostate) */
+ if (aml_node_setval(sc, sc->sc_tts, state) != 0)
+ goto fail_tts;
+ acpi_indicator(sc, ACPI_SST_WAKING); /* blink */
#if NWSDISPLAY > 0
- if (state == ACPI_STATE_S3 || state == ACPI_STATE_S4)
- wsdisplay_suspend();
+ wsdisplay_suspend();
#endif /* NWSDISPLAY > 0 */
+ bufq_quiesce();
- if (state == ACPI_STATE_S3)
- resettodr();
+ if (config_suspend(TAILQ_FIRST(&alldevs), DVACT_QUIESCE))
+ goto fail_quiesce;
- bufq_quiesce();
- config_suspend(TAILQ_FIRST(&alldevs), DVACT_QUIESCE);
+#ifdef MULTIPROCESSOR
+ acpi_sleep_mp();
+#endif
- acpi_saved_spl = splhigh();
- disable_intr();
- cold = 1;
- if (state == ACPI_STATE_S4) {
- acpi_saved_boothowto = boothowto;
- boothowto = RB_RDONLY;
- }
- if (state == ACPI_STATE_S3 || state == ACPI_STATE_S4)
- if (config_suspend(TAILQ_FIRST(&alldevs), DVACT_SUSPEND) != 0) {
- acpi_handle_suspend_failure(sc);
- error = ENXIO;
- goto fail;
- }
+ resettodr();
- /* _PTS(state) */
- if (sc->sc_pts)
- if (aml_evalnode(sc, sc->sc_pts, 1, &env, NULL) != 0) {
- dnprintf(10, "%s evaluating method _PTS failed.\n",
- DEVNAME(sc));
- error = ENXIO;
- goto fail;
- }
+ s = splhigh();
+ disable_intr(); /* PSL_I for resume; PIC/APIC broken until repair */
+ cold = 1; /* Force other code to delay() instead of tsleep() */
- /* enable _LID for wakeup */
- acpibtn_enable_psw();
+ if (config_suspend(TAILQ_FIRST(&alldevs), DVACT_SUSPEND) != 0)
+ goto fail_suspend;
+ acpi_sleep_clocks(sc, state);
- /* Reset the indicator lights to "sleeping" */
- if (sc->sc_sst) {
- env.v_integer = ACPI_SST_SLEEPING;
- aml_evalnode(sc, sc->sc_sst, 1, &env, NULL);
- }
- env.v_integer = state;
+ /* 2nd suspend AML step: _PTS(tostate) */
+ if (aml_node_setval(sc, sc->sc_pts, state) != 0)
+ goto fail_pts;
- sc->sc_state = state;
- /* _GTS(state) */
- if (sc->sc_gts)
- if (aml_evalnode(sc, sc->sc_gts, 1, &env, NULL) != 0) {
- dnprintf(10, "%s evaluating method _GTS failed.\n",
- DEVNAME(sc));
- error = ENXIO;
- goto fail;
- }
+ acpibtn_enable_psw(); /* enable _LID for wakeup */
+ acpi_indicator(sc, ACPI_SST_SLEEPING);
+
+ /* 3rd suspend AML step: _GTS(tostate) */
+ aml_node_setval(sc, sc->sc_gts, state);
/* Clear fixed event status */
- acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0,
- ACPI_PM1_ALL_STS);
+ acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
/* Enable wake GPEs */
acpi_disable_allgpes(sc);
acpi_enable_wakegpes(sc, state);
-fail:
- if (error) {
- bufq_restart();
+ /* Sleep */
+ sc->sc_state = state;
+ error = acpi_sleep_cpu(sc, state);
+ sc->sc_state = ACPI_STATE_S0;
+ /* Resume */
+
+ acpi_resume_clocks(sc); /* AML may need clocks */
+ acpi_resume_pm(sc, state);
+ acpi_resume_cpu(sc);
+ acpibtn_disable_psw(); /* disable _LID for wakeup */
+
+fail_pts:
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_RESUME);
+
+fail_suspend:
+ cold = 0;
+ enable_intr();
+ splx(s);
+
+ inittodr(time_second);
+ /* 3rd resume AML step: _TTS(runstate) */
+ aml_node_setval(sc, sc->sc_tts, sc->sc_state);
+
+#ifdef MULTIPROCESSOR
+ acpi_resume_mp();
+#endif
+
+fail_quiesce:
+ bufq_restart();
#if NWSDISPLAY > 0
- wsdisplay_resume();
+ wsdisplay_resume();
#endif /* NWSDISPLAY > 0 */
- }
+ acpi_record_event(sc, APM_NORMAL_RESUME);
+ acpi_indicator(sc, ACPI_SST_WORKING);
+fail_tts:
return (error);
}
@@ -2209,17 +2110,37 @@ acpi_wakeup(void *arg)
wakeup(sc);
}
+/* XXX
+ * We are going to do AML execution but are not in the acpi thread.
+ * We do not know if the acpi thread is sleeping on acpiec in some
+ * intermediate context. Wish us luck.
+ */
void
acpi_powerdown(void)
{
- /*
- * In case acpi_prepare_sleep fails, we shouldn't try to enter
- * the sleep state. It might cost us the battery.
- */
- acpi_disable_allgpes(acpi_softc);
- acpi_enable_wakegpes(acpi_softc, ACPI_STATE_S5);
- if (acpi_prepare_sleep_state(acpi_softc, ACPI_STATE_S5) == 0)
- acpi_enter_sleep_state(acpi_softc, ACPI_STATE_S5);
+ int state = ACPI_STATE_S5, s;
+ struct acpi_softc *sc = acpi_softc;
+
+ if (acpi_enabled == 0)
+ return;
+
+ s = splhigh();
+ disable_intr();
+ cold = 1;
+
+ /* 1st powerdown AML step: _PTS(tostate) */
+ aml_node_setval(sc, sc->sc_pts, state);
+
+ acpi_disable_allgpes(sc);
+ acpi_enable_wakegpes(sc, state);
+
+ /* 2nd powerdown AML step: _GTS(tostate) */
+ aml_node_setval(sc, sc->sc_gts, state);
+
+ acpi_sleep_pm(sc, state);
+ panic("acpi S5 transition did not happen");
+ while (1)
+ ;
}
void
@@ -2254,10 +2175,10 @@ acpi_thread(void *arg)
if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON))
en |= ACPI_PM1_SLPBTN_EN;
acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
- splx(s);
/* Enable handled GPEs here */
acpi_enable_rungpes(sc);
+ splx(s);
}
while (thread->running) {
diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h
index b791df6092a..2f9b0e1afcd 100644
--- a/sys/dev/acpi/acpivar.h
+++ b/sys/dev/acpi/acpivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpivar.h,v 1.73 2012/10/04 08:32:20 ehrhardt Exp $ */
+/* $OpenBSD: acpivar.h,v 1.74 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -228,7 +228,6 @@ struct acpi_softc {
struct aml_node *sc_sst;
struct aml_node *sc_wak;
int sc_state;
- int sc_nextstate;
struct acpiec_softc *sc_ec; /* XXX assume single EC */
struct acpi_ac_head sc_ac;
@@ -282,12 +281,15 @@ void acpi_attach_machdep(struct acpi_softc *);
int acpi_interrupt(void *);
void acpi_powerdown(void);
void acpi_reset(void);
-void acpi_cpu_flush(struct acpi_softc *, int);
int acpi_sleep_state(struct acpi_softc *, int);
-int acpi_prepare_sleep_state(struct acpi_softc *, int);
-int acpi_enter_sleep_state(struct acpi_softc *, int);
-int acpi_sleep_machdep(struct acpi_softc *, int);
-void acpi_resume_machdep(void);
+void acpi_sleep_clocks(struct acpi_softc *, int);
+int acpi_sleep_cpu(struct acpi_softc *, int);
+void acpi_sleep_mp(void);
+void acpi_sleep_pm(struct acpi_softc *, int);
+void acpi_resume_pm(struct acpi_softc *, int);
+void acpi_resume_clocks(struct acpi_softc *);
+void acpi_resume_cpu(struct acpi_softc *);
+void acpi_resume_mp(void);
void acpi_sleep_walk(struct acpi_softc *, int);
diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c
index 2e1c23b920b..7edd174a772 100644
--- a/sys/dev/ata/wd.c
+++ b/sys/dev/ata/wd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wd.c,v 1.108 2011/07/06 04:49:36 matthew Exp $ */
+/* $OpenBSD: wd.c,v 1.109 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */
/*
@@ -142,7 +142,6 @@ void wdrestart(void *);
int wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *);
void wd_flushcache(struct wd_softc *, int);
void wd_standby(struct wd_softc *, int);
-void wd_shutdown(void *);
/* XXX: these should go elsewhere */
cdev_decl(wd);
@@ -327,10 +326,6 @@ wdattach(struct device *parent, struct device *self, void *aux)
*/
wd->sc_dk.dk_name = wd->sc_dev.dv_xname;
bufq_init(&wd->sc_bufq, BUFQ_DEFAULT);
- wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
- if (wd->sc_sdhook == NULL)
- printf("%s: WARNING: unable to establish shutdown hook\n",
- wd->sc_dev.dv_xname);
timeout_set(&wd->sc_restart_timeout, wdrestart, wd);
/* Attach disk. */
@@ -346,8 +341,11 @@ wdactivate(struct device *self, int act)
switch (act) {
case DVACT_SUSPEND:
+ break;
+ case DVACT_POWERDOWN:
wd_flushcache(wd, AT_POLL);
- wd_standby(wd, AT_POLL);
+ if (boothowto & RB_POWERDOWN)
+ wd_standby(wd, AT_POLL);
break;
case DVACT_RESUME:
/*
@@ -377,10 +375,6 @@ wddetach(struct device *self, int flags)
disk_gone(wdopen, self->dv_unit);
- /* Get rid of the shutdown hook. */
- if (sc->sc_sdhook != NULL)
- shutdownhook_disestablish(sc->sc_sdhook);
-
/* Detach disk. */
bufq_destroy(&sc->sc_bufq);
disk_detach(&sc->sc_dk);
@@ -1142,13 +1136,3 @@ wd_standby(struct wd_softc *wd, int flags)
* standby
*/
}
-
-void
-wd_shutdown(void *arg)
-{
- struct wd_softc *wd = arg;
-
- wd_flushcache(wd, AT_POLL);
- if (boothowto & RB_POWERDOWN)
- wd_standby(wd, AT_POLL);
-}
diff --git a/sys/dev/cardbus/ehci_cardbus.c b/sys/dev/cardbus/ehci_cardbus.c
index bd4d2b913c8..af54433b740 100644
--- a/sys/dev/cardbus/ehci_cardbus.c
+++ b/sys/dev/cardbus/ehci_cardbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci_cardbus.c,v 1.15 2010/03/27 21:40:13 jsg Exp $ */
+/* $OpenBSD: ehci_cardbus.c,v 1.16 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: ehci_cardbus.c,v 1.6.6.3 2004/09/21 13:27:25 skrll Exp $ */
/*
@@ -73,7 +73,7 @@ struct ehci_cardbus_softc {
struct cfattach ehci_cardbus_ca = {
sizeof(struct ehci_cardbus_softc), ehci_cardbus_match,
- ehci_cardbus_attach, ehci_cardbus_detach, ehci_activate
+ ehci_cardbus_attach, ehci_cardbus_detach, ehci_activate
};
#define CARDBUS_CBMEM PCI_CBMEM
@@ -161,8 +161,6 @@ ehci_cardbus_attach(struct device *parent, struct device *self, void *aux)
return;
}
- sc->sc.sc_shutdownhook = shutdownhook_establish(ehci_shutdown, &sc->sc);
-
/* Attach usb device. */
sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
usbctlprint);
@@ -189,4 +187,3 @@ ehci_cardbus_detach(struct device *self, int flags)
}
return (0);
}
-
diff --git a/sys/dev/pci/ahci.c b/sys/dev/pci/ahci.c
index 7bda90956ce..edd071050df 100644
--- a/sys/dev/pci/ahci.c
+++ b/sys/dev/pci/ahci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ahci.c,v 1.193 2012/08/11 13:52:27 jmatthew Exp $ */
+/* $OpenBSD: ahci.c,v 1.194 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
@@ -985,6 +985,9 @@ ahci_pci_activate(struct device *self, int act)
break;
case DVACT_SUSPEND:
rv = config_activate_children(self, act);
+ break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
for (i = 0; i < AHCI_MAX_PORTS; i++) {
if (sc->sc_ports[i] != NULL)
ahci_port_stop(sc->sc_ports[i], 1);
diff --git a/sys/dev/pci/ehci_pci.c b/sys/dev/pci/ehci_pci.c
index 6f46a987f55..11565cf2531 100644
--- a/sys/dev/pci/ehci_pci.c
+++ b/sys/dev/pci/ehci_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci_pci.c,v 1.23 2011/04/26 00:37:34 deraadt Exp $ */
+/* $OpenBSD: ehci_pci.c,v 1.24 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: ehci_pci.c,v 1.15 2004/04/23 21:13:06 itojun Exp $ */
/*
@@ -75,9 +75,10 @@ int ehci_pci_match(struct device *, void *, void *);
void ehci_pci_attach(struct device *, struct device *, void *);
int ehci_pci_detach(struct device *, int);
int ehci_pci_activate(struct device *, int);
+#if 0
void ehci_pci_givecontroller(struct ehci_pci_softc *);
+#endif
void ehci_pci_takecontroller(struct ehci_pci_softc *, int);
-void ehci_pci_shutdown(void *);
struct cfattach ehci_pci_ca = {
sizeof(struct ehci_pci_softc), ehci_pci_match, ehci_pci_attach,
@@ -215,7 +216,6 @@ ehci_pci_attach(struct device *parent, struct device *self, void *aux)
goto disestablish_ret;
}
- sc->sc.sc_shutdownhook = shutdownhook_establish(ehci_pci_shutdown, sc);
splx(s);
/* Attach usb device. */
@@ -235,15 +235,24 @@ int
ehci_pci_activate(struct device *self, int act)
{
struct ehci_pci_softc *sc = (struct ehci_pci_softc *)self;
+ int rv;
- /* On resume, take ownership from the BIOS */
switch (act) {
case DVACT_RESUME:
ehci_pci_takecontroller(sc, 1);
break;
}
- return ehci_activate(self, act);
+ rv = ehci_activate(self, act);
+
+#if 0
+ switch (act) {
+ case DVACT_POWERDOWN:
+ ehci_pci_givecontroller(sc);
+ break;
+ }
+#endif
+ return (rv);
}
int
@@ -266,7 +275,7 @@ ehci_pci_detach(struct device *self, int flags)
return (0);
}
-#if 0 /* not used */
+#if 0
void
ehci_pci_givecontroller(struct ehci_pci_softc *sc)
{
@@ -319,18 +328,6 @@ ehci_pci_takecontroller(struct ehci_pci_softc *sc, int silent)
}
}
-void
-ehci_pci_shutdown(void *v)
-{
- struct ehci_pci_softc *sc = (struct ehci_pci_softc *)v;
-
- ehci_shutdown(&sc->sc);
-#if 0
- /* best not to do this anymore; BIOS SMM spins? */
- ehci_pci_givecontroller(sc);
-#endif
-}
-
int
ehci_sb700_match(struct pci_attach_args *pa)
{
diff --git a/sys/dev/pci/glxpcib.c b/sys/dev/pci/glxpcib.c
index fa1ccaeb16e..30a4dcde277 100644
--- a/sys/dev/pci/glxpcib.c
+++ b/sys/dev/pci/glxpcib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: glxpcib.c,v 1.5 2012/03/06 12:57:36 mikeb Exp $ */
+/* $OpenBSD: glxpcib.c,v 1.6 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org>
@@ -426,6 +426,9 @@ glxpcib_activate(struct device *self, int act)
#endif
break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
+ break;
case DVACT_RESUME:
#ifndef SMALL_KERNEL
if (sc->sc_wdog)
diff --git a/sys/dev/pci/pccbb.c b/sys/dev/pci/pccbb.c
index fd37b407280..e2d233d766e 100644
--- a/sys/dev/pci/pccbb.c
+++ b/sys/dev/pci/pccbb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pccbb.c,v 1.87 2010/12/08 20:22:49 miod Exp $ */
+/* $OpenBSD: pccbb.c,v 1.88 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: pccbb.c,v 1.96 2004/03/28 09:49:31 nakayama Exp $ */
/*
@@ -457,8 +457,6 @@ pccbbattach(struct device *parent, struct device *self, void *aux)
printf("\n");
- shutdownhook_establish(pccbb_shutdown, sc);
-
/* Disable legacy register mapping. */
pccbb_legacy_disable(sc);
@@ -2841,6 +2839,10 @@ pccbbactivate(struct device *self, int act)
sc->sc_iobase[1] = pci_conf_read(pc, tag, PCI_CB_IOBASE1);
sc->sc_iolimit[1] = pci_conf_read(pc, tag, PCI_CB_IOLIMIT1);
break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
+ pccbb_shutdown(self);
+ break;
case DVACT_RESUME:
/* Restore the registers saved above. */
pci_conf_write(pc, tag, PCI_BHLC_REG, sc->sc_bhlcr);
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index a19420b7d18..6bd03cb39dd 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci.c,v 1.96 2012/09/19 23:01:21 kettenis Exp $ */
+/* $OpenBSD: pci.c,v 1.97 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */
/*
@@ -51,6 +51,7 @@ void pciattach(struct device *, struct device *, void *);
int pcidetach(struct device *, int);
int pciactivate(struct device *, int);
void pci_suspend(struct pci_softc *);
+void pci_powerdown(struct pci_softc *);
void pci_resume(struct pci_softc *);
#define NMAPREG ((PCI_MAPREG_END - PCI_MAPREG_START) / \
@@ -215,6 +216,10 @@ pciactivate(struct device *self, int act)
rv = config_activate_children(self, act);
pci_suspend((struct pci_softc *)self);
break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
+ pci_powerdown((struct pci_softc *)self);
+ break;
case DVACT_RESUME:
pci_resume((struct pci_softc *)self);
rv = config_activate_children(self, act);
@@ -266,6 +271,24 @@ pci_suspend(struct pci_softc *sc)
}
pd->pd_msi_mc = reg;
}
+ }
+}
+
+void
+pci_powerdown(struct pci_softc *sc)
+{
+ struct pci_dev *pd;
+ pcireg_t bhlc;
+
+ LIST_FOREACH(pd, &sc->sc_devs, pd_next) {
+ /*
+ * Only handle header type 0 here; PCI-PCI bridges and
+ * CardBus bridges need special handling, which will
+ * be done in their specific drivers.
+ */
+ bhlc = pci_conf_read(sc->sc_pc, pd->pd_tag, PCI_BHLC_REG);
+ if (PCI_HDRTYPE_TYPE(bhlc) != 0)
+ continue;
if (pci_dopm) {
/*
@@ -297,11 +320,10 @@ pci_resume(struct pci_softc *sc)
if (PCI_HDRTYPE_TYPE(bhlc) != 0)
continue;
- if (pci_dopm) {
- /* Restore power. */
+ /* Restore power. */
+ if (pci_dopm)
pci_set_powerstate(sc->sc_pc, pd->pd_tag,
pd->pd_pmcsr_state);
- }
/* Restore the registers saved above. */
for (i = 0; i < NMAPREG; i++)
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c
index 34976ae11a6..45f112c53ea 100644
--- a/sys/dev/pci/pciide.c
+++ b/sys/dev/pci/pciide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide.c,v 1.339 2012/04/22 14:22:28 miod Exp $ */
+/* $OpenBSD: pciide.c,v 1.340 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $ */
/*
@@ -1489,6 +1489,9 @@ pciide_activate(struct device *self, int act)
sc->sc_tag, NFORCE_UDMATIM);
}
break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
+ break;
case DVACT_RESUME:
for (i = 0; i < nitems(sc->sc_save); i++)
pci_conf_write(sc->sc_pc, sc->sc_tag,
diff --git a/sys/dev/pci/ppb.c b/sys/dev/pci/ppb.c
index 32dfce9523e..c9a7f9cca53 100644
--- a/sys/dev/pci/ppb.c
+++ b/sys/dev/pci/ppb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ppb.c,v 1.54 2012/09/07 19:26:48 kettenis Exp $ */
+/* $OpenBSD: ppb.c,v 1.55 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: ppb.c,v 1.16 1997/06/06 23:48:05 thorpej Exp $ */
/*
@@ -389,7 +389,10 @@ ppbactivate(struct device *self, int act)
}
sc->sc_msi_mc = reg;
}
-
+ break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
+
if (pci_dopm) {
/*
* Place the bridge into the lowest possible
diff --git a/sys/dev/pci/sdhc_pci.c b/sys/dev/pci/sdhc_pci.c
index eac6107992a..5abe511d84e 100644
--- a/sys/dev/pci/sdhc_pci.c
+++ b/sys/dev/pci/sdhc_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdhc_pci.c,v 1.12 2011/12/23 21:58:47 kettenis Exp $ */
+/* $OpenBSD: sdhc_pci.c,v 1.13 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
@@ -172,11 +172,6 @@ sdhc_pci_attach(struct device *parent, struct device *self, void *aux)
printf("%s at 0x%x: can't initialize host\n",
sc->sc.sc_dev.dv_xname, reg);
}
-
- /*
- * Establish shutdown hooks.
- */
- (void)shutdownhook_establish(sdhc_shutdown, &sc->sc);
}
void
diff --git a/sys/dev/pci/sili_pci.c b/sys/dev/pci/sili_pci.c
index 2be1405924d..d4f0b6510df 100644
--- a/sys/dev/pci/sili_pci.c
+++ b/sys/dev/pci/sili_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sili_pci.c,v 1.12 2010/08/31 17:13:44 deraadt Exp $ */
+/* $OpenBSD: sili_pci.c,v 1.13 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
@@ -212,6 +212,9 @@ sili_pci_activate(struct device *self, int act)
case DVACT_SUSPEND:
rv = config_activate_children(self, act);
break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
+ break;
case DVACT_RESUME:
sili_resume(sc);
rv = config_activate_children(self, act);
diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c
index 595483c23c9..56f977a1b93 100644
--- a/sys/dev/pci/vga_pci.c
+++ b/sys/dev/pci/vga_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vga_pci.c,v 1.68 2012/08/22 20:58:30 mpi Exp $ */
+/* $OpenBSD: vga_pci.c,v 1.69 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: vga_pci.c,v 1.3 1998/06/08 06:55:58 thorpej Exp $ */
/*
@@ -336,6 +336,9 @@ vga_pci_activate(struct device *self, int act)
#endif
rv = config_activate_children(self, act);
break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
+ break;
}
return (rv);
diff --git a/sys/dev/pcmcia/pcmcia.c b/sys/dev/pcmcia/pcmcia.c
index ef59a7e837f..2637c5e0a20 100644
--- a/sys/dev/pcmcia/pcmcia.c
+++ b/sys/dev/pcmcia/pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcmcia.c,v 1.45 2011/09/17 15:38:43 miod Exp $ */
+/* $OpenBSD: pcmcia.c,v 1.46 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: pcmcia.c,v 1.9 1998/08/13 02:10:55 eeh Exp $ */
/*
@@ -140,6 +140,7 @@ pcmcia_activate(struct device *self, int act)
switch (act) {
case DVACT_QUIESCE:
case DVACT_SUSPEND:
+ case DVACT_POWERDOWN:
case DVACT_RESUME:
for (pf = SIMPLEQ_FIRST(&sc->card.pf_head); pf != NULL;
pf = SIMPLEQ_NEXT(pf, pf_list)) {
diff --git a/sys/dev/pcmcia/wdc_pcmcia.c b/sys/dev/pcmcia/wdc_pcmcia.c
index 803419cc976..ac42b8a3a3e 100644
--- a/sys/dev/pcmcia/wdc_pcmcia.c
+++ b/sys/dev/pcmcia/wdc_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc_pcmcia.c,v 1.27 2011/07/03 15:47:17 matthew Exp $ */
+/* $OpenBSD: wdc_pcmcia.c,v 1.28 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: wdc_pcmcia.c,v 1.19 1999/02/19 21:49:43 abs Exp $ */
/*-
@@ -436,6 +436,9 @@ wdc_pcmcia_activate(self, act)
break;
case DVACT_SUSPEND:
rv = config_activate_children(self, act);
+ break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
if (sc->sc_ih)
pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
sc->sc_ih = NULL;
diff --git a/sys/dev/sdmmc/sdhc.c b/sys/dev/sdmmc/sdhc.c
index 828e54284fb..9f8824661d5 100644
--- a/sys/dev/sdmmc/sdhc.c
+++ b/sys/dev/sdmmc/sdhc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdhc.c,v 1.34 2011/07/31 16:55:01 kettenis Exp $ */
+/* $OpenBSD: sdhc.c,v 1.35 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
@@ -271,6 +271,10 @@ sdhc_activate(struct device *self, int act)
}
rv = config_activate_children(self, act);
break;
+ case DVACT_POWERDOWN:
+ rv = config_activate_children(self, act);
+ sdhc_shutdown(self);
+ break;
case DVACT_RESUME:
/* Restore the host controller state. */
for (n = 0; n < sc->sc_nhosts; n++) {
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index c00470f9991..8dd140ad489 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci.c,v 1.126 2012/08/17 17:29:00 krw Exp $ */
+/* $OpenBSD: ehci.c,v 1.127 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
/*
@@ -1040,9 +1040,6 @@ ehci_detach(struct ehci_softc *sc, int flags)
timeout_del(&sc->sc_tmo_intrlist);
- if (sc->sc_shutdownhook != NULL)
- shutdownhook_disestablish(sc->sc_shutdownhook);
-
usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
/* XXX free other data structures XXX */
@@ -1104,6 +1101,9 @@ ehci_activate(struct device *self, int act)
sc->sc_bus.use_polling--;
break;
+ case DVACT_POWERDOWN:
+ ehci_shutdown(sc);
+ break;
case DVACT_RESUME:
sc->sc_bus.use_polling++;
diff --git a/sys/dev/usb/ehcivar.h b/sys/dev/usb/ehcivar.h
index 0bea547ae82..51a71d1c9a6 100644
--- a/sys/dev/usb/ehcivar.h
+++ b/sys/dev/usb/ehcivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehcivar.h,v 1.22 2012/05/12 17:39:51 mpi Exp $ */
+/* $OpenBSD: ehcivar.h,v 1.23 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */
/*
@@ -126,7 +126,6 @@ typedef struct ehci_softc {
int sc_id_vendor; /* vendor ID for root hub */
u_int32_t sc_cmd; /* shadow of cmd reg during suspend */
- void *sc_shutdownhook; /* cookie from shutdown hook */
usb_dma_t sc_fldma;
ehci_link_t *sc_flist;