Hi, when booting my Asus EEE 901 netbook without battery, the power unit type is reported as Watthour, whereas if booted with battery inserted its Amphour. The same behavior appears on my Samsung netbook at work.
Although not really serious, I just noticed because it broke my shutdown scripts and mode line display. I fixed this by checking the _BIF type on acpi refresh and detaching / reattaching the "last full / warning / low / remaining" capacity sensors if the types differ when battery gets inserted. Works on i386 on Asus EEE 901, will test on Samsung netbook tomorrow. ok? Comments? Index: src/sys/dev/acpi/acpibat.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpibat.c,v retrieving revision 1.58 diff -u -r1.58 acpibat.c --- src/sys/dev/acpi/acpibat.c 10 Nov 2010 21:40:55 -0000 1.58 +++ src/sys/dev/acpi/acpibat.c 23 Nov 2010 21:48:53 -0000 @@ -45,6 +45,7 @@ const char *acpibat_hids[] = { ACPI_DEV_CMB, 0 }; void acpibat_monitor(struct acpibat_softc *); +void acpibat_attach_power_unit_sensors(int, struct acpibat_softc *); void acpibat_refresh(void *); int acpibat_getbif(struct acpibat_softc *); int acpibat_getbst(struct acpibat_softc *); @@ -105,23 +106,15 @@ acpibat_notify, sc, ACPIDEV_POLL); } -void -acpibat_monitor(struct acpibat_softc *sc) +void +acpibat_attach_power_unit_sensors(int type, struct acpibat_softc *sc) { - int type; - - /* assume _BIF and _BST have been called */ - strlcpy(sc->sc_sensdev.xname, DEVNAME(sc), - sizeof(sc->sc_sensdev.xname)); - - type = sc->sc_bif.bif_power_unit ? SENSOR_AMPHOUR : SENSOR_WATTHOUR; - strlcpy(sc->sc_sens[0].desc, "last full capacity", sizeof(sc->sc_sens[0].desc)); sc->sc_sens[0].type = type; sensor_attach(&sc->sc_sensdev, &sc->sc_sens[0]); sc->sc_sens[0].value = sc->sc_bif.bif_last_capacity * 1000; - + strlcpy(sc->sc_sens[1].desc, "warning capacity", sizeof(sc->sc_sens[1].desc)); sc->sc_sens[1].type = type; @@ -134,6 +127,27 @@ sensor_attach(&sc->sc_sensdev, &sc->sc_sens[2]); sc->sc_sens[2].value = sc->sc_bif.bif_low * 1000; + strlcpy(sc->sc_sens[6].desc, "remaining capacity", + sizeof(sc->sc_sens[6].desc)); + sc->sc_sens[6].type = type; + sensor_attach(&sc->sc_sensdev, &sc->sc_sens[6]); + sc->sc_sens[6].value = sc->sc_bst.bst_capacity * 1000; +} + +void +acpibat_monitor(struct acpibat_softc *sc) +{ + int type; + + /* assume _BIF and _BST have been called */ + strlcpy(sc->sc_sensdev.xname, DEVNAME(sc), + sizeof(sc->sc_sensdev.xname)); + + type = sc->sc_bif.bif_power_unit ? SENSOR_AMPHOUR : SENSOR_WATTHOUR; + + /* attach sensors 0,1,2,6 with power unit Ah or Wh */ + acpibat_attach_power_unit_sensors (type, sc); + strlcpy(sc->sc_sens[3].desc, "voltage", sizeof(sc->sc_sens[3].desc)); sc->sc_sens[3].type = SENSOR_VOLTS_DC; sensor_attach(&sc->sc_sensdev, &sc->sc_sens[3]); @@ -150,12 +164,6 @@ sensor_attach(&sc->sc_sensdev, &sc->sc_sens[5]); sc->sc_sens[5].value = sc->sc_bst.bst_rate; - strlcpy(sc->sc_sens[6].desc, "remaining capacity", - sizeof(sc->sc_sens[6].desc)); - sc->sc_sens[6].type = type; - sensor_attach(&sc->sc_sensdev, &sc->sc_sens[6]); - sc->sc_sens[6].value = sc->sc_bst.bst_capacity * 1000; - strlcpy(sc->sc_sens[7].desc, "current voltage", sizeof(sc->sc_sens[7].desc)); sc->sc_sens[7].type = SENSOR_VOLTS_DC; @@ -169,7 +177,7 @@ acpibat_refresh(void *arg) { struct acpibat_softc *sc = arg; - int i; + int i, type; dnprintf(30, "%s: %s: refresh\n", DEVNAME(sc), sc->sc_devnode->name); @@ -187,6 +195,16 @@ } /* _BIF values are static, sensor 0..3 */ + type = sc->sc_bif.bif_power_unit ? SENSOR_AMPHOUR : SENSOR_WATTHOUR; + if (type != sc->sc_sens[0].type) { + /* power units in sensor and _BIF differ */ + sensor_detach(&sc->sc_sensdev, &sc->sc_sens[0]); + sensor_detach(&sc->sc_sensdev, &sc->sc_sens[1]); + sensor_detach(&sc->sc_sensdev, &sc->sc_sens[2]); + sensor_detach(&sc->sc_sensdev, &sc->sc_sens[6]); + + acpibat_attach_power_unit_sensors (type, sc); + } if (sc->sc_bif.bif_last_capacity == BIF_UNKNOWN) { sc->sc_sens[0].value = 0; sc->sc_sens[0].status = SENSOR_S_UNKNOWN;