Example #1
0
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);
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
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);
}