static void acpi_cmbat_get_bst(void *arg) { struct acpi_cmbat_softc *sc; ACPI_STATUS as; ACPI_OBJECT *res; ACPI_HANDLE h; ACPI_BUFFER bst_buffer; device_t dev; ACPI_SERIAL_ASSERT(cmbat); dev = arg; sc = device_get_softc(dev); h = acpi_get_handle(dev); bst_buffer.Pointer = NULL; bst_buffer.Length = ACPI_ALLOCATE_BUFFER; if (!acpi_cmbat_info_expired(&sc->bst_lastupdated)) goto end; as = AcpiEvaluateObject(h, "_BST", NULL, &bst_buffer); if (ACPI_FAILURE(as)) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "error fetching current battery status -- %s\n", AcpiFormatException(as)); goto end; } res = (ACPI_OBJECT *)bst_buffer.Pointer; if (!ACPI_PKG_VALID(res, 4)) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "battery status corrupted\n"); goto end; } if (acpi_PkgInt32(res, 0, &sc->bst.state) != 0) goto end; if (acpi_PkgInt32(res, 1, &sc->bst.rate) != 0) goto end; if (acpi_PkgInt32(res, 2, &sc->bst.cap) != 0) goto end; if (acpi_PkgInt32(res, 3, &sc->bst.volt) != 0) goto end; acpi_cmbat_info_updated(&sc->bst_lastupdated); /* 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) { sc->flags |= ACPI_BATT_STAT_CRITICAL; device_printf(dev, "critically low charge!\n"); } } else sc->flags &= ~ACPI_BATT_STAT_CRITICAL; end: if (bst_buffer.Pointer != NULL) AcpiOsFree(bst_buffer.Pointer); }
static void acpi_cmbat_get_bif(void *context) { device_t dev; struct acpi_cmbat_softc *sc; ACPI_STATUS as; ACPI_OBJECT *res, *tmp; ACPI_HANDLE h; ACPI_BUFFER bif_buffer; dev = context; sc = device_get_softc(dev); h = acpi_get_handle(dev); bif_buffer.Pointer = NULL; if (!acpi_cmbat_info_expired(&sc->bif_lastupdated)) { return; } if (sc->bif_updating) { return; } sc->bif_updating = 1; bif_buffer.Length = ACPI_ALLOCATE_BUFFER; if (ACPI_FAILURE(as = AcpiEvaluateObject(h, "_BIF", NULL, &bif_buffer))) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "error fetching current battery info -- %s\n", AcpiFormatException(as)); goto end; } res = (ACPI_OBJECT *)bif_buffer.Pointer; if ((res == NULL) || (res->Type != ACPI_TYPE_PACKAGE) || (res->Package.Count != 13)) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "battery info corrupted\n"); goto end; } PKG_GETINT(res, tmp, 0, sc->bif.unit, end); PKG_GETINT(res, tmp, 1, sc->bif.dcap, end); PKG_GETINT(res, tmp, 2, sc->bif.lfcap, end); PKG_GETINT(res, tmp, 3, sc->bif.btech, end); PKG_GETINT(res, tmp, 4, sc->bif.dvol, end); PKG_GETINT(res, tmp, 5, sc->bif.wcap, end); PKG_GETINT(res, tmp, 6, sc->bif.lcap, end); PKG_GETINT(res, tmp, 7, sc->bif.gra1, end); PKG_GETINT(res, tmp, 8, sc->bif.gra2, end); PKG_GETSTR(res, tmp, 9, sc->bif.model, ACPI_CMBAT_MAXSTRLEN, end); PKG_GETSTR(res, tmp, 10, sc->bif.serial, ACPI_CMBAT_MAXSTRLEN, end); PKG_GETSTR(res, tmp, 11, sc->bif.type, ACPI_CMBAT_MAXSTRLEN, end); PKG_GETSTR(res, tmp, 12, sc->bif.oeminfo, ACPI_CMBAT_MAXSTRLEN, end); acpi_cmbat_info_updated(&sc->bif_lastupdated); end: if (bif_buffer.Pointer != NULL) AcpiOsFree(bif_buffer.Pointer); sc->bif_updating = 0; }
static void acpi_cmbat_get_bst(void *context) { device_t dev; struct acpi_cmbat_softc *sc; ACPI_STATUS as; ACPI_OBJECT *res, *tmp; ACPI_HANDLE h; ACPI_BUFFER bst_buffer; dev = context; sc = device_get_softc(dev); h = acpi_get_handle(dev); bst_buffer.Pointer = NULL; if (!acpi_cmbat_info_expired(&sc->bst_lastupdated)) { return; } if (sc->bst_updating) { return; } sc->bst_updating = 1; bst_buffer.Length = ACPI_ALLOCATE_BUFFER; if (ACPI_FAILURE(as = AcpiEvaluateObject(h, "_BST", NULL, &bst_buffer))) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "error fetching current battery status -- %s\n", AcpiFormatException(as)); goto end; } res = (ACPI_OBJECT *)bst_buffer.Pointer; if ((res == NULL) || (res->Type != ACPI_TYPE_PACKAGE) || (res->Package.Count != 4)) { ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "battery status corrupted\n"); goto end; } PKG_GETINT(res, tmp, 0, sc->bst.state, end); PKG_GETINT(res, tmp, 1, sc->bst.rate, end); PKG_GETINT(res, tmp, 2, sc->bst.cap, end); PKG_GETINT(res, tmp, 3, sc->bst.volt, end); acpi_cmbat_info_updated(&sc->bst_lastupdated); end: if (bst_buffer.Pointer != NULL) AcpiOsFree(bst_buffer.Pointer); sc->bst_updating = 0; }
int acpi_cmbat_get_battinfo(int unit, struct acpi_battinfo *battinfo) { int error; device_t dev; struct acpi_cmbat_softc *sc; if (unit == -1) { return (acpi_cmbat_get_total_battinfo(battinfo)); } if (acpi_cmbat_info_expired(&acpi_cmbat_info_lastupdated)) { error = acpi_cmbat_get_total_battinfo(battinfo); if (error) { goto out; } } error = 0; if (unit >= acpi_cmbat_units) { error = ENXIO; goto out; } if ((dev = devclass_get_device(acpi_cmbat_devclass, unit)) == NULL) { error = ENXIO; goto out; } if ((sc = device_get_softc(dev)) == NULL) { error = ENXIO; goto out; } if (!sc->present) { battinfo->cap = -1; battinfo->min = -1; battinfo->state = ACPI_BATT_STAT_NOT_PRESENT; } else { battinfo->cap = sc->cap; battinfo->min = sc->min; battinfo->state = sc->bst.state; } out: return (error); }