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 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include "opt_acpi.h"
   31 #include <sys/param.h>
   32 #include <sys/kernel.h>
   33 #include <sys/malloc.h>
   34 #include <sys/bus.h>
   35 #include <sys/ioccom.h>
   36 #include <sys/sysctl.h>
   37 
   38 #include "acpi.h"
   39 #include <dev/acpica/acpivar.h>
   40 #include <dev/acpica/acpiio.h>
   41 
   42 MALLOC_DEFINE(M_ACPIBATT, "acpibatt", "ACPI generic battery data");
   43 
   44 struct acpi_batteries {
   45     TAILQ_ENTRY(acpi_batteries) link;
   46     struct acpi_battdesc        battdesc;
   47 };
   48 
   49 static TAILQ_HEAD(,acpi_batteries) acpi_batteries;
   50 static int                      acpi_batteries_initted;
   51 static int                      acpi_batteries_units;
   52 static int                      acpi_battery_info_expire = 5;
   53 static struct acpi_battinfo     acpi_battery_battinfo;
   54 ACPI_SERIAL_DECL(battery, "ACPI generic battery");
   55 
   56 int
   57 acpi_battery_get_info_expire(void)
   58 {
   59     return (acpi_battery_info_expire);
   60 }
   61 
   62 int
   63 acpi_battery_get_units(void)
   64 {
   65     return (acpi_batteries_units);
   66 }
   67 
   68 int
   69 acpi_battery_get_battdesc(int logical_unit, struct acpi_battdesc *battdesc)
   70 {
   71     struct acpi_batteries *bp;
   72     int error, i;
   73 
   74     error = ENXIO;
   75     ACPI_SERIAL_BEGIN(battery);
   76     if (logical_unit < 0 || logical_unit >= acpi_batteries_units)
   77         goto out;
   78 
   79     i = 0;
   80     TAILQ_FOREACH(bp, &acpi_batteries, link) {
   81         if (logical_unit == i) {
   82             battdesc->type = bp->battdesc.type;
   83             battdesc->phys_unit = bp->battdesc.phys_unit;
   84             error = 0;
   85             break;
   86         }
   87         i++;
   88     }
   89 
   90 out:
   91     ACPI_SERIAL_END(battery);
   92     return (error);
   93 }
   94 
   95 int
   96 acpi_battery_get_battinfo(int unit, struct acpi_battinfo *battinfo)
   97 {
   98     struct acpi_battdesc battdesc;
   99     int error;
  100 
  101     error = 0;
  102     if (unit == -1) {
  103         error = acpi_cmbat_get_battinfo(-1, battinfo);
  104         goto out;
  105     } else {
  106         error = acpi_battery_get_battdesc(unit, &battdesc);
  107         if (error != 0)
  108             goto out;
  109 
  110         switch (battdesc.type) {
  111         case ACPI_BATT_TYPE_CMBAT:
  112             error = acpi_cmbat_get_battinfo(battdesc.phys_unit, battinfo);
  113             break;
  114         default:
  115             error = ENXIO;
  116             break;
  117         }
  118     }
  119 
  120 out:
  121     return (error);
  122 }
  123 
  124 static int
  125 acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg)
  126 {
  127     union acpi_battery_ioctl_arg *ioctl_arg;
  128     int error, logical_unit;
  129 
  130     ioctl_arg = (union acpi_battery_ioctl_arg *)addr;
  131     error = 0;
  132 
  133     /*
  134      * No security check required: information retrieval only.  If
  135      * new functions are added here, a check might be required.
  136      */
  137     switch (cmd) {
  138     case ACPIIO_BATT_GET_UNITS:
  139         *(int *)addr = acpi_battery_get_units();
  140         break;
  141     case ACPIIO_BATT_GET_BATTDESC:
  142         logical_unit = ioctl_arg->unit;
  143         error = acpi_battery_get_battdesc(logical_unit, &ioctl_arg->battdesc);
  144         break;
  145     case ACPIIO_BATT_GET_BATTINFO:
  146         logical_unit = ioctl_arg->unit;
  147         error = acpi_battery_get_battinfo(logical_unit, &ioctl_arg->battinfo);
  148         break;
  149     default:
  150         error = EINVAL;
  151         break;
  152     }
  153 
  154     return (error);
  155 }
  156 
  157 static int
  158 acpi_battery_sysctl(SYSCTL_HANDLER_ARGS)
  159 {
  160     int val, error;
  161 
  162     acpi_battery_get_battinfo(-1, &acpi_battery_battinfo);
  163     val = *(u_int *)oidp->oid_arg1;
  164     error = sysctl_handle_int(oidp, &val, 0, req);
  165     return (error);
  166 }
  167 
  168 static int
  169 acpi_battery_init(void)
  170 {
  171     struct acpi_softc   *sc;
  172     device_t             dev;
  173     int                  error;
  174 
  175     ACPI_SERIAL_ASSERT(battery);
  176 
  177     error = ENXIO;
  178     dev = devclass_get_device(devclass_find("acpi"), 0);
  179     if (dev == NULL)
  180         goto out;
  181     sc = device_get_softc(dev);
  182 
  183     TAILQ_INIT(&acpi_batteries);
  184 
  185     /* XXX We should back out registered ioctls on error. */
  186     error = acpi_register_ioctl(ACPIIO_BATT_GET_UNITS, acpi_battery_ioctl,
  187         NULL);
  188     if (error != 0)
  189         goto out;
  190     error = acpi_register_ioctl(ACPIIO_BATT_GET_BATTDESC, acpi_battery_ioctl,
  191         NULL);
  192     if (error != 0)
  193         goto out;
  194     error = acpi_register_ioctl(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl,
  195         NULL);
  196     if (error != 0)
  197         goto out;
  198 
  199     sysctl_ctx_init(&sc->acpi_battery_sysctl_ctx);
  200     sc->acpi_battery_sysctl_tree = SYSCTL_ADD_NODE(&sc->acpi_battery_sysctl_ctx,
  201         SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO, "battery", CTLFLAG_RD,
  202         0, "");
  203     SYSCTL_ADD_PROC(&sc->acpi_battery_sysctl_ctx,
  204         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  205         OID_AUTO, "life", CTLTYPE_INT | CTLFLAG_RD,
  206         &acpi_battery_battinfo.cap, 0, acpi_battery_sysctl, "I", "");
  207     SYSCTL_ADD_PROC(&sc->acpi_battery_sysctl_ctx,
  208         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  209         OID_AUTO, "time", CTLTYPE_INT | CTLFLAG_RD,
  210         &acpi_battery_battinfo.min, 0, acpi_battery_sysctl, "I", "");
  211     SYSCTL_ADD_PROC(&sc->acpi_battery_sysctl_ctx,
  212         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  213         OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RD,
  214         &acpi_battery_battinfo.state, 0, acpi_battery_sysctl, "I", "");
  215     SYSCTL_ADD_INT(&sc->acpi_battery_sysctl_ctx,
  216         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  217         OID_AUTO, "units", CTLFLAG_RD, &acpi_batteries_units, 0, "");
  218     SYSCTL_ADD_INT(&sc->acpi_battery_sysctl_ctx,
  219         SYSCTL_CHILDREN(sc->acpi_battery_sysctl_tree),
  220         OID_AUTO, "info_expire", CTLFLAG_RD | CTLFLAG_RW,
  221         &acpi_battery_info_expire, 0, "");
  222 
  223     acpi_batteries_initted = TRUE;
  224 
  225 out:
  226     return (error);
  227 }
  228 
  229 int
  230 acpi_battery_register(int type, int phys_unit)
  231 {
  232     struct acpi_batteries *bp;
  233     int error;
  234 
  235     error = 0;
  236     bp = malloc(sizeof(*bp), M_ACPIBATT, M_NOWAIT);
  237     if (bp == NULL)
  238         return (ENOMEM);
  239 
  240     ACPI_SERIAL_BEGIN(battery);
  241     if (!acpi_batteries_initted && (error = acpi_battery_init()) != 0) {
  242         printf("acpi_battery_register failed for unit %d\n", phys_unit);
  243         goto out;
  244     }
  245     bp->battdesc.type = type;
  246     bp->battdesc.phys_unit = phys_unit;
  247     TAILQ_INSERT_TAIL(&acpi_batteries, bp, link);
  248     acpi_batteries_units++;
  249 
  250 out:
  251     ACPI_SERIAL_END(battery);
  252     if (error)
  253         free(bp, M_ACPIBATT);
  254     return (error);
  255 }
  256 
  257 int
  258 acpi_battery_remove(int type, int phys_unit)
  259 {
  260     struct acpi_batteries *bp, *tmp;
  261     int ret;
  262 
  263     ret = ENOENT;
  264     ACPI_SERIAL_BEGIN(battery);
  265     TAILQ_FOREACH_SAFE(bp, &acpi_batteries, link, tmp) {
  266         if (bp->battdesc.type == type && bp->battdesc.phys_unit == phys_unit) {
  267             TAILQ_REMOVE(&acpi_batteries, bp, link);
  268             acpi_batteries_units--;
  269             ret = 0;
  270             break;
  271         }
  272     }
  273     ACPI_SERIAL_END(battery);
  274     if (ret == 0)
  275         free(bp, M_ACPIBATT);
  276     return (ret);
  277 }

Cache object: b259abfea00b9d4a73f8da1c6f4e5e6e


[ 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.