summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/alpha/alpha/machdep.c5
-rw-r--r--sys/arch/amd64/amd64/acpi_machdep.c153
-rw-r--r--sys/arch/amd64/amd64/machdep.c3
-rw-r--r--sys/arch/amd64/pci/pchb.c5
-rw-r--r--sys/arch/arm/xscale/pxa2x0_apm.c8
-rw-r--r--sys/arch/aviion/aviion/machdep.c4
-rw-r--r--sys/arch/hp300/hp300/machdep.c4
-rw-r--r--sys/arch/hppa/hppa/machdep.c3
-rw-r--r--sys/arch/hppa64/hppa64/machdep.c3
-rw-r--r--sys/arch/i386/i386/acpi_machdep.c162
-rw-r--r--sys/arch/i386/i386/apm.c7
-rw-r--r--sys/arch/i386/i386/machdep.c3
-rw-r--r--sys/arch/i386/pci/pchb.c5
-rw-r--r--sys/arch/landisk/landisk/machdep.c3
-rw-r--r--sys/arch/loongson/dev/apm.c8
-rw-r--r--sys/arch/loongson/loongson/machdep.c3
-rw-r--r--sys/arch/luna88k/luna88k/machdep.c4
-rw-r--r--sys/arch/macppc/macppc/machdep.c4
-rw-r--r--sys/arch/mvme68k/mvme68k/machdep.c4
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c4
-rw-r--r--sys/arch/octeon/octeon/machdep.c3
-rw-r--r--sys/arch/sgi/sgi/machdep.c3
-rw-r--r--sys/arch/socppc/socppc/machdep.c4
-rw-r--r--sys/arch/solbourne/solbourne/machdep.c4
-rw-r--r--sys/arch/sparc/sparc/machdep.c4
-rw-r--r--sys/arch/sparc64/sparc64/machdep.c4
-rw-r--r--sys/arch/vax/vax/machdep.c7
-rw-r--r--sys/arch/zaurus/dev/zaurus_apm.c7
-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
-rw-r--r--sys/kern/subr_autoconf.c5
-rw-r--r--sys/scsi/scsiconf.c3
-rw-r--r--sys/scsi/sd.c52
-rw-r--r--sys/scsi/sdvar.h3
-rw-r--r--sys/sys/device.h3
52 files changed, 577 insertions, 535 deletions
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c
index c562ff1843f..2538092cac1 100644
--- a/sys/arch/alpha/alpha/machdep.c
+++ b/sys/arch/alpha/alpha/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.136 2012/08/22 13:33:32 okan Exp $ */
+/* $OpenBSD: machdep.c,v 1.137 2012/10/08 21:47:45 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */
/*-
@@ -1027,9 +1027,8 @@ boot(howto)
dumpsys();
haltsys:
-
- /* run any shutdown hooks */
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
#if defined(MULTIPROCESSOR)
#if 0 /* XXX doesn't work when called from here?! */
diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c
index d9ad4c6790a..b255ee05580 100644
--- a/sys/arch/amd64/amd64/acpi_machdep.c
+++ b/sys/arch/amd64/amd64/acpi_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi_machdep.c,v 1.49 2012/07/13 16:02:24 mlarkin Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.50 2012/10/08 21:47:47 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -23,6 +23,7 @@
#include <sys/memrange.h>
#include <sys/proc.h>
#include <sys/user.h>
+#include <sys/reboot.h>
#include <sys/hibernate.h>
#include <uvm/uvm_extern.h>
@@ -191,24 +192,48 @@ acpi_attach_machdep(struct acpi_softc *sc)
}
void
-acpi_cpu_flush(struct acpi_softc *sc, int state)
+acpi_sleep_clocks(struct acpi_softc *sc, int state)
{
- /*
- * Flush write back caches since we'll lose them.
- */
- if (state > ACPI_STATE_S1)
- wbinvd();
+ rtcstop();
}
-int
-acpi_sleep_machdep(struct acpi_softc *sc, int state)
+/*
+ * We repair the interrupt hardware so that any events which occur
+ * will cause the least number of unexpected side effects. We re-start
+ * the clocks early because we will soon run AML whigh might do DELAY.
+ */
+void
+acpi_resume_clocks(struct acpi_softc *sc)
{
- if (sc->sc_facs == NULL) {
- printf("%s: acpi_sleep_machdep: no FACS\n", DEVNAME(sc));
- return (ENXIO);
- }
+#if NISA > 0
+ i8259_default_setup();
+#endif
+ intr_calculatemasks(curcpu());
- rtcstop();
+#if NIOAPIC > 0
+ ioapic_enable();
+#endif
+
+#if NLAPIC > 0
+ lapic_enable();
+ if (initclock_func == lapic_initclocks)
+ lapic_startclock();
+ lapic_set_lvt();
+#endif
+
+ i8254_startclock();
+ if (initclock_func == i8254_initclocks)
+ rtcstart(); /* in i8254 mode, rtc is profclock */
+}
+
+/*
+ * This function may not have local variables due to a bug between
+ * acpi_savecpu() and the resume path.
+ */
+int
+acpi_sleep_cpu(struct acpi_softc *sc, int state)
+{
+ /* amd64 does not do lazy pmap_activate */
/*
* ACPI defines two wakeup vectors. One is used for ACPI 1.0
@@ -231,62 +256,88 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
if (acpi_savecpu()) {
/* Suspend path */
fpusave_cpu(curcpu(), 1);
-#ifdef MULTIPROCESSOR
- x86_broadcast_ipi(X86_IPI_SYNCH_FPU);
- x86_broadcast_ipi(X86_IPI_HALT);
-#endif
wbinvd();
+
#ifdef HIBERNATE
if (state == ACPI_STATE_S4) {
uvm_pmr_zero_everything();
- if (hibernate_suspend())
- panic("%s: hibernate failed", DEVNAME(sc));
+ if (hibernate_suspend()) {
+ printf("%s: hibernate_suspend failed",
+ DEVNAME(sc));
+ hibernate_free();
+ uvm_pmr_dirty_everything();
+ return (ECANCELED);
+ }
}
#endif
- acpi_enter_sleep_state(sc, state);
- panic("%s: acpi_enter_sleep_state failed", DEVNAME(sc));
- }
- /* Resume path continues here */
+ boothowto |= RB_POWERDOWN;
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
+ boothowto &= ~RB_POWERDOWN;
- /* Reset the vector */
- sc->sc_facs->wakeup_vector = 0;
+ acpi_sleep_pm(sc, state);
+ printf("%s: acpi_sleep_pm failed", DEVNAME(sc));
+ return (ECANCELED);
+ }
+ /* Resume path */
-#if NISA > 0
- i8259_default_setup();
+#ifdef HIBERNATE
+ if (state == ACPI_STATE_S4) {
+ hibernate_free();
+ uvm_pmr_dirty_everything();
+ }
#endif
- intr_calculatemasks(curcpu());
-#if NLAPIC > 0
- lapic_enable();
- if (initclock_func == lapic_initclocks)
- lapic_startclock();
- lapic_set_lvt();
-#endif
+ /* Reset the vectors */
+ sc->sc_facs->wakeup_vector = 0;
+ if (sc->sc_facs->length > 32 && sc->sc_facs->version >= 1)
+ sc->sc_facs->x_wakeup_vector = 0;
- fpuinit(&cpu_info_primary);
+ return (0);
+}
- /* Re-initialise memory range handling */
+void
+acpi_resume_cpu(struct acpi_softc *sc)
+{
+ /* Re-initialise memory range handling on BSP */
if (mem_range_softc.mr_op != NULL)
mem_range_softc.mr_op->initAP(&mem_range_softc);
+ fpuinit(&cpu_info_primary);
+}
-#if NIOAPIC > 0
- ioapic_enable();
-#endif
- i8254_startclock();
- if (initclock_func == i8254_initclocks)
- rtcstart(); /* in i8254 mode, rtc is profclock */
- inittodr(time_second);
+#ifdef MULTIPROCESSOR
+void
+acpi_sleep_mp(void)
+{
+ int i;
- return (0);
-}
+ sched_stop_secondary_cpus();
+ KASSERT(CPU_IS_PRIMARY(curcpu()));
-void cpu_start_secondary(struct cpu_info *ci);
+ /* Wait for cpus to save their floating point context */
+ x86_broadcast_ipi(X86_IPI_SYNCH_FPU);
+ for (i = 0; i < ncpus; i++) {
+ struct cpu_info *ci = cpu_info[i];
+
+ while (!CPU_IS_PRIMARY(curcpu()) && ci->ci_fpcurproc)
+ ;
+ }
+
+ /* Wait for cpus to halt so we know their caches are written back */
+ x86_broadcast_ipi(X86_IPI_HALT);
+ for (i = 0; i < ncpus; i++) {
+ struct cpu_info *ci = cpu_info[i];
+
+ while (!CPU_IS_PRIMARY(curcpu()) &&
+ (ci->ci_flags & CPUF_RUNNING))
+ ;
+ }
+}
void
-acpi_resume_machdep(void)
+acpi_resume_mp(void)
{
-#ifdef MULTIPROCESSOR
+ void cpu_start_secondary(struct cpu_info *ci);
struct cpu_info *ci;
struct proc *p;
struct pcb *pcb;
@@ -324,6 +375,8 @@ acpi_resume_machdep(void)
}
cpu_boot_secondary_processors();
-#endif /* MULTIPROCESSOR */
+ sched_start_secondary_cpus();
}
+#endif /* MULTIPROCESSOR */
+
#endif /* ! SMALL_KERNEL */
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 4406312d808..a6c09fcd299 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.155 2012/06/04 15:19:47 jsing Exp $ */
+/* $OpenBSD: machdep.c,v 1.156 2012/10/08 21:47:47 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
@@ -752,6 +752,7 @@ boot(int howto)
haltsys:
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
#ifdef MULTIPROCESSOR
x86_broadcast_ipi(X86_IPI_HALT);
diff --git a/sys/arch/amd64/pci/pchb.c b/sys/arch/amd64/pci/pchb.c
index e874db8e524..d51c6ddb9a5 100644
--- a/sys/arch/amd64/pci/pchb.c
+++ b/sys/arch/amd64/pci/pchb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pchb.c,v 1.38 2012/09/19 23:23:50 kettenis Exp $ */
+/* $OpenBSD: pchb.c,v 1.39 2012/10/08 21:47:47 deraadt Exp $ */
/* $NetBSD: pchb.c,v 1.1 2003/04/26 18:39:50 fvdl Exp $ */
/*
* Copyright (c) 2000 Michael Shalayeff
@@ -286,6 +286,9 @@ pchbactivate(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:
/* re-enable RNG, if we have it */
if (sc->sc_rng_active)
diff --git a/sys/arch/arm/xscale/pxa2x0_apm.c b/sys/arch/arm/xscale/pxa2x0_apm.c
index 664cc67a341..1807eb2bcde 100644
--- a/sys/arch/arm/xscale/pxa2x0_apm.c
+++ b/sys/arch/arm/xscale/pxa2x0_apm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0_apm.c,v 1.37 2011/07/02 22:20:07 nicm Exp $ */
+/* $OpenBSD: pxa2x0_apm.c,v 1.38 2012/10/08 21:47:47 deraadt Exp $ */
/*-
* Copyright (c) 2001 Alexander Guy. All rights reserved.
@@ -45,6 +45,7 @@
#include <sys/device.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
+#include <sys/reboot.h>
#include <sys/event.h>
#include <machine/conf.h>
@@ -320,6 +321,11 @@ apm_suspend(struct pxa2x0_apm_softc *sc)
s = splhigh();
config_suspend(TAILQ_FIRST(&alldevs), DVACT_SUSPEND);
+
+ boothowto |= RB_POWERDOWN;
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
+ boothowto &= ~RB_POWERDOWN;
+
splx(s);
pxa2x0_apm_sleep(sc);
diff --git a/sys/arch/aviion/aviion/machdep.c b/sys/arch/aviion/aviion/machdep.c
index 69f5e83a660..e17a1f24e7e 100644
--- a/sys/arch/aviion/aviion/machdep.c
+++ b/sys/arch/aviion/aviion/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.47 2011/10/09 17:09:27 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.48 2012/10/08 21:47:47 deraadt Exp $ */
/*
* Copyright (c) 2007 Miodrag Vallat.
*
@@ -329,8 +329,8 @@ boot(howto)
dumpsys();
haltsys:
- /* Run any shutdown hooks. */
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if (howto & RB_HALT) {
printf("System halted.\n\n");
diff --git a/sys/arch/hp300/hp300/machdep.c b/sys/arch/hp300/hp300/machdep.c
index d23ea45a294..3a81cb385de 100644
--- a/sys/arch/hp300/hp300/machdep.c
+++ b/sys/arch/hp300/hp300/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.135 2011/11/01 21:20:55 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.136 2012/10/08 21:47:47 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.121 1999/03/26 23:41:29 mycroft Exp $ */
/*
@@ -615,8 +615,8 @@ boot(howto)
dumpsys();
haltsys:
- /* Run any shutdown hooks. */
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
/* Finally, halt/reboot the system. */
if (howto & RB_HALT) {
diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c
index 9deefc6a7e4..56e22b448b2 100644
--- a/sys/arch/hppa/hppa/machdep.c
+++ b/sys/arch/hppa/hppa/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.207 2012/10/07 20:39:15 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.208 2012/10/08 21:47:47 deraadt Exp $ */
/*
* Copyright (c) 1999-2003 Michael Shalayeff
@@ -920,6 +920,7 @@ boot(int howto)
dumpsys();
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
#ifdef MULTIPROCESSOR
hppa_ipi_broadcast(HPPA_IPI_HALT);
diff --git a/sys/arch/hppa64/hppa64/machdep.c b/sys/arch/hppa64/hppa64/machdep.c
index 8f18688ad7d..9262ad7ee40 100644
--- a/sys/arch/hppa64/hppa64/machdep.c
+++ b/sys/arch/hppa64/hppa64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.48 2012/07/13 15:10:51 jsing Exp $ */
+/* $OpenBSD: machdep.c,v 1.49 2012/10/08 21:47:48 deraadt Exp $ */
/*
* Copyright (c) 2005 Michael Shalayeff
@@ -570,6 +570,7 @@ boot(int howto)
dumpsys();
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
}
/* in case we came on powerfail interrupt */
diff --git a/sys/arch/i386/i386/acpi_machdep.c b/sys/arch/i386/i386/acpi_machdep.c
index ad27b83fbb0..aaea629c52d 100644
--- a/sys/arch/i386/i386/acpi_machdep.c
+++ b/sys/arch/i386/i386/acpi_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi_machdep.c,v 1.43 2012/06/20 17:31:55 mlarkin Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.44 2012/10/08 21:47:48 deraadt Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -23,6 +23,7 @@
#include <sys/memrange.h>
#include <sys/proc.h>
#include <sys/user.h>
+#include <sys/reboot.h>
#include <sys/hibernate.h>
#include <uvm/uvm_extern.h>
@@ -207,38 +208,59 @@ acpi_attach_machdep(struct acpi_softc *sc)
acpi_resume_end - acpi_real_mode_resume);
}
+#if NLAPIC > 0
+int save_lapic_tpr;
+#endif
+
void
-acpi_cpu_flush(struct acpi_softc *sc, int state)
+acpi_sleep_clocks(struct acpi_softc *sc, int state)
{
- /*
- * Flush write back caches since we'll lose them.
- */
- if (state > ACPI_STATE_S1)
- wbinvd();
+ rtcstop();
+#if NLAPIC > 0
+ save_lapic_tpr = lapic_tpr;
+#endif
}
-int
-acpi_sleep_machdep(struct acpi_softc *sc, int state)
+/*
+ * Start the clocks early because AML will be executed next
+ * which might do DELAY.
+ */
+void
+acpi_resume_clocks(struct acpi_softc *sc)
{
- int s;
+#if NISA > 0
+ isa_defaultirq();
+#endif
+ intr_calculatemasks();
- if (sc->sc_facs == NULL) {
- printf("%s: acpi_sleep_machdep: no FACS\n", DEVNAME(sc));
- return (ENXIO);
- }
+#if NIOAPIC > 0
+ ioapic_enable();
+#endif
- rtcstop();
+#if NLAPIC > 0
+ lapic_tpr = save_lapic_tpr;
+ lapic_enable();
+ if (initclock_func == lapic_initclocks)
+ lapic_startclock();
+ lapic_set_lvt();
+#endif
- /* i386 does lazy pmap_activate */
+ i8254_startclock();
+ if (initclock_func == i8254_initclocks)
+ rtcstart(); /* in i8254 mode, rtc is profclock */
+}
+
+/*
+ * This function may not have local variables due to a bug between
+ * acpi_savecpu() and the resume path.
+ */
+int
+acpi_sleep_cpu(struct acpi_softc *sc, int state)
+{
+ /* i386 does lazy pmap_activate: switch to kernel memory view */
pmap_activate(curproc);
/*
- * The local apic may lose its state, so save the Task
- * Priority register where we keep the system priority level.
- */
- s = lapic_tpr;
-
- /*
* ACPI defines two wakeup vectors. One is used for ACPI 1.0
* implementations - it's in the FACS table as wakeup_vector and
* indicates a 32-bit physical address containing real-mode wakeup
@@ -259,71 +281,87 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
if (acpi_savecpu()) {
/* Suspend path */
npxsave_cpu(curcpu(), 1);
-#ifdef MULTIPROCESSOR
- i386_broadcast_ipi(I386_IPI_SYNCH_FPU);
- i386_broadcast_ipi(I386_IPI_HALT);
-#endif
wbinvd();
+
#ifdef HIBERNATE
if (state == ACPI_STATE_S4) {
uvm_pmr_zero_everything();
- if (hibernate_suspend())
- panic("%s: hibernate failed", DEVNAME(sc));
+ if (hibernate_suspend()) {
+ printf("%s: hibernate_suspend failed",
+ DEVNAME(sc));
+ hibernate_free();
+ uvm_pmr_dirty_everything();
+ return (ECANCELED);
+ }
}
#endif
- acpi_enter_sleep_state(sc, state);
- panic("%s: acpi_enter_sleep_state failed", DEVNAME(sc));
- }
- /* Resume path continues here */
+ boothowto |= RB_POWERDOWN;
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
+ boothowto &= ~RB_POWERDOWN;
+
+ acpi_sleep_pm(sc, state);
+ printf("%s: acpi_sleep_pm failed", DEVNAME(sc));
+ return (ECANCELED);
+ }
+ /* Resume path */
#ifdef HIBERNATE
- /* Free piglet and other pages allocated during suspend */
if (state == ACPI_STATE_S4) {
hibernate_free();
uvm_pmr_dirty_everything();
}
#endif
- /* Reset the vector */
+ /* Reset the vectors */
sc->sc_facs->wakeup_vector = 0;
+ if (sc->sc_facs->length > 32 && sc->sc_facs->version >= 1)
+ sc->sc_facs->x_wakeup_vector = 0;
- /* Restore the Task Priority register */
- lapic_tpr = s;
+ return (0);
+}
-#if NISA > 0
- isa_defaultirq();
-#endif
- intr_calculatemasks();
+void
+acpi_resume_cpu(struct acpi_softc *sc)
+{
+ /* Re-initialise memory range handling on BSP */
+ if (mem_range_softc.mr_op != NULL)
+ mem_range_softc.mr_op->initAP(&mem_range_softc);
+ npxinit(&cpu_info_primary);
+}
-#if NLAPIC > 0
- lapic_enable();
- if (initclock_func == lapic_initclocks)
- lapic_startclock();
- lapic_set_lvt();
-#endif
+#ifdef MULTIPROCESSOR
+void
+acpi_sleep_mp()
+{
+ int i;
- npxinit(&cpu_info_primary);
+ sched_stop_secondary_cpus();
+ KASSERT(CPU_IS_PRIMARY(curcpu()));
- /* Re-initialise memory range handling */
- if (mem_range_softc.mr_op != NULL)
- mem_range_softc.mr_op->initAP(&mem_range_softc);
+ /* Wait for cpus to save their floating point context */
+ i386_broadcast_ipi(I386_IPI_SYNCH_FPU);
+ for (i = 0; i < ncpus; i++) {
+ struct cpu_info *ci = cpu_info[i];
-#if NIOAPIC > 0
- ioapic_enable();
-#endif
- i8254_startclock();
- if (initclock_func == i8254_initclocks)
- rtcstart(); /* in i8254 mode, rtc is profclock */
- inittodr(time_second);
+ while (!CPU_IS_PRIMARY(curcpu()) && ci->ci_fpcurproc)
+ ;
+ }
- return (0);
+ /* Wait for cpus to halt so we know their caches are written back */
+ i386_broadcast_ipi(I386_IPI_HALT);
+ for (i = 0; i < ncpus; i++) {
+ struct cpu_info *ci = cpu_info[i];
+
+ while (!CPU_IS_PRIMARY(curcpu()) &&
+ (ci->ci_flags & CPUF_RUNNING))
+ ;
+ }
}
void
-acpi_resume_machdep(void)
+acpi_resume_mp(void)
{
-#ifdef MULTIPROCESSOR
struct cpu_info *ci;
struct proc *p;
struct pcb *pcb;
@@ -357,6 +395,8 @@ acpi_resume_machdep(void)
}
cpu_boot_secondary_processors();
-#endif /* MULTIPROCESSOR */
+ sched_start_secondary_cpus();
}
+#endif /* MULTIPROCESSOR */
+
#endif /* ! SMALL_KERNEL */
diff --git a/sys/arch/i386/i386/apm.c b/sys/arch/i386/i386/apm.c
index c6e1cc1a22a..57f61685a35 100644
--- a/sys/arch/i386/i386/apm.c
+++ b/sys/arch/i386/i386/apm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apm.c,v 1.98 2011/07/02 22:20:07 nicm Exp $ */
+/* $OpenBSD: apm.c,v 1.99 2012/10/08 21:47:48 deraadt Exp $ */
/*-
* Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved.
@@ -49,6 +49,7 @@
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/buf.h>
+#include <sys/reboot.h>
#include <sys/event.h>
#include <machine/conf.h>
@@ -254,6 +255,10 @@ apm_suspend(int state)
disable_intr();
config_suspend(TAILQ_FIRST(&alldevs), DVACT_SUSPEND);
+ boothowto |= RB_POWERDOWN;
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
+ boothowto &= ~RB_POWERDOWN;
+
/* Send machine to sleep */
apm_set_powstate(APM_DEV_ALLDEVS, state);
/* Wake up */
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index 97591d87adb..36f521e3a97 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.512 2012/09/19 20:19:31 jsg Exp $ */
+/* $OpenBSD: machdep.c,v 1.513 2012/10/08 21:47:48 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
@@ -2530,6 +2530,7 @@ boot(int howto)
haltsys:
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
#ifdef MULTIPROCESSOR
i386_broadcast_ipi(I386_IPI_HALT);
diff --git a/sys/arch/i386/pci/pchb.c b/sys/arch/i386/pci/pchb.c
index c74622daf25..03ba73d9e5a 100644
--- a/sys/arch/i386/pci/pchb.c
+++ b/sys/arch/i386/pci/pchb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pchb.c,v 1.86 2012/09/19 23:03:12 kettenis Exp $ */
+/* $OpenBSD: pchb.c,v 1.87 2012/10/08 21:47:48 deraadt Exp $ */
/* $NetBSD: pchb.c,v 1.65 2007/08/15 02:26:13 markd Exp $ */
/*
@@ -429,6 +429,9 @@ pchbactivate(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:
/* re-enable RNG, if we have it */
if (sc->sc_rng_active)
diff --git a/sys/arch/landisk/landisk/machdep.c b/sys/arch/landisk/landisk/machdep.c
index 0b12006638d..7e92e0ac1da 100644
--- a/sys/arch/landisk/landisk/machdep.c
+++ b/sys/arch/landisk/landisk/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.26 2011/06/26 22:39:59 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.27 2012/10/08 21:47:48 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.1 2006/09/01 21:26:18 uwe Exp $ */
/*-
@@ -222,6 +222,7 @@ boot(int howto)
haltsys:
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
_reg_write_1(LANDISK_PWRMNG, PWRMNG_POWEROFF);
diff --git a/sys/arch/loongson/dev/apm.c b/sys/arch/loongson/dev/apm.c
index 37c2bcba289..bc321492ec9 100644
--- a/sys/arch/loongson/dev/apm.c
+++ b/sys/arch/loongson/dev/apm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apm.c,v 1.11 2011/09/20 14:06:26 deraadt Exp $ */
+/* $OpenBSD: apm.c,v 1.12 2012/10/08 21:47:48 deraadt Exp $ */
/*-
* Copyright (c) 2001 Alexander Guy. All rights reserved.
@@ -43,6 +43,7 @@
#include <sys/ioctl.h>
#include <sys/buf.h>
#include <sys/event.h>
+#include <sys/reboot.h>
#include <machine/autoconf.h>
#include <machine/conf.h>
@@ -369,6 +370,11 @@ apm_suspend()
cold = 1;
rv = config_suspend(TAILQ_FIRST(&alldevs), DVACT_SUSPEND);
+
+ boothowto |= RB_POWERDOWN;
+ (void) config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
+ boothowto &= ~RB_POWERDOWN;
+
if (rv == 0) {
rv = sys_platform->suspend();
if (rv == 0)
diff --git a/sys/arch/loongson/loongson/machdep.c b/sys/arch/loongson/loongson/machdep.c
index 4f72f20b3be..5c2afe19934 100644
--- a/sys/arch/loongson/loongson/machdep.c
+++ b/sys/arch/loongson/loongson/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.38 2012/10/03 21:44:51 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.39 2012/10/08 21:47:48 deraadt Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -853,6 +853,7 @@ boot(int howto)
haltsys:
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if (howto & RB_HALT) {
if (howto & RB_POWERDOWN) {
diff --git a/sys/arch/luna88k/luna88k/machdep.c b/sys/arch/luna88k/luna88k/machdep.c
index 8c0cbeccf4b..d0d507b1051 100644
--- a/sys/arch/luna88k/luna88k/machdep.c
+++ b/sys/arch/luna88k/luna88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.81 2012/02/28 13:40:53 aoyama Exp $ */
+/* $OpenBSD: machdep.c,v 1.82 2012/10/08 21:47:48 deraadt Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -507,8 +507,8 @@ boot(howto)
dumpsys();
haltsys:
- /* Run any shutdown hooks. */
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
/* Luna88k supports automatic powerdown */
if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c
index 80c0d732f3c..b040a25ff50 100644
--- a/sys/arch/macppc/macppc/machdep.c
+++ b/sys/arch/macppc/macppc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.132 2012/08/21 09:24:52 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.133 2012/10/08 21:47:48 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
@@ -859,6 +859,7 @@ boot(int howto)
splhigh();
if (howto & RB_HALT) {
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
#if NADB > 0
delay(1000000);
@@ -874,6 +875,7 @@ boot(int howto)
if (!cold && (howto & RB_DUMP))
dumpsys();
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
printf("rebooting\n\n");
#if NADB > 0
diff --git a/sys/arch/mvme68k/mvme68k/machdep.c b/sys/arch/mvme68k/mvme68k/machdep.c
index 1a581e127e8..8637f4d21ca 100644
--- a/sys/arch/mvme68k/mvme68k/machdep.c
+++ b/sys/arch/mvme68k/mvme68k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.126 2011/06/26 22:40:00 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.127 2012/10/08 21:47:48 deraadt Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
@@ -491,8 +491,8 @@ boot(howto)
dumpsys();
haltsys:
- /* Run any shutdown hooks. */
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if (howto & RB_HALT) {
printf("System halted. Press any key to reboot...\n\n");
diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c
index b9f8a00027e..0299d413d85 100644
--- a/sys/arch/mvme88k/mvme88k/machdep.c
+++ b/sys/arch/mvme88k/mvme88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.245 2011/10/09 17:01:34 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.246 2012/10/08 21:47:49 deraadt Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -435,8 +435,8 @@ boot(howto)
dumpsys();
haltsys:
- /* Run any shutdown hooks. */
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if (howto & RB_HALT) {
printf("System halted. Press any key to reboot...\n\n");
diff --git a/sys/arch/octeon/octeon/machdep.c b/sys/arch/octeon/octeon/machdep.c
index 3bd4a1532ba..a10c1c8e299 100644
--- a/sys/arch/octeon/octeon/machdep.c
+++ b/sys/arch/octeon/octeon/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.22 2012/10/03 19:42:54 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.23 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -673,6 +673,7 @@ boot(int howto)
haltsys:
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if (howto & RB_HALT) {
if (howto & RB_POWERDOWN)
diff --git a/sys/arch/sgi/sgi/machdep.c b/sys/arch/sgi/sgi/machdep.c
index bb0d256c724..fa106c14917 100644
--- a/sys/arch/sgi/sgi/machdep.c
+++ b/sys/arch/sgi/sgi/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.131 2012/10/03 11:18:23 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.132 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -867,6 +867,7 @@ boot(int howto)
haltsys:
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if (howto & RB_HALT) {
if (howto & RB_POWERDOWN)
diff --git a/sys/arch/socppc/socppc/machdep.c b/sys/arch/socppc/socppc/machdep.c
index 168075f8fac..ca1a710dae5 100644
--- a/sys/arch/socppc/socppc/machdep.c
+++ b/sys/arch/socppc/socppc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.34 2012/03/14 21:56:46 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.35 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
@@ -1067,6 +1067,7 @@ boot(int howto)
splhigh();
if (howto & RB_HALT) {
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
;
}
@@ -1077,6 +1078,7 @@ boot(int howto)
if (!cold && (howto & RB_DUMP))
dumpsys();
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
printf("rebooting\n\n");
{
diff --git a/sys/arch/solbourne/solbourne/machdep.c b/sys/arch/solbourne/solbourne/machdep.c
index 8a9b17f0fb1..642df6c28df 100644
--- a/sys/arch/solbourne/solbourne/machdep.c
+++ b/sys/arch/solbourne/solbourne/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.23 2012/08/22 13:33:32 okan Exp $ */
+/* $OpenBSD: machdep.c,v 1.24 2012/10/08 21:47:50 deraadt Exp $ */
/* OpenBSD: machdep.c,v 1.105 2005/04/11 15:13:01 deraadt Exp */
/*
@@ -564,8 +564,8 @@ boot(howto)
dumpsys();
haltsys:
- /* Run any shutdown hooks */
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if ((howto & RB_HALT) || (howto & RB_POWERDOWN)) {
printf("halted\n\n");
diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c
index e74b9ecc34f..ae8e84a9bcc 100644
--- a/sys/arch/sparc/sparc/machdep.c
+++ b/sys/arch/sparc/sparc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.140 2012/08/22 13:33:32 okan Exp $ */
+/* $OpenBSD: machdep.c,v 1.141 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.85 1997/09/12 08:55:02 pk Exp $ */
/*
@@ -577,8 +577,8 @@ boot(howto)
dumpsys();
haltsys:
- /* Run any shutdown hooks */
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
if ((howto & RB_HALT) || (howto & RB_POWERDOWN)) {
#if defined(SUN4M)
diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c
index 042cbef9c24..e3c4c9095ff 100644
--- a/sys/arch/sparc64/sparc64/machdep.c
+++ b/sys/arch/sparc64/sparc64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.140 2012/08/24 10:00:55 jsg Exp $ */
+/* $OpenBSD: machdep.c,v 1.141 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */
/*-
@@ -670,8 +670,8 @@ boot(howto)
dumpsys();
haltsys:
- /* Run any shutdown hooks. */
doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
/* If powerdown was requested, do it. */
if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
diff --git a/sys/arch/vax/vax/machdep.c b/sys/arch/vax/vax/machdep.c
index 2dd062a5428..fd8ea7d88ee 100644
--- a/sys/arch/vax/vax/machdep.c
+++ b/sys/arch/vax/vax/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.121 2012/03/24 19:09:20 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.122 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.108 2000/09/13 15:00:23 thorpej Exp $ */
/*
@@ -546,10 +546,11 @@ boot(howto)
if (howto & RB_DUMP)
dumpsys();
- /* Run any shutdown hooks. */
- doshutdownhooks();
haltsys:
+ doshutdownhooks();
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
+
if (howto & RB_HALT) {
if (dep_call->cpu_halt)
(*dep_call->cpu_halt) ();
diff --git a/sys/arch/zaurus/dev/zaurus_apm.c b/sys/arch/zaurus/dev/zaurus_apm.c
index fdcd91475f0..7c026d7c513 100644
--- a/sys/arch/zaurus/dev/zaurus_apm.c
+++ b/sys/arch/zaurus/dev/zaurus_apm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zaurus_apm.c,v 1.20 2010/09/07 16:21:41 deraadt Exp $ */
+/* $OpenBSD: zaurus_apm.c,v 1.21 2012/10/08 21:47:50 deraadt Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
@@ -24,6 +24,7 @@
#include <sys/proc.h>
#include <sys/buf.h>
#include <sys/sysctl.h>
+#include <sys/reboot.h>
#include <arm/xscale/pxa2x0reg.h>
#include <arm/xscale/pxa2x0var.h>
@@ -654,6 +655,10 @@ zapm_poweroff(void)
s = splhigh();
config_suspend(TAILQ_FIRST(&alldevs), DVACT_SUSPEND);
+ boothowto |= RB_POWERDOWN;
+ config_suspend(TAILQ_FIRST(&alldevs), DVACT_POWERDOWN);
+ boothowto &= ~RB_POWERDOWN;
+
/* XXX enable charging during suspend */
/* XXX keep power LED state during suspend */
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;
diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c
index d43827e8db4..ff5c4313db9 100644
--- a/sys/kern/subr_autoconf.c
+++ b/sys/kern/subr_autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_autoconf.c,v 1.66 2011/07/03 15:47:16 matthew Exp $ */
+/* $OpenBSD: subr_autoconf.c,v 1.67 2012/10/08 21:47:50 deraadt Exp $ */
/* $NetBSD: subr_autoconf.c,v 1.21 1996/04/04 06:06:18 cgd Exp $ */
/*
@@ -802,6 +802,7 @@ config_activate_children(struct device *parent, int act)
case DVACT_SUSPEND:
case DVACT_RESUME:
case DVACT_QUIESCE:
+ case DVACT_POWERDOWN:
rv = config_suspend(d, act);
break;
case DVACT_DEACTIVATE:
@@ -822,6 +823,8 @@ config_activate_children(struct device *parent, int act)
#endif
if (act == DVACT_RESUME)
printf("failing resume cannot be handled\n");
+ if (act == DVACT_POWERDOWN)
+ return (rv);
if (act != DVACT_SUSPEND)
return (rv);
diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c
index 7ab9a02d207..c503a5a10ef 100644
--- a/sys/scsi/scsiconf.c
+++ b/sys/scsi/scsiconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.c,v 1.182 2011/09/22 21:36:00 jsing Exp $ */
+/* $OpenBSD: scsiconf.c,v 1.183 2012/10/08 21:47:51 deraadt Exp $ */
/* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */
/*
@@ -251,6 +251,7 @@ scsi_activate_lun(struct scsibus_softc *sc, int target, int lun, int act)
case DVACT_QUIESCE:
case DVACT_SUSPEND:
case DVACT_RESUME:
+ case DVACT_POWERDOWN:
config_suspend(dev, act);
break;
case DVACT_DEACTIVATE:
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 0cb8b51a30a..3b3aeeab7aa 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sd.c,v 1.242 2012/07/09 12:58:01 krw Exp $ */
+/* $OpenBSD: sd.c,v 1.243 2012/10/08 21:47:51 deraadt Exp $ */
/* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */
/*-
@@ -87,7 +87,6 @@ int sddetach(struct device *, int);
void sdminphys(struct buf *);
int sdgetdisklabel(dev_t, struct sd_softc *, struct disklabel *, int);
void sdstart(struct scsi_xfer *);
-void sd_shutdown(void *);
int sd_interpret_sense(struct scsi_xfer *);
int sd_read_cap_10(struct sd_softc *, int);
int sd_read_cap_16(struct sd_softc *, int);
@@ -260,19 +259,6 @@ sdattach(struct device *parent, struct device *self, void *aux)
sd_ioctl_cache(sc, DIOCSCACHE, &dkc);
}
- /*
- * Establish a shutdown hook so that we can ensure that
- * our data has actually made it onto the platter at
- * shutdown time. Note that this relies on the fact
- * that the shutdown hook code puts us at the head of
- * the list (thus guaranteeing that our hook runs before
- * our ancestors').
- */
- if ((sc->sc_sdhook =
- shutdownhook_establish(sd_shutdown, sc)) == NULL)
- printf("%s: WARNING: unable to establish shutdown hook\n",
- sc->sc_dev.dv_xname);
-
/* Attach disk. */
disk_attach(&sc->sc_dev, &sc->sc_dk);
}
@@ -285,6 +271,8 @@ sdactivate(struct device *self, int act)
switch (act) {
case DVACT_SUSPEND:
+ break;
+ case DVACT_POWERDOWN:
/*
* Stop the disk. Stopping the disk should flush the
* cache, but we are paranoid so we flush the cache
@@ -292,8 +280,9 @@ sdactivate(struct device *self, int act)
*/
if ((sc->flags & SDF_DIRTY) != 0)
sd_flush(sc, SCSI_AUTOCONF);
- scsi_start(sc->sc_link, SSS_STOP,
- SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_AUTOCONF);
+ if (boothowto & RB_POWERDOWN)
+ scsi_start(sc->sc_link, SSS_STOP,
+ SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_AUTOCONF);
break;
case DVACT_RESUME:
scsi_start(sc->sc_link, SSS_START,
@@ -316,10 +305,6 @@ sddetach(struct device *self, int flags)
disk_gone(sdopen, 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);
@@ -1118,31 +1103,6 @@ sdgetdisklabel(dev_t dev, struct sd_softc *sc, struct disklabel *lp,
return readdisklabel(DISKLABELDEV(dev), sdstrategy, lp, spoofonly);
}
-
-void
-sd_shutdown(void *arg)
-{
- struct sd_softc *sc = (struct sd_softc *)arg;
-
- /*
- * If the disk cache needs to be flushed, and the disk supports
- * it, flush it. We're cold at this point, so we poll for
- * completion.
- */
- if ((sc->flags & SDF_DIRTY) != 0)
- sd_flush(sc, SCSI_AUTOCONF);
- if (boothowto & RB_POWERDOWN)
- scsi_start(sc->sc_link, SSS_STOP,
- SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_AUTOCONF);
-
- /*
- * There should be no outstanding IO at this point, but lets stop
- * it just in case.
- */
- timeout_del(&sc->sc_timeout);
- scsi_xsh_del(&sc->sc_xsh);
-}
-
/*
* Check Errors
*/
diff --git a/sys/scsi/sdvar.h b/sys/scsi/sdvar.h
index f723a7e9729..4e2accdfde1 100644
--- a/sys/scsi/sdvar.h
+++ b/sys/scsi/sdvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdvar.h,v 1.38 2011/07/11 06:26:09 dlg Exp $ */
+/* $OpenBSD: sdvar.h,v 1.39 2012/10/08 21:47:51 deraadt Exp $ */
/* $NetBSD: sdvar.h,v 1.7 1998/08/17 00:49:03 mycroft Exp $ */
/*-
@@ -69,7 +69,6 @@ struct sd_softc {
u_int32_t unmap_sectors; /* maximum sectors/unmap */
u_int32_t unmap_descs; /* maximum descriptors/unmap */
} params;
- void *sc_sdhook; /* our shutdown hook */
struct timeout sc_timeout;
struct scsi_xshandler sc_xsh;
diff --git a/sys/sys/device.h b/sys/sys/device.h
index ac75c800081..8ef70a0191f 100644
--- a/sys/sys/device.h
+++ b/sys/sys/device.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: device.h,v 1.44 2011/07/03 15:47:16 matthew Exp $ */
+/* $OpenBSD: device.h,v 1.45 2012/10/08 21:47:51 deraadt Exp $ */
/* $NetBSD: device.h,v 1.15 1996/04/09 20:55:24 cgd Exp $ */
/*
@@ -66,6 +66,7 @@ enum devclass {
#define DVACT_SUSPEND 2 /* suspend the device */
#define DVACT_RESUME 3 /* resume the device */
#define DVACT_QUIESCE 4 /* warn the device about suspend */
+#define DVACT_POWERDOWN 5 /* power device down */
struct device {
enum devclass dv_class; /* this device's classification */