PERFORCE change 80886 for review
Robert Watson
rwatson at FreeBSD.org
Sun Jul 24 02:29:44 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=80886
Change 80886 by rwatson at rwatson_zoo on 2005/07/24 02:29:32
Integrate netsmp.
Affected files ...
.. //depot/projects/netsmp/src/sys/dev/acpica/acpi_battery.c#2 integrate
.. //depot/projects/netsmp/src/sys/dev/acpica/acpi_cmbat.c#2 integrate
.. //depot/projects/netsmp/src/sys/dev/acpica/acpi_if.m#2 integrate
.. //depot/projects/netsmp/src/sys/dev/acpica/acpiio.h#2 integrate
.. //depot/projects/netsmp/src/sys/dev/acpica/acpivar.h#2 integrate
.. //depot/projects/netsmp/src/sys/dev/ath/if_ath.c#4 integrate
.. //depot/projects/netsmp/src/sys/i386/acpica/acpi_machdep.c#2 integrate
.. //depot/projects/netsmp/src/sys/libkern/iconv.c#2 integrate
.. //depot/projects/netsmp/src/sys/netgraph/ng_socket.c#2 integrate
.. //depot/projects/netsmp/src/sys/netinet/ip_fastfwd.c#2 integrate
.. //depot/projects/netsmp/src/sys/sys/param.h#2 integrate
Differences ...
==== //depot/projects/netsmp/src/sys/dev/acpica/acpi_battery.c#2 (text+ko) ====
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2005 Nate Lawson
* Copyright (c) 2000 Mitsuru IWASAKI <iwasaki at jp.freebsd.org>
* All rights reserved.
*
@@ -25,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_battery.c,v 1.12 2005/03/17 22:42:49 njl Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_battery.c,v 1.13 2005/07/23 19:35:59 njl Exp $");
#include "opt_acpi.h"
#include <sys/param.h>
@@ -39,96 +40,248 @@
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpiio.h>
-MALLOC_DEFINE(M_ACPIBATT, "acpibatt", "ACPI generic battery data");
+/* Default seconds before re-sampling the battery state. */
+#define ACPI_BATTERY_INFO_EXPIRE 5
-struct acpi_batteries {
- TAILQ_ENTRY(acpi_batteries) link;
- struct acpi_battdesc battdesc;
-};
+static int acpi_batteries_initted;
+static int acpi_battery_info_expire = ACPI_BATTERY_INFO_EXPIRE;
+static struct acpi_battinfo acpi_battery_battinfo;
+static struct sysctl_ctx_list acpi_battery_sysctl_ctx;
+static struct sysctl_oid *acpi_battery_sysctl_tree;
-static TAILQ_HEAD(,acpi_batteries) acpi_batteries;
-static int acpi_batteries_initted;
-static int acpi_batteries_units;
-static int acpi_battery_info_expire = 5;
-static struct acpi_battinfo acpi_battery_battinfo;
ACPI_SERIAL_DECL(battery, "ACPI generic battery");
+static void acpi_reset_battinfo(struct acpi_battinfo *info);
+static int acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg);
+static int acpi_battery_sysctl(SYSCTL_HANDLER_ARGS);
+static int acpi_battery_units_sysctl(SYSCTL_HANDLER_ARGS);
+static int acpi_battery_init(void);
+
+int
+acpi_battery_register(device_t dev)
+{
+ int error;
+
+ error = 0;
+ ACPI_SERIAL_BEGIN(battery);
+ if (!acpi_batteries_initted)
+ error = acpi_battery_init();
+ ACPI_SERIAL_END(battery);
+ return (error);
+}
+
int
-acpi_battery_get_info_expire(void)
+acpi_battery_remove(device_t dev)
{
- return (acpi_battery_info_expire);
+
+ return (0);
}
int
acpi_battery_get_units(void)
{
- return (acpi_batteries_units);
+ devclass_t batt_dc;
+
+ batt_dc = devclass_find("battery");
+ if (batt_dc == NULL)
+ return (0);
+ return (devclass_get_count(batt_dc));
}
int
-acpi_battery_get_battdesc(int unit, struct acpi_battdesc *battdesc)
+acpi_battery_get_info_expire(void)
{
- struct acpi_batteries *bp;
- int error, i;
- error = ENXIO;
- ACPI_SERIAL_BEGIN(battery);
- if (unit < 0 || unit >= acpi_batteries_units)
- goto out;
+ return (acpi_battery_info_expire);
+}
- i = 0;
- TAILQ_FOREACH(bp, &acpi_batteries, link) {
- if (unit == i) {
- battdesc->type = bp->battdesc.type;
- battdesc->phys_unit = bp->battdesc.phys_unit;
- error = 0;
- break;
- }
- i++;
- }
+/* Check _BST results for validity. */
+int
+acpi_battery_bst_valid(struct acpi_bst *bst)
+{
+ if (bst->state >= ACPI_BATT_STAT_MAX || bst->cap == 0xffffffff ||
+ bst->volt == 0xffffffff)
+ return (FALSE);
+ else
+ return (TRUE);
+}
-out:
- ACPI_SERIAL_END(battery);
- return (error);
+/* Check _BIF results for validity. */
+int
+acpi_battery_bif_valid(struct acpi_bif *bif)
+{
+ if (bif->lfcap == 0)
+ return (FALSE);
+ else
+ return (TRUE);
}
+/* Get info about one or all batteries. */
int
-acpi_battery_get_battinfo(int unit, struct acpi_battinfo *battinfo)
+acpi_battery_get_battinfo(device_t dev, struct acpi_battinfo *battinfo)
{
- struct acpi_battdesc battdesc;
- int error;
+ int batt_stat, devcount, dev_idx, error, i;
+ int total_cap, total_min, valid_rate, valid_units;
+ devclass_t batt_dc;
+ device_t batt_dev;
+ struct acpi_bst *bst;
+ struct acpi_bif *bif;
+ struct acpi_battinfo *bi;
+
+ /*
+ * Get the battery devclass and number of devices. If there are none
+ * or error, return immediately.
+ */
+ batt_dc = devclass_find("battery");
+ if (batt_dc == NULL)
+ return (ENXIO);
+ devcount = devclass_get_count(batt_dc);
+ if (devcount == 0)
+ return (ENXIO);
+
+ /*
+ * Allocate storage for all _BST data, their derived battinfo data,
+ * and the current battery's _BIF data.
+ */
+ bst = malloc(devcount * sizeof(*bst), M_TEMP, M_WAITOK);
+ bi = malloc(devcount * sizeof(*bi), M_TEMP, M_WAITOK);
+ bif = malloc(sizeof(*bif), M_TEMP, M_WAITOK);
+
+ /*
+ * Pass 1: for each battery that is present and valid, get its status,
+ * calculate percent capacity remaining, and sum all the current
+ * discharge rates.
+ */
+ dev_idx = -1;
+ batt_stat = valid_rate = valid_units = 0;
+ for (i = 0; i < devcount; i++) {
+ /* Find the device. If it disappeared, the user can try again. */
+ batt_dev = devclass_get_device(batt_dc, i);
+ if (batt_dev == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+
+ /* Default info for every battery is "not present". */
+ acpi_reset_battinfo(&bi[i]);
+
+ /* If examining a specific battery and this is it, record its index. */
+ if (dev != NULL && dev == batt_dev)
+ dev_idx = i;
+
+ /* Be sure we can get various info from the battery. */
+ if (!acpi_BatteryIsPresent(batt_dev) ||
+ ACPI_BATT_GET_STATUS(batt_dev, &bst[i]) != 0 ||
+ ACPI_BATT_GET_INFO(batt_dev, bif) != 0)
+ continue;
+
+ /* If a battery is not installed, we sometimes get strange values. */
+ if (!acpi_battery_bst_valid(&bst[i]) ||
+ !acpi_battery_bif_valid(bif))
+ continue;
+
+ /* Record state and calculate percent capacity remaining. */
+ valid_units++;
+ batt_stat |= bst[i].state;
+ bi[i].state = bst[i].state;
+ bi[i].cap = 100 * bst[i].cap / 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 (bi[i].cap > 100)
+ bi[i].cap = 100;
+
+ /*
+ * On systems with more than one battery, they may get used
+ * sequentially, thus bst.rate may only signify the one currently
+ * in use. For the remaining batteries, bst.rate will be zero,
+ * which makes it impossible to calculate the total remaining time.
+ * Therefore, we sum the bst.rate for batteries in the discharging
+ * state and use the sum to calculate the total remaining time.
+ */
+ if (bst[i].rate > 0 && (bst[i].state & ACPI_BATT_STAT_DISCHARG))
+ valid_rate += bst[i].rate;
+ }
- error = 0;
- if (unit == -1) {
- error = acpi_cmbat_get_battinfo(-1, battinfo);
+ /* If the caller asked for a device but we didn't find it, error. */
+ if (dev != NULL && dev_idx < 0) {
+ error = ENXIO;
goto out;
- } else {
- error = acpi_battery_get_battdesc(unit, &battdesc);
- if (error != 0)
- goto out;
+ }
+
+ /* Pass 2: calculate capacity and remaining time for all batteries. */
+ total_cap = total_min = 0;
+ for (i = 0; i < devcount; i++) {
+ /*
+ * If any batteries are discharging, use the sum of the bst.rate
+ * values. Otherwise, we are on AC power, and there is infinite
+ * time remaining for this battery until we go offline.
+ */
+ if (valid_rate > 0)
+ bi[i].min = 60 * bst[i].cap / valid_rate;
+ else
+ bi[i].min = 0;
+ total_min += bi[i].min;
+ total_cap += bi[i].cap;
+ }
- switch (battdesc.type) {
- case ACPI_BATT_TYPE_CMBAT:
- error = acpi_cmbat_get_battinfo(battdesc.phys_unit, battinfo);
- break;
- default:
- error = ENXIO;
- break;
+ /*
+ * Return total battery percent and time remaining. If there are
+ * no valid batteries, report values as unknown.
+ */
+ if (valid_units > 0) {
+ if (dev == NULL) {
+ battinfo->cap = total_cap / valid_units;
+ battinfo->min = total_min;
+ battinfo->state = batt_stat;
+ battinfo->rate = valid_rate;
+ } else {
+ battinfo->cap = bi[dev_idx].cap;
+ battinfo->min = bi[dev_idx].min;
+ battinfo->state = bi[dev_idx].state;
+ battinfo->rate = bst[dev_idx].rate;
}
- }
+ } else
+ acpi_reset_battinfo(battinfo);
+
+ error = 0;
out:
+ if (bi)
+ free(bi, M_TEMP);
+ if (bif)
+ free(bif, M_TEMP);
+ if (bst)
+ free(bst, M_TEMP);
return (error);
}
+static void
+acpi_reset_battinfo(struct acpi_battinfo *info)
+{
+ info->cap = -1;
+ info->min = -1;
+ info->state = ACPI_BATT_STAT_NOT_PRESENT;
+ info->rate = -1;
+}
+
static int
acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg)
{
union acpi_battery_ioctl_arg *ioctl_arg;
int error, unit;
+ device_t dev;
+ error = ENXIO;
ioctl_arg = (union acpi_battery_ioctl_arg *)addr;
- error = 0;
+ unit = ioctl_arg->unit;
+ if (unit != ACPI_BATTERY_ALL_UNITS)
+ dev = devclass_get_device(devclass_find("battery"), unit);
+ else
+ dev = NULL;
/*
* No security check required: information retrieval only. If
@@ -138,17 +291,20 @@
case ACPIIO_BATT_GET_UNITS:
*(int *)addr = acpi_battery_get_units();
break;
- case ACPIIO_BATT_GET_BATTDESC:
- unit = ioctl_arg->unit;
- error = acpi_battery_get_battdesc(unit, &ioctl_arg->battdesc);
+ case ACPIIO_BATT_GET_BATTINFO:
+ if (dev != NULL || unit == ACPI_BATTERY_ALL_UNITS)
+ error = acpi_battery_get_battinfo(dev, &ioctl_arg->battinfo);
+ break;
+ case ACPIIO_BATT_GET_BIF:
+ if (dev != NULL)
+ error = ACPI_BATT_GET_INFO(dev, &ioctl_arg->bif);
break;
- case ACPIIO_BATT_GET_BATTINFO:
- unit = ioctl_arg->unit;
- error = acpi_battery_get_battinfo(unit, &ioctl_arg->battinfo);
+ case ACPIIO_BATT_GET_BST:
+ if (dev != NULL)
+ error = ACPI_BATT_GET_STATUS(dev, &ioctl_arg->bst);
break;
default:
error = EINVAL;
- break;
}
return (error);
@@ -159,13 +315,23 @@
{
int val, error;
- acpi_battery_get_battinfo(-1, &acpi_battery_battinfo);
+ acpi_battery_get_battinfo(NULL, &acpi_battery_battinfo);
val = *(u_int *)oidp->oid_arg1;
error = sysctl_handle_int(oidp, &val, 0, req);
return (error);
}
static int
+acpi_battery_units_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ int count, error;
+
+ count = acpi_battery_get_units();
+ error = sysctl_handle_int(oidp, &count, 0, req);
+ return (error);
+}
+
+static int
acpi_battery_init(void)
{
struct acpi_softc *sc;
@@ -180,98 +346,54 @@
goto out;
sc = device_get_softc(dev);
- TAILQ_INIT(&acpi_batteries);
-
- /* XXX We should back out registered ioctls on error. */
error = acpi_register_ioctl(ACPIIO_BATT_GET_UNITS, acpi_battery_ioctl,
NULL);
if (error != 0)
goto out;
- error = acpi_register_ioctl(ACPIIO_BATT_GET_BATTDESC, acpi_battery_ioctl,
+ error = acpi_register_ioctl(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl,
NULL);
if (error != 0)
goto out;
- error = acpi_register_ioctl(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl,
- NULL);
+ error = acpi_register_ioctl(ACPIIO_BATT_GET_BIF, acpi_battery_ioctl, NULL);
+ if (error != 0)
+ goto out;
+ error = acpi_register_ioctl(ACPIIO_BATT_GET_BST, acpi_battery_ioctl, NULL);
if (error != 0)
goto out;
- sysctl_ctx_init(&sc->acpi_battery_sysctl_ctx);
- sc->acpi_battery_sysctl_tree = SYSCTL_ADD_NODE(&sc->acpi_battery_sysctl_ctx,
+ sysctl_ctx_init(&acpi_battery_sysctl_ctx);
+ acpi_battery_sysctl_tree = SYSCTL_ADD_NODE(&acpi_battery_sysctl_ctx,
SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO, "battery", CTLFLAG_RD,
0, "");
- SYSCTL_ADD_PROC(&sc->acpi_battery_sysctl_ctx,
- SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
+ SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
+ SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
OID_AUTO, "life", CTLTYPE_INT | CTLFLAG_RD,
&acpi_battery_battinfo.cap, 0, acpi_battery_sysctl, "I", "");
- SYSCTL_ADD_PROC(&sc->acpi_battery_sysctl_ctx,
- SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
+ SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
+ SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
OID_AUTO, "time", CTLTYPE_INT | CTLFLAG_RD,
&acpi_battery_battinfo.min, 0, acpi_battery_sysctl, "I", "");
- SYSCTL_ADD_PROC(&sc->acpi_battery_sysctl_ctx,
- SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
+ SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
+ SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RD,
&acpi_battery_battinfo.state, 0, acpi_battery_sysctl, "I", "");
- SYSCTL_ADD_INT(&sc->acpi_battery_sysctl_ctx,
- SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
- OID_AUTO, "units", CTLFLAG_RD, &acpi_batteries_units, 0, "");
- SYSCTL_ADD_INT(&sc->acpi_battery_sysctl_ctx,
- SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
+ SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
+ SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
+ OID_AUTO, "units", CTLTYPE_INT | CTLFLAG_RD,
+ NULL, 0, acpi_battery_units_sysctl, "I", "");
+ SYSCTL_ADD_INT(&acpi_battery_sysctl_ctx,
+ SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
OID_AUTO, "info_expire", CTLFLAG_RD | CTLFLAG_RW,
&acpi_battery_info_expire, 0, "");
acpi_batteries_initted = TRUE;
out:
- return (error);
-}
-
-int
-acpi_battery_register(int type, int phys_unit)
-{
- struct acpi_batteries *bp;
- int error;
-
- error = 0;
- bp = malloc(sizeof(*bp), M_ACPIBATT, M_NOWAIT);
- if (bp == NULL)
- return (ENOMEM);
-
- ACPI_SERIAL_BEGIN(battery);
- if (!acpi_batteries_initted && (error = acpi_battery_init()) != 0) {
- printf("acpi_battery_register failed for unit %d\n", phys_unit);
- goto out;
+ if (error != 0) {
+ acpi_deregister_ioctl(ACPIIO_BATT_GET_UNITS, acpi_battery_ioctl);
+ acpi_deregister_ioctl(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl);
+ acpi_deregister_ioctl(ACPIIO_BATT_GET_BIF, acpi_battery_ioctl);
+ acpi_deregister_ioctl(ACPIIO_BATT_GET_BST, acpi_battery_ioctl);
}
- bp->battdesc.type = type;
- bp->battdesc.phys_unit = phys_unit;
- TAILQ_INSERT_TAIL(&acpi_batteries, bp, link);
- acpi_batteries_units++;
-
-out:
- ACPI_SERIAL_END(battery);
- if (error)
- free(bp, M_ACPIBATT);
return (error);
}
-
-int
-acpi_battery_remove(int type, int phys_unit)
-{
- struct acpi_batteries *bp, *tmp;
- int ret;
-
- ret = ENOENT;
- ACPI_SERIAL_BEGIN(battery);
- TAILQ_FOREACH_SAFE(bp, &acpi_batteries, link, tmp) {
- if (bp->battdesc.type == type && bp->battdesc.phys_unit == phys_unit) {
- TAILQ_REMOVE(&acpi_batteries, bp, link);
- acpi_batteries_units--;
- ret = 0;
- break;
- }
- }
- ACPI_SERIAL_END(battery);
- if (ret == 0)
- free(bp, M_ACPIBATT);
- return (ret);
-}
==== //depot/projects/netsmp/src/sys/dev/acpica/acpi_cmbat.c#2 (text+ko) ====
@@ -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 at 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: src/sys/dev/acpica/acpi_cmbat.c,v 1.39 2004/12/20 05:03:41 njl Exp $
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/acpica/acpi_cmbat.c,v 1.40 2005/07/23 19:35:59 njl Exp $");
+
#include "opt_acpi.h"
#include <sys/param.h>
#include <sys/kernel.h>
@@ -60,41 +62,29 @@
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 @@
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 @@
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 @@
}
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_SERIAL_ASSERT(cmbat);
- dev = context;
sc = device_get_softc(dev);
h = acpi_get_handle(dev);
bst_buffer.Pointer = NULL;
@@ -205,9 +287,8 @@
}
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_SERIAL_ASSERT(cmbat);
- dev = context;
sc = device_get_softc(dev);
h = acpi_get_handle(dev);
bif_buffer.Pointer = NULL;
@@ -273,319 +353,59 @@
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)
+acpi_cmbat_bif(device_t dev, struct acpi_bif *bifp)
{
- 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)
-{
- 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_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);
- AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_init_battery, dev);
-
return (0);
}
static int
-acpi_cmbat_detach(device_t dev)
+acpi_cmbat_bst(device_t dev, struct acpi_bst *bstp)
{
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_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)
-{
- 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;
- }
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list