The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/acpica/acpi_battery.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  *      $FreeBSD: releng/5.3/sys/dev/acpica/acpi_battery.c 133614 2004-08-13 06:21:41Z njl $
   27  */
   28 
   29 #include "opt_acpi.h"
   30 #include <sys/param.h>
   31 #include <sys/kernel.h>
   32 #include <sys/malloc.h>
   33 #include <sys/bus.h>
   34 #include <sys/ioccom.h>
   35 #include <sys/sysctl.h>
   36 
   37 #include "acpi.h"
   38 #include <dev/acpica/acpivar.h>
   39 #include <dev/acpica/acpiio.h>
   40 
   41 MALLOC_DEFINE(M_ACPIBATT, "acpibatt", "ACPI generic battery data");
   42 
   43 struct acpi_batteries {
   44     TAILQ_ENTRY(acpi_batteries) link;
   45     struct acpi_battdesc        battdesc;
   46 };
   47 
   48 static TAILQ_HEAD(,acpi_batteries) acpi_batteries;
   49 static int                      acpi_batteries_initted;
   50 static int                      acpi_batteries_units;
   51 static int                      acpi_battery_info_expire = 5;
   52 static struct acpi_battinfo     acpi_battery_battinfo;
   53 ACPI_SERIAL_DECL(battery, "ACPI generic battery");
   54 
   55 int
   56 acpi_battery_get_info_expire(void)
   57 {
   58     return (acpi_battery_info_expire);
   59 }
   60 
   61 int
   62 acpi_battery_get_units(void)
   63 {
   64     return (acpi_batteries_units);
   65 }
   66 
   67 int
   68 acpi_battery_get_battdesc(int logical_unit, struct acpi_battdesc *battdesc)
   69 {
   70     struct acpi_batteries *bp;
   71     int error, i;
   72 
   73     error = ENXIO;
   74     ACPI_SERIAL_BEGIN(battery);
   75     if (logical_unit < 0 || logical_unit >= acpi_batteries_units)
   76         goto out;
   77 
   78     i = 0;
   79     TAILQ_FOREACH(bp, &acpi_batteries, link) {
   80         if (logical_unit == i) {
   81             battdesc->type = bp->battdesc.type;
   82             battdesc->phys_unit = bp->battdesc.phys_unit;
   83             error = 0;
   84             break;
   85         }
   86         i++;
   87     }
   88 
   89 out:
   90     ACPI_SERIAL_END(battery);
   91     return (error);
   92 }
   93 
   94 int
   95 acpi_battery_get_battinfo(int unit, struct acpi_battinfo *battinfo)
   96 {
   97     struct acpi_battdesc battdesc;
   98     int error;
   99 
  100     error = 0;
  101     if (unit == -1) {
  102         error = acpi_cmbat_get_battinfo(-1, battinfo);
  103         goto out;
  104     } else {
  105         error = acpi_battery_get_battdesc(unit, &battdesc);
  106         if (error != 0)
  107             goto out;
  108 
  109         switch (battdesc.type) {
  110         case ACPI_BATT_TYPE_CMBAT:
  111             error = acpi_cmbat_get_battinfo(battdesc.phys_unit, battinfo);
  112             break;
  113         default:
  114             error = ENXIO;
  115             break;
  116         }
  117     }
  118 
  119 out:
  120     return (error);
  121 }
  122 
  123 static int
  124 acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg)
  125 {
  126     union acpi_battery_ioctl_arg *ioctl_arg;
  127     int error, logical_unit;
  128 
  129     ioctl_arg = (union acpi_battery_ioctl_arg *)addr;
  130     error = 0;
  131 
  132     /*
  133      * No security check required: information retrieval only.  If
  134      * new functions are added here, a check might be required.
  135      */
  136     switch (cmd) {
  137     case ACPIIO_BATT_GET_UNITS:
  138         *(int *)addr = acpi_battery_get_units();
  139         break;
  140     case ACPIIO_BATT_GET_BATTDESC:
  141         logical_unit = ioctl_arg->unit;
  142         error = acpi_battery_get_battdesc(logical_unit, &ioctl_arg->battdesc);
  143         break;
  144     case ACPIIO_BATT_GET_BATTINFO:
  145         logical_unit = ioctl_arg->unit;
  146         error = acpi_battery_get_battinfo(logical_unit, &ioctl_arg->battinfo);
  147         break;
  148     default:
  149         error = EINVAL;
  150         break;
  151     }
  152 
  153     return (error);
  154 }
  155 
  156 static int
  157 acpi_battery_sysctl(SYSCTL_HANDLER_ARGS)
  158 {
  159     int val, error;
  160 
  161     acpi_battery_get_battinfo(-1, &acpi_battery_battinfo);
  162     val = *(u_int *)oidp->oid_arg1;
  163     error = sysctl_handle_int(oidp, &val, 0, req);
  164     return (error);
  165 }
  166 
  167 static int
  168 acpi_battery_init(void)
  169 {
  170     struct acpi_softc   *sc;
  171     device_t             dev;
  172     int                  error;
  173 
  174     ACPI_SERIAL_ASSERT(battery);
  175 
  176     error = ENXIO;
  177     dev = devclass_get_device(devclass_find("acpi"), 0);
  178     if (dev == NULL)
  179         goto out;
  180     sc = device_get_softc(dev);
  181 
  182     TAILQ_INIT(&acpi_batteries);
  183 
  184     /* XXX We should back out registered ioctls on error. */
  185     error = acpi_register_ioctl(ACPIIO_BATT_GET_UNITS, acpi_battery_ioctl,
  186         NULL);
  187     if (error != 0)
  188         goto out;
  189     error = acpi_register_ioctl(ACPIIO_BATT_GET_BATTDESC, acpi_battery_ioctl,
  190         NULL);
  191     if (error != 0)
  192         goto out;
  193     error = acpi_register_ioctl(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl,
  194         NULL);
  195     if (error != 0)
  196         goto out;
  197 
  198     sysctl_ctx_init(&sc->acpi_battery_sysctl_ctx);
  199     sc->acpi_battery_sysctl_tree = SYSCTL_ADD_NODE(&sc->acpi_battery_sysctl_ctx,
  200         SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO, "battery", CTLFLAG_RD,
  201         0, "");
  202     SYSCTL_ADD_PROC(&sc->acpi_battery_sysctl_ctx,
  203         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  204         OID_AUTO, "life", CTLTYPE_INT | CTLFLAG_RD,
  205         &acpi_battery_battinfo.cap, 0, acpi_battery_sysctl, "I", "");
  206     SYSCTL_ADD_PROC(&sc->acpi_battery_sysctl_ctx,
  207         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  208         OID_AUTO, "time", CTLTYPE_INT | CTLFLAG_RD,
  209         &acpi_battery_battinfo.min, 0, acpi_battery_sysctl, "I", "");
  210     SYSCTL_ADD_PROC(&sc->acpi_battery_sysctl_ctx,
  211         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  212         OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RD,
  213         &acpi_battery_battinfo.state, 0, acpi_battery_sysctl, "I", "");
  214     SYSCTL_ADD_INT(&sc->acpi_battery_sysctl_ctx,
  215         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  216         OID_AUTO, "units", CTLFLAG_RD, &acpi_batteries_units, 0, "");
  217     SYSCTL_ADD_INT(&sc->acpi_battery_sysctl_ctx,
  218         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  219         OID_AUTO, "info_expire", CTLFLAG_RD | CTLFLAG_RW,
  220         &acpi_battery_info_expire, 0, "");
  221 
  222     acpi_batteries_initted = TRUE;
  223 
  224 out:
  225     return (error);
  226 }
  227 
  228 int
  229 acpi_battery_register(int type, int phys_unit)
  230 {
  231     struct acpi_batteries *bp;
  232     int error;
  233 
  234     error = 0;
  235     bp = malloc(sizeof(*bp), M_ACPIBATT, M_NOWAIT);
  236     if (bp == NULL)
  237         return (ENOMEM);
  238 
  239     ACPI_SERIAL_BEGIN(battery);
  240     if (!acpi_batteries_initted && (error = acpi_battery_init()) != 0) {
  241         printf("acpi_battery_register failed for unit %d\n", phys_unit);
  242         goto out;
  243     }
  244     bp->battdesc.type = type;
  245     bp->battdesc.phys_unit = phys_unit;
  246     TAILQ_INSERT_TAIL(&acpi_batteries, bp, link);
  247     acpi_batteries_units++;
  248 
  249 out:
  250     ACPI_SERIAL_END(battery);
  251     if (error)
  252         free(bp, M_ACPIBATT);
  253     return (error);
  254 }
  255 
  256 int
  257 acpi_battery_remove(int type, int phys_unit)
  258 {
  259     struct acpi_batteries *bp, *tmp;
  260     int ret;
  261 
  262     ret = ENOENT;
  263     ACPI_SERIAL_BEGIN(battery);
  264     TAILQ_FOREACH_SAFE(bp, &acpi_batteries, link, tmp) {
  265         if (bp->battdesc.type == type && bp->battdesc.phys_unit == phys_unit) {
  266             TAILQ_REMOVE(&acpi_batteries, bp, link);
  267             acpi_batteries_units--;
  268             ret = 0;
  269             break;
  270         }
  271     }
  272     ACPI_SERIAL_END(battery);
  273     if (ret == 0)
  274         free(bp, M_ACPIBATT);
  275     return (ret);
  276 }

Cache object: 07832c53b2dc0e845feb6de07cd50601


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.