Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Jul 2005 02:29:39 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 80886 for review
Message-ID:  <200507240229.j6O2TdCG065705@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=80886

Change 80886 by rwatson@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@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@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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507240229.j6O2TdCG065705>