small cleanup of acpi battery status setting and checking

This is based on the patch submitted by Yuri Skripachov.
Overview of the changes:
- clarify double-use of some ACPI_BATT_STAT_* definitions
- clean up undefined/extended status bits returned by _BST
- warn about charging+discharging bits being set at the same time

PR:		kern/124744
Submitted by:	Yuri Skripachov <y.skripachov@gmail.com>
Tested by:	Yuri Skripachov <y.skripachov@gmail.com>
MFC after:	2 weeks
This commit is contained in:
Andriy Gapon 2010-12-17 16:21:30 +00:00
parent f23ba7b103
commit 766d7e6539
4 changed files with 23 additions and 4 deletions

View File

@ -102,8 +102,9 @@ acpi_battery_get_info_expire(void)
int
acpi_battery_bst_valid(struct acpi_bst *bst)
{
return (bst->state < ACPI_BATT_STAT_MAX && bst->cap != ACPI_BATT_UNKNOWN &&
bst->volt != ACPI_BATT_UNKNOWN);
return (bst->state != ACPI_BATT_STAT_NOT_PRESENT &&
bst->cap != ACPI_BATT_UNKNOWN && bst->volt != ACPI_BATT_UNKNOWN);
}
/* Check _BIF results for validity. */

View File

@ -279,6 +279,12 @@ acpi_cmbat_get_bst(void *arg)
goto end;
acpi_cmbat_info_updated(&sc->bst_lastupdated);
/* Clear out undefined/extended bits that might be set by hardware. */
sc->bst.state &= ACPI_BATT_STAT_BST_MASK;
if ((sc->bst.state & ACPI_BATT_STAT_INVALID) == ACPI_BATT_STAT_INVALID)
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
"battery reports simultaneous charging and discharging\n");
/* XXX If all batteries are critical, perhaps we should suspend. */
if (sc->bst.state & ACPI_BATT_STAT_CRITICAL) {
if ((sc->flags & ACPI_BATT_STAT_CRITICAL) == 0) {

View File

@ -390,6 +390,7 @@ acpi_smbat_get_bst(device_t dev, struct acpi_bst *bst)
if (val > 0) {
sc->bst.rate = val * factor;
sc->bst.state &= ~SMBATT_BS_DISCHARGING;
sc->bst.state |= ACPI_BATT_STAT_CHARGING;
} else if (val < 0)
sc->bst.rate = (-val) * factor;

View File

@ -74,11 +74,22 @@ struct acpi_bst {
uint32_t volt; /* Present Voltage */
};
/*
* Note that the following definitions represent status bits for internal
* driver state. The first three of them (charging, discharging and critical)
* conveninetly conform to ACPI specification of status returned by _BST
* method. Other definitions (not present, etc) are synthetic.
* Also note that according to the specification the charging and discharging
* status bits must not be set at the same time.
*/
#define ACPI_BATT_STAT_DISCHARG 0x0001
#define ACPI_BATT_STAT_CHARGING 0x0002
#define ACPI_BATT_STAT_CRITICAL 0x0004
#define ACPI_BATT_STAT_NOT_PRESENT 0x0007
#define ACPI_BATT_STAT_MAX 0x0007
#define ACPI_BATT_STAT_INVALID \
(ACPI_BATT_STAT_DISCHARG | ACPI_BATT_STAT_CHARGING)
#define ACPI_BATT_STAT_BST_MASK \
(ACPI_BATT_STAT_INVALID | ACPI_BATT_STAT_CRITICAL)
#define ACPI_BATT_STAT_NOT_PRESENT ACPI_BATT_STAT_BST_MASK
union acpi_battery_ioctl_arg {
int unit; /* Device unit or ACPI_BATTERY_ALL_UNITS. */