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.
This commit is contained in:
parent
d8c4fc9544
commit
0aa12b3498
|
@ -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 @@ apm_suspend(struct apm_softc *sc)
|
|||
|
||||
if (error)
|
||||
apm_resume(sc, 0, 0);
|
||||
else
|
||||
apm_resume(sc, APM_SYS_STANDBY_RESUME, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -341,12 +343,13 @@ apm_standby(struct apm_softc *sc)
|
|||
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 @@ apm_event_handle(struct apm_softc *sc, u_int event_code, u_int event_info)
|
|||
|
||||
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 @@ apm_event_handle(struct apm_softc *sc, u_int event_code, u_int event_info)
|
|||
|
||||
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 */
|
||||
|
|
Loading…
Reference in New Issue