Index: ObsoleteFiles.inc =================================================================== --- ObsoleteFiles.inc +++ ObsoleteFiles.inc @@ -36,6 +36,15 @@ # xargs -n1 | sort | uniq -d; # done +# 20200916: Remove apm +OLD_FILES+=etc/rc.d/apm +OLD_FILES+=etc/rc.d/apmd +OLD_FILES+=etc/apmd.conf +OLD_FILES+=usr/sbin/apmd +OLD_FILES+=usr/share/examples/etc/apmd.conf +OLD_FILES+=usr/share/man/man4/man4.i386/apm.4.gz +OLD_FILES+=usr/share/man/man8/apmconf.8.gz + # 20200910: remove vm_map_create(9) to sync with the code OLD_FILES+=usr/share/man/man9/vm_map_create.9.gz Index: libexec/rc/rc.d/Makefile =================================================================== --- libexec/rc/rc.d/Makefile +++ libexec/rc/rc.d/Makefile @@ -136,19 +136,10 @@ ACPIPACKAGE= acpi .endif -.if ${MK_ACPI} != "no" || ${MK_APM} != "no" +.if ${MK_ACPI} != "no" CONFS+= powerd .endif -.if ${MK_APM} != "no" -CONFGROUPS+= APM -APM+= apm -.if ${MACHINE} == "i386" -APM+= apmd -.endif -APMPACKAGE= apm -.endif - .if ${MK_AUDIT} != "no" CONFGROUPS+= AUDIT AUDIT+= auditd Index: libexec/rc/rc.d/apm =================================================================== --- libexec/rc/rc.d/apm +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ -# - -# PROVIDE: apm -# REQUIRE: DAEMON -# BEFORE: LOGIN -# KEYWORD: nojail - -. /etc/rc.subr - -name="apm" -desc="Advanced power management" -rcvar="apm_enable" -start_precmd="apm_precmd" -command="/usr/sbin/${name}" -start_cmd="${command} -e enable" -stop_cmd="${command} -e disable" -status_cmd="apm_status" - -apm_precmd() -{ - case `${SYSCTL_N} hw.machine_arch` in - i386) - return 0 - ;; - esac - return 1 -} - -apm_status() -{ - case `${command} -s` in - 1) - echo "APM is enabled." - return 0 - ;; - 0) - echo "APM is disabled" - ;; - esac - return 1 -} - -load_rc_config $name -run_rc_command "$1" Index: libexec/rc/rc.d/apmd =================================================================== --- libexec/rc/rc.d/apmd +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ -# - -# PROVIDE: apmd -# REQUIRE: DAEMON apm -# BEFORE: LOGIN -# KEYWORD: nojail shutdown - -. /etc/rc.subr - -name="apmd" -desc="Advanced power management daemon" -rcvar="apmd_enable" -command="/usr/sbin/${name}" -start_precmd="apmd_prestart" - -apmd_prestart() -{ - case `${SYSCTL_N} hw.machine_arch` in - i386) - force_depend apm || return 1 - - # Warn user about acpi apm compatibility support which - # does not work with apmd. - if [ ! -e /dev/apmctl ]; then - warn "/dev/apmctl not found; kernel is missing apm(4)" - fi - ;; - *) - return 1 - ;; - esac -} - -load_rc_config $name -run_rc_command "$1" Index: release/packages/Makefile.package =================================================================== --- release/packages/Makefile.package +++ release/packages/Makefile.package @@ -8,8 +8,6 @@ acpi_DESC= ACPI Utilities amd_COMMENT= AMD Utilities amd_DESC= AMD Utilities -apm_COMMENT= APM Utilities -apm_DESC= APM Utilities at_COMMENT= AT Utilities at_DESC= AT Utilities autofs_COMMENT= Autofs Utilities Index: share/man/man4/man4.i386/Makefile =================================================================== --- share/man/man4/man4.i386/Makefile +++ share/man/man4/man4.i386/Makefile @@ -1,7 +1,6 @@ # $FreeBSD$ -MAN= apm.4 \ - ce.4 \ +MAN= ce.4 \ cp.4 \ CPU_ELAN.4 \ glxiic.4 \ Index: share/man/man4/man4.i386/apm.4 =================================================================== --- share/man/man4/man4.i386/apm.4 +++ /dev/null @@ -1,161 +0,0 @@ -.\" LP (Laptop Package) -.\" -.\" Copyright (c) 1994 by HOSOKAWA, Tatsumi -.\" -.\" 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. -.\" -.\" $FreeBSD$ -.\" -.Dd November 1, 1994 -.Dt APM 4 i386 -.Os -.Sh NAME -.Nm apm -.Nd APM BIOS interface -.Sh SYNOPSIS -.Cd device apm -.Sh DEPRECATION NOTICE -This driver is scheduled for removal prior to the release of -.Fx 13.0 . -.Sh DESCRIPTION -.Nm -is an interface to the Intel / Microsoft APM (Advanced Power Management) BIOS -on laptop PCs. -.Pp -.Nm -provides the following power management functions. -.Bl -enum -offset indent -.It -When the system wakes up from suspended mode, -.Nm -adjusts the system clock to RTC. -.It -When the system wakes up from suspended mode, -.Nm -passes a message to -.Xr syslogd 8 -comprising of system wakeup time and elapsed time during suspended mode. -.It -.Nm -slows CPU clock when there are no system activities (runnable processes, -interrupts, etc.). -This function is available only on systems whose APM -supports CPU idling. -.It -.Nm -exports an application interface as a character device. -Applications -can control APM, or retrieve APM status information via this interface. -.Nm -exports the following interfaces. -These symbols are defined in -.In machine/apm_bios.h . -.Bl -tag -width 4n -offset indent -.It Sy APMIO_SUSPEND -Suspend system. -.It Sy APMIO_GET -Get power management information. -.It Sy APMIO_ENABLE -.It Sy APMIO_DISABLE -Enable / Disable power management. -.It Sy APMIO_HALTCPU -.It Sy APMIO_NOTHALTCPU -Control execution of HLT in the kernel context switch routine. -.It Sy APMIO_GETPWSTATUS -Get per battery information. -.Pp -Some APM implementations execute the HLT -(Halt CPU until an interrupt occurs) -instruction in the -.Dq Em Idle CPU -call, while others do not. -Thus enabling this may result in -redundant HLT executions because -.Dq Em Idle CPU -is called from the kernel context switch routine that inherently executes -HLT. -This may reduce peak system performance. -.Pp -Also the system hangs up if HLT instruction is disabled in the kernel -context switch routine, and if the APM implementation of the machine -does not execute HLT in -.Dq Em Idle CPU . -On some implementations that do not support CPU clock slowdown, APM -might not execute HLT. -.Nm -disables -.Sy APMIO_NOTHALTCPU -operation on such machines. -.Pp -The current version of -.Nm -does not call -.Dq Em Idle CPU -from the kernel context switch routine if clock slowdown is not supported, -and it executes HLT instruction by default. -Therefore, there is -no need to use these two operations in most cases. -.El -.Pp -These interfaces are used by -.Xr apm 8 . -.It -.Nm -polls APM events and handles the following events. -.Bl -column "xxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxx" "xxxxxxxx" -.It Sy "Name" Ta Sy "Action" Ta Sy "Description" -.It Dv "PMEV_STANDBYREQ" Ta No "suspend system" Ta "standby request" -.It Dv "PMEV_SUSPENDREQ" Ta No "suspend system" Ta "suspend request" -.It Dv "PMEV_USERSUSPENDREQ" Ta No "suspend system" Ta "user suspend request" -.It Dv "PMEV_CRITSUSPEND" Ta No "suspend system" Ta "critical suspend request" -.It Dv "PMEV_NORMRESUME" Ta No "resume system" Ta "normal resume" -.It Dv "PMEV_CRITRESUME" Ta No "resume system" Ta "critical resume" -.It Dv "PMEV_STANDBYRESUME" Ta No "resume system" Ta "standby resume" -.It Dv "PMEV_BATTERYLOW" Ta No "notify message" Ta "battery low" -.It Dv "PMEV_UPDATETIME" Ta No "adjust clock" Ta "update time" -.El -.El -.Sh SEE ALSO -.Xr apm 8 , -.Xr zzz 8 -.Sh AUTHORS -.An Tatsumi Hosokawa Aq Mt hosokawa@jp.FreeBSD.org -.Sh BUGS -WARNING! -Many, if not most, of the implementations of APM-bios in laptops -today are buggy. -You may be putting your LCD-display and batteries at -a risk by using this interface. -(The reason this is not a problem for -MS-Windows is that they use the real-mode interface.) -If you see any -weird behavior from your system with this code in use, unplug the -power and batteries ASAP, if not immediately, and disable this code. -.Pp -We are very interested in getting this code working, so please send your -observations of any anomalous behavior to us. -.Pp -When -.Nm -is active, calling the BIOS setup routine by using hot-keys, -may cause serious trouble when resuming the system. -BIOS setup programs should be called during bootstrap, or from DOS. -.Pp -Some APM implementations cannot handle events such as pushing the -power button or closing the cover. -On such implementations, the system -.Ar must -be suspended -.Ar only -by using -.Xr apm 8 -or -.Xr zzz 8 . -.Pp -Disk spin-down, LCD backlight control, and power on demand have not -been supported on the current version. Index: share/mk/src.opts.mk =================================================================== --- share/mk/src.opts.mk +++ share/mk/src.opts.mk @@ -55,7 +55,6 @@ __DEFAULT_YES_OPTIONS = \ ACCT \ ACPI \ - APM \ AT \ ATM \ AUDIT \ Index: sys/conf/files.amd64 =================================================================== --- sys/conf/files.amd64 +++ sys/conf/files.amd64 @@ -357,7 +357,6 @@ dev/speaker/spkr.c optional speaker dev/sume/if_sume.c optional sume dev/superio/superio.c optional superio isa -dev/syscons/apm/apm_saver.c optional apm_saver apm dev/syscons/scvesactl.c optional sc vga vesa dev/syscons/scvgarndr.c optional sc vga dev/tpm/tpm.c optional tpm Index: sys/conf/files.i386 =================================================================== --- sys/conf/files.i386 +++ sys/conf/files.i386 @@ -119,7 +119,6 @@ dev/sbni/if_sbni_pci.c optional sbni pci dev/speaker/spkr.c optional speaker dev/superio/superio.c optional superio isa -dev/syscons/apm/apm_saver.c optional apm_saver apm dev/syscons/scvesactl.c optional sc vga vesa dev/syscons/scvgarndr.c optional sc vga dev/tpm/tpm.c optional tpm @@ -163,7 +162,6 @@ no-obj no-implicit-rule before-depend \ clean "acpi_wakedata.h" # -i386/bios/apm.c optional apm i386/bios/smapi.c optional smapi i386/bios/smapi_bios.S optional smapi i386/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32 Index: sys/dev/syscons/apm/apm_saver.c =================================================================== --- sys/dev/syscons/apm/apm_saver.c +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1999 Nick Sayer (who stole shamelessly from blank_saver) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -extern int apm_display(int newstate); - -extern struct apm_softc apm_softc; - -static int blanked=0; - -static int -apm_saver(video_adapter_t *adp, int blank) -{ - if (!apm_softc.initialized || !apm_softc.active) - return 0; - - if (blank==blanked) - return 0; - - blanked=blank; - - apm_display(!blanked); - - return 0; -} - -static int -apm_init(video_adapter_t *adp) -{ - if (!apm_softc.initialized || !apm_softc.active) - printf("WARNING: apm_saver module requires apm enabled\n"); - return 0; -} - -static int -apm_term(video_adapter_t *adp) -{ - return 0; -} - -static scrn_saver_t apm_module = { - "apm_saver", apm_init, apm_term, apm_saver, NULL, -}; - -SAVER_MODULE(apm_saver, apm_module); -MODULE_DEPEND(apm_saver, apm, 1, 1, 1); Index: sys/i386/bios/apm.h =================================================================== --- sys/i386/bios/apm.h +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * APM (Advanced Power Management) BIOS Device Driver - * - * Copyright (c) 1994 UKAI, Fumitoshi. - * Copyright (c) 1994-1995 by HOSOKAWA, Tatsumi - * Copyright (c) 1996 Nate Williams - * Copyright (c) 1997 Poul-Henning Kamp - * - * 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$ - */ - -#ifndef __APM_H__ -#define __APM_H__ - -#define APM_NEVENTS 16 -#define APM_NPMEV 13 -#define APM_UNKNOWN 0xff - -/* static data */ -struct apm_softc { - 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]; -}; - -#endif /* !__APM_H__ */ Index: sys/i386/bios/apm.c =================================================================== --- sys/i386/bios/apm.c +++ /dev/null @@ -1,1526 +0,0 @@ -/*- - * APM (Advanced Power Management) BIOS Device Driver - * - * Copyright (c) 1994 UKAI, Fumitoshi. - * Copyright (c) 1994-1995 by HOSOKAWA, Tatsumi - * Copyright (c) 1996 Nate Williams - * Copyright (c) 1997 Poul-Henning Kamp - * - * 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) - */ - -/*- - * Copyright (c) 2000 Mitsuru IWASAKI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -/* Used by the apm_saver screen saver module */ -int apm_display(int newstate); -struct apm_softc apm_softc; - -static void apm_resume(void); -static int apm_bioscall(void); -static int apm_check_function_supported(u_int version, u_int func); - -static int apm_pm_func(u_long, void*, ...); - -static u_long apm_version; - -int apm_evindex; - -#define SCFLAG_ONORMAL 0x0000001 -#define SCFLAG_OCTL 0x0000002 -#define SCFLAG_OPEN (SCFLAG_ONORMAL|SCFLAG_OCTL) - -#define APMDEV_NORMAL 0 -#define APMDEV_CTL 1 - -static struct apmhook *hook[NAPM_HOOK]; /* XXX */ - -#define is_enabled(foo) ((foo) ? "enabled" : "disabled") - -/* Map version number to integer (keeps ordering of version numbers) */ -#define INTVERSION(major, minor) ((major)*100 + (minor)) - -static d_open_t apmopen; -static d_close_t apmclose; -static d_write_t apmwrite; -static d_ioctl_t apmioctl; -static d_poll_t apmpoll; - -static struct cdevsw apm_cdevsw = { - .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, - .d_open = apmopen, - .d_close = apmclose, - .d_write = apmwrite, - .d_ioctl = apmioctl, - .d_poll = apmpoll, - .d_name = "apm", -}; - -static int apm_suspend_delay = 1; -static int apm_standby_delay = 1; -static int apm_swab_batt_minutes = 0; -static int apm_debug = 0; - -#define APM_DPRINT(args...) do { \ - if (apm_debug) { \ - printf(args); \ - } \ -} while (0) - -SYSCTL_INT(_machdep, OID_AUTO, apm_suspend_delay, CTLFLAG_RW, &apm_suspend_delay, 1, ""); -SYSCTL_INT(_machdep, OID_AUTO, apm_standby_delay, CTLFLAG_RW, &apm_standby_delay, 1, ""); -SYSCTL_INT(_debug, OID_AUTO, apm_debug, CTLFLAG_RW, &apm_debug, 0, ""); - -SYSCTL_INT(_machdep, OID_AUTO, apm_swab_batt_minutes, CTLFLAG_RWTUN, - &apm_swab_batt_minutes, 0, "Byte swap battery time value."); - -/* - * return 0 if the function successfull, - * return 1 if the function unsuccessfull, - * return -1 if the function unsupported. - */ -static int -apm_bioscall(void) -{ - struct apm_softc *sc = &apm_softc; - int errno = 0; - u_int apm_func = sc->bios.r.eax & 0xff; - - if (!apm_check_function_supported(sc->intversion, apm_func)) { - APM_DPRINT("apm_bioscall: function 0x%x is not supported in v%d.%d\n", - apm_func, sc->majorversion, sc->minorversion); - return (-1); - } - - sc->bios_busy = 1; - if (sc->connectmode == APM_PROT32CONNECT) { - set_bios_selectors(&sc->bios.seg, - BIOSCODE_FLAG | BIOSDATA_FLAG); - errno = bios32(&sc->bios.r, - sc->bios.entry, GSEL(GBIOSCODE32_SEL, SEL_KPL)); - } else { - errno = bios16(&sc->bios, NULL); - } - sc->bios_busy = 0; - return (errno); -} - -/* check whether APM function is supported (1) or not (0). */ -static int -apm_check_function_supported(u_int version, u_int func) -{ - /* except driver version */ - if (func == APM_DRVVERSION) { - return (1); - } - - switch (version) { - case INTVERSION(1, 0): - if (func > APM_GETPMEVENT) { - return (0); /* not supported */ - } - break; - case INTVERSION(1, 1): - if (func > APM_ENGAGEDISENGAGEPM && - func < APM_OEMFUNC) { - return (0); /* not supported */ - } - break; - case INTVERSION(1, 2): - break; - } - - return (1); /* supported */ -} - -/* enable/disable power management */ -static int -apm_enable_disable_pm(int enable) -{ - struct apm_softc *sc = &apm_softc; - - sc->bios.r.eax = (APM_BIOS << 8) | APM_ENABLEDISABLEPM; - - if (sc->intversion >= INTVERSION(1, 1)) - sc->bios.r.ebx = PMDV_ALLDEV; - else - sc->bios.r.ebx = 0xffff; /* APM version 1.0 only */ - sc->bios.r.ecx = enable; - sc->bios.r.edx = 0; - return (apm_bioscall()); -} - -/* register driver version (APM 1.1 or later) */ -static int -apm_driver_version(int version) -{ - struct apm_softc *sc = &apm_softc; - - sc->bios.r.eax = (APM_BIOS << 8) | APM_DRVVERSION; - sc->bios.r.ebx = 0x0; - sc->bios.r.ecx = version; - sc->bios.r.edx = 0; - - if (apm_bioscall() == 0 && sc->bios.r.eax == version) - return (0); - - /* Some old BIOSes don't return the connection version in %ax. */ - if (sc->bios.r.eax == ((APM_BIOS << 8) | APM_DRVVERSION)) - return (0); - - return (1); -} - -/* engage/disengage power management (APM 1.1 or later) */ -static int -apm_engage_disengage_pm(int engage) -{ - struct apm_softc *sc = &apm_softc; - - sc->bios.r.eax = (APM_BIOS << 8) | APM_ENGAGEDISENGAGEPM; - sc->bios.r.ebx = PMDV_ALLDEV; - sc->bios.r.ecx = engage; - sc->bios.r.edx = 0; - return (apm_bioscall()); -} - -/* get PM event */ -static u_int -apm_getevent(void) -{ - struct apm_softc *sc = &apm_softc; - - sc->bios.r.eax = (APM_BIOS << 8) | APM_GETPMEVENT; - - sc->bios.r.ebx = 0; - sc->bios.r.ecx = 0; - sc->bios.r.edx = 0; - if (apm_bioscall()) - return (PMEV_NOEVENT); - return (sc->bios.r.ebx & 0xffff); -} - -/* suspend entire system */ -static int -apm_suspend_system(int state) -{ - struct apm_softc *sc = &apm_softc; - - sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE; - sc->bios.r.ebx = PMDV_ALLDEV; - sc->bios.r.ecx = state; - sc->bios.r.edx = 0; - - if (apm_bioscall()) { - printf("Entire system suspend failure: errcode = %d\n", - 0xff & (sc->bios.r.eax >> 8)); - return 1; - } - - return 0; -} - -/* Display control */ -/* - * Experimental implementation: My laptop machine can't handle this function - * If your laptop can control the display via APM, please inform me. - * HOSOKAWA, Tatsumi - */ -int -apm_display(int newstate) -{ - struct apm_softc *sc = &apm_softc; - - sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE; - sc->bios.r.ebx = PMDV_DISP0; - sc->bios.r.ecx = newstate ? PMST_APMENABLED:PMST_SUSPEND; - sc->bios.r.edx = 0; - if (apm_bioscall() == 0) { - return 0; - } - - /* If failed, then try to blank all display devices instead. */ - sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE; - sc->bios.r.ebx = PMDV_DISPALL; /* all display devices */ - sc->bios.r.ecx = newstate ? PMST_APMENABLED:PMST_SUSPEND; - sc->bios.r.edx = 0; - if (apm_bioscall() == 0) { - return 0; - } - printf("Display off failure: errcode = %d\n", - 0xff & (sc->bios.r.eax >> 8)); - return 1; -} - -/* - * Turn off the entire system. - */ -static void -apm_power_off(void *junk, int howto) -{ - struct apm_softc *sc = &apm_softc; - - /* Not halting powering off, or not active */ - if (!(howto & RB_POWEROFF) || !apm_softc.active) - return; - sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE; - sc->bios.r.ebx = PMDV_ALLDEV; - sc->bios.r.ecx = PMST_OFF; - sc->bios.r.edx = 0; - (void) apm_bioscall(); -} - -/* APM Battery low handler */ -static void -apm_battery_low(void) -{ - printf("\007\007 * * * BATTERY IS LOW * * * \007\007"); -} - -/* APM hook manager */ -static struct apmhook * -apm_add_hook(struct apmhook **list, struct apmhook *ah) -{ - struct apmhook *p, *prev; - - APM_DPRINT("Add hook \"%s\"\n", ah->ah_name); - - if (ah == NULL) - panic("illegal apm_hook!"); - prev = NULL; - for (p = *list; p != NULL; prev = p, p = p->ah_next) - if (p->ah_order > ah->ah_order) - break; - - if (prev == NULL) { - ah->ah_next = *list; - *list = ah; - } else { - ah->ah_next = prev->ah_next; - prev->ah_next = ah; - } - return ah; -} - -static void -apm_del_hook(struct apmhook **list, struct apmhook *ah) -{ - struct apmhook *p, *prev; - - prev = NULL; - for (p = *list; p != NULL; prev = p, p = p->ah_next) - if (p == ah) - goto deleteit; - panic("Tried to delete unregistered apm_hook."); - return; -deleteit: - if (prev != NULL) - prev->ah_next = p->ah_next; - else - *list = p->ah_next; -} - -/* APM driver calls some functions automatically */ -static void -apm_execute_hook(struct apmhook *list) -{ - struct apmhook *p; - - for (p = list; p != NULL; p = p->ah_next) { - APM_DPRINT("Execute APM hook \"%s.\"\n", p->ah_name); - if ((*(p->ah_fun))(p->ah_arg)) - printf("Warning: APM hook \"%s\" failed", p->ah_name); - } -} - -/* establish an apm hook */ -struct apmhook * -apm_hook_establish(int apmh, struct apmhook *ah) -{ - if (apmh < 0 || apmh >= NAPM_HOOK) - return NULL; - - return apm_add_hook(&hook[apmh], ah); -} - -/* disestablish an apm hook */ -void -apm_hook_disestablish(int apmh, struct apmhook *ah) -{ - if (apmh < 0 || apmh >= NAPM_HOOK) - return; - - apm_del_hook(&hook[apmh], ah); -} - -static int apm_record_event(struct apm_softc *, u_int); -static void apm_processevent(void); - -static u_int apm_op_inprog = 0; - -static void -apm_do_suspend(void) -{ - struct apm_softc *sc = &apm_softc; - int error; - - if (sc == NULL || sc->initialized == 0) - return; - - apm_op_inprog = 0; - sc->suspends = sc->suspend_countdown = 0; - - EVENTHANDLER_INVOKE(power_suspend); - - /* - * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since - * non-MPSAFE drivers need this. - */ - mtx_lock(&Giant); - error = DEVICE_SUSPEND(root_bus); - if (error) - goto backout; - - apm_execute_hook(hook[APM_HOOK_SUSPEND]); - if (apm_suspend_system(PMST_SUSPEND) == 0) { - sc->suspending = 1; - apm_processevent(); - mtx_unlock(&Giant); - return; - } - - /* Failure, 'resume' the system again */ - apm_execute_hook(hook[APM_HOOK_RESUME]); - DEVICE_RESUME(root_bus); -backout: - mtx_unlock(&Giant); - EVENTHANDLER_INVOKE(power_resume); -} - -static void -apm_do_standby(void) -{ - struct apm_softc *sc = &apm_softc; - - if (sc == NULL || sc->initialized == 0) - return; - - apm_op_inprog = 0; - sc->standbys = sc->standby_countdown = 0; - - /* - * As far as standby, we don't need to execute - * all of suspend hooks. - */ - if (apm_suspend_system(PMST_STANDBY) == 0) - apm_processevent(); - return; -} - -static void -apm_lastreq_notify(void) -{ - struct apm_softc *sc = &apm_softc; - - sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE; - sc->bios.r.ebx = PMDV_ALLDEV; - sc->bios.r.ecx = PMST_LASTREQNOTIFY; - sc->bios.r.edx = 0; - apm_bioscall(); -} - -static int -apm_lastreq_rejected(void) -{ - struct apm_softc *sc = &apm_softc; - - if (apm_op_inprog == 0) { - return 1; /* no operation in progress */ - } - - sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE; - sc->bios.r.ebx = PMDV_ALLDEV; - sc->bios.r.ecx = PMST_LASTREQREJECT; - sc->bios.r.edx = 0; - - if (apm_bioscall()) { - APM_DPRINT("apm_lastreq_rejected: failed\n"); - return 1; - } - apm_op_inprog = 0; - return 0; -} - -/* - * Public interface to the suspend/resume: - * - * Execute suspend and resume hook before and after sleep, respectively. - * - */ - -void -apm_suspend(int state) -{ - struct apm_softc *sc = &apm_softc; - - if (sc == NULL || sc->initialized == 0) - return; - - switch (state) { - case PMST_SUSPEND: - if (sc->suspends) - return; - sc->suspends++; - sc->suspend_countdown = apm_suspend_delay; - break; - case PMST_STANDBY: - if (sc->standbys) - return; - sc->standbys++; - sc->standby_countdown = apm_standby_delay; - break; - default: - printf("apm_suspend: Unknown Suspend state 0x%x\n", state); - return; - } - - apm_op_inprog++; - apm_lastreq_notify(); -} - -static void -apm_resume(void) -{ - struct apm_softc *sc = &apm_softc; - - if (sc == NULL || sc->initialized == 0 || sc->suspending == 0) - return; - - sc->suspending = 0; - apm_execute_hook(hook[APM_HOOK_RESUME]); - mtx_lock(&Giant); - DEVICE_RESUME(root_bus); - mtx_unlock(&Giant); - EVENTHANDLER_INVOKE(power_resume); -} - -/* get power status per battery */ -static int -apm_get_pwstatus(apm_pwstatus_t app) -{ - struct apm_softc *sc = &apm_softc; - - if (app->ap_device != PMDV_ALLDEV && - (app->ap_device < PMDV_BATT0 || app->ap_device > PMDV_BATT_ALL)) - return 1; - - sc->bios.r.eax = (APM_BIOS << 8) | APM_GETPWSTATUS; - sc->bios.r.ebx = app->ap_device; - sc->bios.r.ecx = 0; - sc->bios.r.edx = 0xffff; /* default to unknown battery time */ - - if (apm_bioscall()) - return 1; - - app->ap_acline = (sc->bios.r.ebx >> 8) & 0xff; - app->ap_batt_stat = sc->bios.r.ebx & 0xff; - app->ap_batt_flag = (sc->bios.r.ecx >> 8) & 0xff; - app->ap_batt_life = sc->bios.r.ecx & 0xff; - sc->bios.r.edx &= 0xffff; - if (apm_swab_batt_minutes) - sc->bios.r.edx = __bswap16(sc->bios.r.edx) | 0x8000; - if (sc->bios.r.edx == 0xffff) /* Time is unknown */ - app->ap_batt_time = -1; - else if (sc->bios.r.edx & 0x8000) /* Time is in minutes */ - app->ap_batt_time = (sc->bios.r.edx & 0x7fff) * 60; - else /* Time is in seconds */ - app->ap_batt_time = sc->bios.r.edx; - - return 0; -} - -/* get APM information */ -static int -apm_get_info(apm_info_t aip) -{ - struct apm_softc *sc = &apm_softc; - struct apm_pwstatus aps; - - bzero(&aps, sizeof(aps)); - aps.ap_device = PMDV_ALLDEV; - if (apm_get_pwstatus(&aps)) - return 1; - - aip->ai_infoversion = 1; - aip->ai_acline = aps.ap_acline; - aip->ai_batt_stat = aps.ap_batt_stat; - aip->ai_batt_life = aps.ap_batt_life; - aip->ai_batt_time = aps.ap_batt_time; - aip->ai_major = (u_int)sc->majorversion; - aip->ai_minor = (u_int)sc->minorversion; - aip->ai_status = (u_int)sc->active; - - sc->bios.r.eax = (APM_BIOS << 8) | APM_GETCAPABILITIES; - sc->bios.r.ebx = 0; - sc->bios.r.ecx = 0; - sc->bios.r.edx = 0; - if (apm_bioscall()) { - aip->ai_batteries = 0xffffffff; /* Unknown */ - aip->ai_capabilities = 0xff00; /* Unknown, with no bits set */ - } else { - aip->ai_batteries = sc->bios.r.ebx & 0xff; - aip->ai_capabilities = sc->bios.r.ecx & 0xff; - } - - bzero(aip->ai_spare, sizeof aip->ai_spare); - - return 0; -} - -/* inform APM BIOS that CPU is idle */ -void -apm_cpu_idle(void) -{ - struct apm_softc *sc = &apm_softc; - - if (sc->active) { - sc->bios.r.eax = (APM_BIOS <<8) | APM_CPUIDLE; - sc->bios.r.edx = sc->bios.r.ecx = sc->bios.r.ebx = 0; - (void) apm_bioscall(); - } - /* - * Some APM implementation halts CPU in BIOS, whenever - * "CPU-idle" function are invoked, but swtch() of - * FreeBSD halts CPU, therefore, CPU is halted twice - * in the sched loop. It makes the interrupt latency - * terribly long and be able to cause a serious problem - * in interrupt processing. We prevent it by removing - * "hlt" operation from swtch() and managed it under - * APM driver. - */ - if (!sc->active || sc->always_halt_cpu) - halt(); /* wait for interrupt */ -} - -/* inform APM BIOS that CPU is busy */ -void -apm_cpu_busy(void) -{ - struct apm_softc *sc = &apm_softc; - - /* - * The APM specification says this is only necessary if your BIOS - * slows down the processor in the idle task, otherwise it's not - * necessary. - */ - if (sc->slow_idle_cpu && sc->active) { - sc->bios.r.eax = (APM_BIOS <<8) | APM_CPUBUSY; - sc->bios.r.edx = sc->bios.r.ecx = sc->bios.r.ebx = 0; - apm_bioscall(); - } -} - -/* - * APM thread loop. - * - * This routine wakes up from time to time to deal with delaying the - * suspend of the system, or other events. - */ -static void -apm_event_thread(void *arg) -{ - struct apm_softc *sc = &apm_softc; - - sc->running = 1; - while (sc->active) { - if (apm_op_inprog) - apm_lastreq_notify(); - if (sc->standbys && sc->standby_countdown-- <= 0) - apm_do_standby(); - if (sc->suspends && sc->suspend_countdown-- <= 0) - apm_do_suspend(); - if (!sc->bios_busy) - apm_processevent(); - mtx_lock(&sc->mtx); - cv_timedwait(&sc->cv, &sc->mtx, 10 * hz / 9); - mtx_unlock(&sc->mtx); - } - sc->running = 0; - kproc_exit(0); -} - -/* enable APM BIOS */ -static void -apm_event_enable(void) -{ - struct apm_softc *sc = &apm_softc; - - APM_DPRINT("called apm_event_enable()\n"); - - if (sc == NULL || sc->initialized == 0) - return; - - /* Start the thread */ - sc->active = 1; - if (kproc_create(apm_event_thread, sc, &sc->event_thread, 0, 0, - "apm worker")) - panic("Cannot create apm worker thread"); - - return; -} - -/* disable APM BIOS */ -static void -apm_event_disable(void) -{ - struct apm_softc *sc = &apm_softc; - - APM_DPRINT("called apm_event_disable()\n"); - - if (sc == NULL || sc->initialized == 0) - return; - - mtx_lock(&sc->mtx); - sc->active = 0; - while (sc->running) { - cv_broadcast(&sc->cv); - msleep(sc->event_thread, &sc->mtx, PWAIT, "apmdie", 0); - } - mtx_unlock(&sc->mtx); - sc->event_thread = NULL; - return; -} - -/* halt CPU in scheduling loop */ -static void -apm_halt_cpu(void) -{ - struct apm_softc *sc = &apm_softc; - - if (sc == NULL || sc->initialized == 0) - return; - - sc->always_halt_cpu = 1; - - return; -} - -/* don't halt CPU in scheduling loop */ -static void -apm_not_halt_cpu(void) -{ - struct apm_softc *sc = &apm_softc; - - if (sc == NULL || sc->initialized == 0) - return; - - sc->always_halt_cpu = 0; - - return; -} - -/* device driver definitions */ - -/* - * Module event - */ - -static int -apm_modevent(struct module *mod, int event, void *junk) -{ - - switch (event) { - case MOD_LOAD: - if (!cold) - return (EPERM); - break; - case MOD_UNLOAD: - if (!cold && power_pm_get_type() == POWER_PM_TYPE_APM) - return (EBUSY); - break; - default: - break; - } - - return (0); -} - -/* - * Create "connection point" - */ -static void -apm_identify(driver_t *driver, device_t parent) -{ - device_t child; - - if (!cold) { - printf("Don't load this driver from userland!!\n"); - return; - } - - if (resource_disabled("apm", 0)) - return; - - child = BUS_ADD_CHILD(parent, 0, "apm", 0); - if (child == NULL) - panic("apm_identify"); -} - -/* - * probe for APM BIOS - */ -static int -apm_probe(device_t dev) -{ -#define APM_KERNBASE KERNBASE - struct vm86frame vmf; - struct apm_softc *sc = &apm_softc; - - device_set_desc(dev, "APM BIOS"); - if (device_get_unit(dev) > 0) { - printf("apm: Only one APM driver supported.\n"); - return ENXIO; - } - - if (power_pm_get_type() != POWER_PM_TYPE_NONE && - power_pm_get_type() != POWER_PM_TYPE_APM) { - printf("apm: Other PM system enabled.\n"); - return ENXIO; - } - - bzero(&vmf, sizeof(struct vm86frame)); /* safety */ - bzero(&apm_softc, sizeof(apm_softc)); - vmf.vmf_ah = APM_BIOS; - vmf.vmf_al = APM_INSTCHECK; - vmf.vmf_bx = 0; - if (vm86_intcall(APM_INT, &vmf)) - return ENXIO; /* APM not found */ - if (vmf.vmf_bx != 0x504d) { - printf("apm: incorrect signature (0x%x)\n", vmf.vmf_bx); - return ENXIO; - } - if ((vmf.vmf_cx & (APM_32BIT_SUPPORT | APM_16BIT_SUPPORT)) == 0) { - printf("apm: protected mode connections are not supported\n"); - return ENXIO; - } - - apm_version = vmf.vmf_ax; - sc->slow_idle_cpu = ((vmf.vmf_cx & APM_CPUIDLE_SLOW) != 0); - sc->disabled = ((vmf.vmf_cx & APM_DISABLED) != 0); - sc->disengaged = ((vmf.vmf_cx & APM_DISENGAGED) != 0); - - vmf.vmf_ah = APM_BIOS; - vmf.vmf_al = APM_DISCONNECT; - vmf.vmf_bx = 0; - vm86_intcall(APM_INT, &vmf); /* disconnect, just in case */ - - if ((vmf.vmf_cx & APM_32BIT_SUPPORT) != 0) { - vmf.vmf_ah = APM_BIOS; - vmf.vmf_al = APM_PROT32CONNECT; - vmf.vmf_bx = 0; - if (vm86_intcall(APM_INT, &vmf)) { - printf("apm: 32-bit connection error.\n"); - return (ENXIO); - } - sc->bios.seg.code32.base = (vmf.vmf_ax << 4) + APM_KERNBASE; - sc->bios.seg.code32.limit = 0xffff; - sc->bios.seg.code16.base = (vmf.vmf_cx << 4) + APM_KERNBASE; - sc->bios.seg.code16.limit = 0xffff; - sc->bios.seg.data.base = (vmf.vmf_dx << 4) + APM_KERNBASE; - sc->bios.seg.data.limit = 0xffff; - sc->bios.entry = vmf.vmf_ebx; - sc->connectmode = APM_PROT32CONNECT; - } else { - /* use 16-bit connection */ - vmf.vmf_ah = APM_BIOS; - vmf.vmf_al = APM_PROT16CONNECT; - vmf.vmf_bx = 0; - if (vm86_intcall(APM_INT, &vmf)) { - printf("apm: 16-bit connection error.\n"); - return (ENXIO); - } - sc->bios.seg.code16.base = (vmf.vmf_ax << 4) + APM_KERNBASE; - sc->bios.seg.code16.limit = 0xffff; - sc->bios.seg.data.base = (vmf.vmf_cx << 4) + APM_KERNBASE; - sc->bios.seg.data.limit = 0xffff; - sc->bios.entry = vmf.vmf_bx; - sc->connectmode = APM_PROT16CONNECT; - } - - return(0); -} - -/* - * return 0 if the user will notice and handle the event, - * return 1 if the kernel driver should do so. - */ -static int -apm_record_event(struct apm_softc *sc, u_int event_type) -{ - struct apm_event_info *evp; - - if ((sc->sc_flags & SCFLAG_OPEN) == 0) - return 1; /* no user waiting */ - if (sc->event_count == APM_NEVENTS) - return 1; /* overflow */ - if (sc->event_filter[event_type] == 0) - return 1; /* not registered */ - evp = &sc->event_list[sc->event_ptr]; - sc->event_count++; - sc->event_ptr++; - sc->event_ptr %= APM_NEVENTS; - evp->type = event_type; - evp->index = ++apm_evindex; - selwakeuppri(&sc->sc_rsel, PZERO); - return (sc->sc_flags & SCFLAG_OCTL) ? 0 : 1; /* user may handle */ -} - -/* Power profile */ -static void -apm_power_profile(struct apm_softc *sc) -{ - int state; - struct apm_info info; - static int apm_acline = 0; - - if (apm_get_info(&info)) - return; - - if (apm_acline != info.ai_acline) { - apm_acline = info.ai_acline; - state = apm_acline ? POWER_PROFILE_PERFORMANCE : POWER_PROFILE_ECONOMY; - power_profile_set_state(state); - } -} - -/* Process APM event */ -static void -apm_processevent(void) -{ - int apm_event; - struct apm_softc *sc = &apm_softc; - -#define OPMEV_DEBUGMESSAGE(symbol) case symbol: \ - APM_DPRINT("Received APM Event: " #symbol "\n"); - - do { - apm_event = apm_getevent(); - switch (apm_event) { - OPMEV_DEBUGMESSAGE(PMEV_STANDBYREQ); - if (apm_op_inprog == 0) { - apm_op_inprog++; - if (apm_record_event(sc, apm_event)) { - apm_suspend(PMST_STANDBY); - } - } - break; - OPMEV_DEBUGMESSAGE(PMEV_USERSTANDBYREQ); - if (apm_op_inprog == 0) { - apm_op_inprog++; - if (apm_record_event(sc, apm_event)) { - apm_suspend(PMST_STANDBY); - } - } - break; - OPMEV_DEBUGMESSAGE(PMEV_SUSPENDREQ); - apm_lastreq_notify(); - if (apm_op_inprog == 0) { - apm_op_inprog++; - if (apm_record_event(sc, apm_event)) { - apm_do_suspend(); - } - } - return; /* XXX skip the rest */ - OPMEV_DEBUGMESSAGE(PMEV_USERSUSPENDREQ); - apm_lastreq_notify(); - if (apm_op_inprog == 0) { - apm_op_inprog++; - if (apm_record_event(sc, apm_event)) { - apm_do_suspend(); - } - } - return; /* XXX skip the rest */ - OPMEV_DEBUGMESSAGE(PMEV_CRITSUSPEND); - apm_do_suspend(); - break; - OPMEV_DEBUGMESSAGE(PMEV_NORMRESUME); - apm_record_event(sc, apm_event); - apm_resume(); - break; - OPMEV_DEBUGMESSAGE(PMEV_CRITRESUME); - apm_record_event(sc, apm_event); - apm_resume(); - break; - OPMEV_DEBUGMESSAGE(PMEV_STANDBYRESUME); - apm_record_event(sc, apm_event); - break; - OPMEV_DEBUGMESSAGE(PMEV_BATTERYLOW); - if (apm_record_event(sc, apm_event)) { - apm_battery_low(); - apm_suspend(PMST_SUSPEND); - } - break; - OPMEV_DEBUGMESSAGE(PMEV_POWERSTATECHANGE); - apm_record_event(sc, apm_event); - apm_power_profile(sc); - break; - OPMEV_DEBUGMESSAGE(PMEV_UPDATETIME); - apm_record_event(sc, apm_event); - inittodr(0); /* adjust time to RTC */ - break; - OPMEV_DEBUGMESSAGE(PMEV_CAPABILITIESCHANGE); - apm_record_event(sc, apm_event); - apm_power_profile(sc); - break; - case PMEV_NOEVENT: - break; - default: - printf("Unknown Original APM Event 0x%x\n", apm_event); - break; - } - } while (apm_event != PMEV_NOEVENT); -} - -static struct timeval suspend_time; -static struct timeval diff_time; - -static int -apm_rtc_suspend(void *arg __unused) -{ - - microtime(&diff_time); - inittodr(0); - microtime(&suspend_time); - timevalsub(&diff_time, &suspend_time); - return (0); -} - -static int -apm_rtc_resume(void *arg __unused) -{ - u_int second, minute, hour; - struct timeval resume_time, tmp_time; - - /* modified for adjkerntz */ - timer_restore(); /* restore the all timers */ - inittodr(0); /* adjust time to RTC */ - microtime(&resume_time); - getmicrotime(&tmp_time); - timevaladd(&tmp_time, &diff_time); - /* Calculate the delta time suspended */ - timevalsub(&resume_time, &suspend_time); - -#ifdef PMTIMER_FIXUP_CALLTODO - /* Fixup the calltodo list with the delta time. */ - adjust_timeout_calltodo(&resume_time); -#endif /* PMTIMER_FIXUP_CALLTODO */ - second = resume_time.tv_sec; - hour = second / 3600; - second %= 3600; - minute = second / 60; - second %= 60; - log(LOG_NOTICE, "wakeup from sleeping state (slept %02d:%02d:%02d)\n", - hour, minute, second); - return (0); -} - -/* - * Attach APM: - * - * Initialize APM driver - */ - -static int -apm_attach(device_t dev) -{ - struct apm_softc *sc = &apm_softc; - int drv_version; - - mtx_init(&sc->mtx, device_get_nameunit(dev), "apm", MTX_DEF); - cv_init(&sc->cv, "cbb cv"); - - if (device_get_flags(dev) & 0x20) - atrtcclock_disable = 1; - - sc->initialized = 0; - - /* Must be externally enabled */ - sc->active = 0; - - /* Always call HLT in idle loop */ - sc->always_halt_cpu = 1; - - getenv_int("debug.apm_debug", &apm_debug); - - /* print bootstrap messages */ - APM_DPRINT("apm: APM BIOS version %04lx\n", apm_version); - APM_DPRINT("apm: Code16 0x%08x, Data 0x%08x\n", - sc->bios.seg.code16.base, sc->bios.seg.data.base); - APM_DPRINT("apm: Code entry 0x%08x, Idling CPU %s, Management %s\n", - sc->bios.entry, is_enabled(sc->slow_idle_cpu), - is_enabled(!sc->disabled)); - APM_DPRINT("apm: CS_limit=0x%x, DS_limit=0x%x\n", - sc->bios.seg.code16.limit, sc->bios.seg.data.limit); - - /* - * In one test, apm bios version was 1.02; an attempt to register - * a 1.04 driver resulted in a 1.00 connection! Registering a - * 1.02 driver resulted in a 1.02 connection. - */ - drv_version = apm_version > 0x102 ? 0x102 : apm_version; - for (; drv_version > 0x100; drv_version--) - if (apm_driver_version(drv_version) == 0) - break; - sc->minorversion = ((drv_version & 0x00f0) >> 4) * 10 + - ((drv_version & 0x000f) >> 0); - sc->majorversion = ((drv_version & 0xf000) >> 12) * 10 + - ((apm_version & 0x0f00) >> 8); - - sc->intversion = INTVERSION(sc->majorversion, sc->minorversion); - - if (sc->intversion >= INTVERSION(1, 1)) - APM_DPRINT("apm: Engaged control %s\n", is_enabled(!sc->disengaged)); - device_printf(dev, "found APM BIOS v%ld.%ld, connected at v%d.%d\n", - ((apm_version & 0xf000) >> 12) * 10 + ((apm_version & 0x0f00) >> 8), - ((apm_version & 0x00f0) >> 4) * 10 + ((apm_version & 0x000f) >> 0), - sc->majorversion, sc->minorversion); - - APM_DPRINT("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu)); - /* enable power management */ - if (sc->disabled) { - if (apm_enable_disable_pm(1)) { - APM_DPRINT("apm: *Warning* enable function failed! [%x]\n", - (sc->bios.r.eax >> 8) & 0xff); - } - } - - /* engage power managment (APM 1.1 or later) */ - if (sc->intversion >= INTVERSION(1, 1) && sc->disengaged) { - if (apm_engage_disengage_pm(1)) { - APM_DPRINT("apm: *Warning* engage function failed err=[%x]", - (sc->bios.r.eax >> 8) & 0xff); - APM_DPRINT(" (Docked or using external power?).\n"); - } - } - - /* Power the system off using APM */ - EVENTHANDLER_REGISTER(shutdown_final, apm_power_off, NULL, - SHUTDOWN_PRI_LAST); - - /* Register APM again to pass the correct argument of pm_func. */ - power_pm_register(POWER_PM_TYPE_APM, apm_pm_func, sc); - - sc->initialized = 1; - sc->suspending = 0; - sc->running = 0; - - make_dev(&apm_cdevsw, APMDEV_NORMAL, - UID_ROOT, GID_OPERATOR, 0664, "apm"); - make_dev(&apm_cdevsw, APMDEV_CTL, - UID_ROOT, GID_OPERATOR, 0660, "apmctl"); - - sc->sc_suspend.ah_fun = apm_rtc_suspend; - sc->sc_suspend.ah_arg = sc; - apm_hook_establish(APM_HOOK_SUSPEND, &sc->sc_suspend); - - sc->sc_resume.ah_fun = apm_rtc_resume; - sc->sc_resume.ah_arg = sc; - apm_hook_establish(APM_HOOK_RESUME, &sc->sc_resume); - - gone_in_dev(dev, 13, "APM support has been removed."); - - return 0; -} - -static int -apmopen(struct cdev *dev, int flag, int fmt, struct thread *td) -{ - struct apm_softc *sc = &apm_softc; - - if (sc == NULL || sc->initialized == 0) - return (ENXIO); - - switch (dev2unit(dev)) { - case APMDEV_CTL: - if (!(flag & FWRITE)) - return EINVAL; - if (sc->sc_flags & SCFLAG_OCTL) - return EBUSY; - sc->sc_flags |= SCFLAG_OCTL; - bzero(sc->event_filter, sizeof sc->event_filter); - break; - case APMDEV_NORMAL: - sc->sc_flags |= SCFLAG_ONORMAL; - break; - } - return 0; -} - -static int -apmclose(struct cdev *dev, int flag, int fmt, struct thread *td) -{ - struct apm_softc *sc = &apm_softc; - - switch (dev2unit(dev)) { - case APMDEV_CTL: - apm_lastreq_rejected(); - sc->sc_flags &= ~SCFLAG_OCTL; - bzero(sc->event_filter, sizeof sc->event_filter); - break; - case APMDEV_NORMAL: - sc->sc_flags &= ~SCFLAG_ONORMAL; - break; - } - if ((sc->sc_flags & SCFLAG_OPEN) == 0) { - sc->event_count = 0; - sc->event_ptr = 0; - } - return 0; -} - -static int -apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) -{ - struct apm_softc *sc = &apm_softc; - struct apm_bios_arg *args; - int error = 0; - int ret; - int newstate; - - if (sc == NULL || sc->initialized == 0) - return (ENXIO); - - APM_DPRINT("APM ioctl: cmd = 0x%lx\n", cmd); - switch (cmd) { - case APMIO_SUSPEND: - if (!(flag & FWRITE)) - return (EPERM); - if (sc->active) - apm_suspend(PMST_SUSPEND); - else - error = EINVAL; - break; - - case APMIO_STANDBY: - if (!(flag & FWRITE)) - return (EPERM); - if (sc->active) - apm_suspend(PMST_STANDBY); - else - error = EINVAL; - break; - - case APMIO_GETINFO_OLD: - { - struct apm_info info; - apm_info_old_t aiop; - - if (apm_get_info(&info)) - error = ENXIO; - aiop = (apm_info_old_t)addr; - aiop->ai_major = info.ai_major; - aiop->ai_minor = info.ai_minor; - aiop->ai_acline = info.ai_acline; - aiop->ai_batt_stat = info.ai_batt_stat; - aiop->ai_batt_life = info.ai_batt_life; - aiop->ai_status = info.ai_status; - } - break; - case APMIO_GETINFO: - if (apm_get_info((apm_info_t)addr)) - error = ENXIO; - break; - case APMIO_GETPWSTATUS: - if (apm_get_pwstatus((apm_pwstatus_t)addr)) - error = ENXIO; - break; - case APMIO_ENABLE: - if (!(flag & FWRITE)) - return (EPERM); - apm_event_enable(); - break; - case APMIO_DISABLE: - if (!(flag & FWRITE)) - return (EPERM); - apm_event_disable(); - break; - case APMIO_HALTCPU: - if (!(flag & FWRITE)) - return (EPERM); - apm_halt_cpu(); - break; - case APMIO_NOTHALTCPU: - if (!(flag & FWRITE)) - return (EPERM); - apm_not_halt_cpu(); - break; - case APMIO_DISPLAY: - if (!(flag & FWRITE)) - return (EPERM); - newstate = *(int *)addr; - if (apm_display(newstate)) - error = ENXIO; - break; - case APMIO_BIOS: - if (!(flag & FWRITE)) - return (EPERM); - /* XXX compatibility with the old interface */ - args = (struct apm_bios_arg *)addr; - sc->bios.r.eax = args->eax; - sc->bios.r.ebx = args->ebx; - sc->bios.r.ecx = args->ecx; - sc->bios.r.edx = args->edx; - sc->bios.r.esi = args->esi; - sc->bios.r.edi = args->edi; - if ((ret = apm_bioscall())) { - /* - * Return code 1 means bios call was unsuccessful. - * Error code is stored in %ah. - * Return code -1 means bios call was unsupported - * in the APM BIOS version. - */ - if (ret == -1) { - error = EINVAL; - } - } else { - /* - * Return code 0 means bios call was successful. - * We need only %al and can discard %ah. - */ - sc->bios.r.eax &= 0xff; - } - args->eax = sc->bios.r.eax; - args->ebx = sc->bios.r.ebx; - args->ecx = sc->bios.r.ecx; - args->edx = sc->bios.r.edx; - args->esi = sc->bios.r.esi; - args->edi = sc->bios.r.edi; - break; - default: - error = EINVAL; - break; - } - - /* for /dev/apmctl */ - if (dev2unit(dev) == APMDEV_CTL) { - struct apm_event_info *evp; - int i; - - error = 0; - switch (cmd) { - case APMIO_NEXTEVENT: - if (!sc->event_count) { - error = EAGAIN; - } else { - evp = (struct apm_event_info *)addr; - i = sc->event_ptr + APM_NEVENTS - sc->event_count; - i %= APM_NEVENTS; - *evp = sc->event_list[i]; - sc->event_count--; - } - break; - case APMIO_REJECTLASTREQ: - if (apm_lastreq_rejected()) { - error = EINVAL; - } - break; - default: - error = EINVAL; - break; - } - } - - return error; -} - -static int -apmwrite(struct cdev *dev, struct uio *uio, int ioflag) -{ - struct apm_softc *sc = &apm_softc; - u_int event_type; - int error; - u_char enabled; - - if (dev2unit(dev) != APMDEV_CTL) - return(ENODEV); - if (uio->uio_resid != sizeof(u_int)) - return(E2BIG); - - if ((error = uiomove((caddr_t)&event_type, sizeof(u_int), uio))) - return(error); - - if (event_type >= APM_NPMEV) - return(EINVAL); - - if (sc->event_filter[event_type] == 0) { - enabled = 1; - } else { - enabled = 0; - } - sc->event_filter[event_type] = enabled; - APM_DPRINT("apmwrite: event 0x%x %s\n", event_type, is_enabled(enabled)); - - return uio->uio_resid; -} - -static int -apmpoll(struct cdev *dev, int events, struct thread *td) -{ - struct apm_softc *sc = &apm_softc; - int revents = 0; - - if (events & (POLLIN | POLLRDNORM)) { - if (sc->event_count) { - revents |= events & (POLLIN | POLLRDNORM); - } else { - selrecord(td, &sc->sc_rsel); - } - } - - return (revents); -} - -static device_method_t apm_methods[] = { - /* Device interface */ - DEVMETHOD(device_identify, apm_identify), - DEVMETHOD(device_probe, apm_probe), - DEVMETHOD(device_attach, apm_attach), - { 0, 0 } -}; - -static driver_t apm_driver = { - "apm", - apm_methods, - 1, /* no softc (XXX) */ -}; - -static devclass_t apm_devclass; - -DRIVER_MODULE(apm, legacy, apm_driver, apm_devclass, apm_modevent, 0); -MODULE_VERSION(apm, 1); - -static int -apm_pm_func(u_long cmd, void *arg, ...) -{ - int state, apm_state; - int error; - va_list ap; - - error = 0; - switch (cmd) { - case POWER_CMD_SUSPEND: - va_start(ap, arg); - state = va_arg(ap, int); - va_end(ap); - - switch (state) { - case POWER_SLEEP_STATE_STANDBY: - apm_state = PMST_STANDBY; - break; - case POWER_SLEEP_STATE_SUSPEND: - case POWER_SLEEP_STATE_HIBERNATE: - apm_state = PMST_SUSPEND; - break; - default: - error = EINVAL; - goto out; - } - - apm_suspend(apm_state); - break; - - default: - error = EINVAL; - goto out; - } - -out: - return (error); -} - -static void -apm_pm_register(void *arg) -{ - - if (!resource_disabled("apm", 0)) - power_pm_register(POWER_PM_TYPE_APM, apm_pm_func, NULL); -} - -SYSINIT(power, SI_SUB_KLD, SI_ORDER_ANY, apm_pm_register, NULL); Index: sys/i386/conf/GENERIC =================================================================== --- sys/i386/conf/GENERIC +++ sys/i386/conf/GENERIC @@ -198,9 +198,6 @@ device agp # support several AGP chipsets -# Power management support (see NOTES for more options) -#device apm - # PCCARD (PCMCIA) support # PCMCIA and cardbus bridge support device cbb # cardbus (yenta) bridge Index: sys/i386/conf/GENERIC.hints =================================================================== --- sys/i386/conf/GENERIC.hints +++ sys/i386/conf/GENERIC.hints @@ -21,8 +21,6 @@ hint.psm.0.irq="12" hint.sc.0.at="isa" hint.sc.0.flags="0x100" -hint.apm.0.disabled="1" -hint.apm.0.flags="0x20" hint.uart.0.at="isa" hint.uart.0.port="0x3F8" hint.uart.0.flags="0x10" Index: sys/i386/conf/NOTES =================================================================== --- sys/i386/conf/NOTES +++ sys/i386/conf/NOTES @@ -275,7 +275,6 @@ device speaker #Play IBM BASIC-style noises out your speaker hint.speaker.0.at="isa" hint.speaker.0.port="0x61" -device apm_saver # Requires APM ##################################################################### @@ -729,7 +728,6 @@ # # Miscellaneous hardware: # -# apm: Laptop Advanced Power Management (experimental) # ipmi: Intelligent Platform Management Interface # smapi: System Management Application Program Interface driver # smbios: DMI/SMBIOS entry point @@ -739,10 +737,6 @@ # si: Specialix International SI/XIO or SX intelligent serial card driver # tpm: Trusted Platform Module -# Notes on APM -# The flags takes the following meaning for apm0: -# 0x0020 Statclock is broken. - # Notes on the Specialix SI/XIO driver: # The host card is memory, not IO mapped. # The Rev 1 host cards use a 64K chunk, on a 32K boundary. @@ -761,8 +755,6 @@ # is the only thing truly supported, but apparently a fair percentage # of the Vaio extra features are controlled by this device. -device apm -hint.apm.0.flags="0x20" device ipmi device smapi device smbios @@ -778,10 +770,6 @@ # # Laptop/Notebook options: -# -# See also: -# apm under `Miscellaneous hardware' -# above. # For older notebooks that signal a powerfail condition (external # power supply dropped, or battery state low) by issuing an NMI: Index: sys/i386/include/apm_segments.h =================================================================== --- sys/i386/include/apm_segments.h +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * LP (Laptop Package) - * - * Copyright (C) 1994 by HOSOKAWA Tatsumi - * - * 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$ - */ - -#ifndef _MACHINE_APM_SEGMENTS_H -#define _MACHINE_APM_SEGMENTS_H - -#define SIZEOF_GDT 8 -#define BOOTSTRAP_GDT_NUM 32 - -#define APM_INIT_CS_INDEX (BOOTSTRAP_GDT_NUM - 4) -#define APM_INIT_DS_INDEX (BOOTSTRAP_GDT_NUM - 3) -#define APM_INIT_CS16_INDEX (BOOTSTRAP_GDT_NUM - 2) -#define APM_INIT_DS16_INDEX (BOOTSTRAP_GDT_NUM - 1) -#define APM_INIT_CS_SEL (APM_INIT_CS_INDEX << 3) -#define APM_INIT_DS_SEL (APM_INIT_DS_INDEX << 3) -#define APM_INIT_CS16_SEL (APM_INIT_CS16_INDEX << 3) -#define APM_INIT_DS16_SEL (APM_INIT_DS16_INDEX << 3) - -#define CS32_ATTRIB 0x409e -#define DS32_ATTRIB 0x4092 -#define CS16_ATTRIB 0x009e -#define DS16_ATTRIB 0x0092 - -#endif Index: sys/i386/include/clock.h =================================================================== --- sys/i386/include/clock.h +++ sys/i386/include/clock.h @@ -30,7 +30,6 @@ */ void startrtclock(void); -void timer_restore(void); void init_TSC(void); void resume_TSC(void); Index: sys/modules/Makefile =================================================================== --- sys/modules/Makefile +++ sys/modules/Makefile @@ -41,7 +41,6 @@ amr \ ${_an} \ ${_aout} \ - ${_apm} \ ${_arcmsr} \ ${_allwinner} \ ${_armv8crypto} \ @@ -743,7 +742,6 @@ # XXX some of these can move now, but are untested on other architectures. _3dfx= 3dfx _3dfx_linux= 3dfx_linux -_apm= apm .if ${MK_SOURCELESS_HOST} != "no" _ce= ce .endif Index: sys/modules/apm/Makefile =================================================================== --- sys/modules/apm/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/i386/bios - -KMOD= apm -SRCS= apm.c apm.h -SRCS+= device_if.h bus_if.h - -EXPORT_SYMS= apm_display \ - apm_softc - -.include Index: sys/modules/syscons/Makefile =================================================================== --- sys/modules/syscons/Makefile +++ sys/modules/syscons/Makefile @@ -1,7 +1,6 @@ # $FreeBSD$ -SUBDIR= ${_apm} \ - beastie \ +SUBDIR= beastie \ blank \ daemon \ dragon \ @@ -15,8 +14,4 @@ star \ warp -.if ${MACHINE_CPUARCH} == "i386" -_apm= apm -.endif - .include Index: sys/modules/syscons/apm/Makefile =================================================================== --- sys/modules/syscons/apm/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/syscons/apm - -KMOD= apm_saver -SRCS= apm_saver.c - -.include Index: sys/x86/isa/clock.c =================================================================== --- sys/x86/isa/clock.c +++ sys/x86/isa/clock.c @@ -388,26 +388,6 @@ set_i8254_freq(MODE_STOP, 0); } -#ifndef __amd64__ -/* - * Restore all the timers non-atomically (XXX: should be atomically). - * - * This function is called from pmtimer_resume() to restore all the timers. - * This should not be necessary, but there are broken laptops that do not - * restore all the timers on resume. The APM spec was at best vague on the - * subject. - * pmtimer is used only with the old APM power management, and not with - * acpi, which is required for amd64, so skip it in that case. - */ -void -timer_restore(void) -{ - - i8254_restore(); /* restore i8254_freq and hz */ - atrtc_restore(); /* reenable RTC interrupts */ -} -#endif - /* This is separate from startrtclock() so that it can be called early. */ void i8254_init(void) Index: tools/build/mk/OptionalObsoleteFiles.inc =================================================================== --- tools/build/mk/OptionalObsoleteFiles.inc +++ tools/build/mk/OptionalObsoleteFiles.inc @@ -54,20 +54,10 @@ OLD_FILES+=usr/share/man/man8/iasl.8.gz .endif -.if ${MK_ACPI} == no && ${MK_APM} == no +.if ${MK_ACPI} == no OLD_FILES+=etc/rc.d/powerd .endif -.if ${MK_APM} == no -OLD_FILES+=etc/rc.d/apm -OLD_FILES+=etc/rc.d/apmd -OLD_FILES+=etc/apmd.conf -OLD_FILES+=usr/sbin/apm -OLD_FILES+=usr/share/examples/etc/apmd.conf -OLD_FILES+=usr/share/man/man8/amd64/apm.8.gz -OLD_FILES+=usr/share/man/man8/amd64/apmconf.8.gz -.endif - .if ${MK_AT} == no OLD_FILES+=etc/pam.d/atrun OLD_FILES+=usr/bin/at Index: tools/build/options/WITHOUT_APM =================================================================== --- tools/build/options/WITHOUT_APM +++ /dev/null @@ -1,5 +0,0 @@ -.\" $FreeBSD$ -Set to not build -.Xr apm 8 , -.Xr apmd 8 -and related programs. Index: usr.sbin/Makefile.amd64 =================================================================== --- usr.sbin/Makefile.amd64 +++ usr.sbin/Makefile.amd64 @@ -4,9 +4,8 @@ # pnpinfo: crashes (not really useful anyway) .if ${MK_ACPI} != "no" SUBDIR+= acpi -.endif -.if ${MK_APM} != "no" SUBDIR+= apm +SUBDIR+= zzz .endif .if ${MK_BHYVE} != "no" SUBDIR+= bhyve @@ -28,4 +27,3 @@ SUBDIR+= ndiscvt .endif SUBDIR+= spkrtest -SUBDIR+= zzz Index: usr.sbin/Makefile.i386 =================================================================== --- usr.sbin/Makefile.i386 +++ usr.sbin/Makefile.i386 @@ -2,10 +2,8 @@ .if ${MK_ACPI} != "no" SUBDIR+= acpi -.endif -.if ${MK_APM} != "no" SUBDIR+= apm -SUBDIR+= apmd +SUBDIR+= zzz .endif SUBDIR+= boot0cfg .if ${MK_TOOLCHAIN} != "no" @@ -23,4 +21,3 @@ .endif SUBDIR+= pnpinfo SUBDIR+= spkrtest -SUBDIR+= zzz Index: usr.sbin/apmd/Makefile =================================================================== --- usr.sbin/apmd/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# $FreeBSD$ - -CONFS= apmd.conf -PROG= apmd -MAN= apmd.8 -MANSUBDIR= /i386 -SRCS= apmd.c apmdlex.l apmdparse.y y.tab.h - -PACKAGE=apm - -WARNS?= 3 - -CFLAGS+= -I${.CURDIR} - -test: - ./apmd -d -f etc/apmd.conf -n - -.include Index: usr.sbin/apmd/Makefile.depend =================================================================== --- usr.sbin/apmd/Makefile.depend +++ /dev/null @@ -1,15 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: usr.sbin/apmd/README =================================================================== --- usr.sbin/apmd/README +++ /dev/null @@ -1,213 +0,0 @@ -FreeBSD apmd Package Release Notes (19990711 version) - -1. What is "apmd"? -================== - -The apmd package provides a means of handling various APM events from -userland code. Using apmd.conf, the apmd(8) configuration file, you -can select the APM events to be handled from userland and specify the -commands for a given event, allowing APM behaviour to be configured -flexibly. - - -2. How to install the apmd package -================================== - -2.1 Making the apmd control device file ---------------------------------------- - -apmd(8) uses the new special device file /dev/apmctl. This should be -created as follows: - -# cd /dev -# mknod apmctl c 39 8 - -2.2 Applying the kernel patch and building a new kernel -------------------------------------------------------- - -The next step is to apply the patch against the sys source tree. -Go to the source directory (eg. /usr/src/ or /usr/PAO3/src/) and run -the patch command as follows: - -# gzip -cd [somewhere]/apmd-sys-R320.diff | patch - -For PAO3 users, the patch file name would be apmd-sys-PAO3.diff -instead of apmd-sys-R320.diff. After this step has completed -successfully, build and install a new kernel and reboot your system. - -2.3 Making the apmd program ---------------------------- - -Go to src/usr.sbin/ and extract the apmd tarball as follows: - -# tar xzpvf [somewhere]/apmd-usr.sbin.tar.gz - -Before doing a make all, you need to copy apm_bios.h in the sys source -tree to /usr/include/machine/ first: - -# cp /sys/i386/include/apm_bios.h /usr/include/machine/ - -Then do the build and install steps in the apmd directory: - -# cd src/usr.sbin/apmd -# make depend all install - -2.4 Setting up the configuration file and userland script ---------------------------------------------------------- - -In src/usr.sbin/apm/etc/ there are example configuration and userland -script files which are invoked automatically when the APM BIOS informs -apmd of an event, such as suspend request. Copy these files to -/etc/ as follows: - -# cp src/usr.sbin/apm/etc/* /etc/ - - -3. Running the apmd daemon program -================================== - -To run apmd(8) in background mode, simply type ``apmd''. - -# apmd - -To make a running apmd reload /etc/apmd.conf, send a SIGHUP signal to -the apmd(8) process. - -# kill -HUP [apmd pid] -or -# killall -HUP apmd - -apmd has some command line options. For the details, please -refer to the manpage of apmd. - -4. Configuration file -===================== - -The structure of the apmd configuration file is quite simple. For -example: - -apm_event SUSPENDREQ { - exec "sync && sync && sync"; - exec "sleep 1"; - exec "zzz"; -} - -Will cause apmd to receive the APM event SUSPENDREQ (which may be -posted by an LCD close), run the sync command 3 times and wait for a -while, then execute zzz (apm -z) to put the system in the suspend -state. - -4.1 The apm_event keyword -------------------------- -`apm_event' is the keyword which indicates the start of configuration for -each events. - -4.2 APM events --------------- - -If you wish to execute the same commands for different events, the -event names should be delimited by a comma. The following are valid -event names: - -o Events ignored by the kernel if apmd is running: - -STANDBYREQ -SUSPENDREQ -USERSUSPENDREQ -BATTERYLOW - -o Events passed to apmd after kernel handling: - -NORMRESUME -CRITRESUME -STANDBYRESUME -POWERSTATECHANGE -UPDATETIME - - -Other events will not be sent to apmd. - -4.3 command line syntax ------------------------ - -In the example above, the three lines beginning with `exec' are commands -for the event. Each line should be terminated with a semicolon. The -command list for the event should be enclosed by `{' and `}'. apmd(8) -uses /bin/sh for double-quotation enclosed command execution, just as -with system(3). Each command is executed in order until the end of -the list is reached or a command finishes with a non-zero status code. -apmd(8) will report any failed command's status code via syslog(3) -and will then reject the request event posted by APM BIOS. - -4.4 Built-in functions ----------------------- - -You can also specify apmd built-in functions instead of command lines. -A built-in function name should be terminated with a semicolon, just as -with a command line. -The following built-in functions are currently supported: - -o reject; - - Reject last request posted by the APM BIOS. This can be used to reject a - SUSPEND request when the LCD is closed and put the system in a STANDBY - state instead. - - - -5. EXAMPLES -=========== - -Sample configuration commands include: - -apm_event SUSPENDREQ { - exec "/etc/rc.suspend"; -} - -apm_event USERSUSPENDREQ { - exec "sync && sync && sync"; - exec "sleep 1"; - exec "apm -z"; -} - -apm_event NORMRESUME, STANDBYRESUME { - exec "/etc/rc.resume"; -} - -# resume event configuration for serial mouse users by -# reinitializing a moused(8) connected to a serial port. -# -#apm_event NORMRESUME { -# exec "kill -HUP `cat /var/run/moused.pid`"; -#} - -# suspend request event configuration for ATA HDD users: -# execute standby instead of suspend. -# -#apm_event SUSPENDREQ { -# reject; -# exec "sync && sync && sync"; -# exec "sleep 1"; -# exec "apm -Z"; -#} - - -6. Call for developers -====================== - -The initial version of apmd(8) was implemented primarily to test the -kernel support code and was ALPHA quality. Based on that code, the -current version was developed by KOIE Hidetaka . -However, we're still looking around for interesting new features and -ideas, so if you have any thoughts, please let us know. -Documentation is also sparse, and the manpage have just written. -If you wish to collaborate on this work, please e-mail me: -iwasaki@freebsd.org. - - -June 1, 1999 -Created by: iwasaki@FreeBSD.org -Edited by: jkh@FreeBSD.org - nick@foobar.org - -$FreeBSD$ Index: usr.sbin/apmd/apmd.h =================================================================== --- usr.sbin/apmd/apmd.h +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * APM (Advanced Power Management) Event Dispatcher - * - * Copyright (c) 1999 Mitsuru IWASAKI - * Copyright (c) 1999 KOIE Hidetaka - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#define APMD_CONFIGFILE "/etc/apmd.conf" -#define APM_CTL_DEVICEFILE "/dev/apmctl" -#define APM_NORM_DEVICEFILE "/dev/apm" -#define APMD_PIDFILE "/var/run/apmd.pid" -#define NICE_INCR -20 - -enum { - EVENT_NOEVENT, - EVENT_STANDBYREQ, - EVENT_SUSPENDREQ, - EVENT_NORMRESUME, - EVENT_CRITRESUME, - EVENT_BATTERYLOW, - EVENT_POWERSTATECHANGE, - EVENT_UPDATETIME, - EVENT_CRITSUSPEND, - EVENT_USERSTANDBYREQ, - EVENT_USERSUSPENDREQ, - EVENT_STANDBYRESUME, - EVENT_CAPABILITIESCHANGE, - EVENT_MAX -}; - -struct event_cmd_op { - int (* act)(void *this); - void (* dump)(void *this, FILE * fp); - struct event_cmd * (* clone)(void *this); - void (* free)(void *this); -}; -struct event_cmd { - struct event_cmd * next; - size_t len; - char * name; - struct event_cmd_op * op; -}; -struct event_cmd_exec { - struct event_cmd evcmd; - char * line; /* Command line */ -}; -struct event_cmd_reject { - struct event_cmd evcmd; -}; - -struct event_config { - const char *name; - struct event_cmd * cmdlist; - int rejectable; -}; - -struct battery_watch_event { - struct battery_watch_event *next; - int level; - enum { - BATTERY_CHARGING, - BATTERY_DISCHARGING - } direction; - enum { - BATTERY_MINUTES, - BATTERY_PERCENT - } type; - int done; - struct event_cmd *cmdlist; -}; - - -extern struct event_cmd_op event_cmd_exec_ops; -extern struct event_cmd_op event_cmd_reject_ops; -extern struct event_config events[EVENT_MAX]; -extern struct battery_watch_event *battery_watch_list; - -extern int register_battery_handlers( - int level, int direction, - struct event_cmd *cmdlist); -extern int register_apm_event_handlers( - bitstr_t bit_decl(evlist, EVENT_MAX), - struct event_cmd *cmdlist); -extern void free_event_cmd_list(struct event_cmd *p); - -extern int yyparse(void); - -void yyerror(const char *); -int yylex(void); - -struct event_cmd *event_cmd_default_clone(void *); -int event_cmd_exec_act(void *); -void event_cmd_exec_dump(void *, FILE *); -struct event_cmd *event_cmd_exec_clone(void *); -void event_cmd_exec_free(void *); -int event_cmd_reject_act(void *); -struct event_cmd *clone_event_cmd_list(struct event_cmd *); -int exec_run_cmd(struct event_cmd *); -int exec_event_cmd(struct event_config *); -void read_config(void); -void dump_config(void); -void destroy_config(void); -void restart(void); -void enque_signal(int); -void wait_child(void); -int proc_signal(int); -void proc_apmevent(int); -void check_battery(void); -void event_loop(void); Index: usr.sbin/apmd/apmd.8 =================================================================== --- usr.sbin/apmd/apmd.8 +++ /dev/null @@ -1,322 +0,0 @@ -.\" Copyright (c) 1999 Mitsuru IWASAKI -.\" Copyright (c) 1999 KOIE Hidetaka -.\" Copyright (c) 1999 Yoshihiko SARUMARU -.\" Copyright (c) 1999 Norihiro Kumagai -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)apmd.8 1.1 (FreeBSD) 6/28/99 -.\" $FreeBSD$ -.\" -.Dd June 28, 1999 -.Dt APMD 8 i386 -.Os -.Sh NAME -.Nm apmd -.Nd Advanced Power Management monitor daemon -.Sh SYNOPSIS -.Nm -.Op Fl d -.Op Fl f file -.Op Fl s -.Op Fl v -.Sh DESCRIPTION -The -.Nm -utility -monitors the occurrence of the specified Advanced Power Management -.Pq Tn APM -events and, if one of the events occurs, it executes the sequence of -commands corresponding to the event. -Only the events specified in the -configuration file are notified to -.Nm ; -all other events are ignored. -For each event posted by the APM BIOS, -.Nm -invokes the sequence of commands specified in the configuration file. -When -.Nm -is running with monitoring suspend/standby requests, -the kernel will not process those requests. -Therefore, if you wish action to be taken when these events -occur, you need to explicitly configure the appropriate commands or -built-in functions in the configuration file. -.Pp -The -.Nm -utility recognizes the following runtime options: -.Bl -tag -width f_file -.It Fl d -Starts in debug mode. -This causes -.Nm -to execute in the foreground instead of in daemon mode. -.It Fl f Ar file -Specifies a different configuration file -.Ar file -to be used in place of the default -.Pa /etc/apmd.conf . -.It Fl s -Causes -.Nm -to simulate a POWERSTATECHANGE event when a power state change is detected -(AC_POWER_STATE) but the bios of the laptop does not report it. -This enables you to do things like dimming the LCD backlight when you unplug -the power cord. -.It Fl v -Verbose mode. -.El -.Pp -When -.Nm -starts, it reads the configuration file -.Pa ( /etc/apmd.conf -as default) -and notifies the set of events to be monitored to the APM device driver. -When it terminates, the APM device driver automatically cancels -monitored events. -.Pp -If the -.Nm -process receives a -.Dv SIGHUP , -it will reread its configuration file and -notify the APM device driver of any changes to its configuration. -.Pp -The -.Nm -utility uses the device -.Pa /dev/apmctl -to issue -.Xr ioctl 2 -requests for monitoring events and for controlling the APM system. -This device file is opened exclusively, so only a single -.Nm -process can be running at any time. -.Pp -When -.Nm -receives an APM event, it forks a child process to execute the -commands specified in the configuration file and then continues -listening for more events. -The child process executes the commands -specified, one at a time and in the order that they are listed. -.Pp -While -.Nm -is processing the command list for SUSPEND/STANDBY requests, the APM kernel -device driver issues notifications to APM BIOS once per second so that the -BIOS knows that there are still some commands pending, and that it should not -complete the request just yet. -.Pp -The -.Nm -utility creates the file -.Pa /var/run/apmd.pid , -and stores its process -id there. -This can be used to kill or reconfigure -.Nm . -.Sh CONFIGURATION FILE -The structure of the -.Nm -configuration file is quite simple. -For example: -.Bd -literal -apm_event SUSPENDREQ { - exec "sync && sync && sync"; - exec "sleep 1"; - exec "zzz"; -} -.Ed -.Pp -will cause -.Nm -to receive the APM event -.Ql SUSPENDREQ -(which may be posted by an LCD close), run the -.Ql sync -command 3 times and wait for a while, then execute -.Nm zzz ( Ns Nm apm Fl z ) -to put the system in the suspend state. -.Bl -bullet -.It -The apm_event keyword -.Bd -ragged -offset indent -.Ql apm_event -is the keyword which indicates the start of configuration for -each event. -.Ed -.It -APM events -.Bd -ragged -offset indent -If you wish to execute the same commands for different events, the -event names should be delimited by a comma. -The following are -valid event names: -.Bl -item -.It -- Events ignored by the kernel if -.Nm -is running: -.Pp -.Bl -tag -width USERSUSPENDREQ -compact -offset indent -.It STANDBYREQ -.It USERSTANDBYREQ -.It SUSPENDREQ -should include sync in the command list, -.It USERSUSPENDREQ -should include sync in the command list, -.It BATTERYLOW -only zzz should be specified in the command list. -.El -.It -- Events passed to -.Nm -after kernel handling: -.Pp -.Bl -tag -width USERSUSPENDREQ -compact -offset indent -.It NORMRESUME -.It CRITRESUME -.It STANDBYRESUME -.It POWERSTATECHANGE -.It UPDATETIME -.It CAPABILITIESCHANGE -.El -.Pp -Other events will not be sent to -.Nm . -.El -.Ed -.It -command line syntax -.Bd -ragged -offset indent -In the example above, the three lines beginning with -.Ql exec -are commands for the event. -Each line should be terminated with a semicolon. -The command list for the event should be enclosed by -.Ql { -and -.Ql } . -The -.Nm -utility uses -.Pa /bin/sh -for double-quotation enclosed command execution, just as with -.Xr system 3 . -Each command is executed in order until the end of -the list is reached or a command finishes with a non-zero status code. -The -.Nm -utility will report any failed command's status code via -.Xr syslog 3 -and will then reject the request event posted by the APM BIOS. -.Ed -.It -Built-in functions -.Bd -ragged -offset indent -You can also specify -.Nm -built-in functions instead of command lines. -A built-in function name should be terminated with a semicolon, -just as with a command line. -The following built-in functions are currently supported: -.Bl -item -.It -.Bl -tag -width ".It - reject" -.It - reject -Reject last request posted by APM BIOS. -This can be used to reject -a SUSPEND request when the LCD is closed and put the system in a -STANDBY state instead. -.El -.El -.Ed -.El -.Sh FILES -.Bl -tag -width /etc/apmd.conf -compact -.It Pa /etc/apmd.conf -.It Pa /dev/apmctl -.It Pa /var/run/apmd.pid -.El -.Sh EXAMPLES -Sample configuration commands include: -.Bd -literal -apm_event SUSPENDREQ { - exec "/etc/rc.suspend apm suspend"; -} - -apm_event USERSUSPENDREQ { - exec "sync && sync && sync"; - exec "sleep 1"; - exec "apm -z"; -} - -apm_event NORMRESUME { - exec "/etc/rc.resume apm suspend"; -} - -apm_event STANDBYRESUME { - exec "/etc/rc.resume apm standby"; -} - -# resume event configuration for serial mouse users by -# reinitializing a moused(8) connected to a serial port. -# -#apm_event NORMRESUME { -# exec "kill -HUP `cat /var/run/moused.pid`"; -#} -# -# suspend request event configuration for ATA HDD users: -# execute standby instead of suspend. -# -#apm_event SUSPENDREQ { -# reject; -# exec "sync && sync && sync"; -# exec "sleep 1"; -# exec "apm -Z"; -#} -.Ed -.Sh SEE ALSO -.Xr apm 4 , -.Xr apm 8 -.Sh HISTORY -The -.Nm -utility appeared in -.Fx 3.3 . -.Sh AUTHORS -.An Mitsuru IWASAKI Aq Mt iwasaki@FreeBSD.org -.An KOIE Hidetaka Aq Mt koie@suri.co.jp -.Pp -.An -nosplit -Some contributions made by -.An Warner Losh Aq Mt imp@FreeBSD.org , -.An Hiroshi Yamashita Aq Mt bluemoon@msj.biglobe.ne.jp , -.An Yoshihiko SARUMARU Aq Mt mistral@imasy.or.jp , -.An Norihiro Kumagai Aq Mt kuma@nk.rim.or.jp , -.An NAKAGAWA Yoshihisa Aq Mt nakagawa@jp.FreeBSD.org , -and -.An Nick Hilliard Aq Mt nick@foobar.org . Index: usr.sbin/apmd/apmd.c =================================================================== --- usr.sbin/apmd/apmd.c +++ /dev/null @@ -1,707 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * APM (Advanced Power Management) Event Dispatcher - * - * Copyright (c) 1999 Mitsuru IWASAKI - * Copyright (c) 1999 KOIE Hidetaka - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "apmd.h" - -int debug_level = 0; -int verbose = 0; -int soft_power_state_change = 0; -const char *apmd_configfile = APMD_CONFIGFILE; -const char *apmd_pidfile = APMD_PIDFILE; -int apmctl_fd = -1, apmnorm_fd = -1; - -/* - * table of event handlers - */ -#define EVENT_CONFIG_INITIALIZER(EV,R) { #EV, NULL, R }, -struct event_config events[EVENT_MAX] = { - EVENT_CONFIG_INITIALIZER(NOEVENT, 0) - EVENT_CONFIG_INITIALIZER(STANDBYREQ, 1) - EVENT_CONFIG_INITIALIZER(SUSPENDREQ, 1) - EVENT_CONFIG_INITIALIZER(NORMRESUME, 0) - EVENT_CONFIG_INITIALIZER(CRITRESUME, 0) - EVENT_CONFIG_INITIALIZER(BATTERYLOW, 0) - EVENT_CONFIG_INITIALIZER(POWERSTATECHANGE, 0) - EVENT_CONFIG_INITIALIZER(UPDATETIME, 0) - EVENT_CONFIG_INITIALIZER(CRITSUSPEND, 1) - EVENT_CONFIG_INITIALIZER(USERSTANDBYREQ, 1) - EVENT_CONFIG_INITIALIZER(USERSUSPENDREQ, 1) - EVENT_CONFIG_INITIALIZER(STANDBYRESUME, 0) - EVENT_CONFIG_INITIALIZER(CAPABILITIESCHANGE, 0) -}; - -/* - * List of battery events - */ -struct battery_watch_event *battery_watch_list = NULL; - -#define BATT_CHK_INTV 10 /* how many seconds between battery state checks? */ - -/* - * default procedure - */ -struct event_cmd * -event_cmd_default_clone(void *this) -{ - struct event_cmd * oldone = this; - struct event_cmd * newone = malloc(oldone->len); - - newone->next = NULL; - newone->len = oldone->len; - newone->name = oldone->name; - newone->op = oldone->op; - return newone; -} - -/* - * exec command - */ -int -event_cmd_exec_act(void *this) -{ - struct event_cmd_exec * p = this; - int status = -1; - pid_t pid; - - switch ((pid = fork())) { - case -1: - warn("cannot fork"); - break; - case 0: - /* child process */ - signal(SIGHUP, SIG_DFL); - signal(SIGCHLD, SIG_DFL); - signal(SIGTERM, SIG_DFL); - execl(_PATH_BSHELL, "sh", "-c", p->line, (char *)NULL); - _exit(127); - default: - /* parent process */ - do { - pid = waitpid(pid, &status, 0); - } while (pid == -1 && errno == EINTR); - break; - } - return status; -} -void -event_cmd_exec_dump(void *this, FILE *fp) -{ - fprintf(fp, " \"%s\"", ((struct event_cmd_exec *)this)->line); -} -struct event_cmd * -event_cmd_exec_clone(void *this) -{ - struct event_cmd_exec * newone = (struct event_cmd_exec *) event_cmd_default_clone(this); - struct event_cmd_exec * oldone = this; - - newone->evcmd.next = NULL; - newone->evcmd.len = oldone->evcmd.len; - newone->evcmd.name = oldone->evcmd.name; - newone->evcmd.op = oldone->evcmd.op; - if ((newone->line = strdup(oldone->line)) == NULL) - err(1, "out of memory"); - return (struct event_cmd *) newone; -} -void -event_cmd_exec_free(void *this) -{ - free(((struct event_cmd_exec *)this)->line); -} -struct event_cmd_op event_cmd_exec_ops = { - event_cmd_exec_act, - event_cmd_exec_dump, - event_cmd_exec_clone, - event_cmd_exec_free -}; - -/* - * reject command - */ -int -event_cmd_reject_act(void *this __unused) -{ - int rc = 0; - - if (ioctl(apmctl_fd, APMIO_REJECTLASTREQ, NULL)) { - syslog(LOG_NOTICE, "fail to reject\n"); - rc = -1; - } - return rc; -} -struct event_cmd_op event_cmd_reject_ops = { - event_cmd_reject_act, - NULL, - event_cmd_default_clone, - NULL -}; - -/* - * manipulate event_config - */ -struct event_cmd * -clone_event_cmd_list(struct event_cmd *p) -{ - struct event_cmd dummy; - struct event_cmd *q = &dummy; - for ( ;p; p = p->next) { - assert(p->op->clone); - if ((q->next = p->op->clone(p)) == NULL) - err(1, "out of memory"); - q = q->next; - } - q->next = NULL; - return dummy.next; -} -void -free_event_cmd_list(struct event_cmd *p) -{ - struct event_cmd * q; - for ( ; p ; p = q) { - q = p->next; - if (p->op->free) - p->op->free(p); - free(p); - } -} -int -register_battery_handlers( - int level, int direction, - struct event_cmd *cmdlist) -{ - /* - * level is negative if it's in "minutes", non-negative if - * percentage. - * - * direction =1 means we care about this level when charging, - * direction =-1 means we care about it when discharging. - */ - if (level>100) /* percentage > 100 */ - return -1; - if (abs(direction) != 1) /* nonsense direction value */ - return -1; - - if (cmdlist) { - struct battery_watch_event *we; - - if ((we = malloc(sizeof(struct battery_watch_event))) == NULL) - err(1, "out of memory"); - - we->next = battery_watch_list; /* starts at NULL */ - battery_watch_list = we; - we->level = abs(level); - we->type = (level<0)?BATTERY_MINUTES:BATTERY_PERCENT; - we->direction = (direction<0)?BATTERY_DISCHARGING: - BATTERY_CHARGING; - we->done = 0; - we->cmdlist = clone_event_cmd_list(cmdlist); - } - return 0; -} -int -register_apm_event_handlers( - bitstr_t bit_decl(evlist, EVENT_MAX), - struct event_cmd *cmdlist) -{ - if (cmdlist) { - bitstr_t bit_decl(tmp, EVENT_MAX); - memcpy(&tmp, evlist, bitstr_size(EVENT_MAX)); - - for (;;) { - int n; - struct event_cmd *p; - struct event_cmd *q; - bit_ffs(tmp, EVENT_MAX, &n); - if (n < 0) - break; - p = events[n].cmdlist; - if ((q = clone_event_cmd_list(cmdlist)) == NULL) - err(1, "out of memory"); - if (p) { - while (p->next != NULL) - p = p->next; - p->next = q; - } else { - events[n].cmdlist = q; - } - bit_clear(tmp, n); - } - } - return 0; -} - -/* - * execute command - */ -int -exec_run_cmd(struct event_cmd *p) -{ - int status = 0; - - for (; p; p = p->next) { - assert(p->op->act); - if (verbose) - syslog(LOG_INFO, "action: %s", p->name); - status = p->op->act(p); - if (status) { - syslog(LOG_NOTICE, "command finished with %d\n", status); - break; - } - } - return status; -} - -/* - * execute command -- the event version - */ -int -exec_event_cmd(struct event_config *ev) -{ - int status = 0; - - status = exec_run_cmd(ev->cmdlist); - if (status && ev->rejectable) { - syslog(LOG_ERR, "canceled"); - event_cmd_reject_act(NULL); - } - return status; -} - -/* - * read config file - */ -extern FILE * yyin; -extern int yydebug; - -void -read_config(void) -{ - int i; - - if ((yyin = fopen(apmd_configfile, "r")) == NULL) { - err(1, "cannot open config file"); - } - -#ifdef DEBUG - yydebug = debug_level; -#endif - - if (yyparse() != 0) - err(1, "cannot parse config file"); - - fclose(yyin); - - /* enable events */ - for (i = 0; i < EVENT_MAX; i++) { - if (events[i].cmdlist) { - u_int event_type = i; - if (write(apmctl_fd, &event_type, sizeof(u_int)) == -1) { - err(1, "cannot enable event 0x%x", event_type); - } - } - } -} - -void -dump_config(void) -{ - int i; - struct battery_watch_event *q; - - for (i = 0; i < EVENT_MAX; i++) { - struct event_cmd * p; - if ((p = events[i].cmdlist)) { - fprintf(stderr, "apm_event %s {\n", events[i].name); - for ( ; p ; p = p->next) { - fprintf(stderr, "\t%s", p->name); - if (p->op->dump) - p->op->dump(p, stderr); - fprintf(stderr, ";\n"); - } - fprintf(stderr, "}\n"); - } - } - for (q = battery_watch_list ; q != NULL ; q = q -> next) { - struct event_cmd * p; - fprintf(stderr, "apm_battery %d%s %s {\n", - q -> level, - (q -> type == BATTERY_PERCENT)?"%":"m", - (q -> direction == BATTERY_CHARGING)?"charging": - "discharging"); - for ( p = q -> cmdlist; p ; p = p->next) { - fprintf(stderr, "\t%s", p->name); - if (p->op->dump) - p->op->dump(p, stderr); - fprintf(stderr, ";\n"); - } - fprintf(stderr, "}\n"); - } -} - -void -destroy_config(void) -{ - int i; - struct battery_watch_event *q; - - /* disable events */ - for (i = 0; i < EVENT_MAX; i++) { - if (events[i].cmdlist) { - u_int event_type = i; - if (write(apmctl_fd, &event_type, sizeof(u_int)) == -1) { - err(1, "cannot disable event 0x%x", event_type); - } - } - } - - for (i = 0; i < EVENT_MAX; i++) { - struct event_cmd * p; - if ((p = events[i].cmdlist)) - free_event_cmd_list(p); - events[i].cmdlist = NULL; - } - - for( ; battery_watch_list; battery_watch_list = battery_watch_list -> next) { - free_event_cmd_list(battery_watch_list->cmdlist); - q = battery_watch_list->next; - free(battery_watch_list); - battery_watch_list = q; - } -} - -void -restart(void) -{ - destroy_config(); - read_config(); - if (verbose) - dump_config(); -} - -/* - * write pid file - */ -static void -write_pid(void) -{ - FILE *fp = fopen(apmd_pidfile, "w"); - - if (fp) { - fprintf(fp, "%ld\n", (long)getpid()); - fclose(fp); - } -} - -/* - * handle signals - */ -static int signal_fd[2]; - -void -enque_signal(int sig) -{ - if (write(signal_fd[1], &sig, sizeof sig) != sizeof sig) - err(1, "cannot process signal."); -} - -void -wait_child(void) -{ - int status; - while (waitpid(-1, &status, WNOHANG) > 0) - ; -} - -int -proc_signal(int fd) -{ - int rc = 0; - int sig; - - while (read(fd, &sig, sizeof sig) == sizeof sig) { - syslog(LOG_INFO, "caught signal: %d", sig); - switch (sig) { - case SIGHUP: - syslog(LOG_NOTICE, "restart by SIG"); - restart(); - break; - case SIGTERM: - syslog(LOG_NOTICE, "going down on signal %d", sig); - rc = -1; - return rc; - case SIGCHLD: - wait_child(); - break; - default: - warn("unexpected signal(%d) received.", sig); - break; - } - } - return rc; -} -void -proc_apmevent(int fd) -{ - struct apm_event_info apmevent; - - while (ioctl(fd, APMIO_NEXTEVENT, &apmevent) == 0) { - int status; - syslog(LOG_NOTICE, "apmevent %04x index %d\n", - apmevent.type, apmevent.index); - syslog(LOG_INFO, "apm event: %s", events[apmevent.type].name); - if (fork() == 0) { - status = exec_event_cmd(&events[apmevent.type]); - exit(status); - } - } -} - -#define AC_POWER_STATE ((pw_info.ai_acline == 1) ? BATTERY_CHARGING :\ - BATTERY_DISCHARGING) - -void -check_battery(void) -{ - - static int first_time=1, last_state; - int status; - - struct apm_info pw_info; - struct battery_watch_event *p; - - /* If we don't care, don't bother */ - if (battery_watch_list == NULL) - return; - - if (first_time) { - if ( ioctl(apmnorm_fd, APMIO_GETINFO, &pw_info) < 0) - err(1, "cannot check battery state."); -/* - * This next statement isn't entirely true. The spec does not tie AC - * line state to battery charging or not, but this is a bit lazier to do. - */ - last_state = AC_POWER_STATE; - first_time = 0; - return; /* We can't process events, we have no baseline */ - } - - /* - * XXX - should we do this a bunch of times and perform some sort - * of smoothing or correction? - */ - if ( ioctl(apmnorm_fd, APMIO_GETINFO, &pw_info) < 0) - err(1, "cannot check battery state."); - - /* - * If we're not in the state now that we were in last time, - * then it's a transition, which means we must clean out - * the event-caught state. - */ - if (last_state != AC_POWER_STATE) { - if (soft_power_state_change && fork() == 0) { - status = exec_event_cmd(&events[PMEV_POWERSTATECHANGE]); - exit(status); - } - last_state = AC_POWER_STATE; - for (p = battery_watch_list ; p!=NULL ; p = p -> next) - p->done = 0; - } - for (p = battery_watch_list ; p != NULL ; p = p -> next) - if (p -> direction == AC_POWER_STATE && - !(p -> done) && - ((p -> type == BATTERY_PERCENT && - p -> level == (int)pw_info.ai_batt_life) || - (p -> type == BATTERY_MINUTES && - p -> level == (pw_info.ai_batt_time / 60)))) { - p -> done++; - if (verbose) - syslog(LOG_NOTICE, "Caught battery event: %s, %d%s", - (p -> direction == BATTERY_CHARGING)?"charging":"discharging", - p -> level, - (p -> type == BATTERY_PERCENT)?"%":" minutes"); - if (fork() == 0) { - status = exec_run_cmd(p -> cmdlist); - exit(status); - } - } -} -void -event_loop(void) -{ - int fdmax = 0; - struct sigaction nsa; - fd_set master_rfds; - sigset_t sigmask, osigmask; - - FD_ZERO(&master_rfds); - FD_SET(apmctl_fd, &master_rfds); - fdmax = apmctl_fd > fdmax ? apmctl_fd : fdmax; - - FD_SET(signal_fd[0], &master_rfds); - fdmax = signal_fd[0] > fdmax ? signal_fd[0] : fdmax; - - memset(&nsa, 0, sizeof nsa); - nsa.sa_handler = enque_signal; - sigfillset(&nsa.sa_mask); - nsa.sa_flags = SA_RESTART; - sigaction(SIGHUP, &nsa, NULL); - sigaction(SIGCHLD, &nsa, NULL); - sigaction(SIGTERM, &nsa, NULL); - - sigemptyset(&sigmask); - sigaddset(&sigmask, SIGHUP); - sigaddset(&sigmask, SIGCHLD); - sigaddset(&sigmask, SIGTERM); - sigprocmask(SIG_SETMASK, &sigmask, &osigmask); - - while (1) { - fd_set rfds; - int res; - struct timeval to; - - to.tv_sec = BATT_CHK_INTV; - to.tv_usec = 0; - - memcpy(&rfds, &master_rfds, sizeof rfds); - sigprocmask(SIG_SETMASK, &osigmask, NULL); - if ((res=select(fdmax + 1, &rfds, 0, 0, &to)) < 0) { - if (errno != EINTR) - err(1, "select"); - } - sigprocmask(SIG_SETMASK, &sigmask, NULL); - - if (res == 0) { /* time to check the battery */ - check_battery(); - continue; - } - - if (FD_ISSET(signal_fd[0], &rfds)) { - if (proc_signal(signal_fd[0]) < 0) - return; - } - - if (FD_ISSET(apmctl_fd, &rfds)) - proc_apmevent(apmctl_fd); - } -} - -int -main(int ac, char* av[]) -{ - int ch; - int daemonize = 1; - char *prog; - int logopt = LOG_NDELAY | LOG_PID; - - while ((ch = getopt(ac, av, "df:sv")) != -1) { - switch (ch) { - case 'd': - daemonize = 0; - debug_level++; - break; - case 'f': - apmd_configfile = optarg; - break; - case 's': - soft_power_state_change = 1; - break; - case 'v': - verbose = 1; - break; - default: - err(1, "unknown option `%c'", ch); - } - } - - if (daemonize) - daemon(0, 0); - -#ifdef NICE_INCR - nice(NICE_INCR); -#endif - - if (!daemonize) - logopt |= LOG_PERROR; - - prog = strrchr(av[0], '/'); - openlog(prog ? prog+1 : av[0], logopt, LOG_DAEMON); - - syslog(LOG_NOTICE, "start"); - - if (pipe(signal_fd) < 0) - err(1, "pipe"); - if (fcntl(signal_fd[0], F_SETFL, O_NONBLOCK) < 0) - err(1, "fcntl"); - - if ((apmnorm_fd = open(APM_NORM_DEVICEFILE, O_RDWR)) == -1) { - err(1, "cannot open device file `%s'", APM_NORM_DEVICEFILE); - } - - if (fcntl(apmnorm_fd, F_SETFD, 1) == -1) { - err(1, "cannot set close-on-exec flag for device file '%s'", APM_NORM_DEVICEFILE); - } - - if ((apmctl_fd = open(APM_CTL_DEVICEFILE, O_RDWR)) == -1) { - err(1, "cannot open device file `%s'", APM_CTL_DEVICEFILE); - } - - if (fcntl(apmctl_fd, F_SETFD, 1) == -1) { - err(1, "cannot set close-on-exec flag for device file '%s'", APM_CTL_DEVICEFILE); - } - - restart(); - write_pid(); - event_loop(); - exit(EXIT_SUCCESS); -} - Index: usr.sbin/apmd/apmd.conf =================================================================== --- usr.sbin/apmd/apmd.conf +++ /dev/null @@ -1,55 +0,0 @@ -# apmd Configuration File -# -# $FreeBSD$ -# - -apm_event SUSPENDREQ { - exec "/etc/rc.suspend apm suspend"; -} - -apm_event USERSUSPENDREQ { - exec "sync && sync && sync"; - exec "sleep 1"; - exec "apm -z"; -} - -apm_event NORMRESUME { - exec "/etc/rc.resume apm suspend"; -} - -apm_event STANDBYRESUME { - exec "/etc/rc.resume apm standby"; -} - -# resume event configuration for serial mouse users by -# reinitializing a moused(8) connected to a serial port. -# -#apm_event NORMRESUME { -# exec "kill -HUP `cat /var/run/moused.pid`"; -#} - -# suspend request event configuration for ATA HDD users: -# execute standby instead of suspend. -# -#apm_event SUSPENDREQ { -# reject; -# exec "sync && sync && sync"; -# exec "sleep 1"; -# exec "apm -Z"; -#} - -# Sample entries for battery state monitoring -#apm_battery 5% discharging { -# exec "logger -p user.emerg battery status critical!"; -# exec "echo T250L8CE-GE-C >/dev/speaker"; -#} -#apm_battery 1% discharging { -# exec "logger -p user.emerg battery low - emergency suspend"; -# exec "echo T250L16B+BA+AG+GF+FED+DC+CC >/dev/speaker"; -# exec "apm -z"; -#} -#apm_battery 99% charging { -# exec "logger -p user.notice battery fully charged"; -#} - -# apmd Configuration ends here Index: usr.sbin/apmd/apmdlex.l =================================================================== --- usr.sbin/apmd/apmdlex.l +++ /dev/null @@ -1,120 +0,0 @@ -%{ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * APM (Advanced Power Management) Event Dispatcher - * - * Copyright (c) 1999 Mitsuru IWASAKI - * Copyright (c) 1999 KOIE Hidetaka - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include "apmd.h" -#include "y.tab.h" - -int lineno; -int first_time; -%} - -/* We don't need it, avoid the warning. */ -%option noyywrap -%option nounput -%option noinput - -%s TOP - -%% - -%{ - if (first_time) { - BEGIN TOP; - lineno = 1; - first_time = 0; - } -%} - -[ \t]+ ; -\n lineno++; -, { return COMMA; } -; { return SEMICOLON; } -#.*$ ; - -apm_event { return APMEVENT; } - -NOEVENT { yylval.ev = EVENT_NOEVENT; return EVENT; } -STANDBYREQ { yylval.ev = EVENT_STANDBYREQ; return EVENT; } -SUSPENDREQ { yylval.ev = EVENT_SUSPENDREQ; return EVENT; } -NORMRESUME { yylval.ev = EVENT_NORMRESUME; return EVENT; } -CRITRESUME { yylval.ev = EVENT_CRITRESUME; return EVENT; } -BATTERYLOW { yylval.ev = EVENT_BATTERYLOW; return EVENT; } -POWERSTATECHANGE { yylval.ev = EVENT_POWERSTATECHANGE; return EVENT; } -UPDATETIME { yylval.ev = EVENT_UPDATETIME; return EVENT; } -CRITSUSPEND { yylval.ev = EVENT_CRITSUSPEND; return EVENT; } -USERSTANDBYREQ { yylval.ev = EVENT_USERSTANDBYREQ; return EVENT; } -USERSUSPENDREQ { yylval.ev = EVENT_USERSUSPENDREQ; return EVENT; } -STANDBYRESUME { yylval.ev = EVENT_STANDBYRESUME; return EVENT; } -CAPABILITIESCHANGE { yylval.ev = EVENT_CAPABILITIESCHANGE; return EVENT; } - -apm_battery { return APMBATT; } - -charging { return BATTCHARGE; } -discharging { return BATTDISCHARGE; } -[0-9]+% { - yylval.i = atoi(yytext); - return BATTPERCENT; - } -[0-9]+[Mm] { - yylval.i = -atoi(yytext); - return BATTTIME; - } - -exec { return EXECCMD; } -reject { return REJECTCMD; } - -\{ { return BEGINBLOCK; } -\} { return ENDBLOCK; } -\"[^"]+\" { - int len = strlen(yytext) - 2; - if ((yylval.str = (char *) malloc(len + 1)) == NULL) - goto out; - memcpy(yylval.str, yytext + 1, len); - yylval.str[len] = '\0'; - out: - return STRING; - } - -[^"{},;#\n\t ]+ { yylval.str = strdup(yytext); return UNKNOWN; } -%% - -void -yyerror(const char *s) -{ - syslog(LOG_ERR, "line %d: %s%s %s.\n", lineno, yytext, yytext?":":"", s); -} Index: usr.sbin/apmd/apmdparse.y =================================================================== --- usr.sbin/apmd/apmdparse.y +++ /dev/null @@ -1,208 +0,0 @@ -%{ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * APM (Advanced Power Management) Event Dispatcher - * - * Copyright (c) 1999 Mitsuru IWASAKI - * Copyright (c) 1999 KOIE Hidetaka - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include "apmd.h" - -#ifdef DEBUG -#define YYDEBUG 1 -#endif - -extern int first_time; - -%} - -%union { - char *str; - bitstr_t bit_decl(evlist, EVENT_MAX); - int ev; - struct event_cmd * evcmd; - int i; -} - -%token BEGINBLOCK ENDBLOCK -%token COMMA SEMICOLON -%token APMEVENT -%token APMBATT -%token BATTCHARGE BATTDISCHARGE -%token BATTTIME BATTPERCENT -%token EXECCMD REJECTCMD -%token EVENT -%token STRING UNKNOWN - -%type apm_battery_level -%type apm_battery_direction -%type string -%type unknown -%type event_list -%type cmd_list -%type cmd -%type exec_cmd reject_cmd - -%% - -config_file - : { first_time = 1; } config_list - ; - -config_list - : config - | config_list config - ; - -config - : apm_event_statement - | apm_battery_statement - ; - -apm_event_statement - : APMEVENT event_list BEGINBLOCK cmd_list ENDBLOCK - { - if (register_apm_event_handlers($2, $4) < 0) - abort(); /* XXX */ - free_event_cmd_list($4); - } - ; - -apm_battery_level - : BATTPERCENT - { - $$ = $1; - } - | BATTTIME - { - $$ = $1; - } - ; - -apm_battery_direction - : BATTCHARGE - { - $$ = 1; - } - | BATTDISCHARGE - { - $$ = -1; - } - ; -apm_battery_statement - : APMBATT apm_battery_level apm_battery_direction - BEGINBLOCK cmd_list ENDBLOCK - { - if (register_battery_handlers($2, $3, $5) < 0) - abort(); /* XXX */ - free_event_cmd_list($5); - } - ; - -event_list - : EVENT - { - bit_nclear($$, 0, EVENT_MAX - 1); - bit_set($$, $1); - } - | event_list COMMA EVENT - { - memcpy(&($$), &($1), bitstr_size(EVENT_MAX)); - bit_set($$, $3); - } - ; - -cmd_list - : /* empty */ - { - $$ = NULL; - } - | cmd_list cmd - { - struct event_cmd * p = $1; - if (p) { - while (p->next != NULL) - p = p->next; - p->next = $2; - $$ = $1; - } else { - $$ = $2; - } - } - ; - -cmd - : exec_cmd SEMICOLON { $$ = $1; } - | reject_cmd SEMICOLON { $$ = $1; } - ; - -exec_cmd - : EXECCMD string - { - size_t len = sizeof (struct event_cmd_exec); - struct event_cmd_exec *cmd = malloc(len); - cmd->evcmd.next = NULL; - cmd->evcmd.len = len; - cmd->evcmd.name = "exec"; - cmd->evcmd.op = &event_cmd_exec_ops; - cmd->line = $2; - $$ = (struct event_cmd *) cmd; - } - ; - -reject_cmd - : REJECTCMD - { - size_t len = sizeof (struct event_cmd_reject); - struct event_cmd_reject *cmd = malloc(len); - cmd->evcmd.next = NULL; - cmd->evcmd.len = len; - cmd->evcmd.name = "reject"; - cmd->evcmd.op = &event_cmd_reject_ops; - $$ = (struct event_cmd *) cmd; - } - ; - -string - : STRING { $$ = $1; } - ; - -unknown - : UNKNOWN - { - $$ = $1; - } - ; -%% - Index: usr.sbin/apmd/contrib/pccardq.c =================================================================== --- usr.sbin/apmd/contrib/pccardq.c +++ /dev/null @@ -1,286 +0,0 @@ -/* $FreeBSD$ */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char *const pccardd_file = "/var/tmp/.pccardd"; -const char *prog = "pccardq"; -const char *tmp_dir = "/tmp"; -unsigned slot_map = ~0; - -void -usage(void) -{ - fprintf(stderr, "usage: %s [-a] [-n] [-s slot]\n", prog); -} - -int -proc_arg(int ac, char **av) -{ - int rc = -1; - int ch; - - char *p = strrchr(av[0], '/'); - prog = p ? p + 1 : av[0]; - - tmp_dir = getenv("TMPDIR") ? getenv("TMPDIR") : tmp_dir; - - while ((ch = getopt(ac, av, "ans:")) != -1) { - switch (ch) { - case 'a': - slot_map = ~0; - break; - case 'n': - slot_map = 0; - break; - case 's': - { - int n = atoi(optarg); - if (n < 0 || n >= CHAR_BIT * sizeof slot_map) { - warnc(0, "Invalid slot number."); - usage(); - goto out; - } - if (slot_map == ~0) - slot_map = 0; - slot_map |= 1 << n; - } - break; - default: - usage(); - goto out; - } - } - - rc = 0; - out: - return rc; -} - -int -connect_to_pccardd(char **path) -{ - int so = -1; - int pccardd_len; - struct sockaddr_un pccardq; - struct sockaddr_un pccardd; - - if ((so = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { - warn("socket"); - goto err; - } - - snprintf(pccardq.sun_path, sizeof pccardq.sun_path, - "%s/%s%ld%ld", tmp_dir, prog, (long) getpid(), (long) time(0)); - pccardq.sun_family = AF_UNIX; - pccardq.sun_len = offsetof(struct sockaddr_un, sun_path) + strlen(pccardq.sun_path); - if (bind(so, (struct sockaddr *) &pccardq, pccardq.sun_len) < 0) { - warn("bind: %s", pccardq.sun_path); - goto err; - } - if ((*path = strdup(pccardq.sun_path)) == NULL) { - warn("strdup"); - goto err; - } - - pccardd_len = strlen(pccardd_file) + 1; - if (pccardd_len > sizeof pccardd.sun_path) { - warnc(0, "%s: too long", pccardd_file); - goto err; - } - pccardd.sun_len = offsetof(struct sockaddr_un, sun_path) + pccardd_len; - pccardd.sun_family = AF_UNIX; - strcpy(pccardd.sun_path, pccardd_file); - if (connect(so, (struct sockaddr *) &pccardd, pccardd.sun_len) < 0) { - warn("connect: %s", pccardd_file); - goto err; - } - return so; - err: - if (so >= 0) - close(so); - return -1; -} - -int -get_slot_number(int so) -{ - char buf[8]; - int rv; - int nslot; - - if ((rv = write(so, "S", 1)) < 1) { - warn("write"); - goto err; - } else if (rv != 1) { - warnc(0, "write: fail."); - goto err; - } - - if ((rv = read(so, buf, sizeof buf)) < 0) { - warn("read"); - goto err; - } - buf[sizeof buf - 1] = 0; - if (sscanf(buf, "%d", &nslot) != 1) { - warnc(0, "Invalid response."); - goto err; - } - return nslot; - err: - return -1; -} - -enum { - SLOT_EMPTY = 0, - SLOT_FILLED = 1, - SLOT_INACTIVE = 2, - SLOT_UNDEFINED = 9 -}; - -int -get_slot_info(int so, int slot, char **manuf, char **version, char - **device, int *state) -{ - int rc = -1; - int rv; - static char buf[1024]; - int slen; - char *s; - char *sl; - - char *_manuf; - char *_version; - char *_device; - - if ((slen = snprintf(buf, sizeof buf, "N%d", slot)) < 0) { - warnc(0, "write"); - goto err; - } - - if ((rv = write(so, buf, slen)) < 0) { - warn("write"); - goto err; - } else if (rv != slen) { - warnc(0, "write"); - goto err; - } - - if ((rv = read(so, buf, sizeof buf)) < 0) { - warn("read"); - goto err; - } - - s = buf; - if ((sl = strsep(&s, "~")) == NULL) - goto parse_err; - if (atoi(sl) != slot) - goto parse_err; - if ((_manuf = strsep(&s, "~")) == NULL) - goto parse_err; - if ((_version = strsep(&s, "~")) == NULL) - goto parse_err; - if ((_device = strsep(&s, "~")) == NULL) - goto parse_err; - if (sscanf(s, "%1d", state) != 1) - goto parse_err; - if (s != NULL && strchr(s, '~') != NULL) - goto parse_err; - - if ((*manuf = strdup(_manuf)) == NULL) { - warn("strdup"); - goto err; - } - if ((*version = strdup(_version)) == NULL) { - warn("strdup"); - goto err; - } - if ((*device = strdup(_device)) == NULL) { - warn("strdup"); - goto err; - } - if (*manuf == NULL || *version == NULL || *device == NULL) { - warn("strdup"); - goto err; - } - - rc = 0; - err: - return rc; - parse_err: - warnc(0, "Invalid response: %*s", rv, buf); - return rc; -} - -const char * -strstate(int state) -{ - switch (state) { - case 0: - return "empty"; - case 1: - return "filled"; - case 2: - return "inactive"; - default: - return "unknown"; - } -} - -int -main(int ac, char **av) -{ - char *path = NULL; - int so = -1; - int nslot; - int i; - - if (proc_arg(ac, av) < 0) - goto out; - if ((so = connect_to_pccardd(&path)) < 0) - goto out; - if ((nslot = get_slot_number(so)) < 0) - goto out; - if (slot_map == 0) { - printf("%d\n", nslot); - } else { - for (i = 0; i < nslot; i++) { - if ((slot_map & (1 << i))) { - char *manuf; - char *version; - char *device; - int state; - - if (get_slot_info(so, i, &manuf, &version, &device, - &state) < 0) - goto out; - if (manuf == NULL || version == NULL || device == NULL) - goto out; - printf("%d~%s~%s~%s~%s\n", - i, manuf, version, device, strstate(state)); - free(manuf); - free(version); - free(device); - } - } - } - out: - if (path) { - unlink(path); - free(path); - } - if (so >= 0) - close(so); - exit(0); -} Index: usr.sbin/powerd/powerd.8 =================================================================== --- usr.sbin/powerd/powerd.8 +++ usr.sbin/powerd/powerd.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 3, 2020 +.Dd September 18, 2020 .Dt POWERD 8 .Os .Sh NAME @@ -125,10 +125,7 @@ Enforces method for AC line state refresh; by default, it is chosen automatically. The set of valid methods is -.Cm sysctl , devd -and -.Cm apm -(i386 only). +.Cm sysctl , devd . .It Fl v Verbose mode. Messages about power changes will be printed to stdout and @@ -142,7 +139,6 @@ .El .Sh SEE ALSO .Xr acpi 4 , -.Xr apm 4 , .Xr cpufreq 4 .Sh HISTORY The Index: usr.sbin/powerd/powerd.c =================================================================== --- usr.sbin/powerd/powerd.c +++ usr.sbin/powerd/powerd.c @@ -49,14 +49,6 @@ #include #include -#ifdef __i386__ -#define USE_APM -#endif - -#ifdef USE_APM -#include -#endif - #define DEFAULT_ACTIVE_PERCENT 75 #define DEFAULT_IDLE_PERCENT 50 #define DEFAULT_POLL_INTERVAL 250 /* Poll interval in milliseconds */ @@ -82,7 +74,6 @@ #define ACPIAC "hw.acpi.acline" #define PMUAC "dev.pmu.0.acline" -#define APMDEV "/dev/apm" #define DEVDPIPE "/var/run/devd.pipe" #define DEVCTL_MAXBUF 1024 @@ -117,15 +108,9 @@ ac_none, ac_sysctl, ac_acpi_devd, -#ifdef USE_APM - ac_apm, -#endif } acline_mode_t; static acline_mode_t acline_mode; static acline_mode_t acline_mode_user = ac_none; -#ifdef USE_APM -static int apm_fd = -1; -#endif static int devd_pipe = -1; #define DEVD_RETRY_INTERVAL 60 /* seconds */ @@ -290,8 +275,8 @@ } /* - * Try to use ACPI to find the AC line status. If this fails, fall back - * to APM. If nothing succeeds, we'll just run in default mode. + * Try to use ACPI to find the AC line status. If nothing succeeds, + * we'll just run in default mode. */ static void acline_init(void) @@ -314,13 +299,6 @@ acline_mode = ac_sysctl; if (vflag) warnx("using sysctl for AC line status"); -#endif -#ifdef USE_APM - } else if ((skip_source_check || acline_mode_user == ac_apm) && - (apm_fd = open(APMDEV, O_RDONLY)) >= 0) { - if (vflag) - warnx("using APM for AC line status"); - acline_mode = ac_apm; #endif } else { warnx("unable to determine AC line status"); @@ -362,32 +340,10 @@ else acline_status = SRC_UNKNOWN; } -#ifdef USE_APM - if (acline_mode == ac_apm) { - struct apm_info info; - - if (ioctl(apm_fd, APMIO_GETINFO, &info) == 0) { - acline_status = (info.ai_acline ? SRC_AC : SRC_BATTERY); - } else { - close(apm_fd); - apm_fd = -1; - acline_mode = ac_none; - acline_status = SRC_UNKNOWN; - } - } -#endif /* try to (re)connect to devd */ -#ifdef USE_APM - if ((acline_mode == ac_sysctl && - (acline_mode_user == ac_none || - acline_mode_user == ac_acpi_devd)) || - (acline_mode == ac_apm && - acline_mode_user == ac_acpi_devd)) { -#else if (acline_mode == ac_sysctl && (acline_mode_user == ac_none || acline_mode_user == ac_acpi_devd)) { -#endif struct timeval now; gettimeofday(&now, NULL); @@ -459,10 +415,6 @@ acline_mode_user = ac_sysctl; else if (strcmp(arg, "devd") == 0) acline_mode_user = ac_acpi_devd; -#ifdef USE_APM - else if (strcmp(arg, "apm") == 0) - acline_mode_user = ac_apm; -#endif else errx(1, "bad option: -%c %s", (char)ch, optarg); } @@ -623,7 +575,7 @@ pidfile_write(pfh); } - /* Decide whether to use ACPI or APM to read the AC line status. */ + /* Decide to use ACPI to read the AC line status. */ acline_init(); /* Index: usr.sbin/zzz/zzz.8 =================================================================== --- usr.sbin/zzz/zzz.8 +++ usr.sbin/zzz/zzz.8 @@ -24,12 +24,12 @@ .\" .\" $FreeBSD$ .\" -.Dd July 13, 2003 +.Dd September 18, 2020 .Dt ZZZ 8 .Os .Sh NAME .Nm zzz -.Nd suspend an ACPI or APM system +.Nd suspend an ACPI system .Sh SYNOPSIS .Nm .Sh DESCRIPTION @@ -38,16 +38,8 @@ utility checks for .Tn ACPI -or -.Tn APM support and then suspends the system appropriately. For -.Tn APM , -.Pp -.Dl apm -z -.Pp -will be issued. -For .Tn ACPI, the configured suspend state will be looked up, checked to see if it is supported and, @@ -57,9 +49,7 @@ will be issued. .Sh SEE ALSO .Xr acpi 4 , -.Xr apm 4 , -.Xr acpiconf 8 , -.Xr apm 8 +.Xr acpiconf 8 .Sh AUTHORS This manual page was written by .An Nate Lawson Aq Mt njl@FreeBSD.org . Index: usr.sbin/zzz/zzz.sh =================================================================== --- usr.sbin/zzz/zzz.sh +++ usr.sbin/zzz/zzz.sh @@ -1,8 +1,7 @@ #!/bin/sh # -# Suspend the system using either ACPI or APM. -# For APM, "apm -z" will be issued. -# For ACPI, the configured suspend state will be looked up, checked to see +# Suspend the system using either ACPI +# The configured suspend state will be looked up, checked to see # if it is supported, and "acpiconf -s " will be issued. # # Mark Santcroos @@ -13,7 +12,6 @@ ACPI_SUSPEND_STATE=hw.acpi.suspend_state ACPI_SUPPORTED_STATES=hw.acpi.supported_sleep_state -APM_SUSPEND_DELAY=machdep.apm_suspend_delay # Check for ACPI support if sysctl $ACPI_SUSPEND_STATE >/dev/null 2>&1; then @@ -32,12 +30,8 @@ echo -n "is not supported. " echo "Supported states: $SUPPORTED_STATES" fi -# Check for APM support -elif sysctl $APM_SUSPEND_DELAY >/dev/null 2>&1; then - # Execute APM style suspend command - exec apm -z else - echo "Error: no ACPI or APM suspend support found." + echo "Error: no ACPI suspend support found." fi exit 1