git: 8a3fafc82114 - main - acpi/apm: Improve APM ioctl interface emulation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 11 Jan 2024 00:06:31 UTC
The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=8a3fafc821149e800747cd92afee092fd131c402 commit 8a3fafc821149e800747cd92afee092fd131c402 Author: Warner Losh <imp@FreeBSD.org> AuthorDate: 2024-01-03 23:18:23 +0000 Commit: Warner Losh <imp@FreeBSD.org> CommitDate: 2024-01-11 00:05:00 +0000 acpi/apm: Improve APM ioctl interface emulation The apm(8) program documents certain states, but doesn't document the 'unknown' state. It reports things correctly for systems with a battery, but incorrectly for systems without one. Emulate the old interface a little better by saying ac power is online if we have no status (instead of unknown), the battery has a high charge of 255% if there's no battery (instead of -1). Programs, like emacs, expect to see only the documented values and misbehave when they see something else. This is closer to what would happen on old-school APM machines. Sadly (or not) I have no access to old-school APM machines to 100% confirm this, but reading the spec, old code and testing with emacs' mode line with battery suggests these values are more correct. emacs has never been converted to acpi_conf due to permissions issues with acpi devices. Fixing the kernel is preferable to hacking apm(8) for these special cases because other programs that use these interfaces will also be more correct. The kernel also has more data with which to decide what to return. Sponsored by: Netflix MFC After: 1 week --- sys/x86/acpica/acpi_apm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/x86/acpica/acpi_apm.c b/sys/x86/acpica/acpi_apm.c index ffefcdf733c2..fcc1663b9a84 100644 --- a/sys/x86/acpica/acpi_apm.c +++ b/sys/x86/acpica/acpi_apm.c @@ -141,18 +141,18 @@ acpi_capm_get_info(apm_info_t aip) aip->ai_capabilities= 0xff00; /* unknown */ if (acpi_acad_get_acline(&acline)) - aip->ai_acline = APM_UNKNOWN; /* unknown */ + aip->ai_acline = 1; /* no info -- on-line best guess */ else aip->ai_acline = acline; /* on/off */ if (acpi_battery_get_battinfo(NULL, &batt) != 0) { - aip->ai_batt_stat = APM_UNKNOWN; - aip->ai_batt_life = APM_UNKNOWN; - aip->ai_batt_time = -1; /* unknown */ - aip->ai_batteries = ~0U; /* unknown */ + aip->ai_batt_stat = 0; /* "high" old I/F has no unknown state */ + aip->ai_batt_life = 255; /* N/A, not -1 */ + aip->ai_batt_time = -1; /* unknown */ + aip->ai_batteries = ~0U; /* unknown */ } else { aip->ai_batt_stat = acpi_capm_convert_battstate(&batt); - aip->ai_batt_life = batt.cap; + aip->ai_batt_life = (batt.cap == -1) ? 255 : batt.cap; aip->ai_batt_time = (batt.min == -1) ? -1 : batt.min * 60; aip->ai_batteries = acpi_battery_get_units(); } @@ -186,11 +186,11 @@ acpi_capm_get_pwstatus(apm_pwstatus_t app) app->ap_batt_stat = acpi_capm_convert_battstate(&batt); app->ap_batt_flag = acpi_capm_convert_battflags(&batt); - app->ap_batt_life = batt.cap; + app->ap_batt_life = (batt.cap == -1) ? 255 : batt.cap; app->ap_batt_time = (batt.min == -1) ? -1 : batt.min * 60; if (acpi_acad_get_acline(&acline)) - app->ap_acline = APM_UNKNOWN; + app->ap_acline = 1; /* no info -- on-line best guess */ else app->ap_acline = acline; /* on/off */