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 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/malloc.h> 36 #include <sys/mutex.h> 37 #include <sys/bus.h> 38 #include <sys/conf.h> 39 #include <sys/ioccom.h> 40 #include <sys/reboot.h> 41 #include <sys/sysctl.h> 42 #include <sys/ctype.h> 43 44 #include <machine/clock.h> 45 46 #include <machine/resource.h> 47 48 #include "acpi.h" 49 50 #include <dev/acpica/acpivar.h> 51 #include <dev/acpica/acpiio.h> 52 53 MALLOC_DEFINE(M_ACPIDEV, "acpidev", "ACPI devices"); 54 55 /* 56 * Hooks for the ACPI CA debugging infrastructure 57 */ 58 #define _COMPONENT BUS_MANAGER 59 MODULE_NAME("ACPI") 60 61 /* 62 * Character device 63 */ 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 acpiopen, 72 acpiclose, 73 noread, 74 nowrite, 75 acpiioctl, 76 nopoll, 77 nommap, 78 nostrategy, 79 "acpi", 80 CDEV_MAJOR, 81 nodump, 82 nopsize, 83 0, 84 -1 85 }; 86 87 static void acpi_identify(driver_t *driver, device_t parent); 88 static int acpi_probe(device_t dev); 89 static int acpi_attach(device_t dev); 90 static device_t acpi_add_child(device_t bus, int order, const char *name, int unit); 91 static int acpi_print_resources(struct resource_list *rl, const char *name, int type, 92 const char *format); 93 static int acpi_print_child(device_t bus, device_t child); 94 static int acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result); 95 static int acpi_write_ivar(device_t dev, device_t child, int index, uintptr_t value); 96 static int acpi_set_resource(device_t dev, device_t child, int type, int rid, u_long start, 97 u_long count); 98 static int acpi_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, 99 u_long *countp); 100 static struct resource *acpi_alloc_resource(device_t bus, device_t child, int type, int *rid, 101 u_long start, u_long end, u_long count, u_int flags); 102 static int acpi_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r); 103 104 static void acpi_probe_children(device_t bus); 105 static ACPI_STATUS acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status); 106 107 static void acpi_shutdown_pre_sync(void *arg, int howto); 108 static void acpi_shutdown_final(void *arg, int howto); 109 110 #ifdef ACPI_DEBUG 111 static void acpi_set_debugging(void); 112 #endif 113 114 static void acpi_system_eventhandler_sleep(void *arg, int state); 115 static void acpi_system_eventhandler_wakeup(void *arg, int state); 116 117 static device_method_t acpi_methods[] = { 118 /* Device interface */ 119 DEVMETHOD(device_identify, acpi_identify), 120 DEVMETHOD(device_probe, acpi_probe), 121 DEVMETHOD(device_attach, acpi_attach), 122 DEVMETHOD(device_shutdown, bus_generic_shutdown), 123 DEVMETHOD(device_suspend, bus_generic_suspend), 124 DEVMETHOD(device_resume, bus_generic_resume), 125 126 /* Bus interface */ 127 DEVMETHOD(bus_add_child, acpi_add_child), 128 DEVMETHOD(bus_print_child, acpi_print_child), 129 DEVMETHOD(bus_read_ivar, acpi_read_ivar), 130 DEVMETHOD(bus_write_ivar, acpi_write_ivar), 131 DEVMETHOD(bus_set_resource, acpi_set_resource), 132 DEVMETHOD(bus_get_resource, acpi_get_resource), 133 DEVMETHOD(bus_alloc_resource, acpi_alloc_resource), 134 DEVMETHOD(bus_release_resource, acpi_release_resource), 135 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 136 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 137 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 138 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 139 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 140 141 {0, 0} 142 }; 143 144 static driver_t acpi_driver = { 145 "acpi", 146 acpi_methods, 147 sizeof(struct acpi_softc), 148 }; 149 150 devclass_t acpi_devclass; 151 DRIVER_MODULE(acpi, nexus, acpi_driver, acpi_devclass, 0, 0); 152 153 SYSCTL_INT(_debug, OID_AUTO, acpi_debug_layer, CTLFLAG_RW, &AcpiDbgLayer, 0, ""); 154 SYSCTL_INT(_debug, OID_AUTO, acpi_debug_level, CTLFLAG_RW, &AcpiDbgLevel, 0, ""); 155 156 /* 157 * Detect ACPI, perform early initialisation 158 */ 159 static void 160 acpi_identify(driver_t *driver, device_t parent) 161 { 162 device_t child; 163 ACPI_PHYSICAL_ADDRESS rsdp; 164 int error; 165 #ifdef ENABLE_DEBUGGER 166 char *debugpoint = getenv("debug.acpi.debugger"); 167 #endif 168 169 FUNCTION_TRACE(__FUNCTION__); 170 171 if(!cold){ 172 printf("Don't load this driver from userland!!\n"); 173 return ; 174 } 175 176 /* 177 * Make sure we're not being doubly invoked. 178 */ 179 if (device_find_child(parent, "acpi", 0) != NULL) 180 return_VOID; 181 182 #ifdef ACPI_DEBUG 183 acpi_set_debugging(); 184 #endif 185 186 /* 187 * Start up ACPICA 188 */ 189 #ifdef ENABLE_DEBUGGER 190 if (debugpoint && !strcmp(debugpoint, "init")) 191 acpi_EnterDebugger(); 192 #endif 193 if ((error = AcpiInitializeSubsystem()) != AE_OK) { 194 printf("ACPI: initialisation failed: %s\n", acpi_strerror(error)); 195 return_VOID; 196 } 197 #ifdef ENABLE_DEBUGGER 198 if (debugpoint && !strcmp(debugpoint, "tables")) 199 acpi_EnterDebugger(); 200 #endif 201 if (((error = AcpiFindRootPointer(&rsdp)) != AE_OK) || 202 ((error = AcpiLoadTables(rsdp)) != AE_OK)) { 203 printf("ACPI: table load failed: %s\n", acpi_strerror(error)); 204 return_VOID; 205 } 206 207 /* 208 * Attach the actual ACPI device. 209 */ 210 if ((child = BUS_ADD_CHILD(parent, 0, "acpi", 0)) == NULL) { 211 device_printf(parent, "ACPI: could not attach\n"); 212 return_VOID; 213 } 214 } 215 216 /* 217 * Fetch some descriptive data from ACPI to put in our attach message 218 */ 219 static int 220 acpi_probe(device_t dev) 221 { 222 ACPI_TABLE_HEADER th; 223 char buf[20]; 224 int error; 225 226 FUNCTION_TRACE(__FUNCTION__); 227 228 if ((error = AcpiGetTableHeader(ACPI_TABLE_XSDT, 1, &th)) != AE_OK) { 229 device_printf(dev, "couldn't get XSDT header: %s\n", acpi_strerror(error)); 230 return_VALUE(ENXIO); 231 } 232 sprintf(buf, "%.6s %.8s", th.OemId, th.OemTableId); 233 device_set_desc_copy(dev, buf); 234 235 return_VALUE(0); 236 } 237 238 static int 239 acpi_attach(device_t dev) 240 { 241 struct acpi_softc *sc; 242 int error; 243 #ifdef ENABLE_DEBUGGER 244 char *debugpoint = getenv("debug.acpi.debugger"); 245 #endif 246 247 FUNCTION_TRACE(__FUNCTION__); 248 249 sc = device_get_softc(dev); 250 bzero(sc, sizeof(*sc)); 251 sc->acpi_dev = dev; 252 253 #ifdef ENABLE_DEBUGGER 254 if (debugpoint && !strcmp(debugpoint, "spaces")) 255 acpi_EnterDebugger(); 256 #endif 257 258 /* 259 * Install the default address space handlers. 260 */ 261 if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 262 ADDRESS_SPACE_SYSTEM_MEMORY, 263 ACPI_DEFAULT_HANDLER, 264 NULL, NULL)) != AE_OK) { 265 device_printf(dev, "could not initialise SystemMemory handler: %s\n", acpi_strerror(error)); 266 return_VALUE(ENXIO); 267 } 268 if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 269 ADDRESS_SPACE_SYSTEM_IO, 270 ACPI_DEFAULT_HANDLER, 271 NULL, NULL)) != AE_OK) { 272 device_printf(dev, "could not initialise SystemIO handler: %s\n", acpi_strerror(error)); 273 return_VALUE(ENXIO); 274 } 275 if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 276 ADDRESS_SPACE_PCI_CONFIG, 277 ACPI_DEFAULT_HANDLER, 278 NULL, NULL)) != AE_OK) { 279 device_printf(dev, "could not initialise PciConfig handler: %s\n", acpi_strerror(error)); 280 return_VALUE(ENXIO); 281 } 282 283 /* 284 * Bring ACPI fully online. 285 * 286 * Note that we request that device _STA and _INI methods not be run (ACPI_NO_DEVICE_INIT) 287 * and the final object initialisation pass be skipped (ACPI_NO_OBJECT_INIT). 288 * 289 * XXX We need to arrange for the object init pass after we have attached all our 290 * child devices. 291 */ 292 #ifdef ENABLE_DEBUGGER 293 if (debugpoint && !strcmp(debugpoint, "enable")) 294 acpi_EnterDebugger(); 295 #endif 296 if ((error = AcpiEnableSubsystem(ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT)) != AE_OK) { 297 device_printf(dev, "could not enable ACPI: %s\n", acpi_strerror(error)); 298 return_VALUE(ENXIO); 299 } 300 301 /* 302 * Dispatch the default sleep state to devices. 303 * TBD: should be configured from userland policy manager. 304 */ 305 sc->acpi_power_button_sx = ACPI_POWER_BUTTON_DEFAULT_SX; 306 sc->acpi_sleep_button_sx = ACPI_SLEEP_BUTTON_DEFAULT_SX; 307 sc->acpi_lid_switch_sx = ACPI_LID_SWITCH_DEFAULT_SX; 308 309 /* Enable and clear fixed events and install handlers. */ 310 if (AcpiGbl_FADT != NULL && AcpiGbl_FADT->PwrButton == 0) { 311 AcpiEnableEvent(ACPI_EVENT_POWER_BUTTON, ACPI_EVENT_FIXED); 312 AcpiClearEvent(ACPI_EVENT_POWER_BUTTON, ACPI_EVENT_FIXED); 313 AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON, acpi_eventhandler_power_button_for_sleep, sc); 314 device_printf(dev, "power button is handled as a fixed feature programming model.\n"); 315 } 316 if (AcpiGbl_FADT != NULL && AcpiGbl_FADT->SleepButton == 0) { 317 AcpiEnableEvent(ACPI_EVENT_SLEEP_BUTTON, ACPI_EVENT_FIXED); 318 AcpiClearEvent(ACPI_EVENT_SLEEP_BUTTON, ACPI_EVENT_FIXED); 319 AcpiInstallFixedEventHandler(ACPI_EVENT_SLEEP_BUTTON, acpi_eventhandler_sleep_button_for_sleep, sc); 320 device_printf(dev, "sleep button is handled as a fixed feature programming model.\n"); 321 } 322 323 /* 324 * Scan the namespace and attach/initialise children. 325 */ 326 #ifdef ENABLE_DEBUGGER 327 if (debugpoint && !strcmp(debugpoint, "probe")) 328 acpi_EnterDebugger(); 329 #endif 330 if (!acpi_disabled("bus")) 331 acpi_probe_children(dev); 332 333 /* 334 * Register our shutdown handlers 335 */ 336 EVENTHANDLER_REGISTER(shutdown_pre_sync, acpi_shutdown_pre_sync, sc, SHUTDOWN_PRI_LAST); 337 EVENTHANDLER_REGISTER(shutdown_final, acpi_shutdown_final, sc, SHUTDOWN_PRI_LAST); 338 339 /* 340 * Register our acpi event handlers. 341 * XXX should be configurable eg. via userland policy manager. 342 */ 343 EVENTHANDLER_REGISTER(acpi_sleep_event, acpi_system_eventhandler_sleep, sc, ACPI_EVENT_PRI_LAST); 344 EVENTHANDLER_REGISTER(acpi_wakeup_event, acpi_system_eventhandler_wakeup, sc, ACPI_EVENT_PRI_LAST); 345 346 /* 347 * Flag our initial states. 348 */ 349 sc->acpi_enabled = 1; 350 sc->acpi_sstate = ACPI_STATE_S0; 351 352 /* 353 * Create the control device 354 */ 355 sc->acpi_dev_t = make_dev(&acpi_cdevsw, 0, 0, 5, 0660, "acpi"); 356 sc->acpi_dev_t->si_drv1 = sc; 357 358 #ifdef ENABLE_DEBUGGER 359 if (debugpoint && !strcmp(debugpoint, "running")) 360 acpi_EnterDebugger(); 361 #endif 362 return_VALUE(0); 363 } 364 365 /* 366 * Handle a new device being added 367 */ 368 static device_t 369 acpi_add_child(device_t bus, int order, const char *name, int unit) 370 { 371 struct acpi_device *ad; 372 device_t child; 373 374 if ((ad = malloc(sizeof(*ad), M_ACPIDEV, M_NOWAIT)) == NULL) 375 return(NULL); 376 bzero(ad, sizeof(*ad)); 377 378 resource_list_init(&ad->ad_rl); 379 380 child = device_add_child_ordered(bus, order, name, unit); 381 if (child != NULL) 382 device_set_ivars(child, ad); 383 return(child); 384 } 385 386 /* 387 * Print child device resource usage 388 */ 389 static int 390 acpi_print_resources(struct resource_list *rl, const char *name, int type, const char *format) 391 { 392 struct resource_list_entry *rle; 393 int printed, retval; 394 395 printed = 0; 396 retval = 0; 397 398 if (!SLIST_FIRST(rl)) 399 return(0); 400 401 /* Yes, this is kinda cheating */ 402 SLIST_FOREACH(rle, rl, link) { 403 if (rle->type == type) { 404 if (printed == 0) 405 retval += printf(" %s ", name); 406 else if (printed > 0) 407 retval += printf(","); 408 printed++; 409 retval += printf(format, rle->start); 410 if (rle->count > 1) { 411 retval += printf("-"); 412 retval += printf(format, rle->start + 413 rle->count - 1); 414 } 415 } 416 } 417 return(retval); 418 } 419 420 static int 421 acpi_print_child(device_t bus, device_t child) 422 { 423 struct acpi_device *adev = device_get_ivars(child); 424 struct resource_list *rl = &adev->ad_rl; 425 int retval = 0; 426 427 retval += bus_print_child_header(bus, child); 428 retval += acpi_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); 429 retval += acpi_print_resources(rl, "iomem", SYS_RES_MEMORY, "%#lx"); 430 retval += acpi_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); 431 retval += bus_print_child_footer(bus, child); 432 433 return(retval); 434 } 435 436 437 /* 438 * Handle per-device ivars 439 */ 440 static int 441 acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) 442 { 443 struct acpi_device *ad; 444 445 if ((ad = device_get_ivars(child)) == NULL) { 446 printf("device has no ivars\n"); 447 return(ENOENT); 448 } 449 450 switch(index) { 451 /* ACPI ivars */ 452 case ACPI_IVAR_HANDLE: 453 *(ACPI_HANDLE *)result = ad->ad_handle; 454 break; 455 case ACPI_IVAR_MAGIC: 456 *(int *)result = ad->ad_magic; 457 break; 458 case ACPI_IVAR_PRIVATE: 459 *(void **)result = ad->ad_private; 460 break; 461 462 default: 463 panic("bad ivar read request (%d)\n", index); 464 return(ENOENT); 465 } 466 return(0); 467 } 468 469 static int 470 acpi_write_ivar(device_t dev, device_t child, int index, uintptr_t value) 471 { 472 struct acpi_device *ad; 473 474 if ((ad = device_get_ivars(child)) == NULL) { 475 printf("device has no ivars\n"); 476 return(ENOENT); 477 } 478 479 switch(index) { 480 /* ACPI ivars */ 481 case ACPI_IVAR_HANDLE: 482 ad->ad_handle = (ACPI_HANDLE)value; 483 break; 484 case ACPI_IVAR_MAGIC: 485 ad->ad_magic = (int )value; 486 break; 487 case ACPI_IVAR_PRIVATE: 488 ad->ad_private = (void *)value; 489 break; 490 491 default: 492 panic("bad ivar write request (%d)\n", index); 493 return(ENOENT); 494 } 495 return(0); 496 } 497 498 /* 499 * Handle child resource allocation/removal 500 */ 501 static int 502 acpi_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) 503 { 504 struct acpi_device *ad = device_get_ivars(child); 505 struct resource_list *rl = &ad->ad_rl; 506 507 resource_list_add(rl, type, rid, start, start + count -1, count); 508 509 return(0); 510 } 511 512 static int 513 acpi_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) 514 { 515 struct acpi_device *ad = device_get_ivars(child); 516 struct resource_list *rl = &ad->ad_rl; 517 struct resource_list_entry *rle; 518 519 rle = resource_list_find(rl, type, rid); 520 if (!rle) 521 return(ENOENT); 522 523 if (startp) 524 *startp = rle->start; 525 if (countp) 526 *countp = rle->count; 527 528 return(0); 529 } 530 531 static struct resource * 532 acpi_alloc_resource(device_t bus, device_t child, int type, int *rid, 533 u_long start, u_long end, u_long count, u_int flags) 534 { 535 struct acpi_device *ad = device_get_ivars(child); 536 struct resource_list *rl = &ad->ad_rl; 537 538 return(resource_list_alloc(rl, bus, child, type, rid, start, end, count, flags)); 539 } 540 541 static int 542 acpi_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) 543 { 544 struct acpi_device *ad = device_get_ivars(child); 545 struct resource_list *rl = &ad->ad_rl; 546 547 return(resource_list_release(rl, bus, child, type, rid, r)); 548 } 549 550 /* 551 * Scan relevant portions of the ACPI namespace and attach child devices. 552 * 553 * Note that we only expect to find devices in the \_TZ_, \_SI_ and \_SB_ scopes, 554 * and \_TZ_ becomes obsolete in the ACPI 2.0 spec. 555 */ 556 static void 557 acpi_probe_children(device_t bus) 558 { 559 ACPI_HANDLE parent; 560 static char *scopes[] = {"\\_TZ_", "\\_SI", "\\_SB_", NULL}; 561 int i; 562 563 FUNCTION_TRACE(__FUNCTION__); 564 565 /* 566 * Create any static children by calling device identify methods. 567 */ 568 DEBUG_PRINT(TRACE_OBJECTS, ("device identify routines\n")); 569 bus_generic_probe(bus); 570 571 /* 572 * Scan the namespace and insert placeholders for all the devices that 573 * we find. 574 * 575 * Note that we use AcpiWalkNamespace rather than AcpiGetDevices because 576 * we want to create nodes for all devices, not just those that are currently 577 * present. (This assumes that we don't want to create/remove devices as they 578 * appear, which might be smarter.) 579 */ 580 DEBUG_PRINT(TRACE_OBJECTS, ("namespace scan\n")); 581 for (i = 0; scopes[i] != NULL; i++) 582 if ((AcpiGetHandle(ACPI_ROOT_OBJECT, scopes[i], &parent)) == AE_OK) 583 AcpiWalkNamespace(ACPI_TYPE_ANY, parent, 100, acpi_probe_child, bus, NULL); 584 585 /* 586 * Scan all of the child devices we have created and let them probe/attach. 587 */ 588 DEBUG_PRINT(TRACE_OBJECTS, ("first bus_generic_attach\n")); 589 bus_generic_attach(bus); 590 591 /* 592 * Some of these children may have attached others as part of their attach 593 * process (eg. the root PCI bus driver), so rescan. 594 */ 595 DEBUG_PRINT(TRACE_OBJECTS, ("second bus_generic_attach\n")); 596 bus_generic_attach(bus); 597 598 return_VOID; 599 } 600 601 /* 602 * Evaluate a child device and determine whether we might attach a device to 603 * it. 604 */ 605 static ACPI_STATUS 606 acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status) 607 { 608 ACPI_OBJECT_TYPE type; 609 device_t child, bus = (device_t)context; 610 611 FUNCTION_TRACE(__FUNCTION__); 612 613 /* 614 * Skip this device if we think we'll have trouble with it. 615 */ 616 if (acpi_avoid(handle)) 617 return_ACPI_STATUS(AE_OK); 618 619 if (AcpiGetType(handle, &type) == AE_OK) { 620 switch(type) { 621 case ACPI_TYPE_DEVICE: 622 case ACPI_TYPE_PROCESSOR: 623 case ACPI_TYPE_THERMAL: 624 case ACPI_TYPE_POWER: 625 if (acpi_disabled("children")) 626 break; 627 /* 628 * Create a placeholder device for this node. Sort the placeholder 629 * so that the probe/attach passes will run breadth-first. 630 */ 631 DEBUG_PRINT(TRACE_OBJECTS, ("scanning '%s'\n", acpi_name(handle))) 632 child = BUS_ADD_CHILD(bus, level * 10, NULL, -1); 633 acpi_set_handle(child, handle); 634 DEBUG_EXEC(device_probe_and_attach(child)); 635 break; 636 } 637 } 638 return_ACPI_STATUS(AE_OK); 639 } 640 641 static void 642 acpi_shutdown_pre_sync(void *arg, int howto) 643 { 644 /* 645 * Disable all ACPI events before soft off, otherwise the system 646 * will be turned on again on some laptops. 647 * 648 * XXX this should probably be restricted to masking some events just 649 * before powering down, since we may still need ACPI during the 650 * shutdown process. 651 */ 652 acpi_Disable((struct acpi_softc *)arg); 653 } 654 655 static void 656 acpi_shutdown_final(void *arg, int howto) 657 { 658 ACPI_STATUS status; 659 660 if (howto & RB_POWEROFF) { 661 printf("Power system off using ACPI...\n"); 662 if ((status = AcpiSetSystemSleepState(ACPI_STATE_S5)) != AE_OK) { 663 printf("ACPI power-off failed - %s\n", acpi_strerror(status)); 664 } else { 665 DELAY(1000000); 666 printf("ACPI power-off failed - timeout\n"); 667 } 668 } 669 } 670 671 /* 672 * Match a HID string against a device 673 */ 674 BOOLEAN 675 acpi_MatchHid(device_t dev, char *hid) 676 { 677 ACPI_HANDLE h; 678 ACPI_DEVICE_INFO devinfo; 679 ACPI_STATUS error; 680 681 if (hid == NULL) 682 return(FALSE); 683 if ((h = acpi_get_handle(dev)) == NULL) 684 return(FALSE); 685 if ((error = AcpiGetObjectInfo(h, &devinfo)) != AE_OK) 686 return(FALSE); 687 if ((devinfo.Valid & ACPI_VALID_HID) && !strcmp(hid, devinfo.HardwareId)) 688 return(TRUE); 689 return(FALSE); 690 } 691 692 /* 693 * Perform the tedious double-get procedure required for fetching something into 694 * an ACPI_BUFFER that has not been initialised. 695 */ 696 ACPI_STATUS 697 acpi_GetIntoBuffer(ACPI_HANDLE handle, ACPI_STATUS (*func)(ACPI_HANDLE, ACPI_BUFFER *), ACPI_BUFFER *buf) 698 { 699 ACPI_STATUS status; 700 701 buf->Length = 0; 702 buf->Pointer = NULL; 703 704 if ((status = func(handle, buf)) != AE_BUFFER_OVERFLOW) 705 return(status); 706 if ((buf->Pointer = AcpiOsCallocate(buf->Length)) == NULL) 707 return(AE_NO_MEMORY); 708 return(func(handle, buf)); 709 } 710 711 /* 712 * Allocate a buffer with a preset data size. 713 */ 714 ACPI_BUFFER * 715 acpi_AllocBuffer(int size) 716 { 717 ACPI_BUFFER *buf; 718 719 if ((buf = malloc(size + sizeof(*buf), M_ACPIDEV, M_NOWAIT)) == NULL) 720 return(NULL); 721 buf->Length = size; 722 buf->Pointer = (void *)(buf + 1); 723 return(buf); 724 } 725 726 /* 727 * Set the system sleep state 728 * 729 * Currently we only support S1 and S5 730 */ 731 ACPI_STATUS 732 acpi_SetSleepState(struct acpi_softc *sc, int state) 733 { 734 ACPI_STATUS status = AE_OK; 735 736 FUNCTION_TRACE_U32(__FUNCTION__, state); 737 738 switch (state) { 739 case ACPI_STATE_S0: /* XXX only for testing */ 740 status = AcpiSetSystemSleepState((UINT8)state); 741 if (status != AE_OK) { 742 device_printf(sc->acpi_dev, "AcpiSetSystemSleepState failed - %s\n", acpi_strerror(status)); 743 } 744 break; 745 746 case ACPI_STATE_S1: 747 /* 748 * Inform all devices that we are going to sleep. 749 */ 750 if (DEVICE_SUSPEND(root_bus) != 0) { 751 /* 752 * Re-wake the system. 753 * 754 * XXX note that a better two-pass approach with a 'veto' pass 755 * followed by a "real thing" pass would be better, but the 756 * current bus interface does not provide for this. 757 */ 758 DEVICE_RESUME(root_bus); 759 return_ACPI_STATUS(AE_ERROR); 760 } 761 sc->acpi_sstate = state; 762 status = AcpiSetSystemSleepState((UINT8)state); 763 if (status != AE_OK) { 764 device_printf(sc->acpi_dev, "AcpiSetSystemSleepState failed - %s\n", acpi_strerror(status)); 765 } 766 DEVICE_RESUME(root_bus); 767 sc->acpi_sstate = ACPI_STATE_S0; 768 break; 769 770 case ACPI_STATE_S5: 771 /* 772 * Shut down cleanly and power off. This will call us back through the 773 * shutdown handlers. 774 */ 775 shutdown_nice(RB_POWEROFF); 776 break; 777 778 default: 779 status = AE_BAD_PARAMETER; 780 break; 781 } 782 return_ACPI_STATUS(status); 783 } 784 785 /* 786 * Enable/Disable ACPI 787 */ 788 ACPI_STATUS 789 acpi_Enable(struct acpi_softc *sc) 790 { 791 ACPI_STATUS status; 792 u_int32_t flags; 793 794 FUNCTION_TRACE(__FUNCTION__); 795 796 flags = ACPI_NO_ADDRESS_SPACE_INIT | ACPI_NO_HARDWARE_INIT | 797 ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT; 798 if (!sc->acpi_enabled) { 799 status = AcpiEnableSubsystem(flags); 800 } else { 801 status = AE_OK; 802 } 803 if (status == AE_OK) 804 sc->acpi_enabled = 1; 805 return_ACPI_STATUS(status); 806 } 807 808 ACPI_STATUS 809 acpi_Disable(struct acpi_softc *sc) 810 { 811 ACPI_STATUS status; 812 813 FUNCTION_TRACE(__FUNCTION__); 814 815 if (sc->acpi_enabled) { 816 status = AcpiDisable(); 817 } else { 818 status = AE_OK; 819 } 820 if (status == AE_OK) 821 sc->acpi_enabled = 0; 822 return_ACPI_STATUS(status); 823 } 824 825 /* 826 * Returns true if the device is actually present and should 827 * be attached to. This requires the present, enabled, UI-visible 828 * and diagnostics-passed bits to be set. 829 */ 830 BOOLEAN 831 acpi_DeviceIsPresent(device_t dev) 832 { 833 ACPI_HANDLE h; 834 ACPI_DEVICE_INFO devinfo; 835 ACPI_STATUS error; 836 837 if ((h = acpi_get_handle(dev)) == NULL) 838 return(FALSE); 839 if ((error = AcpiGetObjectInfo(h, &devinfo)) != AE_OK) 840 return(FALSE); 841 if ((devinfo.Valid & ACPI_VALID_HID) && (devinfo.CurrentStatus & 0xf)) 842 return(TRUE); 843 return(FALSE); 844 } 845 846 /* 847 * Evaluate a path that should return a number 848 */ 849 ACPI_STATUS 850 acpi_EvaluateNumber(ACPI_HANDLE handle, char *path, int *number) 851 { 852 ACPI_STATUS error; 853 ACPI_BUFFER buf; 854 int param[4]; 855 856 if (handle == NULL) 857 handle = ACPI_ROOT_OBJECT; 858 buf.Pointer = ¶m[0]; 859 buf.Length = sizeof(param); 860 if ((error = AcpiEvaluateObject(handle, path, NULL, &buf)) == AE_OK) { 861 if (param[0] == ACPI_TYPE_NUMBER) { 862 *number = param[1]; 863 } else { 864 error = AE_TYPE; 865 } 866 } 867 return(error); 868 } 869 870 /* 871 * ACPI Event Handlers 872 */ 873 874 /* System Event Handlers (registered by EVENTHANDLER_REGISTER) */ 875 876 static void 877 acpi_system_eventhandler_sleep(void *arg, int state) 878 { 879 FUNCTION_TRACE_U32(__FUNCTION__, state); 880 881 if (state >= ACPI_STATE_S0 && state <= ACPI_STATE_S5) 882 acpi_SetSleepState((struct acpi_softc *)arg, state); 883 return_VOID; 884 } 885 886 static void 887 acpi_system_eventhandler_wakeup(void *arg, int state) 888 { 889 FUNCTION_TRACE_U32(__FUNCTION__, state); 890 891 /* Well, what to do? :-) */ 892 893 return_VOID; 894 } 895 896 /* 897 * ACPICA Event Handlers (FixedEvent, also called from button notify handler) 898 */ 899 UINT32 900 acpi_eventhandler_power_button_for_sleep(void *context) 901 { 902 struct acpi_softc *sc = (struct acpi_softc *)context; 903 904 FUNCTION_TRACE(__FUNCTION__); 905 906 EVENTHANDLER_INVOKE(acpi_sleep_event, sc->acpi_power_button_sx); 907 908 return_VALUE(INTERRUPT_HANDLED); 909 } 910 911 UINT32 912 acpi_eventhandler_power_button_for_wakeup(void *context) 913 { 914 struct acpi_softc *sc = (struct acpi_softc *)context; 915 916 FUNCTION_TRACE(__FUNCTION__); 917 918 EVENTHANDLER_INVOKE(acpi_wakeup_event, sc->acpi_power_button_sx); 919 920 return_VALUE(INTERRUPT_HANDLED); 921 } 922 923 UINT32 924 acpi_eventhandler_sleep_button_for_sleep(void *context) 925 { 926 struct acpi_softc *sc = (struct acpi_softc *)context; 927 928 FUNCTION_TRACE(__FUNCTION__); 929 930 EVENTHANDLER_INVOKE(acpi_sleep_event, sc->acpi_sleep_button_sx); 931 932 return_VALUE(INTERRUPT_HANDLED); 933 } 934 935 UINT32 936 acpi_eventhandler_sleep_button_for_wakeup(void *context) 937 { 938 struct acpi_softc *sc = (struct acpi_softc *)context; 939 940 FUNCTION_TRACE(__FUNCTION__); 941 942 EVENTHANDLER_INVOKE(acpi_wakeup_event, sc->acpi_sleep_button_sx); 943 944 return_VALUE(INTERRUPT_HANDLED); 945 } 946 947 /* 948 * XXX This is kinda ugly, and should not be here. 949 */ 950 struct acpi_staticbuf { 951 ACPI_BUFFER buffer; 952 char data[512]; 953 }; 954 955 char * 956 acpi_strerror(ACPI_STATUS excep) 957 { 958 static struct acpi_staticbuf buf; 959 960 buf.buffer.Length = 512; 961 buf.buffer.Pointer = &buf.data[0]; 962 963 if (AcpiFormatException(excep, &buf.buffer) == AE_OK) 964 return(buf.buffer.Pointer); 965 return("(error formatting exception)"); 966 } 967 968 char * 969 acpi_name(ACPI_HANDLE handle) 970 { 971 static struct acpi_staticbuf buf; 972 973 buf.buffer.Length = 512; 974 buf.buffer.Pointer = &buf.data[0]; 975 976 if (AcpiGetName(handle, ACPI_FULL_PATHNAME, &buf.buffer) == AE_OK) 977 return(buf.buffer.Pointer); 978 return("(unknown path)"); 979 } 980 981 /* 982 * Debugging/bug-avoidance. Avoid trying to fetch info on various 983 * parts of the namespace. 984 */ 985 int 986 acpi_avoid(ACPI_HANDLE handle) 987 { 988 char *cp, *np; 989 int len; 990 991 np = acpi_name(handle); 992 if (*np == '\\') 993 np++; 994 if ((cp = getenv("debug.acpi.avoid")) == NULL) 995 return(0); 996 997 /* scan the avoid list checking for a match */ 998 for (;;) { 999 while ((*cp != 0) && isspace(*cp)) 1000 cp++; 1001 if (*cp == 0) 1002 break; 1003 len = 0; 1004 while ((cp[len] != 0) && !isspace(cp[len])) 1005 len++; 1006 if (!strncmp(cp, np, len)) { 1007 DEBUG_PRINT(TRACE_OBJECTS, ("avoiding '%s'\n", np)); 1008 return(1); 1009 } 1010 cp += len; 1011 } 1012 return(0); 1013 } 1014 1015 /* 1016 * Debugging/bug-avoidance. Disable ACPI subsystem components. 1017 */ 1018 int 1019 acpi_disabled(char *subsys) 1020 { 1021 char *cp; 1022 int len; 1023 1024 if ((cp = getenv("debug.acpi.disable")) == NULL) 1025 return(0); 1026 if (!strcmp(cp, "all")) 1027 return(1); 1028 1029 /* scan the disable list checking for a match */ 1030 for (;;) { 1031 while ((*cp != 0) && isspace(*cp)) 1032 cp++; 1033 if (*cp == 0) 1034 break; 1035 len = 0; 1036 while ((cp[len] != 0) && !isspace(cp[len])) 1037 len++; 1038 if (!strncmp(cp, subsys, len)) { 1039 DEBUG_PRINT(TRACE_OBJECTS, ("disabled '%s'\n", subsys)); 1040 return(1); 1041 } 1042 cp += len; 1043 } 1044 return(0); 1045 } 1046 1047 /* 1048 * Control interface. 1049 * 1050 * We multiplex ioctls for all participating ACPI devices here. Individual 1051 * drivers wanting to be accessible via /dev/acpi should use the register/deregister 1052 * interface to make their handlers visible. 1053 */ 1054 struct acpi_ioctl_hook 1055 { 1056 TAILQ_ENTRY(acpi_ioctl_hook) link; 1057 u_long cmd; 1058 int (* fn)(u_long cmd, caddr_t addr, void *arg); 1059 void *arg; 1060 }; 1061 1062 static TAILQ_HEAD(,acpi_ioctl_hook) acpi_ioctl_hooks; 1063 static int acpi_ioctl_hooks_initted; 1064 1065 /* 1066 * Register an ioctl handler. 1067 */ 1068 int 1069 acpi_register_ioctl(u_long cmd, int (* fn)(u_long cmd, caddr_t addr, void *arg), void *arg) 1070 { 1071 struct acpi_ioctl_hook *hp; 1072 1073 if ((hp = malloc(sizeof(*hp), M_ACPIDEV, M_NOWAIT)) == NULL) 1074 return(ENOMEM); 1075 hp->cmd = cmd; 1076 hp->fn = fn; 1077 hp->arg = arg; 1078 if (acpi_ioctl_hooks_initted == 0) { 1079 TAILQ_INIT(&acpi_ioctl_hooks); 1080 acpi_ioctl_hooks_initted = 1; 1081 } 1082 TAILQ_INSERT_TAIL(&acpi_ioctl_hooks, hp, link); 1083 return(0); 1084 } 1085 1086 /* 1087 * Deregister an ioctl handler. 1088 */ 1089 void 1090 acpi_deregister_ioctl(u_long cmd, int (* fn)(u_long cmd, caddr_t addr, void *arg)) 1091 { 1092 struct acpi_ioctl_hook *hp; 1093 1094 TAILQ_FOREACH(hp, &acpi_ioctl_hooks, link) 1095 if ((hp->cmd == cmd) && (hp->fn == fn)) 1096 break; 1097 1098 if (hp != NULL) { 1099 TAILQ_REMOVE(&acpi_ioctl_hooks, hp, link); 1100 free(hp, M_ACPIDEV); 1101 } 1102 } 1103 1104 static int 1105 acpiopen(dev_t dev, int flag, int fmt, struct proc *p) 1106 { 1107 return(0); 1108 } 1109 1110 static int 1111 acpiclose(dev_t dev, int flag, int fmt, struct proc *p) 1112 { 1113 return(0); 1114 } 1115 1116 static int 1117 acpiioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 1118 { 1119 struct acpi_softc *sc; 1120 struct acpi_ioctl_hook *hp; 1121 int error, xerror, state; 1122 1123 error = state = 0; 1124 sc = dev->si_drv1; 1125 1126 /* 1127 * Scan the list of registered ioctls, looking for handlers. 1128 */ 1129 if (acpi_ioctl_hooks_initted) { 1130 TAILQ_FOREACH(hp, &acpi_ioctl_hooks, link) { 1131 if (hp->cmd == cmd) { 1132 xerror = hp->fn(cmd, addr, hp->arg); 1133 if (xerror != 0) 1134 error = xerror; 1135 goto out; 1136 } 1137 } 1138 } 1139 1140 /* 1141 * Core system ioctls. 1142 */ 1143 switch (cmd) { 1144 case ACPIIO_ENABLE: 1145 if (ACPI_FAILURE(acpi_Enable(sc))) 1146 error = ENXIO; 1147 break; 1148 1149 case ACPIIO_DISABLE: 1150 if (ACPI_FAILURE(acpi_Disable(sc))) 1151 error = ENXIO; 1152 break; 1153 1154 case ACPIIO_SETSLPSTATE: 1155 if (!sc->acpi_enabled) { 1156 error = ENXIO; 1157 break; 1158 } 1159 state = *(int *)addr; 1160 if (state >= ACPI_STATE_S0 && state <= ACPI_STATE_S5) { 1161 acpi_SetSleepState(sc, state); 1162 } else { 1163 error = EINVAL; 1164 } 1165 break; 1166 1167 default: 1168 if (error == 0) 1169 error = EINVAL; 1170 break; 1171 } 1172 1173 out: 1174 return(error); 1175 } 1176 1177 #ifdef ACPI_DEBUG 1178 /* 1179 * Support for parsing debug options from the kernel environment. 1180 * 1181 * Bits may be set in the AcpiDbgLayer and AcpiDbgLevel debug registers 1182 * by specifying the names of the bits in the debug.acpi.layer and 1183 * debug.acpi.level environment variables. Bits may be unset by 1184 * prefixing the bit name with !. 1185 */ 1186 struct debugtag 1187 { 1188 char *name; 1189 UINT32 value; 1190 }; 1191 1192 static struct debugtag dbg_layer[] = { 1193 {"GLOBAL", 0x00000001}, 1194 {"COMMON", 0x00000002}, 1195 {"PARSER", 0x00000004}, 1196 {"DISPATCHER", 0x00000008}, 1197 {"INTERPRETER", 0x00000010}, 1198 {"NAMESPACE", 0x00000020}, 1199 {"RESOURCE_MANAGER", 0x00000040}, 1200 {"TABLE_MANAGER", 0x00000080}, 1201 {"EVENT_HANDLING", 0x00000100}, 1202 {"HARDWARE", 0x00000200}, 1203 {"MISCELLANEOUS", 0x00000400}, 1204 {"OS_DEPENDENT", 0x00000800}, 1205 {"BUS_MANAGER", 0x00001000}, 1206 {"PROCESSOR_CONTROL", 0x00002000}, 1207 {"SYSTEM_CONTROL", 0x00004000}, 1208 {"THERMAL_CONTROL", 0x00008000}, 1209 {"POWER_CONTROL", 0x00010000}, 1210 {"EMBEDDED_CONTROLLER", 0x00020000}, 1211 {"BATTERY", 0x00040000}, 1212 {"DEBUGGER", 0x00100000}, 1213 {"ALL_COMPONENTS", 0x001FFFFF}, 1214 {NULL, 0} 1215 }; 1216 1217 static struct debugtag dbg_level[] = { 1218 {"ACPI_OK", 0x00000001}, 1219 {"ACPI_INFO", 0x00000002}, 1220 {"ACPI_WARN", 0x00000004}, 1221 {"ACPI_ERROR", 0x00000008}, 1222 {"ACPI_FATAL", 0x00000010}, 1223 {"ACPI_DEBUG_OBJECT", 0x00000020}, 1224 {"ACPI_ALL", 0x0000003F}, 1225 {"TRACE_PARSE", 0x00000100}, 1226 {"TRACE_DISPATCH", 0x00000200}, 1227 {"TRACE_LOAD", 0x00000400}, 1228 {"TRACE_EXEC", 0x00000800}, 1229 {"TRACE_NAMES", 0x00001000}, 1230 {"TRACE_OPREGION", 0x00002000}, 1231 {"TRACE_BFIELD", 0x00004000}, 1232 {"TRACE_TRASH", 0x00008000}, 1233 {"TRACE_TABLES", 0x00010000}, 1234 {"TRACE_FUNCTIONS", 0x00020000}, 1235 {"TRACE_VALUES", 0x00040000}, 1236 {"TRACE_OBJECTS", 0x00080000}, 1237 {"TRACE_ALLOCATIONS", 0x00100000}, 1238 {"TRACE_RESOURCES", 0x00200000}, 1239 {"TRACE_IO", 0x00400000}, 1240 {"TRACE_INTERRUPTS", 0x00800000}, 1241 {"TRACE_USER_REQUESTS", 0x01000000}, 1242 {"TRACE_PACKAGE", 0x02000000}, 1243 {"TRACE_MUTEX", 0x04000000}, 1244 {"TRACE_ALL", 0x0FFFFF00}, 1245 {"VERBOSE_AML_DISASSEMBLE", 0x10000000}, 1246 {"VERBOSE_INFO", 0x20000000}, 1247 {"VERBOSE_TABLES", 0x40000000}, 1248 {"VERBOSE_EVENTS", 0x80000000}, 1249 {"VERBOSE_ALL", 0xF0000000}, 1250 {NULL, 0} 1251 }; 1252 1253 static void 1254 acpi_parse_debug(char *cp, struct debugtag *tag, UINT32 *flag) 1255 { 1256 char *ep; 1257 int i, l; 1258 int set; 1259 1260 while (*cp) { 1261 if (isspace(*cp)) { 1262 cp++; 1263 continue; 1264 } 1265 ep = cp; 1266 while (*ep && !isspace(*ep)) 1267 ep++; 1268 if (*cp == '!') { 1269 set = 0; 1270 cp++; 1271 if (cp == ep) 1272 continue; 1273 } else { 1274 set = 1; 1275 } 1276 l = ep - cp; 1277 for (i = 0; tag[i].name != NULL; i++) { 1278 if (!strncmp(cp, tag[i].name, l)) { 1279 if (set) { 1280 *flag |= tag[i].value; 1281 } else { 1282 *flag &= ~tag[i].value; 1283 } 1284 printf("ACPI_DEBUG: set '%s'\n", tag[i].name); 1285 } 1286 } 1287 cp = ep; 1288 } 1289 } 1290 1291 static void 1292 acpi_set_debugging(void) 1293 { 1294 char *cp; 1295 1296 AcpiDbgLayer = 0; 1297 AcpiDbgLevel = 0; 1298 if ((cp = getenv("debug.acpi.layer")) != NULL) 1299 acpi_parse_debug(cp, &dbg_layer[0], &AcpiDbgLayer); 1300 if ((cp = getenv("debug.acpi.level")) != NULL) 1301 acpi_parse_debug(cp, &dbg_level[0], &AcpiDbgLevel); 1302 1303 printf("ACPI debug layer 0x%x debug level 0x%x\n", AcpiDbgLayer, AcpiDbgLevel); 1304 } 1305 #endif 1306