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.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 Takanori Watanabe <takawata@jp.freebsd.org>
    3  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
    4  * Copyright (c) 2000, 2001 Michael Smith
    5  * Copyright (c) 2000 BSDi
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  *      $FreeBSD: releng/5.2/sys/dev/acpica/acpi.c 123973 2003-12-29 15:48:16Z jhb $
   30  */
   31 
   32 #include "opt_acpi.h"
   33 #include <sys/param.h>
   34 #include <sys/kernel.h>
   35 #include <sys/proc.h>
   36 #include <sys/fcntl.h>
   37 #include <sys/malloc.h>
   38 #include <sys/bus.h>
   39 #include <sys/conf.h>
   40 #include <sys/ioccom.h>
   41 #include <sys/reboot.h>
   42 #include <sys/sysctl.h>
   43 #include <sys/ctype.h>
   44 #include <sys/linker.h>
   45 #include <sys/power.h>
   46 
   47 #include <machine/clock.h>
   48 #include <machine/resource.h>
   49 #include <machine/bus.h>
   50 #include <sys/rman.h>
   51 #include <isa/isavar.h>
   52 
   53 #include "acpi.h"
   54 #include <dev/acpica/acpivar.h>
   55 #include <dev/acpica/acpiio.h>
   56 #include <contrib/dev/acpica/acnamesp.h>
   57 
   58 MALLOC_DEFINE(M_ACPIDEV, "acpidev", "ACPI devices");
   59 
   60 /* Hooks for the ACPI CA debugging infrastructure */
   61 #define _COMPONENT      ACPI_BUS
   62 ACPI_MODULE_NAME("ACPI")
   63 
   64 static d_open_t         acpiopen;
   65 static d_close_t        acpiclose;
   66 static d_ioctl_t        acpiioctl;
   67 
   68 #define CDEV_MAJOR 152
   69 static struct cdevsw acpi_cdevsw = {
   70         .d_open =       acpiopen,
   71         .d_close =      acpiclose,
   72         .d_ioctl =      acpiioctl,
   73         .d_name =       "acpi",
   74         .d_maj =        CDEV_MAJOR,
   75 };
   76 
   77 static const char* sleep_state_names[] = {
   78     "S0", "S1", "S2", "S3", "S4", "S5", "NONE"};
   79 
   80 /* this has to be static, as the softc is gone when we need it */
   81 static int acpi_off_state = ACPI_STATE_S5;
   82 
   83 #if __FreeBSD_version >= 500000
   84 struct mtx      acpi_mutex;
   85 #endif
   86 
   87 static int      acpi_modevent(struct module *mod, int event, void *junk);
   88 static void     acpi_identify(driver_t *driver, device_t parent);
   89 static int      acpi_probe(device_t dev);
   90 static int      acpi_attach(device_t dev);
   91 static device_t acpi_add_child(device_t bus, int order, const char *name,
   92                         int unit);
   93 static int      acpi_print_child(device_t bus, device_t child);
   94 static int      acpi_read_ivar(device_t dev, device_t child, int index,
   95                         uintptr_t *result);
   96 static int      acpi_write_ivar(device_t dev, device_t child, int index,
   97                         uintptr_t value);
   98 static int      acpi_set_resource(device_t dev, device_t child, int type,
   99                         int rid, u_long start, u_long count);
  100 static int      acpi_get_resource(device_t dev, device_t child, int type,
  101                         int rid, u_long *startp, u_long *countp);
  102 static struct resource *acpi_alloc_resource(device_t bus, device_t child,
  103                         int type, int *rid, u_long start, u_long end,
  104                         u_long count, u_int flags);
  105 static int      acpi_release_resource(device_t bus, device_t child, int type,
  106                         int rid, struct resource *r);
  107 static uint32_t acpi_isa_get_logicalid(device_t dev);
  108 static int      acpi_isa_get_compatid(device_t dev, uint32_t *cids, int count);
  109 static int      acpi_isa_pnp_probe(device_t bus, device_t child,
  110                         struct isa_pnp_id *ids);
  111 static void     acpi_probe_children(device_t bus);
  112 static ACPI_STATUS acpi_probe_child(ACPI_HANDLE handle, UINT32 level,
  113                         void *context, void **status);
  114 static void     acpi_shutdown_pre_sync(void *arg, int howto);
  115 static void     acpi_shutdown_final(void *arg, int howto);
  116 static void     acpi_enable_fixed_events(struct acpi_softc *sc);
  117 static void     acpi_system_eventhandler_sleep(void *arg, int state);
  118 static void     acpi_system_eventhandler_wakeup(void *arg, int state);
  119 static int      acpi_supported_sleep_state_sysctl(SYSCTL_HANDLER_ARGS);
  120 static int      acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS);
  121 static int      acpi_pm_func(u_long cmd, void *arg, ...);
  122 
  123 static device_method_t acpi_methods[] = {
  124     /* Device interface */
  125     DEVMETHOD(device_identify,          acpi_identify),
  126     DEVMETHOD(device_probe,             acpi_probe),
  127     DEVMETHOD(device_attach,            acpi_attach),
  128     DEVMETHOD(device_detach,            bus_generic_detach),
  129     DEVMETHOD(device_shutdown,          bus_generic_shutdown),
  130     DEVMETHOD(device_suspend,           bus_generic_suspend),
  131     DEVMETHOD(device_resume,            bus_generic_resume),
  132 
  133     /* Bus interface */
  134     DEVMETHOD(bus_add_child,            acpi_add_child),
  135     DEVMETHOD(bus_print_child,          acpi_print_child),
  136     DEVMETHOD(bus_read_ivar,            acpi_read_ivar),
  137     DEVMETHOD(bus_write_ivar,           acpi_write_ivar),
  138     DEVMETHOD(bus_set_resource,         acpi_set_resource),
  139     DEVMETHOD(bus_get_resource,         acpi_get_resource),
  140     DEVMETHOD(bus_alloc_resource,       acpi_alloc_resource),
  141     DEVMETHOD(bus_release_resource,     acpi_release_resource),
  142     DEVMETHOD(bus_driver_added,         bus_generic_driver_added),
  143     DEVMETHOD(bus_activate_resource,    bus_generic_activate_resource),
  144     DEVMETHOD(bus_deactivate_resource,  bus_generic_deactivate_resource),
  145     DEVMETHOD(bus_setup_intr,           bus_generic_setup_intr),
  146     DEVMETHOD(bus_teardown_intr,        bus_generic_teardown_intr),
  147 
  148     /* ISA emulation */
  149     DEVMETHOD(isa_pnp_probe,            acpi_isa_pnp_probe),
  150 
  151     {0, 0}
  152 };
  153 
  154 static driver_t acpi_driver = {
  155     "acpi",
  156     acpi_methods,
  157     sizeof(struct acpi_softc),
  158 };
  159 
  160 static devclass_t acpi_devclass;
  161 DRIVER_MODULE(acpi, nexus, acpi_driver, acpi_devclass, acpi_modevent, 0);
  162 MODULE_VERSION(acpi, 100);
  163 
  164 SYSCTL_NODE(_debug, OID_AUTO, acpi, CTLFLAG_RW, NULL, "ACPI debugging");
  165 static char acpi_ca_version[12];
  166 SYSCTL_STRING(_debug_acpi, OID_AUTO, acpi_ca_version, CTLFLAG_RD,
  167               acpi_ca_version, 0, "Version of Intel ACPI-CA");
  168 
  169 /*
  170  * ACPI can only be loaded as a module by the loader; activating it after
  171  * system bootstrap time is not useful, and can be fatal to the system.
  172  * It also cannot be unloaded, since the entire system bus heirarchy hangs
  173  * off it.
  174  */
  175 static int
  176 acpi_modevent(struct module *mod, int event, void *junk)
  177 {
  178     switch(event) {
  179     case MOD_LOAD:
  180         if (!cold) {
  181             printf("The ACPI driver cannot be loaded after boot.\n");
  182             return (EPERM);
  183         }
  184         break;
  185     case MOD_UNLOAD:
  186         if (!cold && power_pm_get_type() == POWER_PM_TYPE_ACPI)
  187             return (EBUSY);
  188         break;
  189     default:
  190         break;
  191     }
  192     return (0);
  193 }
  194 
  195 /*
  196  * Detect ACPI, perform early initialisation
  197  */
  198 static void
  199 acpi_identify(driver_t *driver, device_t parent)
  200 {
  201     device_t    child;
  202     int         error;
  203 #ifdef ACPI_DEBUGGER
  204     char        *debugpoint;
  205 #endif
  206 
  207     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
  208 
  209     if (!cold)
  210         return_VOID;
  211 
  212     /* Check that we haven't been disabled with a hint. */
  213     if (resource_disabled("acpi", 0))
  214         return_VOID;
  215 
  216     snprintf(acpi_ca_version, sizeof(acpi_ca_version), "0x%x",
  217              ACPI_CA_VERSION);
  218 
  219     /* Make sure we're not being doubly invoked. */
  220     if (device_find_child(parent, "acpi", 0) != NULL)
  221         return_VOID;
  222 
  223 #if __FreeBSD_version >= 500000
  224     /* Initialise the ACPI mutex */
  225     mtx_init(&acpi_mutex, "ACPI global lock", NULL, MTX_DEF);
  226 #endif
  227 
  228     /* Start up the ACPI CA subsystem. */
  229 #ifdef ACPI_DEBUGGER
  230     debugpoint = getenv("debug.acpi.debugger");
  231     if (debugpoint) {
  232         if (!strcmp(debugpoint, "init"))
  233             acpi_EnterDebugger();
  234         freeenv(debugpoint);
  235     }
  236 #endif
  237     if (ACPI_FAILURE(error = AcpiInitializeSubsystem())) {
  238         printf("ACPI: initialisation failed: %s\n", AcpiFormatException(error));
  239         return_VOID;
  240     }
  241 #ifdef ACPI_DEBUGGER
  242     debugpoint = getenv("debug.acpi.debugger");
  243     if (debugpoint) {
  244         if (!strcmp(debugpoint, "tables"))
  245             acpi_EnterDebugger();
  246         freeenv(debugpoint);
  247     }
  248 #endif
  249 
  250     if (ACPI_FAILURE(error = AcpiLoadTables())) {
  251         printf("ACPI: table load failed: %s\n", AcpiFormatException(error));
  252         return_VOID;
  253     }
  254     
  255     /* Attach the actual ACPI device. */
  256     if ((child = BUS_ADD_CHILD(parent, 0, "acpi", 0)) == NULL) {
  257         device_printf(parent, "ACPI: could not attach\n");
  258         return_VOID;
  259     }
  260 }
  261 
  262 /*
  263  * Fetch some descriptive data from ACPI to put in our attach message
  264  */
  265 static int
  266 acpi_probe(device_t dev)
  267 {
  268     ACPI_TABLE_HEADER   th;
  269     char                buf[20];
  270     ACPI_STATUS         status;
  271     int                 error;
  272     ACPI_LOCK_DECL;
  273 
  274     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
  275 
  276     if (power_pm_get_type() != POWER_PM_TYPE_NONE &&
  277         power_pm_get_type() != POWER_PM_TYPE_ACPI) {
  278 
  279         device_printf(dev, "Other PM system enabled.\n");
  280         return_VALUE(ENXIO);
  281     }
  282 
  283     ACPI_LOCK;
  284 
  285     if (ACPI_FAILURE(status = AcpiGetTableHeader(ACPI_TABLE_XSDT, 1, &th))) {
  286         device_printf(dev, "couldn't get XSDT header: %s\n",
  287                       AcpiFormatException(status));
  288         error = ENXIO;
  289     } else {
  290         sprintf(buf, "%.6s %.8s", th.OemId, th.OemTableId);
  291         device_set_desc_copy(dev, buf);
  292         error = 0;
  293     }
  294     ACPI_UNLOCK;
  295     return_VALUE(error);
  296 }
  297 
  298 static int
  299 acpi_attach(device_t dev)
  300 {
  301     struct acpi_softc   *sc;
  302     ACPI_STATUS         status;
  303     int                 error;
  304     UINT32              flags;
  305     char                *env;
  306 #ifdef ACPI_DEBUGGER
  307     char                *debugpoint;
  308 #endif
  309     ACPI_LOCK_DECL;
  310 
  311     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
  312     ACPI_LOCK;
  313     sc = device_get_softc(dev);
  314     bzero(sc, sizeof(*sc));
  315     sc->acpi_dev = dev;
  316 
  317 #ifdef ACPI_DEBUGGER
  318     debugpoint = getenv("debug.acpi.debugger");
  319     if (debugpoint) {
  320         if (!strcmp(debugpoint, "spaces"))
  321             acpi_EnterDebugger();
  322         freeenv(debugpoint);
  323     }
  324 #endif
  325 
  326     /* Install the default address space handlers. */
  327     error = ENXIO;
  328     status = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
  329                 ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL);
  330     if (ACPI_FAILURE(status)) {
  331         device_printf(dev, "Could not initialise SystemMemory handler: %s\n",
  332                       AcpiFormatException(status));
  333         goto out;
  334     }
  335     status = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
  336                 ACPI_ADR_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL);
  337     if (ACPI_FAILURE(status)) {
  338         device_printf(dev, "Could not initialise SystemIO handler: %s\n",
  339                       AcpiFormatException(status));
  340         goto out;
  341     }
  342     status = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
  343                 ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
  344     if (ACPI_FAILURE(status)) {
  345         device_printf(dev, "could not initialise PciConfig handler: %s\n",
  346                       AcpiFormatException(status));
  347         goto out;
  348     }
  349 
  350     /*
  351      * Bring ACPI fully online.
  352      *
  353      * Note that some systems (specifically, those with namespace evaluation
  354      * issues that require the avoidance of parts of the namespace) must
  355      * avoid running _INI and _STA on everything, as well as dodging the final
  356      * object init pass.
  357      *
  358      * For these devices, we set ACPI_NO_DEVICE_INIT and ACPI_NO_OBJECT_INIT).
  359      *
  360      * XXX We should arrange for the object init pass after we have attached
  361      *     all our child devices, but on many systems it works here.
  362      */
  363 #ifdef ACPI_DEBUGGER
  364     debugpoint = getenv("debug.acpi.debugger");
  365     if (debugpoint) {
  366         if (!strcmp(debugpoint, "enable"))
  367             acpi_EnterDebugger();
  368         freeenv(debugpoint);
  369     }
  370 #endif
  371     flags = 0;
  372     if (testenv("debug.acpi.avoid"))
  373         flags = ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT;
  374     if (ACPI_FAILURE(status = AcpiEnableSubsystem(flags))) {
  375         device_printf(dev, "Could not enable ACPI: %s\n",
  376                       AcpiFormatException(status));
  377         goto out;
  378     }
  379 
  380     /*
  381      * Call the ECDT probe function to provide EC functionality before
  382      * the namespace has been evaluated.
  383      */
  384     acpi_ec_ecdt_probe(dev);
  385 
  386     if (ACPI_FAILURE(status = AcpiInitializeObjects(flags))) {
  387         device_printf(dev, "Could not initialize ACPI objects: %s\n",
  388                       AcpiFormatException(status));
  389         goto out;
  390     }
  391 
  392     /*
  393      * Setup our sysctl tree.
  394      *
  395      * XXX: This doesn't check to make sure that none of these fail.
  396      */
  397     sysctl_ctx_init(&sc->acpi_sysctl_ctx);
  398     sc->acpi_sysctl_tree = SYSCTL_ADD_NODE(&sc->acpi_sysctl_ctx,
  399                                SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
  400                                device_get_name(dev), CTLFLAG_RD, 0, "");
  401     SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  402         OID_AUTO, "supported_sleep_state", CTLTYPE_STRING | CTLFLAG_RD,
  403         0, 0, acpi_supported_sleep_state_sysctl, "A", "");
  404     SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  405         OID_AUTO, "power_button_state", CTLTYPE_STRING | CTLFLAG_RW,
  406         &sc->acpi_power_button_sx, 0, acpi_sleep_state_sysctl, "A", "");
  407     SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  408         OID_AUTO, "sleep_button_state", CTLTYPE_STRING | CTLFLAG_RW,
  409         &sc->acpi_sleep_button_sx, 0, acpi_sleep_state_sysctl, "A", "");
  410     SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  411         OID_AUTO, "lid_switch_state", CTLTYPE_STRING | CTLFLAG_RW,
  412         &sc->acpi_lid_switch_sx, 0, acpi_sleep_state_sysctl, "A", "");
  413     SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  414         OID_AUTO, "standby_state", CTLTYPE_STRING | CTLFLAG_RW,
  415         &sc->acpi_standby_sx, 0, acpi_sleep_state_sysctl, "A", "");
  416     SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  417         OID_AUTO, "suspend_state", CTLTYPE_STRING | CTLFLAG_RW,
  418         &sc->acpi_suspend_sx, 0, acpi_sleep_state_sysctl, "A", "");
  419     SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  420         OID_AUTO, "sleep_delay", CTLFLAG_RD | CTLFLAG_RW,
  421         &sc->acpi_sleep_delay, 0, "sleep delay");
  422     SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  423         OID_AUTO, "s4bios", CTLFLAG_RD | CTLFLAG_RW,
  424         &sc->acpi_s4bios, 0, "S4BIOS mode");
  425     SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  426         OID_AUTO, "verbose", CTLFLAG_RD | CTLFLAG_RW,
  427         &sc->acpi_verbose, 0, "verbose mode");
  428     SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
  429         OID_AUTO, "disable_on_poweroff", CTLFLAG_RD | CTLFLAG_RW,
  430         &sc->acpi_disable_on_poweroff, 0, "ACPI subsystem disable on poweroff");
  431 
  432     /*
  433      * Default to 5 seconds before sleeping to give some machines time to
  434      * stabilize.
  435      */
  436     sc->acpi_sleep_delay = 5;
  437     sc->acpi_disable_on_poweroff = 1;
  438     if (bootverbose)
  439         sc->acpi_verbose = 1;
  440     if ((env = getenv("hw.acpi.verbose")) && strcmp(env, "")) {
  441         sc->acpi_verbose = 1;
  442         freeenv(env);
  443     }
  444 
  445     /* Only enable S4BIOS by default if the FACS says it is available. */
  446     if (AcpiGbl_FACS->S4Bios_f != 0)
  447             sc->acpi_s4bios = 1;
  448 
  449     /*
  450      * Dispatch the default sleep state to devices.
  451      * TBD: should be configured from userland policy manager.
  452      */
  453     sc->acpi_power_button_sx = ACPI_POWER_BUTTON_DEFAULT_SX;
  454     sc->acpi_sleep_button_sx = ACPI_SLEEP_BUTTON_DEFAULT_SX;
  455     sc->acpi_lid_switch_sx = ACPI_LID_SWITCH_DEFAULT_SX;
  456     sc->acpi_standby_sx = ACPI_STATE_S1;
  457     sc->acpi_suspend_sx = ACPI_STATE_S3;
  458 
  459     acpi_enable_fixed_events(sc);
  460 
  461     /*
  462      * Scan the namespace and attach/initialise children.
  463      */
  464 #ifdef ACPI_DEBUGGER
  465     debugpoint = getenv("debug.acpi.debugger");
  466     if (debugpoint) {
  467         if (!strcmp(debugpoint, "probe"))
  468             acpi_EnterDebugger();
  469         freeenv(debugpoint);
  470     }
  471 #endif
  472 
  473     /* Register our shutdown handlers */
  474     EVENTHANDLER_REGISTER(shutdown_pre_sync, acpi_shutdown_pre_sync, sc,
  475         SHUTDOWN_PRI_LAST);
  476     EVENTHANDLER_REGISTER(shutdown_final, acpi_shutdown_final, sc,
  477         SHUTDOWN_PRI_LAST);
  478 
  479     /*
  480      * Register our acpi event handlers.
  481      * XXX should be configurable eg. via userland policy manager.
  482      */
  483     EVENTHANDLER_REGISTER(acpi_sleep_event, acpi_system_eventhandler_sleep,
  484         sc, ACPI_EVENT_PRI_LAST);
  485     EVENTHANDLER_REGISTER(acpi_wakeup_event, acpi_system_eventhandler_wakeup,
  486         sc, ACPI_EVENT_PRI_LAST);
  487 
  488     /* Flag our initial states. */
  489     sc->acpi_enabled = 1;
  490     sc->acpi_sstate = ACPI_STATE_S0;
  491     sc->acpi_sleep_disabled = 0;
  492 
  493     /* Create the control device */
  494     sc->acpi_dev_t = make_dev(&acpi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644,
  495                               "acpi");
  496     sc->acpi_dev_t->si_drv1 = sc;
  497 
  498 #ifdef ACPI_DEBUGGER
  499     debugpoint = getenv("debug.acpi.debugger");
  500     if (debugpoint) {
  501         if (strcmp(debugpoint, "running") == 0)
  502             acpi_EnterDebugger();
  503         freeenv(debugpoint);
  504     }
  505 #endif
  506 
  507 #ifdef ACPI_USE_THREADS
  508     if ((error = acpi_task_thread_init()))
  509         goto out;
  510 #endif
  511 
  512     if ((error = acpi_machdep_init(dev)))
  513         goto out;
  514 
  515     /* Register ACPI again to pass the correct argument of pm_func. */
  516     power_pm_register(POWER_PM_TYPE_ACPI, acpi_pm_func, sc);
  517 
  518     if (!acpi_disabled("bus"))
  519         acpi_probe_children(dev);
  520 
  521     error = 0;
  522 
  523  out:
  524     ACPI_UNLOCK;
  525     return_VALUE (error);
  526 }
  527 
  528 /*
  529  * Handle a new device being added
  530  */
  531 static device_t
  532 acpi_add_child(device_t bus, int order, const char *name, int unit)
  533 {
  534     struct acpi_device  *ad;
  535     device_t            child;
  536 
  537     if ((ad = malloc(sizeof(*ad), M_ACPIDEV, M_NOWAIT | M_ZERO)) == NULL)
  538         return (NULL);
  539 
  540     resource_list_init(&ad->ad_rl);
  541     
  542     child = device_add_child_ordered(bus, order, name, unit);
  543     if (child != NULL)
  544         device_set_ivars(child, ad);
  545     return (child);
  546 }
  547 
  548 static int
  549 acpi_print_child(device_t bus, device_t child)
  550 {
  551     struct acpi_device   *adev = device_get_ivars(child);
  552     struct resource_list *rl = &adev->ad_rl;
  553     int retval = 0;
  554 
  555     retval += bus_print_child_header(bus, child);
  556     retval += resource_list_print_type(rl, "port",  SYS_RES_IOPORT, "%#lx");
  557     retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#lx");
  558     retval += resource_list_print_type(rl, "irq",   SYS_RES_IRQ,    "%ld");
  559     retval += resource_list_print_type(rl, "drq",   SYS_RES_DRQ,    "%ld");
  560     retval += bus_print_child_footer(bus, child);
  561 
  562     return (retval);
  563 }
  564 
  565 
  566 /*
  567  * Handle per-device ivars
  568  */
  569 static int
  570 acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
  571 {
  572     struct acpi_device  *ad;
  573 
  574     if ((ad = device_get_ivars(child)) == NULL) {
  575         printf("device has no ivars\n");
  576         return (ENOENT);
  577     }
  578 
  579     /* ACPI and ISA compatibility ivars */
  580     switch(index) {
  581     case ACPI_IVAR_HANDLE:
  582         *(ACPI_HANDLE *)result = ad->ad_handle;
  583         break;
  584     case ACPI_IVAR_MAGIC:
  585         *(int *)result = ad->ad_magic;
  586         break;
  587     case ACPI_IVAR_PRIVATE:
  588         *(void **)result = ad->ad_private;
  589         break;
  590     case ISA_IVAR_VENDORID:
  591     case ISA_IVAR_SERIAL:
  592     case ISA_IVAR_COMPATID:
  593         *(int *)result = -1;
  594         break;
  595     case ISA_IVAR_LOGICALID:
  596         *(int *)result = acpi_isa_get_logicalid(child);
  597         break;
  598     default:
  599         return (ENOENT);
  600     }
  601 
  602     return (0);
  603 }
  604 
  605 static int
  606 acpi_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
  607 {
  608     struct acpi_device  *ad;
  609 
  610     if ((ad = device_get_ivars(child)) == NULL) {
  611         printf("device has no ivars\n");
  612         return (ENOENT);
  613     }
  614 
  615     switch(index) {
  616     case ACPI_IVAR_HANDLE:
  617         ad->ad_handle = (ACPI_HANDLE)value;
  618         break;
  619     case ACPI_IVAR_MAGIC:
  620         ad->ad_magic = (int)value;
  621         break;
  622     case ACPI_IVAR_PRIVATE:
  623         ad->ad_private = (void *)value;
  624         break;
  625     default:
  626         panic("bad ivar write request (%d)", index);
  627         return (ENOENT);
  628     }
  629 
  630     return (0);
  631 }
  632 
  633 ACPI_HANDLE
  634 acpi_get_handle(device_t dev)
  635 {
  636     uintptr_t up;
  637     ACPI_HANDLE h;
  638 
  639     if (BUS_READ_IVAR(device_get_parent(dev), dev, ACPI_IVAR_HANDLE, &up))
  640         return(NULL);
  641     h = (ACPI_HANDLE)up;
  642     return (h);
  643 }
  644             
  645 int
  646 acpi_set_handle(device_t dev, ACPI_HANDLE h)
  647 {
  648     uintptr_t up;
  649 
  650     up = (uintptr_t)h;
  651     return (BUS_WRITE_IVAR(device_get_parent(dev), dev, ACPI_IVAR_HANDLE, up));
  652 }
  653             
  654 int
  655 acpi_get_magic(device_t dev)
  656 {
  657     uintptr_t up;
  658     int m;
  659 
  660     if (BUS_READ_IVAR(device_get_parent(dev), dev, ACPI_IVAR_MAGIC, &up))
  661         return(0);
  662     m = (int)up;
  663     return (m);
  664 }
  665 
  666 int
  667 acpi_set_magic(device_t dev, int m)
  668 {
  669     uintptr_t up;
  670 
  671     up = (uintptr_t)m;
  672     return (BUS_WRITE_IVAR(device_get_parent(dev), dev, ACPI_IVAR_MAGIC, up));
  673 }
  674 
  675 void *
  676 acpi_get_private(device_t dev)
  677 {
  678     uintptr_t up;
  679     void *p;
  680 
  681     if (BUS_READ_IVAR(device_get_parent(dev), dev, ACPI_IVAR_PRIVATE, &up))
  682         return (NULL);
  683     p = (void *)up;
  684     return (p);
  685 }
  686 
  687 int
  688 acpi_set_private(device_t dev, void *p)
  689 {
  690     uintptr_t up;
  691 
  692     up = (uintptr_t)p;
  693     return (BUS_WRITE_IVAR(device_get_parent(dev), dev, ACPI_IVAR_PRIVATE, up));
  694 }
  695 
  696 ACPI_OBJECT_TYPE
  697 acpi_get_type(device_t dev)
  698 {
  699     ACPI_HANDLE         h;
  700     ACPI_OBJECT_TYPE    t;
  701 
  702     if ((h = acpi_get_handle(dev)) == NULL)
  703         return (ACPI_TYPE_NOT_FOUND);
  704     if (AcpiGetType(h, &t) != AE_OK)
  705         return (ACPI_TYPE_NOT_FOUND);
  706     return (t);
  707 }
  708 
  709 /*
  710  * Handle child resource allocation/removal
  711  */
  712 static int
  713 acpi_set_resource(device_t dev, device_t child, int type, int rid,
  714                   u_long start, u_long count)
  715 {
  716     struct acpi_device          *ad = device_get_ivars(child);
  717     struct resource_list        *rl = &ad->ad_rl;
  718 
  719     resource_list_add(rl, type, rid, start, start + count -1, count);
  720 
  721     return(0);
  722 }
  723 
  724 static int
  725 acpi_get_resource(device_t dev, device_t child, int type, int rid,
  726                   u_long *startp, u_long *countp)
  727 {
  728     struct acpi_device          *ad = device_get_ivars(child);
  729     struct resource_list        *rl = &ad->ad_rl;
  730     struct resource_list_entry  *rle;
  731 
  732     rle = resource_list_find(rl, type, rid);
  733     if (!rle)
  734         return(ENOENT);
  735         
  736     if (startp)
  737         *startp = rle->start;
  738     if (countp)
  739         *countp = rle->count;
  740 
  741     return (0);
  742 }
  743 
  744 static struct resource *
  745 acpi_alloc_resource(device_t bus, device_t child, int type, int *rid,
  746                     u_long start, u_long end, u_long count, u_int flags)
  747 {
  748     struct acpi_device *ad = device_get_ivars(child);
  749     struct resource_list *rl = &ad->ad_rl;
  750 
  751     return (resource_list_alloc(rl, bus, child, type, rid, start, end, count,
  752             flags));
  753 }
  754 
  755 static int
  756 acpi_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r)
  757 {
  758     struct acpi_device *ad = device_get_ivars(child);
  759     struct resource_list *rl = &ad->ad_rl;
  760 
  761     return (resource_list_release(rl, bus, child, type, rid, r));
  762 }
  763 
  764 /* Allocate an IO port or memory resource, given its GAS. */
  765 struct resource *
  766 acpi_bus_alloc_gas(device_t dev, int *rid, ACPI_GENERIC_ADDRESS *gas)
  767 {
  768     int type;
  769 
  770     if (gas == NULL || !ACPI_VALID_ADDRESS(gas->Address) ||
  771         gas->RegisterBitWidth < 8)
  772         return (NULL);
  773 
  774     switch (gas->AddressSpaceId) {
  775     case ACPI_ADR_SPACE_SYSTEM_MEMORY:
  776         type = SYS_RES_MEMORY;
  777         break;
  778     case ACPI_ADR_SPACE_SYSTEM_IO:
  779         type = SYS_RES_IOPORT;
  780         break;
  781     default:
  782         return (NULL);
  783     }
  784 
  785     bus_set_resource(dev, type, *rid, gas->Address, gas->RegisterBitWidth / 8);
  786     return (bus_alloc_resource(dev, type, rid, 0, ~0, 1, RF_ACTIVE));
  787 }
  788 
  789 /*
  790  * Handle ISA-like devices probing for a PnP ID to match.
  791  */
  792 #define PNP_EISAID(s)                           \
  793         ((((s[0] - '@') & 0x1f) << 2)           \
  794          | (((s[1] - '@') & 0x18) >> 3)         \
  795          | (((s[1] - '@') & 0x07) << 13)        \
  796          | (((s[2] - '@') & 0x1f) << 8)         \
  797          | (PNP_HEXTONUM(s[4]) << 16)           \
  798          | (PNP_HEXTONUM(s[3]) << 20)           \
  799          | (PNP_HEXTONUM(s[6]) << 24)           \
  800          | (PNP_HEXTONUM(s[5]) << 28))
  801 
  802 static uint32_t
  803 acpi_isa_get_logicalid(device_t dev)
  804 {
  805     ACPI_DEVICE_INFO    *devinfo;
  806     ACPI_BUFFER         buf;
  807     ACPI_HANDLE         h;
  808     ACPI_STATUS         error;
  809     u_int32_t           pnpid;
  810     ACPI_LOCK_DECL;
  811 
  812     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
  813 
  814     pnpid = 0;
  815     ACPI_LOCK;
  816     
  817     /* Fetch and validate the HID. */
  818     if ((h = acpi_get_handle(dev)) == NULL)
  819         return (0);
  820     buf.Pointer = NULL;
  821     buf.Length = ACPI_ALLOCATE_BUFFER;
  822     error = AcpiGetObjectInfo(h, &buf);
  823     if (ACPI_FAILURE(error))
  824         return (0);
  825     devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
  826 
  827     if ((devinfo->Valid & ACPI_VALID_HID) != 0)
  828         pnpid = PNP_EISAID(devinfo->HardwareId.Value);
  829 
  830     AcpiOsFree(buf.Pointer);
  831     ACPI_UNLOCK;
  832     return_VALUE (pnpid);
  833 }
  834 
  835 static int
  836 acpi_isa_get_compatid(device_t dev, uint32_t *cids, int count)
  837 {
  838     ACPI_DEVICE_INFO    *devinfo;
  839     ACPI_BUFFER         buf;
  840     ACPI_HANDLE         h;
  841     ACPI_STATUS         error;
  842     uint32_t            *pnpid;
  843     int                 valid, i;
  844     ACPI_LOCK_DECL;
  845 
  846     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
  847 
  848     pnpid = cids;
  849     valid = 0;
  850     ACPI_LOCK;
  851     
  852     /* Fetch and validate the CID */
  853     if ((h = acpi_get_handle(dev)) == NULL)
  854         return (0);
  855     buf.Pointer = NULL;
  856     buf.Length = ACPI_ALLOCATE_BUFFER;
  857     error = AcpiGetObjectInfo(h, &buf);
  858     if (ACPI_FAILURE(error))
  859         return (0);
  860     devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
  861     if ((devinfo->Valid & ACPI_VALID_CID) == 0)
  862         goto out;
  863 
  864     if (devinfo->CompatibilityId.Count < count)
  865         count = devinfo->CompatibilityId.Count;
  866     for (i = 0; i < count; i++) {
  867         if (strncmp(devinfo->CompatibilityId.Id[i].Value, "PNP", 3) != 0)
  868             continue;
  869         *pnpid++ = PNP_EISAID(devinfo->CompatibilityId.Id[i].Value);
  870         valid++;
  871     }
  872 
  873 out:
  874     AcpiOsFree(buf.Pointer);
  875     ACPI_UNLOCK;
  876     return_VALUE (valid);
  877 }
  878 
  879 static int
  880 acpi_isa_pnp_probe(device_t bus, device_t child, struct isa_pnp_id *ids)
  881 {
  882     int                 result, cid_count, i;
  883     uint32_t            lid, cids[8];
  884 
  885     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
  886 
  887     /*
  888      * ISA-style drivers attached to ACPI may persist and
  889      * probe manually if we return ENOENT.  We never want
  890      * that to happen, so don't ever return it.
  891      */
  892     result = ENXIO;
  893 
  894     /* Scan the supplied IDs for a match */
  895     lid = acpi_isa_get_logicalid(child);
  896     cid_count = acpi_isa_get_compatid(child, cids, 8);
  897     while (ids && ids->ip_id) {
  898         if (lid == ids->ip_id) {
  899             result = 0;
  900             goto out;
  901         }
  902         for (i = 0; i < cid_count; i++) {
  903             if (cids[i] == ids->ip_id) {
  904                 result = 0;
  905                 goto out;
  906             }
  907         }
  908         ids++;
  909     }
  910 
  911  out:
  912     return_VALUE (result);
  913 }
  914 
  915 /*
  916  * Scan relevant portions of the ACPI namespace and attach child devices.
  917  *
  918  * Note that we only expect to find devices in the \_PR_, \_TZ_, \_SI_ and
  919  * \_SB_ scopes, and \_PR_ and \_TZ_ become obsolete in the ACPI 2.0 spec.
  920  */
  921 static void
  922 acpi_probe_children(device_t bus)
  923 {
  924     ACPI_HANDLE parent;
  925     ACPI_STATUS status;
  926     static char *scopes[] = {"\\_PR_", "\\_TZ_", "\\_SI", "\\_SB_", NULL};
  927     int         i;
  928 
  929     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
  930     ACPI_ASSERTLOCK;
  931 
  932     /* Create any static children by calling device identify methods. */
  933     ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "device identify routines\n"));
  934     bus_generic_probe(bus);
  935 
  936     /*
  937      * Scan the namespace and insert placeholders for all the devices that
  938      * we find.
  939      *
  940      * Note that we use AcpiWalkNamespace rather than AcpiGetDevices because
  941      * we want to create nodes for all devices, not just those that are
  942      * currently present. (This assumes that we don't want to create/remove
  943      * devices as they appear, which might be smarter.)
  944      */
  945     ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "namespace scan\n"));
  946     for (i = 0; scopes[i] != NULL; i++) {
  947         status = AcpiGetHandle(ACPI_ROOT_OBJECT, scopes[i], &parent);
  948         if (ACPI_SUCCESS(status)) {
  949             AcpiWalkNamespace(ACPI_TYPE_ANY, parent, 100, acpi_probe_child,
  950                               bus, NULL);
  951         }
  952     }
  953 
  954     /*
  955      * Scan all of the child devices we have created and let them probe/attach.
  956      */
  957     ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "first bus_generic_attach\n"));
  958     bus_generic_attach(bus);
  959 
  960     /*
  961      * Some of these children may have attached others as part of their attach
  962      * process (eg. the root PCI bus driver), so rescan.
  963      */
  964     ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "second bus_generic_attach\n"));
  965     bus_generic_attach(bus);
  966 
  967     ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "done attaching children\n"));
  968     return_VOID;
  969 }
  970 
  971 /*
  972  * Evaluate a child device and determine whether we might attach a device to
  973  * it.
  974  */
  975 static ACPI_STATUS
  976 acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
  977 {
  978     ACPI_OBJECT_TYPE    type;
  979     device_t            child, bus = (device_t)context;
  980 
  981     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
  982 
  983     /* Skip this device if we think we'll have trouble with it. */
  984     if (acpi_avoid(handle))
  985         return_ACPI_STATUS (AE_OK);
  986 
  987     if (ACPI_SUCCESS(AcpiGetType(handle, &type))) {
  988         switch(type) {
  989         case ACPI_TYPE_DEVICE:
  990         case ACPI_TYPE_PROCESSOR:
  991         case ACPI_TYPE_THERMAL:
  992         case ACPI_TYPE_POWER:
  993             if (acpi_disabled("children"))
  994                 break;
  995 
  996             /* 
  997              * Create a placeholder device for this node.  Sort the placeholder
  998              * so that the probe/attach passes will run breadth-first.
  999              */
 1000             ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n",
 1001                              acpi_name(handle)));
 1002             child = BUS_ADD_CHILD(bus, level * 10, NULL, -1);
 1003             if (child == NULL)
 1004                 break;
 1005             acpi_set_handle(child, handle);
 1006 
 1007             /*
 1008              * Check that the device is present.  If it's not present,
 1009              * leave it disabled (so that we have a device_t attached to
 1010              * the handle, but we don't probe it).
 1011              */
 1012             if (type == ACPI_TYPE_DEVICE && !acpi_DeviceIsPresent(child)) {
 1013                 device_disable(child);
 1014                 break;
 1015             }
 1016 
 1017             /*
 1018              * Get the device's resource settings and attach them.
 1019              * Note that if the device has _PRS but no _CRS, we need
 1020              * to decide when it's appropriate to try to configure the
 1021              * device.  Ignore the return value here; it's OK for the
 1022              * device not to have any resources.
 1023              */
 1024             acpi_parse_resources(child, handle, &acpi_res_parse_set);
 1025 
 1026             /* If we're debugging, probe/attach now rather than later */
 1027             ACPI_DEBUG_EXEC(device_probe_and_attach(child));
 1028             break;
 1029         }
 1030     }
 1031 
 1032     return_ACPI_STATUS (AE_OK);
 1033 }
 1034 
 1035 static void
 1036 acpi_shutdown_pre_sync(void *arg, int howto)
 1037 {
 1038     struct acpi_softc *sc = arg;
 1039 
 1040     ACPI_ASSERTLOCK;
 1041 
 1042     /*
 1043      * Disable all ACPI events before soft off, otherwise the system
 1044      * will be turned on again on some laptops.
 1045      *
 1046      * XXX this should probably be restricted to masking some events just
 1047      *     before powering down, since we may still need ACPI during the
 1048      *     shutdown process.
 1049      */
 1050     if (sc->acpi_disable_on_poweroff)
 1051         acpi_Disable(sc);
 1052 }
 1053 
 1054 static void
 1055 acpi_shutdown_final(void *arg, int howto)
 1056 {
 1057     ACPI_STATUS status;
 1058 
 1059     ACPI_ASSERTLOCK;
 1060 
 1061     if ((howto & RB_POWEROFF) != 0) {
 1062         printf("Powering system off using ACPI\n");
 1063         status = AcpiEnterSleepStatePrep(acpi_off_state);
 1064         if (ACPI_FAILURE(status)) {
 1065             printf("AcpiEnterSleepStatePrep failed - %s\n",
 1066                    AcpiFormatException(status));
 1067             return;
 1068         }
 1069         ACPI_DISABLE_IRQS();
 1070         status = AcpiEnterSleepState(acpi_off_state);
 1071         if (ACPI_FAILURE(status)) {
 1072             printf("ACPI power-off failed - %s\n", AcpiFormatException(status));
 1073         } else {
 1074             DELAY(1000000);
 1075             printf("ACPI power-off failed - timeout\n");
 1076         }
 1077     } else {
 1078         printf("Shutting down ACPI\n");
 1079         AcpiTerminate();
 1080     }
 1081 }
 1082 
 1083 static void
 1084 acpi_enable_fixed_events(struct acpi_softc *sc)
 1085 {
 1086     static int  first_time = 1;
 1087 
 1088     ACPI_ASSERTLOCK;
 1089 
 1090     /* Enable and clear fixed events and install handlers. */
 1091     if (AcpiGbl_FADT != NULL && AcpiGbl_FADT->PwrButton == 0) {
 1092         AcpiEnableEvent(ACPI_EVENT_POWER_BUTTON, 0);
 1093         AcpiClearEvent(ACPI_EVENT_POWER_BUTTON);
 1094         AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON,
 1095                                      acpi_eventhandler_power_button_for_sleep,
 1096                                      sc);
 1097         if (first_time)
 1098             device_printf(sc->acpi_dev, "Power Button (fixed)\n");
 1099     }
 1100     if (AcpiGbl_FADT != NULL && AcpiGbl_FADT->SleepButton == 0) {
 1101         AcpiEnableEvent(ACPI_EVENT_SLEEP_BUTTON, 0);
 1102         AcpiClearEvent(ACPI_EVENT_SLEEP_BUTTON);
 1103         AcpiInstallFixedEventHandler(ACPI_EVENT_SLEEP_BUTTON,
 1104                                      acpi_eventhandler_sleep_button_for_sleep,
 1105                                      sc);
 1106         if (first_time)
 1107             device_printf(sc->acpi_dev, "Sleep Button (fixed)\n");
 1108     }
 1109 
 1110     first_time = 0;
 1111 }
 1112 
 1113 /*
 1114  * Returns true if the device is actually present and should
 1115  * be attached to.  This requires the present, enabled, UI-visible 
 1116  * and diagnostics-passed bits to be set.
 1117  */
 1118 BOOLEAN
 1119 acpi_DeviceIsPresent(device_t dev)
 1120 {
 1121     ACPI_DEVICE_INFO    *devinfo;
 1122     ACPI_HANDLE         h;
 1123     ACPI_BUFFER         buf;
 1124     ACPI_STATUS         error;
 1125     int                 ret;
 1126 
 1127     ACPI_ASSERTLOCK;
 1128     
 1129     ret = FALSE;
 1130     if ((h = acpi_get_handle(dev)) == NULL)
 1131         return (FALSE);
 1132     buf.Pointer = NULL;
 1133     buf.Length = ACPI_ALLOCATE_BUFFER;
 1134     error = AcpiGetObjectInfo(h, &buf);
 1135     if (ACPI_FAILURE(error))
 1136         return (FALSE);
 1137     devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
 1138 
 1139     /* If no _STA method, must be present */
 1140     if ((devinfo->Valid & ACPI_VALID_STA) == 0)
 1141         ret = TRUE;
 1142 
 1143     /* Return true for 'present' and 'functioning' */
 1144     if ((devinfo->CurrentStatus & 0x9) == 0x9)
 1145         ret = TRUE;
 1146 
 1147     AcpiOsFree(buf.Pointer);
 1148     return (ret);
 1149 }
 1150 
 1151 /*
 1152  * Returns true if the battery is actually present and inserted.
 1153  */
 1154 BOOLEAN
 1155 acpi_BatteryIsPresent(device_t dev)
 1156 {
 1157     ACPI_DEVICE_INFO    *devinfo;
 1158     ACPI_HANDLE         h;
 1159     ACPI_BUFFER         buf;
 1160     ACPI_STATUS         error;
 1161     int                 ret;
 1162 
 1163     ACPI_ASSERTLOCK;
 1164     
 1165     ret = FALSE;
 1166     if ((h = acpi_get_handle(dev)) == NULL)
 1167         return (FALSE);
 1168     buf.Pointer = NULL;
 1169     buf.Length = ACPI_ALLOCATE_BUFFER;
 1170     error = AcpiGetObjectInfo(h, &buf);
 1171     if (ACPI_FAILURE(error))
 1172         return (FALSE);
 1173     devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
 1174 
 1175     /* If no _STA method, must be present */
 1176     if ((devinfo->Valid & ACPI_VALID_STA) == 0)
 1177         ret = TRUE;
 1178 
 1179     /* Return true for 'present' and 'functioning' */
 1180     if ((devinfo->CurrentStatus & 0x19) == 0x19)
 1181         ret = TRUE;
 1182 
 1183     AcpiOsFree(buf.Pointer);
 1184     return (ret);
 1185 }
 1186 
 1187 /*
 1188  * Match a HID string against a device
 1189  */
 1190 BOOLEAN
 1191 acpi_MatchHid(device_t dev, char *hid) 
 1192 {
 1193     ACPI_DEVICE_INFO    *devinfo;
 1194     ACPI_HANDLE         h;
 1195     ACPI_BUFFER         buf;
 1196     ACPI_STATUS         error;
 1197     int                 ret, i;
 1198 
 1199     ACPI_ASSERTLOCK;
 1200 
 1201     ret = FALSE;
 1202     if (hid == NULL)
 1203         return (FALSE);
 1204     if ((h = acpi_get_handle(dev)) == NULL)
 1205         return (FALSE);
 1206     buf.Pointer = NULL;
 1207     buf.Length = ACPI_ALLOCATE_BUFFER;
 1208     error = AcpiGetObjectInfo(h, &buf);
 1209     if (ACPI_FAILURE(error))
 1210         return (FALSE);
 1211     devinfo = (ACPI_DEVICE_INFO *)buf.Pointer;
 1212 
 1213     if ((devinfo->Valid & ACPI_VALID_HID) != 0 &&
 1214         strcmp(hid, devinfo->HardwareId.Value) == 0)
 1215             ret = TRUE;
 1216     else if ((devinfo->Valid & ACPI_VALID_CID) != 0) {
 1217         for (i = 0; i < devinfo->CompatibilityId.Count; i++) {
 1218             if (strcmp(hid, devinfo->CompatibilityId.Id[i].Value) == 0) {
 1219                 ret = TRUE;
 1220                 break;
 1221             }
 1222         }
 1223     }
 1224 
 1225     AcpiOsFree(buf.Pointer);
 1226     return (ret);
 1227 }
 1228 
 1229 /*
 1230  * Return the handle of a named object within our scope, ie. that of (parent)
 1231  * or one if its parents.
 1232  */
 1233 ACPI_STATUS
 1234 acpi_GetHandleInScope(ACPI_HANDLE parent, char *path, ACPI_HANDLE *result)
 1235 {
 1236     ACPI_HANDLE         r;
 1237     ACPI_STATUS         status;
 1238 
 1239     ACPI_ASSERTLOCK;
 1240 
 1241     /* Walk back up the tree to the root */
 1242     for (;;) {
 1243         status = AcpiGetHandle(parent, path, &r);
 1244         if (ACPI_SUCCESS(status)) {
 1245             *result = r;
 1246             return (AE_OK);
 1247         }
 1248         if (status != AE_NOT_FOUND)
 1249             return (AE_OK);
 1250         if (ACPI_FAILURE(AcpiGetParent(parent, &r)))
 1251             return (AE_NOT_FOUND);
 1252         parent = r;
 1253     }
 1254 }
 1255 
 1256 /*
 1257  * Allocate a buffer with a preset data size.
 1258  */
 1259 ACPI_BUFFER *
 1260 acpi_AllocBuffer(int size)
 1261 {
 1262     ACPI_BUFFER *buf;
 1263 
 1264     if ((buf = malloc(size + sizeof(*buf), M_ACPIDEV, M_NOWAIT)) == NULL)
 1265         return (NULL);
 1266     buf->Length = size;
 1267     buf->Pointer = (void *)(buf + 1);
 1268     return (buf);
 1269 }
 1270 
 1271 /*
 1272  * Evaluate a path that should return an integer.
 1273  */
 1274 ACPI_STATUS
 1275 acpi_EvaluateInteger(ACPI_HANDLE handle, char *path, int *number)
 1276 {
 1277     ACPI_STATUS status;
 1278     ACPI_BUFFER buf;
 1279     ACPI_OBJECT param;
 1280 
 1281     ACPI_ASSERTLOCK;
 1282 
 1283     if (handle == NULL)
 1284         handle = ACPI_ROOT_OBJECT;
 1285 
 1286     /*
 1287      * Assume that what we've been pointed at is an Integer object, or
 1288      * a method that will return an Integer.
 1289      */
 1290     buf.Pointer = &param;
 1291     buf.Length = sizeof(param);
 1292     status = AcpiEvaluateObject(handle, path, NULL, &buf);
 1293     if (ACPI_SUCCESS(status)) {
 1294         if (param.Type == ACPI_TYPE_INTEGER)
 1295             *number = param.Integer.Value;
 1296         else
 1297             status = AE_TYPE;
 1298     }
 1299 
 1300     /* 
 1301      * In some applications, a method that's expected to return an Integer
 1302      * may instead return a Buffer (probably to simplify some internal
 1303      * arithmetic).  We'll try to fetch whatever it is, and if it's a Buffer,
 1304      * convert it into an Integer as best we can.
 1305      *
 1306      * This is a hack.
 1307      */
 1308     if (status == AE_BUFFER_OVERFLOW) {
 1309         if ((buf.Pointer = AcpiOsAllocate(buf.Length)) == NULL) {
 1310             status = AE_NO_MEMORY;
 1311         } else {
 1312             status = AcpiEvaluateObject(handle, path, NULL, &buf);
 1313             if (ACPI_SUCCESS(status))
 1314                 status = acpi_ConvertBufferToInteger(&buf, number);
 1315             AcpiOsFree(buf.Pointer);
 1316         }
 1317     }
 1318     return (status);
 1319 }
 1320 
 1321 ACPI_STATUS
 1322 acpi_ConvertBufferToInteger(ACPI_BUFFER *bufp, int *number)
 1323 {
 1324     ACPI_OBJECT *p;
 1325     int         i;
 1326 
 1327     p = (ACPI_OBJECT *)bufp->Pointer;
 1328     if (p->Type == ACPI_TYPE_INTEGER) {
 1329         *number = p->Integer.Value;
 1330         return (AE_OK);
 1331     }
 1332     if (p->Type != ACPI_TYPE_BUFFER)
 1333         return (AE_TYPE);
 1334     if (p->Buffer.Length > sizeof(int))
 1335         return (AE_BAD_DATA);
 1336 
 1337     *number = 0;
 1338     for (i = 0; i < p->Buffer.Length; i++)
 1339         *number += (*(p->Buffer.Pointer + i) << (i * 8));
 1340     return (AE_OK);
 1341 }
 1342 
 1343 /*
 1344  * Iterate over the elements of an a package object, calling the supplied
 1345  * function for each element.
 1346  *
 1347  * XXX possible enhancement might be to abort traversal on error.
 1348  */
 1349 ACPI_STATUS
 1350 acpi_ForeachPackageObject(ACPI_OBJECT *pkg,
 1351         void (*func)(ACPI_OBJECT *comp, void *arg), void *arg)
 1352 {
 1353     ACPI_OBJECT *comp;
 1354     int         i;
 1355     
 1356     if (pkg == NULL || pkg->Type != ACPI_TYPE_PACKAGE)
 1357         return (AE_BAD_PARAMETER);
 1358 
 1359     /* Iterate over components */
 1360     i = 0;
 1361     comp = pkg->Package.Elements;
 1362     for (; i < pkg->Package.Count; i++, comp++)
 1363         func(comp, arg);
 1364 
 1365     return (AE_OK);
 1366 }
 1367 
 1368 /*
 1369  * Find the (index)th resource object in a set.
 1370  */
 1371 ACPI_STATUS
 1372 acpi_FindIndexedResource(ACPI_BUFFER *buf, int index, ACPI_RESOURCE **resp)
 1373 {
 1374     ACPI_RESOURCE       *rp;
 1375     int                 i;
 1376 
 1377     rp = (ACPI_RESOURCE *)buf->Pointer;
 1378     i = index;
 1379     while (i-- > 0) {
 1380         /* Range check */       
 1381         if (rp > (ACPI_RESOURCE *)((u_int8_t *)buf->Pointer + buf->Length))
 1382             return (AE_BAD_PARAMETER);
 1383 
 1384         /* Check for terminator */
 1385         if (rp->Id == ACPI_RSTYPE_END_TAG || rp->Length == 0)
 1386             return (AE_NOT_FOUND);
 1387         rp = ACPI_RESOURCE_NEXT(rp);
 1388     }
 1389     if (resp != NULL)
 1390         *resp = rp;
 1391 
 1392     return (AE_OK);
 1393 }
 1394 
 1395 /*
 1396  * Append an ACPI_RESOURCE to an ACPI_BUFFER.
 1397  *
 1398  * Given a pointer to an ACPI_RESOURCE structure, expand the ACPI_BUFFER
 1399  * provided to contain it.  If the ACPI_BUFFER is empty, allocate a sensible
 1400  * backing block.  If the ACPI_RESOURCE is NULL, return an empty set of
 1401  * resources.
 1402  */
 1403 #define ACPI_INITIAL_RESOURCE_BUFFER_SIZE       512
 1404 
 1405 ACPI_STATUS
 1406 acpi_AppendBufferResource(ACPI_BUFFER *buf, ACPI_RESOURCE *res)
 1407 {
 1408     ACPI_RESOURCE       *rp;
 1409     void                *newp;
 1410     
 1411     /* Initialise the buffer if necessary. */
 1412     if (buf->Pointer == NULL) {
 1413         buf->Length = ACPI_INITIAL_RESOURCE_BUFFER_SIZE;
 1414         if ((buf->Pointer = AcpiOsAllocate(buf->Length)) == NULL)
 1415             return (AE_NO_MEMORY);
 1416         rp = (ACPI_RESOURCE *)buf->Pointer;
 1417         rp->Id = ACPI_RSTYPE_END_TAG;
 1418         rp->Length = 0;
 1419     }
 1420     if (res == NULL)
 1421         return (AE_OK);
 1422     
 1423     /*
 1424      * Scan the current buffer looking for the terminator.
 1425      * This will either find the terminator or hit the end
 1426      * of the buffer and return an error.
 1427      */
 1428     rp = (ACPI_RESOURCE *)buf->Pointer;
 1429     for (;;) {
 1430         /* Range check, don't go outside the buffer */
 1431         if (rp >= (ACPI_RESOURCE *)((u_int8_t *)buf->Pointer + buf->Length))
 1432             return (AE_BAD_PARAMETER);
 1433         if (rp->Id == ACPI_RSTYPE_END_TAG || rp->Length == 0)
 1434             break;
 1435         rp = ACPI_RESOURCE_NEXT(rp);
 1436     }
 1437 
 1438     /*
 1439      * Check the size of the buffer and expand if required.
 1440      *
 1441      * Required size is:
 1442      *  size of existing resources before terminator + 
 1443      *  size of new resource and header +
 1444      *  size of terminator.
 1445      *
 1446      * Note that this loop should really only run once, unless
 1447      * for some reason we are stuffing a *really* huge resource.
 1448      */
 1449     while ((((u_int8_t *)rp - (u_int8_t *)buf->Pointer) + 
 1450             res->Length + ACPI_RESOURCE_LENGTH_NO_DATA +
 1451             ACPI_RESOURCE_LENGTH) >= buf->Length) {
 1452         if ((newp = AcpiOsAllocate(buf->Length * 2)) == NULL)
 1453             return (AE_NO_MEMORY);
 1454         bcopy(buf->Pointer, newp, buf->Length);
 1455         rp = (ACPI_RESOURCE *)((u_int8_t *)newp +
 1456                                ((u_int8_t *)rp - (u_int8_t *)buf->Pointer));
 1457         AcpiOsFree(buf->Pointer);
 1458         buf->Pointer = newp;
 1459         buf->Length += buf->Length;
 1460     }
 1461     
 1462     /* Insert the new resource. */
 1463     bcopy(res, rp, res->Length + ACPI_RESOURCE_LENGTH_NO_DATA);
 1464     
 1465     /* And add the terminator. */
 1466     rp = ACPI_RESOURCE_NEXT(rp);
 1467     rp->Id = ACPI_RSTYPE_END_TAG;
 1468     rp->Length = 0;
 1469 
 1470     return (AE_OK);
 1471 }
 1472 
 1473 /*
 1474  * Set interrupt model.
 1475  */
 1476 ACPI_STATUS
 1477 acpi_SetIntrModel(int model)
 1478 {
 1479     ACPI_OBJECT_LIST ArgList;
 1480     ACPI_OBJECT Arg;
 1481 
 1482     Arg.Type = ACPI_TYPE_INTEGER;
 1483     Arg.Integer.Value = model;
 1484     ArgList.Count = 1;
 1485     ArgList.Pointer = &Arg;
 1486     return (AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &ArgList, NULL));
 1487 }
 1488 
 1489 #define ACPI_MINIMUM_AWAKETIME  5
 1490 
 1491 static void
 1492 acpi_sleep_enable(void *arg)
 1493 {
 1494     ((struct acpi_softc *)arg)->acpi_sleep_disabled = 0;
 1495 }
 1496 
 1497 /*
 1498  * Set the system sleep state
 1499  *
 1500  * Currently we support S1-S5 but S4 is only S4BIOS
 1501  */
 1502 ACPI_STATUS
 1503 acpi_SetSleepState(struct acpi_softc *sc, int state)
 1504 {
 1505     ACPI_STATUS status = AE_OK;
 1506     UINT8       TypeA;
 1507     UINT8       TypeB;
 1508 
 1509     ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
 1510     ACPI_ASSERTLOCK;
 1511 
 1512     /* Avoid reentry if already attempting to suspend. */
 1513     if (sc->acpi_sstate != ACPI_STATE_S0)
 1514         return_ACPI_STATUS (AE_BAD_PARAMETER);
 1515 
 1516     /* We recently woke up so don't suspend again for a while. */
 1517     if (sc->acpi_sleep_disabled)
 1518         return_ACPI_STATUS (AE_OK);
 1519 
 1520     switch (state) {
 1521     case ACPI_STATE_S1:
 1522     case ACPI_STATE_S2:
 1523     case ACPI_STATE_S3:
 1524     case ACPI_STATE_S4:
 1525         status = AcpiGetSleepTypeData((UINT8)state, &TypeA, &TypeB);
 1526         if (status == AE_NOT_FOUND) {
 1527             device_printf(sc->acpi_dev,
 1528                           "Sleep state S%d not supported by BIOS\n", state);
 1529             break;
 1530         } else if (ACPI_FAILURE(status)) {
 1531             device_printf(sc->acpi_dev, "AcpiGetSleepTypeData failed - %s\n",
 1532                           AcpiFormatException(status));
 1533             break;
 1534         }
 1535 
 1536         sc->acpi_sstate = state;
 1537         sc->acpi_sleep_disabled = 1;
 1538 
 1539         /* Inform all devices that we are going to sleep. */
 1540         if (DEVICE_SUSPEND(root_bus) != 0) {
 1541             /*
 1542              * Re-wake the system.
 1543              *
 1544              * XXX note that a better two-pass approach with a 'veto' pass
 1545              *     followed by a "real thing" pass would be better, but the
 1546              *     current bus interface does not provide for this.
 1547              */
 1548             DEVICE_RESUME(root_bus);
 1549             return_ACPI_STATUS (AE_ERROR);
 1550         }
 1551 
 1552         status = AcpiEnterSleepStatePrep(state);
 1553         if (ACPI_FAILURE(status)) {
 1554             device_printf(sc->acpi_dev, "AcpiEnterSleepStatePrep failed - %s\n",
 1555                           AcpiFormatException(status));
 1556             break;
 1557         }
 1558 
 1559         if (sc->acpi_sleep_delay > 0)
 1560             DELAY(sc->acpi_sleep_delay * 1000000);
 1561 
 1562         if (state != ACPI_STATE_S1) {
 1563             acpi_sleep_machdep(sc, state);
 1564 
 1565             /* AcpiEnterSleepState() may be incomplete, unlock if locked. */
 1566             if (AcpiGbl_MutexInfo[ACPI_MTX_HARDWARE].OwnerId !=
 1567                 ACPI_MUTEX_NOT_ACQUIRED) {
 1568 
 1569                 AcpiUtReleaseMutex(ACPI_MTX_HARDWARE);
 1570             }
 1571 
 1572             /* Re-enable ACPI hardware on wakeup from sleep state 4. */
 1573             if (state == ACPI_STATE_S4)
 1574                 AcpiEnable();
 1575         } else {
 1576             status = AcpiEnterSleepState((UINT8)state);
 1577             if (ACPI_FAILURE(status)) {
 1578                 device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n",
 1579                               AcpiFormatException(status));
 1580                 break;
 1581             }
 1582         }
 1583         AcpiLeaveSleepState((UINT8)state);
 1584         DEVICE_RESUME(root_bus);
 1585         sc->acpi_sstate = ACPI_STATE_S0;
 1586         acpi_enable_fixed_events(sc);
 1587         break;
 1588     case ACPI_STATE_S5:
 1589         /*
 1590          * Shut down cleanly and power off.  This will call us back through the
 1591          * shutdown handlers.
 1592          */
 1593         shutdown_nice(RB_POWEROFF);
 1594         break;
 1595     case ACPI_STATE_S0:
 1596     default:
 1597         status = AE_BAD_PARAMETER;
 1598         break;
 1599     }
 1600 
 1601     /* Disable a second sleep request for a short period */
 1602     if (sc->acpi_sleep_disabled)
 1603         timeout(acpi_sleep_enable, (caddr_t)sc, hz * ACPI_MINIMUM_AWAKETIME);
 1604 
 1605     return_ACPI_STATUS (status);
 1606 }
 1607 
 1608 /*
 1609  * Enable/Disable ACPI
 1610  */
 1611 ACPI_STATUS
 1612 acpi_Enable(struct acpi_softc *sc)
 1613 {
 1614     ACPI_STATUS status;
 1615     u_int32_t   flags;
 1616 
 1617     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 1618     ACPI_ASSERTLOCK;
 1619 
 1620     flags = ACPI_NO_ADDRESS_SPACE_INIT | ACPI_NO_HARDWARE_INIT |
 1621             ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT;
 1622     if (!sc->acpi_enabled)
 1623         status = AcpiEnableSubsystem(flags);
 1624     else
 1625         status = AE_OK;
 1626 
 1627     if (status == AE_OK)
 1628         sc->acpi_enabled = 1;
 1629 
 1630     return_ACPI_STATUS (status);
 1631 }
 1632 
 1633 ACPI_STATUS
 1634 acpi_Disable(struct acpi_softc *sc)
 1635 {
 1636     ACPI_STATUS status;
 1637 
 1638     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 1639     ACPI_ASSERTLOCK;
 1640 
 1641     if (sc->acpi_enabled)
 1642         status = AcpiDisable();
 1643     else
 1644         status = AE_OK;
 1645 
 1646     if (status == AE_OK)
 1647         sc->acpi_enabled = 0;
 1648 
 1649     return_ACPI_STATUS (status);
 1650 }
 1651 
 1652 /*
 1653  * ACPI Event Handlers
 1654  */
 1655 
 1656 /* System Event Handlers (registered by EVENTHANDLER_REGISTER) */
 1657 
 1658 static void
 1659 acpi_system_eventhandler_sleep(void *arg, int state)
 1660 {
 1661     ACPI_LOCK_DECL;
 1662     ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
 1663 
 1664     ACPI_LOCK;
 1665     if (state >= ACPI_STATE_S0 && state <= ACPI_S_STATES_MAX)
 1666         acpi_SetSleepState((struct acpi_softc *)arg, state);
 1667     ACPI_UNLOCK;
 1668     return_VOID;
 1669 }
 1670 
 1671 static void
 1672 acpi_system_eventhandler_wakeup(void *arg, int state)
 1673 {
 1674     ACPI_LOCK_DECL;
 1675     ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
 1676 
 1677     /* Well, what to do? :-) */
 1678 
 1679     ACPI_LOCK;
 1680     ACPI_UNLOCK;
 1681 
 1682     return_VOID;
 1683 }
 1684 
 1685 /* 
 1686  * ACPICA Event Handlers (FixedEvent, also called from button notify handler)
 1687  */
 1688 UINT32
 1689 acpi_eventhandler_power_button_for_sleep(void *context)
 1690 {
 1691     struct acpi_softc   *sc = (struct acpi_softc *)context;
 1692 
 1693     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 1694 
 1695     EVENTHANDLER_INVOKE(acpi_sleep_event, sc->acpi_power_button_sx);
 1696 
 1697     return_VALUE (ACPI_INTERRUPT_HANDLED);
 1698 }
 1699 
 1700 UINT32
 1701 acpi_eventhandler_power_button_for_wakeup(void *context)
 1702 {
 1703     struct acpi_softc   *sc = (struct acpi_softc *)context;
 1704 
 1705     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 1706 
 1707     EVENTHANDLER_INVOKE(acpi_wakeup_event, sc->acpi_power_button_sx);
 1708 
 1709     return_VALUE (ACPI_INTERRUPT_HANDLED);
 1710 }
 1711 
 1712 UINT32
 1713 acpi_eventhandler_sleep_button_for_sleep(void *context)
 1714 {
 1715     struct acpi_softc   *sc = (struct acpi_softc *)context;
 1716 
 1717     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 1718 
 1719     EVENTHANDLER_INVOKE(acpi_sleep_event, sc->acpi_sleep_button_sx);
 1720 
 1721     return_VALUE (ACPI_INTERRUPT_HANDLED);
 1722 }
 1723 
 1724 UINT32
 1725 acpi_eventhandler_sleep_button_for_wakeup(void *context)
 1726 {
 1727     struct acpi_softc   *sc = (struct acpi_softc *)context;
 1728 
 1729     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 1730 
 1731     EVENTHANDLER_INVOKE(acpi_wakeup_event, sc->acpi_sleep_button_sx);
 1732 
 1733     return_VALUE (ACPI_INTERRUPT_HANDLED);
 1734 }
 1735 
 1736 /*
 1737  * XXX This is kinda ugly, and should not be here.
 1738  */
 1739 struct acpi_staticbuf {
 1740     ACPI_BUFFER buffer;
 1741     char        data[512];
 1742 };
 1743 
 1744 char *
 1745 acpi_name(ACPI_HANDLE handle)
 1746 {
 1747     static struct acpi_staticbuf        buf;
 1748 
 1749     ACPI_ASSERTLOCK;
 1750 
 1751     buf.buffer.Length = 512;
 1752     buf.buffer.Pointer = &buf.data[0];
 1753 
 1754     if (ACPI_SUCCESS(AcpiGetName(handle, ACPI_FULL_PATHNAME, &buf.buffer)))
 1755         return (buf.buffer.Pointer);
 1756 
 1757     return ("(unknown path)");
 1758 }
 1759 
 1760 /*
 1761  * Debugging/bug-avoidance.  Avoid trying to fetch info on various
 1762  * parts of the namespace.
 1763  */
 1764 int
 1765 acpi_avoid(ACPI_HANDLE handle)
 1766 {
 1767     char        *cp, *env, *np;
 1768     int         len;
 1769 
 1770     np = acpi_name(handle);
 1771     if (*np == '\\')
 1772         np++;
 1773     if ((env = getenv("debug.acpi.avoid")) == NULL)
 1774         return (0);
 1775 
 1776     /* Scan the avoid list checking for a match */
 1777     cp = env;
 1778     for (;;) {
 1779         while ((*cp != 0) && isspace(*cp))
 1780             cp++;
 1781         if (*cp == 0)
 1782             break;
 1783         len = 0;
 1784         while ((cp[len] != 0) && !isspace(cp[len]))
 1785             len++;
 1786         if (!strncmp(cp, np, len)) {
 1787             freeenv(env);
 1788             return(1);
 1789         }
 1790         cp += len;
 1791     }
 1792     freeenv(env);
 1793 
 1794     return (0);
 1795 }
 1796 
 1797 /*
 1798  * Debugging/bug-avoidance.  Disable ACPI subsystem components.
 1799  */
 1800 int
 1801 acpi_disabled(char *subsys)
 1802 {
 1803     char        *cp, *env;
 1804     int         len;
 1805 
 1806     if ((env = getenv("debug.acpi.disable")) == NULL)
 1807         return (0);
 1808     if (!strcmp(env, "all")) {
 1809         freeenv(env);
 1810         return (1);
 1811     }
 1812 
 1813     /* scan the disable list checking for a match */
 1814     cp = env;
 1815     for (;;) {
 1816         while ((*cp != 0) && isspace(*cp))
 1817             cp++;
 1818         if (*cp == 0)
 1819             break;
 1820         len = 0;
 1821         while ((cp[len] != 0) && !isspace(cp[len]))
 1822             len++;
 1823         if (!strncmp(cp, subsys, len)) {
 1824             freeenv(env);
 1825             return (1);
 1826         }
 1827         cp += len;
 1828     }
 1829     freeenv(env);
 1830 
 1831     return (0);
 1832 }
 1833 
 1834 /*
 1835  * Device wake capability enable/disable.
 1836  */
 1837 void
 1838 acpi_device_enable_wake_capability(ACPI_HANDLE h, int enable)
 1839 {
 1840     ACPI_OBJECT_LIST            ArgList;
 1841     ACPI_OBJECT                 Arg;
 1842 
 1843     /*
 1844      * TBD: All Power Resources referenced by elements 2 through N
 1845      *      of the _PRW object are put into the ON state.
 1846      */
 1847 
 1848     ArgList.Count = 1;
 1849     ArgList.Pointer = &Arg;
 1850 
 1851     Arg.Type = ACPI_TYPE_INTEGER;
 1852     Arg.Integer.Value = enable;
 1853 
 1854     (void)AcpiEvaluateObject(h, "_PSW", &ArgList, NULL);
 1855 }
 1856 
 1857 void
 1858 acpi_device_enable_wake_event(ACPI_HANDLE h)
 1859 {
 1860     struct acpi_softc           *sc;
 1861     ACPI_STATUS                 status;
 1862     ACPI_BUFFER                 prw_buffer;
 1863     ACPI_OBJECT                 *res;
 1864 
 1865     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 1866 
 1867     sc = devclass_get_softc(acpi_devclass, 0);
 1868     if (sc == NULL)
 1869         return;
 1870 
 1871     /*
 1872      * _PRW object is only required for devices that have the ability
 1873      * to wake the system from a system sleeping state.
 1874      */
 1875     prw_buffer.Length = ACPI_ALLOCATE_BUFFER;
 1876     status = AcpiEvaluateObject(h, "_PRW", NULL, &prw_buffer);
 1877     if (ACPI_FAILURE(status))
 1878         return;
 1879 
 1880     res = (ACPI_OBJECT *)prw_buffer.Pointer;
 1881     if (res == NULL)
 1882         return;
 1883 
 1884     if ((res->Type != ACPI_TYPE_PACKAGE) || (res->Package.Count < 2)) {
 1885         goto out;
 1886     }
 1887 
 1888     /*
 1889      * The element 1 of the _PRW object:
 1890      * The lowest power system sleeping state that can be entered
 1891      * while still providing wake functionality.
 1892      * The sleeping state being entered must be greater or equal to
 1893      * the power state declared in element 1 of the _PRW object.
 1894      */
 1895     if (res->Package.Elements[1].Type != ACPI_TYPE_INTEGER)
 1896         goto out;
 1897 
 1898     if (sc->acpi_sstate > res->Package.Elements[1].Integer.Value)
 1899         goto out;
 1900 
 1901     /*
 1902      * The element 0 of the _PRW object:
 1903      */
 1904     switch(res->Package.Elements[0].Type) {
 1905     case ACPI_TYPE_INTEGER:
 1906         /* 
 1907          * If the data type of this package element is numeric, then this
 1908          * _PRW package element is the bit index in the GPEx_EN, in the
 1909          * GPE blocks described in the FADT, of the enable bit that is
 1910          * enabled for the wake event.
 1911          */
 1912 
 1913         status = AcpiEnableGpe(NULL, res->Package.Elements[0].Integer.Value,
 1914                                ACPI_EVENT_WAKE_ENABLE);
 1915         if (ACPI_FAILURE(status))
 1916             printf("%s: EnableEvent Failed\n", __func__);
 1917         break;
 1918     case ACPI_TYPE_PACKAGE:
 1919         /*
 1920          * XXX TBD
 1921          *
 1922          * If the data type of this package element is a package, then this
 1923          * _PRW package element is itself a package containing two
 1924          * elements. The first is an object reference to the GPE Block
 1925          * device that contains the GPE that will be triggered by the wake
 1926          * event. The second element is numeric and it contains the bit
 1927          * index in the GPEx_EN, in the GPE Block referenced by the
 1928          * first element in the package, of the enable bit that is enabled for
 1929          * the wake event.
 1930          * For example, if this field is a package then it is of the form:
 1931          * Package() {\_SB.PCI0.ISA.GPE, 2}
 1932          */
 1933         break;
 1934     default:
 1935         break;
 1936     }
 1937 
 1938 out:
 1939     if (prw_buffer.Pointer != NULL)
 1940         AcpiOsFree(prw_buffer.Pointer);
 1941 }
 1942 
 1943 /*
 1944  * Control interface.
 1945  *
 1946  * We multiplex ioctls for all participating ACPI devices here.  Individual 
 1947  * drivers wanting to be accessible via /dev/acpi should use the
 1948  * register/deregister interface to make their handlers visible.
 1949  */
 1950 struct acpi_ioctl_hook
 1951 {
 1952     TAILQ_ENTRY(acpi_ioctl_hook) link;
 1953     u_long                       cmd;
 1954     acpi_ioctl_fn                fn;
 1955     void                         *arg;
 1956 };
 1957 
 1958 static TAILQ_HEAD(,acpi_ioctl_hook)     acpi_ioctl_hooks;
 1959 static int                              acpi_ioctl_hooks_initted;
 1960 
 1961 /*
 1962  * Register an ioctl handler.
 1963  */
 1964 int
 1965 acpi_register_ioctl(u_long cmd, acpi_ioctl_fn fn, void *arg)
 1966 {
 1967     struct acpi_ioctl_hook      *hp;
 1968 
 1969     if ((hp = malloc(sizeof(*hp), M_ACPIDEV, M_NOWAIT)) == NULL)
 1970         return (ENOMEM);
 1971     hp->cmd = cmd;
 1972     hp->fn = fn;
 1973     hp->arg = arg;
 1974     if (acpi_ioctl_hooks_initted == 0) {
 1975         TAILQ_INIT(&acpi_ioctl_hooks);
 1976         acpi_ioctl_hooks_initted = 1;
 1977     }
 1978     TAILQ_INSERT_TAIL(&acpi_ioctl_hooks, hp, link);
 1979     return (0);
 1980 }
 1981 
 1982 /*
 1983  * Deregister an ioctl handler.
 1984  */
 1985 void    
 1986 acpi_deregister_ioctl(u_long cmd, acpi_ioctl_fn fn)
 1987 {
 1988     struct acpi_ioctl_hook      *hp;
 1989 
 1990     TAILQ_FOREACH(hp, &acpi_ioctl_hooks, link)
 1991         if ((hp->cmd == cmd) && (hp->fn == fn))
 1992             break;
 1993 
 1994     if (hp != NULL) {
 1995         TAILQ_REMOVE(&acpi_ioctl_hooks, hp, link);
 1996         free(hp, M_ACPIDEV);
 1997     }
 1998 }
 1999 
 2000 static int
 2001 acpiopen(dev_t dev, int flag, int fmt, d_thread_t *td)
 2002 {
 2003     return (0);
 2004 }
 2005 
 2006 static int
 2007 acpiclose(dev_t dev, int flag, int fmt, d_thread_t *td)
 2008 {
 2009     return (0);
 2010 }
 2011 
 2012 static int
 2013 acpiioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, d_thread_t *td)
 2014 {
 2015     struct acpi_softc           *sc;
 2016     struct acpi_ioctl_hook      *hp;
 2017     int                         error, xerror, state;
 2018     ACPI_LOCK_DECL;
 2019 
 2020     ACPI_LOCK;
 2021 
 2022     error = state = 0;
 2023     sc = dev->si_drv1;
 2024 
 2025     /*
 2026      * Scan the list of registered ioctls, looking for handlers.
 2027      */
 2028     if (acpi_ioctl_hooks_initted) {
 2029         TAILQ_FOREACH(hp, &acpi_ioctl_hooks, link) {
 2030             if (hp->cmd == cmd) {
 2031                 xerror = hp->fn(cmd, addr, hp->arg);
 2032                 if (xerror != 0)
 2033                     error = xerror;
 2034                 goto out;
 2035             }
 2036         }
 2037     }
 2038 
 2039     /*
 2040      * Core ioctls are not permitted for non-writable user.
 2041      * Currently, other ioctls just fetch information.
 2042      * Not changing system behavior.
 2043      */
 2044     if((flag & FWRITE) == 0)
 2045         return (EPERM);
 2046 
 2047     /* Core system ioctls. */
 2048     switch (cmd) {
 2049     case ACPIIO_ENABLE:
 2050         if (ACPI_FAILURE(acpi_Enable(sc)))
 2051             error = ENXIO;
 2052         break;
 2053     case ACPIIO_DISABLE:
 2054         if (ACPI_FAILURE(acpi_Disable(sc)))
 2055             error = ENXIO;
 2056         break;
 2057     case ACPIIO_SETSLPSTATE:
 2058         if (!sc->acpi_enabled) {
 2059             error = ENXIO;
 2060             break;
 2061         }
 2062         state = *(int *)addr;
 2063         if (state >= ACPI_STATE_S0  && state <= ACPI_S_STATES_MAX) {
 2064             if (ACPI_FAILURE(acpi_SetSleepState(sc, state)))
 2065                 error = EINVAL;
 2066         } else {
 2067             error = EINVAL;
 2068         }
 2069         break;
 2070     default:
 2071         if (error == 0)
 2072             error = EINVAL;
 2073         break;
 2074     }
 2075 
 2076 out:
 2077     ACPI_UNLOCK;
 2078     return (error);
 2079 }
 2080 
 2081 static int
 2082 acpi_supported_sleep_state_sysctl(SYSCTL_HANDLER_ARGS)
 2083 {
 2084     char sleep_state[4];
 2085     char buf[16];
 2086     int error;
 2087     UINT8 state, TypeA, TypeB;
 2088 
 2089     buf[0] = '\0';
 2090     for (state = ACPI_STATE_S1; state < ACPI_S_STATES_MAX+1; state++) {
 2091         if (ACPI_SUCCESS(AcpiGetSleepTypeData(state, &TypeA, &TypeB))) {
 2092             sprintf(sleep_state, "S%d ", state);
 2093             strcat(buf, sleep_state);
 2094         }
 2095     }
 2096     error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
 2097     return (error);
 2098 }
 2099 
 2100 static int
 2101 acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS)
 2102 {
 2103     char sleep_state[10];
 2104     int error;
 2105     u_int new_state, old_state;
 2106 
 2107     old_state = *(u_int *)oidp->oid_arg1;
 2108     if (old_state > ACPI_S_STATES_MAX+1) {
 2109         strcpy(sleep_state, "unknown");
 2110     } else {
 2111         bzero(sleep_state, sizeof(sleep_state));
 2112         strncpy(sleep_state, sleep_state_names[old_state],
 2113                 sizeof(sleep_state_names[old_state]));
 2114     }
 2115     error = sysctl_handle_string(oidp, sleep_state, sizeof(sleep_state), req);
 2116     if (error == 0 && req->newptr != NULL) {
 2117         new_state = ACPI_STATE_S0;
 2118         for (; new_state <= ACPI_S_STATES_MAX + 1; new_state++) {
 2119             if (strncmp(sleep_state, sleep_state_names[new_state],
 2120                         sizeof(sleep_state)) == 0)
 2121                 break;
 2122         }
 2123         if (new_state <= ACPI_S_STATES_MAX + 1) {
 2124             if (new_state != old_state)
 2125                 *(u_int *)oidp->oid_arg1 = new_state;
 2126         } else {
 2127             error = EINVAL;
 2128         }
 2129     }
 2130 
 2131     return (error);
 2132 }
 2133 
 2134 /* Inform devctl(4) when we receive a Notify. */
 2135 void
 2136 acpi_UserNotify(const char *subsystem, ACPI_HANDLE h, uint8_t notify)
 2137 {
 2138     char                notify_buf[16];
 2139     ACPI_BUFFER         handle_buf;
 2140     ACPI_STATUS         status;
 2141 
 2142     if (subsystem == NULL)
 2143         return;
 2144 
 2145     handle_buf.Pointer = NULL;
 2146     handle_buf.Length = ACPI_ALLOCATE_BUFFER;
 2147     status = AcpiNsHandleToPathname(h, &handle_buf);
 2148     if (ACPI_FAILURE(status))
 2149         return;
 2150     snprintf(notify_buf, sizeof(notify_buf), "notify=0x%02x", notify);
 2151     devctl_notify("ACPI", subsystem, handle_buf.Pointer, notify_buf);
 2152     AcpiOsFree(handle_buf.Pointer);
 2153 }
 2154 
 2155 #ifdef ACPI_DEBUG
 2156 /*
 2157  * Support for parsing debug options from the kernel environment.
 2158  *
 2159  * Bits may be set in the AcpiDbgLayer and AcpiDbgLevel debug registers
 2160  * by specifying the names of the bits in the debug.acpi.layer and
 2161  * debug.acpi.level environment variables.  Bits may be unset by 
 2162  * prefixing the bit name with !.
 2163  */
 2164 struct debugtag
 2165 {
 2166     char        *name;
 2167     UINT32      value;
 2168 };
 2169 
 2170 static struct debugtag  dbg_layer[] = {
 2171     {"ACPI_UTILITIES",          ACPI_UTILITIES},
 2172     {"ACPI_HARDWARE",           ACPI_HARDWARE},
 2173     {"ACPI_EVENTS",             ACPI_EVENTS},
 2174     {"ACPI_TABLES",             ACPI_TABLES},
 2175     {"ACPI_NAMESPACE",          ACPI_NAMESPACE},
 2176     {"ACPI_PARSER",             ACPI_PARSER},
 2177     {"ACPI_DISPATCHER",         ACPI_DISPATCHER},
 2178     {"ACPI_EXECUTER",           ACPI_EXECUTER},
 2179     {"ACPI_RESOURCES",          ACPI_RESOURCES},
 2180     {"ACPI_CA_DEBUGGER",        ACPI_CA_DEBUGGER},
 2181     {"ACPI_OS_SERVICES",        ACPI_OS_SERVICES},
 2182     {"ACPI_CA_DISASSEMBLER",    ACPI_CA_DISASSEMBLER},
 2183     {"ACPI_ALL_COMPONENTS",     ACPI_ALL_COMPONENTS},
 2184 
 2185     {"ACPI_BUS",                ACPI_BUS},
 2186     {"ACPI_SYSTEM",             ACPI_SYSTEM},
 2187     {"ACPI_POWER",              ACPI_POWER},
 2188     {"ACPI_EC",                 ACPI_EC},
 2189     {"ACPI_AC_ADAPTER",         ACPI_AC_ADAPTER},
 2190     {"ACPI_BATTERY",            ACPI_BATTERY},
 2191     {"ACPI_BUTTON",             ACPI_BUTTON},
 2192     {"ACPI_PROCESSOR",          ACPI_PROCESSOR},
 2193     {"ACPI_THERMAL",            ACPI_THERMAL},
 2194     {"ACPI_FAN",                ACPI_FAN},
 2195     {"ACPI_ALL_DRIVERS",        ACPI_ALL_DRIVERS},
 2196     {NULL, 0}
 2197 };
 2198 
 2199 static struct debugtag dbg_level[] = {
 2200     {"ACPI_LV_ERROR",           ACPI_LV_ERROR},
 2201     {"ACPI_LV_WARN",            ACPI_LV_WARN},
 2202     {"ACPI_LV_INIT",            ACPI_LV_INIT},
 2203     {"ACPI_LV_DEBUG_OBJECT",    ACPI_LV_DEBUG_OBJECT},
 2204     {"ACPI_LV_INFO",            ACPI_LV_INFO},
 2205     {"ACPI_LV_ALL_EXCEPTIONS",  ACPI_LV_ALL_EXCEPTIONS},
 2206 
 2207     /* Trace verbosity level 1 [Standard Trace Level] */
 2208     {"ACPI_LV_INIT_NAMES",      ACPI_LV_INIT_NAMES},
 2209     {"ACPI_LV_PARSE",           ACPI_LV_PARSE},
 2210     {"ACPI_LV_LOAD",            ACPI_LV_LOAD},
 2211     {"ACPI_LV_DISPATCH",        ACPI_LV_DISPATCH},
 2212     {"ACPI_LV_EXEC",            ACPI_LV_EXEC},
 2213     {"ACPI_LV_NAMES",           ACPI_LV_NAMES},
 2214     {"ACPI_LV_OPREGION",        ACPI_LV_OPREGION},
 2215     {"ACPI_LV_BFIELD",          ACPI_LV_BFIELD},
 2216     {"ACPI_LV_TABLES",          ACPI_LV_TABLES},
 2217     {"ACPI_LV_VALUES",          ACPI_LV_VALUES},
 2218     {"ACPI_LV_OBJECTS",         ACPI_LV_OBJECTS},
 2219     {"ACPI_LV_RESOURCES",       ACPI_LV_RESOURCES},
 2220     {"ACPI_LV_USER_REQUESTS",   ACPI_LV_USER_REQUESTS},
 2221     {"ACPI_LV_PACKAGE",         ACPI_LV_PACKAGE},
 2222     {"ACPI_LV_VERBOSITY1",      ACPI_LV_VERBOSITY1},
 2223 
 2224     /* Trace verbosity level 2 [Function tracing and memory allocation] */
 2225     {"ACPI_LV_ALLOCATIONS",     ACPI_LV_ALLOCATIONS},
 2226     {"ACPI_LV_FUNCTIONS",       ACPI_LV_FUNCTIONS},
 2227     {"ACPI_LV_OPTIMIZATIONS",   ACPI_LV_OPTIMIZATIONS},
 2228     {"ACPI_LV_VERBOSITY2",      ACPI_LV_VERBOSITY2},
 2229     {"ACPI_LV_ALL",             ACPI_LV_ALL},
 2230 
 2231     /* Trace verbosity level 3 [Threading, I/O, and Interrupts] */
 2232     {"ACPI_LV_MUTEX",           ACPI_LV_MUTEX},
 2233     {"ACPI_LV_THREADS",         ACPI_LV_THREADS},
 2234     {"ACPI_LV_IO",              ACPI_LV_IO},
 2235     {"ACPI_LV_INTERRUPTS",      ACPI_LV_INTERRUPTS},
 2236     {"ACPI_LV_VERBOSITY3",      ACPI_LV_VERBOSITY3},
 2237 
 2238     /* Exceptionally verbose output -- also used in the global "DebugLevel"  */
 2239     {"ACPI_LV_AML_DISASSEMBLE", ACPI_LV_AML_DISASSEMBLE},
 2240     {"ACPI_LV_VERBOSE_INFO",    ACPI_LV_VERBOSE_INFO},
 2241     {"ACPI_LV_FULL_TABLES",     ACPI_LV_FULL_TABLES},
 2242     {"ACPI_LV_EVENTS",          ACPI_LV_EVENTS},
 2243     {"ACPI_LV_VERBOSE",         ACPI_LV_VERBOSE},
 2244     {NULL, 0}
 2245 };    
 2246 
 2247 static void
 2248 acpi_parse_debug(char *cp, struct debugtag *tag, UINT32 *flag)
 2249 {
 2250     char        *ep;
 2251     int         i, l;
 2252     int         set;
 2253 
 2254     while (*cp) {
 2255         if (isspace(*cp)) {
 2256             cp++;
 2257             continue;
 2258         }
 2259         ep = cp;
 2260         while (*ep && !isspace(*ep))
 2261             ep++;
 2262         if (*cp == '!') {
 2263             set = 0;
 2264             cp++;
 2265             if (cp == ep)
 2266                 continue;
 2267         } else {
 2268             set = 1;
 2269         }
 2270         l = ep - cp;
 2271         for (i = 0; tag[i].name != NULL; i++) {
 2272             if (!strncmp(cp, tag[i].name, l)) {
 2273                 if (set)
 2274                     *flag |= tag[i].value;
 2275                 else
 2276                     *flag &= ~tag[i].value;
 2277                 printf("ACPI_DEBUG: set '%s'\n", tag[i].name);
 2278             }
 2279         }
 2280         cp = ep;
 2281     }
 2282 }
 2283 
 2284 static void
 2285 acpi_set_debugging(void *junk)
 2286 {
 2287     char        *cp;
 2288 
 2289     if (cold) {
 2290         AcpiDbgLayer = 0;
 2291         AcpiDbgLevel = 0;
 2292     }
 2293 
 2294     if ((cp = getenv("debug.acpi.layer")) != NULL) {
 2295         acpi_parse_debug(cp, &dbg_layer[0], &AcpiDbgLayer);
 2296         freeenv(cp);
 2297     }
 2298     if ((cp = getenv("debug.acpi.level")) != NULL) {
 2299         acpi_parse_debug(cp, &dbg_level[0], &AcpiDbgLevel);
 2300         freeenv(cp);
 2301     }
 2302 
 2303     if (cold) {
 2304         printf("ACPI debug layer 0x%x debug level 0x%x\n",
 2305                AcpiDbgLayer, AcpiDbgLevel);
 2306     }
 2307 }
 2308 SYSINIT(acpi_debugging, SI_SUB_TUNABLES, SI_ORDER_ANY, acpi_set_debugging,
 2309         NULL);
 2310 
 2311 static int
 2312 acpi_debug_sysctl(SYSCTL_HANDLER_ARGS)
 2313 {
 2314     char        *options;
 2315     int          error, len, *dbg;
 2316     struct       debugtag *tag;
 2317 
 2318     len = 512;
 2319     MALLOC(options, char *, len, M_TEMP, M_WAITOK);
 2320     options[0] = '\0';
 2321 
 2322     if (strcmp(oidp->oid_arg1, "debug.acpi.layer") == 0) {
 2323         tag = &dbg_layer[0];
 2324         dbg = &AcpiDbgLayer;
 2325     } else {
 2326         tag = &dbg_level[0];
 2327         dbg = &AcpiDbgLevel;
 2328     }
 2329 
 2330     /* Get old values if this is a get request. */
 2331     if (*dbg == 0) {
 2332         strlcpy(options, "NONE", sizeof(options));
 2333     } else if (req->newptr == NULL) {
 2334         for (; tag->name != NULL; tag++) {
 2335             if ((*dbg & tag->value) == tag->value) {
 2336                 strlcat(options, tag->name, len);
 2337                 strlcat(options, " ", len); /* XXX */
 2338             }
 2339         }
 2340     }
 2341 
 2342     error = sysctl_handle_string(oidp, options, len, req);
 2343 
 2344     /* If the user is setting a string, parse it. */
 2345     if (error == 0 && req->newptr != NULL) {
 2346         *dbg = 0;
 2347         setenv((char *)oidp->oid_arg1, (char *)req->newptr);
 2348         acpi_set_debugging(NULL);
 2349     }
 2350     FREE(options, M_TEMP);
 2351 
 2352     return (error);
 2353 }
 2354 SYSCTL_PROC(_debug_acpi, OID_AUTO, layer, CTLFLAG_RW | CTLTYPE_STRING,
 2355             "debug.acpi.layer", 0, acpi_debug_sysctl, "A", "");
 2356 SYSCTL_PROC(_debug_acpi, OID_AUTO, level, CTLFLAG_RW | CTLTYPE_STRING,
 2357             "debug.acpi.level", 0, acpi_debug_sysctl, "A", "");
 2358 #endif
 2359 
 2360 static int
 2361 acpi_pm_func(u_long cmd, void *arg, ...)
 2362 {
 2363         int     state, acpi_state;
 2364         int     error;
 2365         struct  acpi_softc *sc;
 2366         va_list ap;
 2367 
 2368         error = 0;
 2369         switch (cmd) {
 2370         case POWER_CMD_SUSPEND:
 2371                 sc = (struct acpi_softc *)arg;
 2372                 if (sc == NULL) {
 2373                         error = EINVAL;
 2374                         goto out;
 2375                 }
 2376 
 2377                 va_start(ap, arg);
 2378                 state = va_arg(ap, int);
 2379                 va_end(ap);     
 2380 
 2381                 switch (state) {
 2382                 case POWER_SLEEP_STATE_STANDBY:
 2383                         acpi_state = sc->acpi_standby_sx;
 2384                         break;
 2385                 case POWER_SLEEP_STATE_SUSPEND:
 2386                         acpi_state = sc->acpi_suspend_sx;
 2387                         break;
 2388                 case POWER_SLEEP_STATE_HIBERNATE:
 2389                         acpi_state = ACPI_STATE_S4;
 2390                         break;
 2391                 default:
 2392                         error = EINVAL;
 2393                         goto out;
 2394                 }
 2395 
 2396                 acpi_SetSleepState(sc, acpi_state);
 2397                 break;
 2398         default:
 2399                 error = EINVAL;
 2400                 goto out;
 2401         }
 2402 
 2403 out:
 2404         return (error);
 2405 }
 2406 
 2407 static void
 2408 acpi_pm_register(void *arg)
 2409 {
 2410     if (!cold || resource_disabled("acpi", 0))
 2411         return;
 2412 
 2413     power_pm_register(POWER_PM_TYPE_ACPI, acpi_pm_func, NULL);
 2414 }
 2415 
 2416 SYSINIT(power, SI_SUB_KLD, SI_ORDER_ANY, acpi_pm_register, 0);

Cache object: 20a9e6786591780b562a8fc17e1f967d


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