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