Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/apm Fix apm(4) suspend/resume:
details: https://anonhg.NetBSD.org/src/rev/a227f8982e21
branches: trunk
changeset: 752903:a227f8982e21
user: bouyer <bouyer%NetBSD.org@localhost>
date: Wed Mar 10 20:30:00 2010 +0000
description:
Fix apm(4) suspend/resume:
- apm_suspend() and apm_standby() will call splhhigh() before entering
standby or suspend. After resume, the system go back tsleep()ing
in the apm thread without restoring the ipl (this is done in
apm_resume()), and calling tlseep() at IPL_HIGH cause a DIAGNOSTIC
panic (and other bad things, I guess).
Fix by calling apm_resume() from within apm_suspend() or apm_standby(),
after aa_set_powstate() has returned.
- In apm_event_handle(), we test (apm_standbys || apm_suspends) to set
apm_damn_fool_bios to 1 and break the while() loop in apm_periodic_check().
But we set apm_standbys or apm_suspends to non-0 only if apm_op_inprog
is 0 and we failed to record the apm event. With apmd listening
we usually succeed recording the event, so apm_standbys/apm_suspends remains
0 and we never go out of the while() loop.
Fix by apm_op_inprog instead of (apm_standbys || apm_suspends)
to break the loop.
diffstat:
sys/dev/apm/apm.c | 13 ++++++++-----
1 files changed, 8 insertions(+), 5 deletions(-)
diffs (60 lines):
diff -r e9e0e00e239e -r a227f8982e21 sys/dev/apm/apm.c
--- a/sys/dev/apm/apm.c Wed Mar 10 19:23:57 2010 +0000
+++ b/sys/dev/apm/apm.c Wed Mar 10 20:30:00 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: apm.c,v 1.25 2009/11/23 02:13:45 rmind Exp $ */
+/* $NetBSD: apm.c,v 1.26 2010/03/10 20:30:00 bouyer Exp $ */
/*-
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apm.c,v 1.25 2009/11/23 02:13:45 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apm.c,v 1.26 2010/03/10 20:30:00 bouyer Exp $");
#include "opt_apm.h"
@@ -317,6 +317,8 @@
if (error)
apm_resume(sc, 0, 0);
+ else
+ apm_resume(sc, APM_SYS_STANDBY_RESUME, 0);
}
static void
@@ -341,12 +343,13 @@
APM_SYS_STANDBY);
if (error)
apm_resume(sc, 0, 0);
+ else
+ apm_resume(sc, APM_SYS_STANDBY_RESUME, 0);
}
static void
apm_resume(struct apm_softc *sc, u_int event_type, u_int event_info)
{
-
if (sc->sc_power_state == PWR_RESUME) {
#ifdef APMDEBUG
aprint_debug_dev(sc->sc_dev, "apm_resume: already running?\n");
@@ -420,7 +423,7 @@
case APM_STANDBY_REQ:
DPRINTF(APMDEBUG_EVENTS, ("apmev: system standby request\n"));
- if (apm_standbys || apm_suspends) {
+ if (apm_op_inprog) {
DPRINTF(APMDEBUG_EVENTS | APMDEBUG_ANOM,
("damn fool BIOS did not wait for answer\n"));
/* just give up the fight */
@@ -452,7 +455,7 @@
case APM_SUSPEND_REQ:
DPRINTF(APMDEBUG_EVENTS, ("apmev: system suspend request\n"));
- if (apm_standbys || apm_suspends) {
+ if (apm_op_inprog) {
DPRINTF(APMDEBUG_EVENTS | APMDEBUG_ANOM,
("damn fool BIOS did not wait for answer\n"));
/* just give up the fight */
Home |
Main Index |
Thread Index |
Old Index