Hi, this patch fixes wrong power unit reporting when booting without battery and inserting the battery later on Asus EEE 901 and Samsung N220 on i386. Both normally report amphour, but sensors gets fixed to watthour when booting without battery. When type change is detected on battery event, this patch detaches old sensors and attaches new ones with correct type.
Have send this to @misc a few months ago without reaction. Patch ok? Anyone here interested in this? regards Matthias 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 3 Apr 2011 12:20:57 -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,17 +106,9 @@ 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; @@ -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;