Module Name:    src
Committed By:   bouyer
Date:           Wed Mar 10 20:30:00 UTC 2010

Modified Files:
        src/sys/dev/apm: apm.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/sys/dev/apm/apm.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/apm/apm.c
diff -u src/sys/dev/apm/apm.c:1.25 src/sys/dev/apm/apm.c:1.26
--- src/sys/dev/apm/apm.c:1.25	Mon Nov 23 02:13:45 2009
+++ src/sys/dev/apm/apm.c	Wed Mar 10 20:30:00 2010
@@ -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 */

Reply via email to