File:  [DragonFly] / src / sys / dev / acpica5 / acpi.c
Revision 1.1: download - view: text, annotated - select for diffs
Sat Feb 21 06:48:08 2004 UTC (10 years, 7 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
Bring in the FreeBSD-5 ACPICA code as a module.  Note: not hooked up yet,
still under development.  Also note that the original ACPICA code is being
left intact.

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