freebsd-dev/sys/i386/bios/apm.h
Warner Losh d708737568 APM was calling the suspend process from a timeout. This meant that
other timeouts could not happen while suspending, including timeouts
for things like msleep.  This caused the system to hang on suspend
when the cbb was enabled, since its suspend path powered down the
socket which used a timeout to wait for it to be done.

APM now creates a thread when it is enabled, and deletes the thread
when it is disabled.  This thread takes the place of the timeout by
doing its polling every ~.9s.  When the thread is disabled, it will
wakeup early, otherwise it times out and polls the varius things the
old timeout polled (APM events, suspend delays, etc).

This makes my Sony VAIO 505TS suspend/resume correctly when APM is
enabled (ACPI is black listed on my 505TS).

This will likely fix other problems with the suspend path where
drivers would sleep with msleep and/or do other timeouts.  Maybe
there's some special case code that would use DELAY while suspending
and msleep otherwise that can be revisited and removed.

This was also tested by glebius@, who pointed out that in the patch I
sent him, I'd forgotten apm_saver.c

MFC After: 3 weeks
2006-05-25 23:06:38 +00:00

54 lines
1.5 KiB
C

/*-
* APM (Advanced Power Management) BIOS Device Driver
*
* Copyright (c) 1994 UKAI, Fumitoshi.
* Copyright (c) 1994-1995 by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org>
* Copyright (c) 1996 Nate Williams <nate@FreeBSD.org>
* Copyright (c) 1997 Poul-Henning Kamp <phk@FreeBSD.org>
*
* This software may be used, modified, copied, and distributed, in
* both source and binary form provided that the above copyright and
* these terms are retained. Under no circumstances is the author
* responsible for the proper functioning of this software, nor does
* the author assume any responsibility for damages incurred with its
* use.
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
* $FreeBSD$
*/
#define APM_NEVENTS 16
#define APM_NPMEV 13
#define APM_UNKNOWN 0xff
/* static data */
struct apm_softc {
#ifdef PC98
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
struct resource *sc_res;
#endif
struct mtx mtx;
struct cv cv;
struct proc *event_thread;
int initialized, active, running, bios_busy;
int always_halt_cpu, slow_idle_cpu;
int disabled, disengaged;
int suspending;
int standby_countdown, suspend_countdown;
u_int minorversion, majorversion;
u_int intversion, connectmode;
u_int standbys, suspends;
struct bios_args bios;
struct apmhook sc_suspend;
struct apmhook sc_resume;
struct selinfo sc_rsel;
int sc_flags;
int event_count;
int event_ptr;
struct apm_event_info event_list[APM_NEVENTS];
u_char event_filter[APM_NPMEV];
};