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