mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
apm(8): Remove support for APM BIOS
Drop support for queries and commands that are not supported by ACPI's /dev/apm interface. This includes dropping support for enabling/disabling APM BIOS used by /etc/rc.d/apm. Reviewed by: ziaee, imp Differential Revision: https://reviews.freebsd.org/D59941
This commit is contained in:
1 parent
8cf4fe39e8
commit
40ce54ccd9
7 files changed
+26
-394
No files matched your search
@@ -51,6 +51,9 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20260930: apm(8) only displays ACPI status
|
||||
OLD_FILES+=etc/rc.d/apm
|
||||
|
||||
# 20260930: apm(4) not i386-specific
|
||||
OLD_FILES+=usr/share/man/man4/i386/apm.4.gz
|
||||
|
||||
|
||||
@@ -97,12 +97,6 @@ ACPIPACKAGE= acpi
|
||||
ACPI= power_profile
|
||||
.endif
|
||||
|
||||
.if ${MACHINE} == "i386"
|
||||
CONFGROUPS.${MK_APM}+= APM
|
||||
APMPACKAGE= apm
|
||||
APM= apm
|
||||
.endif
|
||||
|
||||
CONFGROUPS.${MK_AUDIT}+= AUDIT
|
||||
AUDITPACKAGE= audit
|
||||
AUDIT= auditd \
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
#
|
||||
|
||||
# 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
|
||||
|
||||
# doesn't make sense to run in a svcj: nojail keyword
|
||||
apm_svcj="NO"
|
||||
|
||||
run_rc_command "$1"
|
||||
@@ -293,14 +293,6 @@ A list of jail properties for the service.
|
||||
See
|
||||
.Sx SERVICE JAILS
|
||||
for a list of valid properties.
|
||||
.It Va apm_enable
|
||||
.Pq Vt bool
|
||||
If set to
|
||||
.Dq Li YES ,
|
||||
enable support for Automatic Power Management with
|
||||
the
|
||||
.Xr apm 8
|
||||
command.
|
||||
.It Va devd_enable
|
||||
.Pq Vt bool
|
||||
Run
|
||||
@@ -5170,7 +5162,6 @@ to
|
||||
.Xr security 7 ,
|
||||
.Xr tuning 7 ,
|
||||
.Xr accton 8 ,
|
||||
.Xr apm 8 ,
|
||||
.Xr bsdinstall 8 ,
|
||||
.Xr bthidd 8 ,
|
||||
.Xr chkprintcap 8 ,
|
||||
|
||||
@@ -60,10 +60,8 @@ OLD_FILES+=etc/devd/power_profile.conf
|
||||
.endif
|
||||
|
||||
.if ${MK_APM} == no
|
||||
OLD_FILES+=etc/rc.d/apm
|
||||
OLD_FILES+=usr/sbin/apm
|
||||
.elif ${TARGET_ARCH} != "i386"
|
||||
OLD_FILES+=etc/rc.d/apm
|
||||
OLD_FILES+=usr/share/man/man8/apm.8.gz
|
||||
.endif
|
||||
|
||||
.if ${MK_AT} == no
|
||||
|
||||
+12
-72
@@ -9,25 +9,19 @@
|
||||
.\" the author assume any responsibility for damages incurred with its
|
||||
.\" use.
|
||||
.\"
|
||||
.Dd September 23, 2026
|
||||
.Dd September 30, 2026
|
||||
.Dt APM 8 i386
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm apm
|
||||
.Nd control the APM BIOS and display its information
|
||||
.Nd display power management status
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl ablstzZ
|
||||
.Op Fl d Ar enable
|
||||
.Op Fl e Ar enable
|
||||
.Op Fl h Ar enable
|
||||
.Op Fl r Ar delta
|
||||
.Op Fl abltzZ
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility
|
||||
controls the Intel / Microsoft APM (Advanced Power Management) BIOS and
|
||||
displays the current status of APM on laptop PCs.
|
||||
utility reports power management status.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
@@ -52,49 +46,10 @@ status,
|
||||
status,
|
||||
.Dq charging
|
||||
status respectively.
|
||||
.It Fl d Ar enable
|
||||
Disable/enable suspending of the display separately from a normal suspend
|
||||
using the boolean value for
|
||||
.Ar enable .
|
||||
This feature seems to not work on many different laptops,
|
||||
including the Libretto 30CT and 50CT.
|
||||
.It Fl e Ar enable
|
||||
Enable or disable APM functions of the computer,
|
||||
depending on the boolean
|
||||
.Ar enable
|
||||
argument.
|
||||
.It Fl h Ar enable
|
||||
Depending on the boolean value of
|
||||
.Ar enable ,
|
||||
enable or disable the HLT instruction in the kernel context switch routine.
|
||||
These options are not necessary for almost all APM implementations,
|
||||
but for some implementations whose
|
||||
.Dq Pa Idle CPU
|
||||
call executes both CPU clock slowdown and HLT instruction,
|
||||
.Fl h Cm false
|
||||
is necessary to prevent the system from reducing its peak performance.
|
||||
See
|
||||
.Xr apm 4
|
||||
for details.
|
||||
.It Fl l
|
||||
Display the remaining battery percentage.
|
||||
If your laptop does not
|
||||
support this function, 255 is displayed.
|
||||
.It Fl r Ar delta
|
||||
Enable the resume wakeup timer, if the laptop supports it.
|
||||
This
|
||||
does not actually suspend the laptop, but if the laptop is suspended,
|
||||
and it supports resume from suspend, then it will be resumed after
|
||||
.Ar delta
|
||||
seconds (from when you run this command, not from when you suspend).
|
||||
.It Fl s
|
||||
Display the status of the APM support as an integer value.
|
||||
The values
|
||||
0 and 1 correspond to the
|
||||
.Dq disabled
|
||||
state or
|
||||
.Dq enabled
|
||||
state respectively.
|
||||
.It Fl t
|
||||
Display the estimated remaining battery lifetime in seconds.
|
||||
If
|
||||
@@ -103,12 +58,6 @@ it is unknown, -1 is displayed.
|
||||
Transition the system into standby mode.
|
||||
This mode uses less power than
|
||||
full power mode, but more than suspend mode.
|
||||
Some laptops support
|
||||
resuming from this state on timer or Ring Indicator events.
|
||||
The
|
||||
output of
|
||||
.Nm
|
||||
tells what your laptop claims to support.
|
||||
.It Fl z
|
||||
Suspend the system.
|
||||
.El
|
||||
@@ -119,24 +68,15 @@ displays information and current status of APM in verbose mode.
|
||||
If multiple display options are given, the values are displayed one
|
||||
per line in the order given here.
|
||||
.Sh SEE ALSO
|
||||
.Xr acpiconf 8 ,
|
||||
.Xr acpi 4 ,
|
||||
.Xr apm 4 ,
|
||||
.Xr zzz 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility originally controlled the Advanced Power Management (APM) BIOS
|
||||
extension on i386,
|
||||
now it interfaces with ACPI.
|
||||
.Sh AUTHORS
|
||||
.An Tatsumi Hosokawa Aq Mt [email protected]
|
||||
.Sh BUGS
|
||||
Some APM implementations do not support parameters needed by
|
||||
.Nm .
|
||||
On such systems,
|
||||
.Nm
|
||||
displays them as unknown.
|
||||
.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
|
||||
.Nm
|
||||
or
|
||||
.Nm zzz .
|
||||
+10
-254
@@ -13,103 +13,29 @@
|
||||
* Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <machine/apm_bios.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define APMDEV "/dev/apm"
|
||||
|
||||
#define APM_UNKNOWN 255
|
||||
|
||||
#define xh(a) (((a) & 0xff00) >> 8)
|
||||
#define xl(a) ((a) & 0xff)
|
||||
#define APMERR(a) xh(a)
|
||||
|
||||
static int cmos_wall = 0; /* True when wall time is in cmos clock, else UTC */
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: apm [-ablstzZ] [-d enable ] [ -e enable ] "
|
||||
"[ -h enable ] [-r delta]\n");
|
||||
"usage: apm [-abltzZ]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 1 for boolean true, and 0 for false, according to the
|
||||
* interpretation of the string argument given.
|
||||
*/
|
||||
static int
|
||||
is_true(const char *boolean)
|
||||
{
|
||||
char *endp;
|
||||
long val;
|
||||
|
||||
val = strtoul(boolean, &endp, 0);
|
||||
if (*endp == '\0')
|
||||
return (val != 0 ? 1 : 0);
|
||||
if (strcasecmp(boolean, "true") == 0 ||
|
||||
strcasecmp(boolean, "yes") == 0 ||
|
||||
strcasecmp(boolean, "enable") == 0)
|
||||
return (1);
|
||||
if (strcasecmp(boolean, "false") == 0 ||
|
||||
strcasecmp(boolean, "no") == 0 ||
|
||||
strcasecmp(boolean, "disable") == 0)
|
||||
return (0);
|
||||
/* Well, I have no idea what the user wants, so... */
|
||||
warnx("invalid boolean argument \"%s\"", boolean);
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
int2bcd(int i)
|
||||
{
|
||||
int retval = 0;
|
||||
int base = 0;
|
||||
|
||||
if (i >= 10000)
|
||||
return -1;
|
||||
|
||||
while (i) {
|
||||
retval |= (i % 10) << base;
|
||||
i /= 10;
|
||||
base += 4;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
bcd2int(int bcd)
|
||||
{
|
||||
int retval = 0;
|
||||
int place = 1;
|
||||
|
||||
if (bcd > 0x9999)
|
||||
return -1;
|
||||
|
||||
while (bcd) {
|
||||
retval += (bcd & 0xf) * place;
|
||||
bcd >>= 4;
|
||||
place *= 10;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
apm_suspend(int fd)
|
||||
{
|
||||
@@ -131,18 +57,6 @@ apm_getinfo(int fd, apm_info_t aip)
|
||||
err(1, "ioctl(APMIO_GETINFO)");
|
||||
}
|
||||
|
||||
static void
|
||||
apm_enable(int fd, int enable)
|
||||
{
|
||||
if (enable) {
|
||||
if (ioctl(fd, APMIO_ENABLE) == -1)
|
||||
err(1, "ioctl(APMIO_ENABLE)");
|
||||
} else {
|
||||
if (ioctl(fd, APMIO_DISABLE) == -1)
|
||||
err(1, "ioctl(APMIO_DISABLE)");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_batt_time(int batt_time)
|
||||
{
|
||||
@@ -188,10 +102,8 @@ print_batt_stat(u_int batt_stat)
|
||||
}
|
||||
|
||||
static void
|
||||
print_all_info(int fd, apm_info_t aip, int bioscall_available)
|
||||
print_all_info(int fd, apm_info_t aip)
|
||||
{
|
||||
struct apm_bios_arg args;
|
||||
int apmerr;
|
||||
const char *line_msg[] = { "off-line", "on-line" , "backup power"};
|
||||
|
||||
printf("APM version: %d.%d\n", aip->ai_major, aip->ai_minor);
|
||||
@@ -237,69 +149,6 @@ print_all_info(int fd, apm_info_t aip, int bioscall_available)
|
||||
}
|
||||
}
|
||||
|
||||
if (bioscall_available) {
|
||||
/*
|
||||
* try to get the suspend timer
|
||||
*/
|
||||
bzero(&args, sizeof(args));
|
||||
args.eax = (APM_BIOS) << 8 | APM_RESUMETIMER;
|
||||
args.ebx = PMDV_APMBIOS;
|
||||
args.ecx = 0x0001;
|
||||
if (ioctl(fd, APMIO_BIOS, &args)) {
|
||||
printf("Resume timer: unknown\n");
|
||||
} else {
|
||||
apmerr = APMERR(args.eax);
|
||||
if (apmerr == 0x0d || apmerr == 0x86)
|
||||
printf("Resume timer: disabled\n");
|
||||
else if (apmerr)
|
||||
warnx(
|
||||
"failed to get the resume timer: APM error0x%x", apmerr);
|
||||
else {
|
||||
/*
|
||||
* OK. We have the time (all bcd).
|
||||
* CH - seconds
|
||||
* DH - hours
|
||||
* DL - minutes
|
||||
* xh(SI) - month (1-12)
|
||||
* xl(SI) - day of month (1-31)
|
||||
* DI - year
|
||||
*/
|
||||
struct tm tm;
|
||||
char buf[1024];
|
||||
time_t t;
|
||||
|
||||
tm.tm_sec = bcd2int(xh(args.ecx));
|
||||
tm.tm_min = bcd2int(xl(args.edx));
|
||||
tm.tm_hour = bcd2int(xh(args.edx));
|
||||
tm.tm_mday = bcd2int(xl(args.esi));
|
||||
tm.tm_mon = bcd2int(xh(args.esi)) - 1;
|
||||
tm.tm_year = bcd2int(args.edi) - 1900;
|
||||
if (cmos_wall)
|
||||
t = mktime(&tm);
|
||||
else
|
||||
t = timegm(&tm);
|
||||
if (t != -1) {
|
||||
tm = *localtime(&t);
|
||||
strftime(buf, sizeof(buf), "%c", &tm);
|
||||
printf("Resume timer: %s\n", buf);
|
||||
} else
|
||||
printf("Resume timer: unknown\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the ring indicator resume state
|
||||
*/
|
||||
bzero(&args, sizeof(args));
|
||||
args.eax = (APM_BIOS) << 8 | APM_RESUMEONRING;
|
||||
args.ebx = PMDV_APMBIOS;
|
||||
args.ecx = 0x0002;
|
||||
if (ioctl(fd, APMIO_BIOS, &args) == 0) {
|
||||
printf("Resume on ring indicator: %sabled\n",
|
||||
args.ecx ? "en" : "dis");
|
||||
}
|
||||
}
|
||||
|
||||
if (aip->ai_infoversion >= 1) {
|
||||
if (aip->ai_capabilities == 0xff00)
|
||||
return;
|
||||
@@ -324,72 +173,15 @@ print_all_info(int fd, apm_info_t aip, int bioscall_available)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* currently, it can turn off the display, but the display never comes
|
||||
* back until the machine suspend/resumes :-).
|
||||
*/
|
||||
static void
|
||||
apm_display(int fd, int newstate)
|
||||
{
|
||||
if (ioctl(fd, APMIO_DISPLAY, &newstate) == -1)
|
||||
err(1, "ioctl(APMIO_DISPLAY)");
|
||||
}
|
||||
|
||||
static void
|
||||
apm_haltcpu(int fd, int enable)
|
||||
{
|
||||
if (enable) {
|
||||
if (ioctl(fd, APMIO_HALTCPU, NULL) == -1)
|
||||
err(1, "ioctl(APMIO_HALTCPU)");
|
||||
} else {
|
||||
if (ioctl(fd, APMIO_NOTHALTCPU, NULL) == -1)
|
||||
err(1, "ioctl(APMIO_NOTHALTCPU)");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
apm_set_timer(int fd, int delta)
|
||||
{
|
||||
time_t tmr;
|
||||
struct tm *tm;
|
||||
struct apm_bios_arg args;
|
||||
|
||||
tmr = time(NULL) + delta;
|
||||
if (cmos_wall)
|
||||
tm = localtime(&tmr);
|
||||
else
|
||||
tm = gmtime(&tmr);
|
||||
bzero(&args, sizeof(args));
|
||||
args.eax = (APM_BIOS) << 8 | APM_RESUMETIMER;
|
||||
args.ebx = PMDV_APMBIOS;
|
||||
if (delta > 0) {
|
||||
args.ecx = (int2bcd(tm->tm_sec) << 8) | 0x02;
|
||||
args.edx = (int2bcd(tm->tm_hour) << 8) | int2bcd(tm->tm_min);
|
||||
args.esi = (int2bcd(tm->tm_mon + 1) << 8) | int2bcd(tm->tm_mday);
|
||||
args.edi = int2bcd(tm->tm_year + 1900);
|
||||
} else {
|
||||
args.ecx = 0x0000;
|
||||
}
|
||||
if (ioctl(fd, APMIO_BIOS, &args)) {
|
||||
err(1,"set resume timer");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int c, fd;
|
||||
int dosleep = 0, all_info = 1, apm_status = 0, batt_status = 0;
|
||||
int display = -1, batt_life = 0, ac_status = 0, standby = 0;
|
||||
int batt_time = 0, delta = 0, enable = -1, haltcpu = -1;
|
||||
int bioscall_available = 0;
|
||||
size_t cmos_wall_len = sizeof(cmos_wall);
|
||||
int dosleep = 0, all_info = 1, batt_status = 0;
|
||||
int batt_life = 0, ac_status = 0, standby = 0;
|
||||
int batt_time = 0;
|
||||
|
||||
if (sysctlbyname("machdep.wall_cmos_clock", &cmos_wall, &cmos_wall_len,
|
||||
NULL, 0) == -1)
|
||||
err(1, "sysctlbyname(machdep.wall_cmos_clock)");
|
||||
|
||||
while ((c = getopt(argc, argv, "abe:h:lRr:stzd:Z")) != -1) {
|
||||
while ((c = getopt(argc, argv, "abltzZ")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
ac_status = 1;
|
||||
@@ -399,32 +191,10 @@ main(int argc, char *argv[])
|
||||
batt_status = 1;
|
||||
all_info = 0;
|
||||
break;
|
||||
case 'd':
|
||||
display = is_true(optarg);
|
||||
all_info = 0;
|
||||
break;
|
||||
case 'l':
|
||||
batt_life = 1;
|
||||
all_info = 0;
|
||||
break;
|
||||
case 'R':
|
||||
delta = -1;
|
||||
break;
|
||||
case 'r':
|
||||
delta = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
apm_status = 1;
|
||||
all_info = 0;
|
||||
break;
|
||||
case 'e':
|
||||
enable = is_true(optarg);
|
||||
all_info = 0;
|
||||
break;
|
||||
case 'h':
|
||||
haltcpu = is_true(optarg);
|
||||
all_info = 0;
|
||||
break;
|
||||
case 't':
|
||||
batt_time = 1;
|
||||
all_info = 0;
|
||||
@@ -444,44 +214,30 @@ main(int argc, char *argv[])
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
}
|
||||
if (haltcpu != -1 || enable != -1 || display != -1 || delta || dosleep
|
||||
|| standby) {
|
||||
if (dosleep || standby)
|
||||
fd = open(APMDEV, O_RDWR);
|
||||
bioscall_available = 1;
|
||||
} else if ((fd = open(APMDEV, O_RDWR)) >= 0)
|
||||
bioscall_available = 1;
|
||||
else
|
||||
fd = open(APMDEV, O_RDONLY);
|
||||
if (fd == -1)
|
||||
err(1, "can't open %s", APMDEV);
|
||||
if (enable != -1)
|
||||
apm_enable(fd, enable);
|
||||
if (haltcpu != -1)
|
||||
apm_haltcpu(fd, haltcpu);
|
||||
if (delta)
|
||||
apm_set_timer(fd, delta);
|
||||
if (dosleep)
|
||||
apm_suspend(fd);
|
||||
else if (standby)
|
||||
apm_standby(fd);
|
||||
else if (delta == 0) {
|
||||
else {
|
||||
struct apm_info info;
|
||||
|
||||
apm_getinfo(fd, &info);
|
||||
if (all_info)
|
||||
print_all_info(fd, &info, bioscall_available);
|
||||
print_all_info(fd, &info);
|
||||
if (ac_status)
|
||||
printf("%d\n", info.ai_acline);
|
||||
if (batt_status)
|
||||
printf("%d\n", info.ai_batt_stat);
|
||||
if (batt_life)
|
||||
printf("%d\n", info.ai_batt_life);
|
||||
if (apm_status)
|
||||
printf("%d\n", info.ai_status);
|
||||
if (batt_time)
|
||||
printf("%d\n", info.ai_batt_time);
|
||||
if (display != -1)
|
||||
apm_display(fd, display);
|
||||
}
|
||||
close(fd);
|
||||
exit(0);
|
||||
|
||||
Reference in new issue
Block a user