summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi_cmbat.c
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2005-07-23 19:36:00 +0000
committernjl <njl@FreeBSD.org>2005-07-23 19:36:00 +0000
commit1cb806cc9e5fbdc3e914ad946522d64a8237ff6a (patch)
tree098bd44131b4884e3f9bfa4b18f7728aa68f1ff4 /sys/dev/acpica/acpi_cmbat.c
parentdd4ae2e4bda1d9276dd71e2dd37fe3ee108c4d91 (diff)
downloadFreeBSD-src-1cb806cc9e5fbdc3e914ad946522d64a8237ff6a.zip
FreeBSD-src-1cb806cc9e5fbdc3e914ad946522d64a8237ff6a.tar.gz
Rewrite the acpi_battery interface to allow for other battery types
(i.e., smart battery) and fix various bugs found during the cleanup. API changes: * kernel access: Access to individual batteries is now via devclass_find("battery"). Introduce new methods ACPI_BATT_GET_STATUS (for _BST-formatted data) and ACPI_BATT_GET_INFO (for _BIF-formatted data). The helper function acpi_battery_get_battinfo() now takes a device_t instead of a unit # argument. If dev is NULL, this signifies all batteries. * ioctl access: The ACPIIO_BATT_GET_TYPE and ACPIIO_BATT_GET_BATTDESC ioctls have been removed. Since there is now no need for a mapping between "virtual" unit and physical unit, usermode programs can just specify the unit directly and skip the old translation steps. In fact, acpiconf(8) was actually already doing this and virtual unit was the same as physical unit in all cases since there was previously only one battery type (acpi_cmbat). Additionally, we now map the ACPIIO_BATT_GET_BIF and ACPIIO_BATT_GET_BST ioctls for all batteries, if they provide the associated methods. * apm compatibility device/ioctls: no change * sysctl: no change Since most third-party applications use the apm(4) compat interface, there should be very few affected applications (if any). Reviewed by: bruno MFC after: 5 days
Diffstat (limited to 'sys/dev/acpica/acpi_cmbat.c')
-rw-r--r--sys/dev/acpica/acpi_cmbat.c509
1 files changed, 149 insertions, 360 deletions
diff --git a/sys/dev/acpica/acpi_cmbat.c b/sys/dev/acpica/acpi_cmbat.c
index 54e4982..e60ea17 100644
--- a/sys/dev/acpica/acpi_cmbat.c
+++ b/sys/dev/acpica/acpi_cmbat.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2005 Nate Lawson
* Copyright (c) 2000 Munehiro Matsuda
* Copyright (c) 2000 Takanori Watanabe
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
@@ -24,10 +25,11 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/kernel.h>
@@ -60,41 +62,29 @@ ACPI_MODULE_NAME("BATTERY")
struct acpi_cmbat_softc {
device_t dev;
+ int flags;
struct acpi_bif bif;
struct acpi_bst bst;
struct timespec bif_lastupdated;
struct timespec bst_lastupdated;
-
- int flags;
- int present;
- int cap;
- int min;
- int full_charge_time;
- int initializing;
- int phys_unit;
};
-static struct timespec acpi_cmbat_info_lastupdated;
ACPI_SERIAL_DECL(cmbat, "ACPI cmbat");
-/* XXX: devclass_get_maxunit() don't give us the current allocated units. */
-static int acpi_cmbat_units = 0;
-
-static int acpi_cmbat_info_expired(struct timespec *);
-static void acpi_cmbat_info_updated(struct timespec *);
-static void acpi_cmbat_get_bst(void *);
-static void acpi_cmbat_get_bif(void *);
-static void acpi_cmbat_notify_handler(ACPI_HANDLE, UINT32, void *);
-static int acpi_cmbat_probe(device_t);
-static int acpi_cmbat_attach(device_t);
-static int acpi_cmbat_detach(device_t);
-static int acpi_cmbat_resume(device_t);
-static int acpi_cmbat_ioctl(u_long, caddr_t, void *);
-static int acpi_cmbat_is_bst_valid(struct acpi_bst*);
-static int acpi_cmbat_is_bif_valid(struct acpi_bif*);
-static int acpi_cmbat_get_total_battinfo(struct acpi_battinfo *);
-static void acpi_cmbat_init_battery(void *);
+static int acpi_cmbat_probe(device_t dev);
+static int acpi_cmbat_attach(device_t dev);
+static int acpi_cmbat_detach(device_t dev);
+static int acpi_cmbat_resume(device_t dev);
+static void acpi_cmbat_notify_handler(ACPI_HANDLE h, UINT32 notify,
+ void *context);
+static int acpi_cmbat_info_expired(struct timespec *lastupdated);
+static void acpi_cmbat_info_updated(struct timespec *lastupdated);
+static void acpi_cmbat_get_bst(device_t dev);
+static void acpi_cmbat_get_bif(device_t dev);
+static int acpi_cmbat_bst(device_t dev, struct acpi_bst *bstp);
+static int acpi_cmbat_bif(device_t dev, struct acpi_bif *bifp);
+static void acpi_cmbat_init_battery(void *arg);
static device_method_t acpi_cmbat_methods[] = {
/* Device interface */
@@ -103,11 +93,15 @@ static device_method_t acpi_cmbat_methods[] = {
DEVMETHOD(device_detach, acpi_cmbat_detach),
DEVMETHOD(device_resume, acpi_cmbat_resume),
+ /* ACPI battery interface */
+ DEVMETHOD(acpi_batt_get_info, acpi_cmbat_bif),
+ DEVMETHOD(acpi_batt_get_status, acpi_cmbat_bst),
+
{0, 0}
};
static driver_t acpi_cmbat_driver = {
- "acpi_cmbat",
+ "battery",
acpi_cmbat_methods,
sizeof(struct acpi_cmbat_softc),
};
@@ -117,6 +111,96 @@ DRIVER_MODULE(acpi_cmbat, acpi, acpi_cmbat_driver, acpi_cmbat_devclass, 0, 0);
MODULE_DEPEND(acpi_cmbat, acpi, 1, 1, 1);
static int
+acpi_cmbat_probe(device_t dev)
+{
+ static char *cmbat_ids[] = { "PNP0C0A", NULL };
+
+ if (acpi_disabled("cmbat") ||
+ ACPI_ID_PROBE(device_get_parent(dev), dev, cmbat_ids) == NULL)
+ return (ENXIO);
+
+ device_set_desc(dev, "ACPI Control Method Battery");
+ return (0);
+}
+
+static int
+acpi_cmbat_attach(device_t dev)
+{
+ int error;
+ ACPI_HANDLE handle;
+ struct acpi_cmbat_softc *sc;
+
+ sc = device_get_softc(dev);
+ handle = acpi_get_handle(dev);
+ sc->dev = dev;
+
+ timespecclear(&sc->bif_lastupdated);
+ timespecclear(&sc->bst_lastupdated);
+
+ error = acpi_battery_register(dev);
+ if (error != 0) {
+ device_printf(dev, "registering battery failed\n");
+ return (error);
+ }
+
+ /*
+ * Install a system notify handler in addition to the device notify.
+ * Toshiba notebook uses this alternate notify for its battery.
+ */
+ AcpiInstallNotifyHandler(handle, ACPI_ALL_NOTIFY,
+ acpi_cmbat_notify_handler, dev);
+
+ AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_init_battery, dev);
+
+ return (0);
+}
+
+static int
+acpi_cmbat_detach(device_t dev)
+{
+
+ acpi_battery_remove(dev);
+ return (0);
+}
+
+static int
+acpi_cmbat_resume(device_t dev)
+{
+
+ AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_init_battery, dev);
+ return (0);
+}
+
+static void
+acpi_cmbat_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
+{
+ struct acpi_cmbat_softc *sc;
+ device_t dev;
+
+ dev = (device_t)context;
+ sc = device_get_softc(dev);
+
+ /*
+ * Clear the appropriate last updated time. The next call to retrieve
+ * the battery status will get the new value for us. We don't need to
+ * acquire a lock since we are only clearing the time stamp and since
+ * calling _BST/_BIF can trigger a notify, we could deadlock also.
+ */
+ switch (notify) {
+ case ACPI_NOTIFY_DEVICE_CHECK:
+ case ACPI_BATTERY_BST_CHANGE:
+ timespecclear(&sc->bst_lastupdated);
+ break;
+ case ACPI_NOTIFY_BUS_CHECK:
+ case ACPI_BATTERY_BIF_CHANGE:
+ timespecclear(&sc->bif_lastupdated);
+ break;
+ }
+
+ acpi_UserNotify("CMBAT", h, notify);
+}
+
+static int
acpi_cmbat_info_expired(struct timespec *lastupdated)
{
struct timespec curtime;
@@ -145,9 +229,8 @@ acpi_cmbat_info_updated(struct timespec *lastupdated)
}
static void
-acpi_cmbat_get_bst(void *context)
+acpi_cmbat_get_bst(device_t dev)
{
- device_t dev;
struct acpi_cmbat_softc *sc;
ACPI_STATUS as;
ACPI_OBJECT *res;
@@ -156,7 +239,6 @@ acpi_cmbat_get_bst(void *context)
ACPI_SERIAL_ASSERT(cmbat);
- dev = context;
sc = device_get_softc(dev);
h = acpi_get_handle(dev);
bst_buffer.Pointer = NULL;
@@ -205,9 +287,8 @@ end:
}
static void
-acpi_cmbat_get_bif(void *context)
+acpi_cmbat_get_bif(device_t dev)
{
- device_t dev;
struct acpi_cmbat_softc *sc;
ACPI_STATUS as;
ACPI_OBJECT *res;
@@ -216,7 +297,6 @@ acpi_cmbat_get_bif(void *context)
ACPI_SERIAL_ASSERT(cmbat);
- dev = context;
sc = device_get_softc(dev);
h = acpi_get_handle(dev);
bif_buffer.Pointer = NULL;
@@ -273,319 +353,59 @@ end:
AcpiOsFree(bif_buffer.Pointer);
}
-static void
-acpi_cmbat_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
-{
- device_t dev;
- struct acpi_cmbat_softc *sc;
-
- dev = (device_t)context;
- sc = device_get_softc(dev);
-
- acpi_UserNotify("CMBAT", h, notify);
-
- /*
- * Clear the appropriate last updated time. The next call to retrieve
- * the battery status will get the new value for us. We don't need to
- * acquire a lock since we are only clearing the time stamp and since
- * calling _BST/_BIF can trigger a notify, we could deadlock also.
- */
- switch (notify) {
- case ACPI_NOTIFY_DEVICE_CHECK:
- case ACPI_BATTERY_BST_CHANGE:
- timespecclear(&sc->bst_lastupdated);
- break;
- case ACPI_NOTIFY_BUS_CHECK:
- case ACPI_BATTERY_BIF_CHANGE:
- timespecclear(&sc->bif_lastupdated);
- break;
- default:
- break;
- }
-}
-
-static int
-acpi_cmbat_probe(device_t dev)
-{
- static char *cmbat_ids[] = { "PNP0C0A", NULL };
-
- if (acpi_disabled("cmbat") ||
- ACPI_ID_PROBE(device_get_parent(dev), dev, cmbat_ids) == NULL)
- return (ENXIO);
-
- device_set_desc(dev, "Control Method Battery");
- return (0);
-}
-
static int
-acpi_cmbat_attach(device_t dev)
+acpi_cmbat_bif(device_t dev, struct acpi_bif *bifp)
{
- int error;
- ACPI_HANDLE handle;
struct acpi_cmbat_softc *sc;
sc = device_get_softc(dev);
- handle = acpi_get_handle(dev);
- sc->dev = dev;
-
- /*
- * Install a system notify handler in addition to the device notify.
- * Toshiba notebook uses this alternate notify for its battery.
- */
- AcpiInstallNotifyHandler(handle, ACPI_ALL_NOTIFY,
- acpi_cmbat_notify_handler, dev);
-
- ACPI_SERIAL_BEGIN(cmbat);
- timespecclear(&sc->bif_lastupdated);
- timespecclear(&sc->bst_lastupdated);
- if (acpi_cmbat_units == 0) {
- error = acpi_register_ioctl(ACPIIO_CMBAT_GET_BIF,
- acpi_cmbat_ioctl, NULL);
- if (error != 0) {
- device_printf(dev, "register bif ioctl failed\n");
- return (error);
- }
- error = acpi_register_ioctl(ACPIIO_CMBAT_GET_BST,
- acpi_cmbat_ioctl, NULL);
- if (error != 0) {
- device_printf(dev, "register bst ioctl failed\n");
- return (error);
- }
- }
-
- sc->phys_unit = acpi_cmbat_units;
- error = acpi_battery_register(ACPI_BATT_TYPE_CMBAT, sc->phys_unit);
- if (error != 0) {
- device_printf(dev, "registering battery %d failed\n", sc->phys_unit);
- return (error);
- }
- acpi_cmbat_units++;
- timespecclear(&acpi_cmbat_info_lastupdated);
- ACPI_SERIAL_END(cmbat);
-
- AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_init_battery, dev);
-
- return (0);
-}
-
-static int
-acpi_cmbat_detach(device_t dev)
-{
- struct acpi_cmbat_softc *sc;
-
- sc = device_get_softc(dev);
ACPI_SERIAL_BEGIN(cmbat);
- acpi_battery_remove(ACPI_BATT_TYPE_CMBAT, sc->phys_unit);
- acpi_cmbat_units--;
+ acpi_cmbat_get_bif(dev);
+ bifp->units = sc->bif.units;
+ bifp->dcap = sc->bif.dcap;
+ bifp->lfcap = sc->bif.lfcap;
+ bifp->btech = sc->bif.btech;
+ bifp->dvol = sc->bif.dvol;
+ bifp->wcap = sc->bif.wcap;
+ bifp->lcap = sc->bif.lcap;
+ bifp->gra1 = sc->bif.gra1;
+ bifp->gra2 = sc->bif.gra2;
+ strncpy(bifp->model, sc->bif.model, sizeof(sc->bif.model));
+ strncpy(bifp->serial, sc->bif.serial, sizeof(sc->bif.serial));
+ strncpy(bifp->type, sc->bif.type, sizeof(sc->bif.type));
+ strncpy(bifp->oeminfo, sc->bif.oeminfo, sizeof(sc->bif.oeminfo));
ACPI_SERIAL_END(cmbat);
- return (0);
-}
-static int
-acpi_cmbat_resume(device_t dev)
-{
- AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_init_battery, dev);
return (0);
}
static int
-acpi_cmbat_ioctl(u_long cmd, caddr_t addr, void *arg)
+acpi_cmbat_bst(device_t dev, struct acpi_bst *bstp)
{
- device_t dev;
- union acpi_battery_ioctl_arg *ioctl_arg;
struct acpi_cmbat_softc *sc;
- struct acpi_bif *bifp;
- struct acpi_bst *bstp;
- ioctl_arg = (union acpi_battery_ioctl_arg *)addr;
- dev = devclass_get_device(acpi_cmbat_devclass, ioctl_arg->unit);
- if (dev == NULL)
- return (ENXIO);
sc = device_get_softc(dev);
- /*
- * No security check required: information retrieval only. If
- * new functions are added here, a check might be required.
- */
ACPI_SERIAL_BEGIN(cmbat);
- switch (cmd) {
- case ACPIIO_CMBAT_GET_BIF:
- acpi_cmbat_get_bif(dev);
- bifp = &ioctl_arg->bif;
- bifp->units = sc->bif.units;
- bifp->dcap = sc->bif.dcap;
- bifp->lfcap = sc->bif.lfcap;
- bifp->btech = sc->bif.btech;
- bifp->dvol = sc->bif.dvol;
- bifp->wcap = sc->bif.wcap;
- bifp->lcap = sc->bif.lcap;
- bifp->gra1 = sc->bif.gra1;
- bifp->gra2 = sc->bif.gra2;
- strncpy(bifp->model, sc->bif.model, sizeof(sc->bif.model));
- strncpy(bifp->serial, sc->bif.serial, sizeof(sc->bif.serial));
- strncpy(bifp->type, sc->bif.type, sizeof(sc->bif.type));
- strncpy(bifp->oeminfo, sc->bif.oeminfo, sizeof(sc->bif.oeminfo));
- break;
- case ACPIIO_CMBAT_GET_BST:
- bstp = &ioctl_arg->bst;
- if (acpi_BatteryIsPresent(dev)) {
- acpi_cmbat_get_bst(dev);
- bstp->state = sc->bst.state;
- bstp->rate = sc->bst.rate;
- bstp->cap = sc->bst.cap;
- bstp->volt = sc->bst.volt;
- } else {
- bstp->state = ACPI_BATT_STAT_NOT_PRESENT;
- }
- break;
- default:
- break;
- }
+ if (acpi_BatteryIsPresent(dev)) {
+ acpi_cmbat_get_bst(dev);
+ bstp->state = sc->bst.state;
+ bstp->rate = sc->bst.rate;
+ bstp->cap = sc->bst.cap;
+ bstp->volt = sc->bst.volt;
+ } else
+ bstp->state = ACPI_BATT_STAT_NOT_PRESENT;
ACPI_SERIAL_END(cmbat);
return (0);
}
-static int
-acpi_cmbat_is_bst_valid(struct acpi_bst *bst)
-{
- if (bst->state >= ACPI_BATT_STAT_MAX || bst->cap == 0xffffffff ||
- bst->volt == 0xffffffff)
- return (FALSE);
- else
- return (TRUE);
-}
-
-static int
-acpi_cmbat_is_bif_valid(struct acpi_bif *bif)
-{
- if (bif->lfcap == 0)
- return (FALSE);
- else
- return (TRUE);
-}
-
-static int
-acpi_cmbat_get_total_battinfo(struct acpi_battinfo *battinfo)
-{
- int i;
- int error;
- int batt_stat;
- int valid_rate, valid_units;
- int cap, min;
- int total_cap, total_min, total_full;
- struct acpi_cmbat_softc *sc;
-
- ACPI_SERIAL_ASSERT(cmbat);
-
- cap = min = -1;
- batt_stat = ACPI_BATT_STAT_NOT_PRESENT;
- error = 0;
-
- /* Get battery status, valid rate and valid units */
- batt_stat = valid_rate = valid_units = 0;
- for (i = 0; i < acpi_cmbat_units; i++) {
- sc = devclass_get_softc(acpi_cmbat_devclass, i);
- if (sc == NULL)
- continue;
- sc->present = acpi_BatteryIsPresent(sc->dev);
- if (!sc->present)
- continue;
- acpi_cmbat_get_bst(sc->dev);
-
- /* If battery not installed, we get strange values */
- if (!acpi_cmbat_is_bst_valid(&sc->bst) ||
- !acpi_cmbat_is_bif_valid(&sc->bif)) {
- sc->present = FALSE;
- continue;
- }
-
- valid_units++;
- sc->cap = 100 * sc->bst.cap / sc->bif.lfcap;
-
- /*
- * Some laptops report the "design-capacity" instead of the
- * "real-capacity" when the battery is fully charged.
- * That breaks the above arithmetic as it needs to be 100% maximum.
- */
- if (sc->cap > 100)
- sc->cap = 100;
-
- batt_stat |= sc->bst.state;
-
- /*
- * XXX Hack to calculate total battery time.
- *
- * On systems with more than one battery, they may get used
- * sequentially, thus bst.rate may only signify the one in use.
- * For the remaining batteries, bst.rate will be zero, which
- * makes it impossible to calculate the remaining time. Some
- * other systems may need the sum of all the bst.rate values
- * when discharging. Therefore, we sum the bst.rate for valid
- * batteries (ones in the discharging state) and use the sum
- * to calculate the total remaining time.
- */
- if (sc->bst.rate > 0) {
- if (sc->bst.state & ACPI_BATT_STAT_DISCHARG)
- valid_rate += sc->bst.rate;
- }
- }
-
- /* Calculate total battery capacity and time */
- total_cap = total_min = total_full = 0;
- for (i = 0; i < acpi_cmbat_units; i++) {
- sc = devclass_get_softc(acpi_cmbat_devclass, i);
- if (!sc->present)
- continue;
-
- /*
- * If any batteries are discharging, use the sum of the bst.rate
- * values. Otherwise, use the full charge time to estimate
- * remaining time. If neither are available, assume no charge.
- */
- if (valid_rate > 0)
- sc->min = 60 * sc->bst.cap / valid_rate;
- else if (sc->full_charge_time > 0)
- sc->min = (sc->full_charge_time * sc->cap) / 100;
- else
- sc->min = 0;
- total_min += sc->min;
- total_cap += sc->cap;
- total_full += sc->full_charge_time;
- }
-
- /* Battery life */
- if (valid_units == 0) {
- cap = -1;
- batt_stat = ACPI_BATT_STAT_NOT_PRESENT;
- } else
- cap = total_cap / valid_units;
-
- /* Battery time */
- if (valid_units == 0)
- min = -1;
- else if (valid_rate == 0 || (batt_stat & ACPI_BATT_STAT_CHARGING)) {
- if (total_full == 0)
- min = -1;
- else
- min = (total_full * cap) / 100;
- } else
- min = total_min;
- acpi_cmbat_info_updated(&acpi_cmbat_info_lastupdated);
-
- battinfo->cap = cap;
- battinfo->min = min;
- battinfo->state = batt_stat;
-
- return (error);
-}
-
static void
acpi_cmbat_init_battery(void *arg)
{
struct acpi_cmbat_softc *sc;
- int retry;
+ int retry, valid;
device_t dev;
dev = (device_t)arg;
@@ -593,9 +413,13 @@ acpi_cmbat_init_battery(void *arg)
ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
"battery initialization start\n");
+ /*
+ * Try repeatedly to get valid data from the battery. Since the
+ * embedded controller isn't always ready just after boot, we may have
+ * to wait a while.
+ */
for (retry = 0; retry < ACPI_CMBAT_RETRY_MAX; retry++, AcpiOsSleep(10000)) {
- sc->present = acpi_BatteryIsPresent(dev);
- if (!sc->present)
+ if (!acpi_BatteryIsPresent(dev))
continue;
ACPI_SERIAL_BEGIN(cmbat);
@@ -603,10 +427,11 @@ acpi_cmbat_init_battery(void *arg)
timespecclear(&sc->bif_lastupdated);
acpi_cmbat_get_bst(dev);
acpi_cmbat_get_bif(dev);
+ valid = acpi_battery_bst_valid(&sc->bst) &&
+ acpi_battery_bif_valid(&sc->bif);
ACPI_SERIAL_END(cmbat);
- if (acpi_cmbat_is_bst_valid(&sc->bst) &&
- acpi_cmbat_is_bif_valid(&sc->bif))
+ if (valid)
break;
}
@@ -618,39 +443,3 @@ acpi_cmbat_init_battery(void *arg)
"battery initialization done, tried %d times\n", retry + 1);
}
}
-
-/*
- * Public interfaces.
- */
-int
-acpi_cmbat_get_battinfo(int unit, struct acpi_battinfo *battinfo)
-{
- int error;
- struct acpi_cmbat_softc *sc;
-
- ACPI_SERIAL_BEGIN(cmbat);
- error = acpi_cmbat_get_total_battinfo(battinfo);
- if (unit == -1 || error)
- goto out;
-
- error = ENXIO;
- if (unit >= acpi_cmbat_units)
- goto out;
- if ((sc = devclass_get_softc(acpi_cmbat_devclass, unit)) == NULL)
- 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;
- }
- error = 0;
-
-out:
- ACPI_SERIAL_END(cmbat);
- return (error);
-}
OpenPOWER on IntegriCloud