1 /* 2 * acpi_bus.c - ACPI Bus Driver ($Revision: 80 $) 3 * 4 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 5 * 6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or (at 11 * your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 * 22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 */ 24 25 /* 26 * Modified for ReactOS and latest ACPICA 27 * Copyright (C)2009 Samuel Serapion 28 */ 29 30 #include <precomp.h> 31 32 #define NDEBUG 33 #include <debug.h> 34 35 #define _COMPONENT ACPI_BUS_COMPONENT 36 ACPI_MODULE_NAME ("acpi_bus") 37 38 #define WALK_UP 0 39 #define WALK_DOWN 1 40 41 #define STRUCT_TO_INT(s) (*((int*)&s)) 42 #define HAS_CHILDREN(d) ((d)->children.next != &((d)->children)) 43 #define HAS_SIBLINGS(d) (((d)->parent) && ((d)->node.next != &(d)->parent->children)) 44 #define NODE_TO_DEVICE(n) (list_entry(n, struct acpi_device, node)) 45 46 int event_is_open; 47 extern void acpi_pic_sci_set_trigger(unsigned int irq, UINT16 trigger); 48 49 typedef int (*acpi_bus_walk_callback)(struct acpi_device*, int, void*); 50 51 struct acpi_device *acpi_root; 52 KSPIN_LOCK acpi_bus_event_lock; 53 LIST_HEAD(acpi_bus_event_list); 54 //DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); 55 KEVENT AcpiEventQueue; 56 KDPC event_dpc; 57 58 int ProcessorCount, PowerDeviceCount, PowerButtonCount, FixedPowerButtonCount; 59 int FixedSleepButtonCount, SleepButtonCount, ThermalZoneCount; 60 61 static int 62 acpi_device_register ( 63 struct acpi_device *device, 64 struct acpi_device *parent) 65 { 66 int result = 0; 67 68 if (!device) 69 return_VALUE(AE_BAD_PARAMETER); 70 71 return_VALUE(result); 72 } 73 74 75 static int 76 acpi_device_unregister ( 77 struct acpi_device *device) 78 { 79 if (!device) 80 return_VALUE(AE_BAD_PARAMETER); 81 82 #ifdef CONFIG_LDM 83 put_device(&device->dev); 84 #endif /*CONFIG_LDM*/ 85 86 return_VALUE(0); 87 } 88 89 90 /* -------------------------------------------------------------------------- 91 Device Management 92 -------------------------------------------------------------------------- */ 93 94 void 95 acpi_bus_data_handler ( 96 ACPI_HANDLE handle, 97 void *context) 98 { 99 DPRINT1("acpi_bus_data_handler not implemented\n"); 100 101 /* TBD */ 102 103 return; 104 } 105 106 107 int 108 acpi_bus_get_device ( 109 ACPI_HANDLE handle, 110 struct acpi_device **device) 111 { 112 ACPI_STATUS status = AE_OK; 113 114 if (!device) 115 return_VALUE(AE_BAD_PARAMETER); 116 117 /* TBD: Support fixed-feature devices */ 118 119 status = AcpiGetData(handle, acpi_bus_data_handler, (void**)device); 120 if (ACPI_FAILURE(status) || !*device) { 121 DPRINT( "Error getting context for object [%p]\n", 122 handle); 123 return_VALUE(AE_NOT_FOUND); 124 } 125 126 return 0; 127 } 128 129 ACPI_STATUS acpi_bus_get_status_handle(ACPI_HANDLE handle, 130 unsigned long long *sta) 131 { 132 ACPI_STATUS status; 133 134 status = acpi_evaluate_integer(handle, "_STA", NULL, sta); 135 if (ACPI_SUCCESS(status)) 136 return AE_OK; 137 138 if (status == AE_NOT_FOUND) { 139 *sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | 140 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; 141 return AE_OK; 142 } 143 return status; 144 } 145 146 int 147 acpi_bus_get_status ( 148 struct acpi_device *device) 149 { 150 ACPI_STATUS status; 151 unsigned long long sta; 152 153 status = acpi_bus_get_status_handle(device->handle, &sta); 154 if (ACPI_FAILURE(status)) 155 return -1; 156 157 STRUCT_TO_INT(device->status) = (int) sta; 158 159 if (device->status.functional && !device->status.present) { 160 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: " 161 "functional but not present;\n", 162 device->pnp.bus_id, 163 (UINT32) STRUCT_TO_INT(device->status))); 164 } 165 166 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", 167 device->pnp.bus_id, 168 (UINT32) STRUCT_TO_INT(device->status))); 169 return 0; 170 } 171 172 void acpi_bus_private_data_handler(ACPI_HANDLE handle, 173 void *context) 174 { 175 return; 176 } 177 178 int acpi_bus_get_private_data(ACPI_HANDLE handle, void **data) 179 { 180 ACPI_STATUS status = AE_OK; 181 182 if (!*data) 183 return -1; 184 185 status = AcpiGetData(handle, acpi_bus_private_data_handler, data); 186 if (ACPI_FAILURE(status) || !*data) { 187 DPRINT("No context for object [%p]\n", handle); 188 return -1; 189 } 190 191 return 0; 192 } 193 /* -------------------------------------------------------------------------- 194 Power Management 195 -------------------------------------------------------------------------- */ 196 197 int 198 acpi_bus_get_power ( 199 ACPI_HANDLE handle, 200 int *state) 201 { 202 int result = 0; 203 ACPI_STATUS status = 0; 204 struct acpi_device *device = NULL; 205 unsigned long long psc = 0; 206 207 result = acpi_bus_get_device(handle, &device); 208 if (result) 209 return_VALUE(result); 210 211 *state = ACPI_STATE_UNKNOWN; 212 213 if (!device->flags.power_manageable) { 214 /* TBD: Non-recursive algorithm for walking up hierarchy */ 215 if (device->parent) 216 *state = device->parent->power.state; 217 else 218 *state = ACPI_STATE_D0; 219 } 220 else { 221 /* 222 * Get the device's power state either directly (via _PSC) or 223 * indirectly (via power resources). 224 */ 225 if (device->power.flags.explicit_get) { 226 status = acpi_evaluate_integer(device->handle, "_PSC", 227 NULL, &psc); 228 if (ACPI_FAILURE(status)) 229 return_VALUE(AE_NOT_FOUND); 230 device->power.state = (int) psc; 231 } 232 else if (device->power.flags.power_resources) { 233 result = acpi_power_get_inferred_state(device); 234 if (result) 235 return_VALUE(result); 236 } 237 238 *state = device->power.state; 239 } 240 241 DPRINT("Device [%s] power state is D%d\n", 242 device->pnp.bus_id, device->power.state); 243 244 return_VALUE(0); 245 } 246 247 248 int 249 acpi_bus_set_power ( 250 ACPI_HANDLE handle, 251 int state) 252 { 253 int result = 0; 254 ACPI_STATUS status = AE_OK; 255 struct acpi_device *device = NULL; 256 char object_name[5] = {'_','P','S','0'+state,'\0'}; 257 258 259 result = acpi_bus_get_device(handle, &device); 260 if (result) 261 return_VALUE(result); 262 263 if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) 264 return_VALUE(AE_BAD_PARAMETER); 265 266 /* Make sure this is a valid target state */ 267 268 if (!device->flags.power_manageable) { 269 DPRINT1( "Device is not power manageable\n"); 270 return_VALUE(AE_NOT_FOUND); 271 } 272 /* 273 * Get device's current power state 274 */ 275 //if (!acpi_power_nocheck) { 276 /* 277 * Maybe the incorrect power state is returned on the bogus 278 * bios, which is different with the real power state. 279 * For example: the bios returns D0 state and the real power 280 * state is D3. OS expects to set the device to D0 state. In 281 * such case if OS uses the power state returned by the BIOS, 282 * the device can't be transisted to the correct power state. 283 * So if the acpi_power_nocheck is set, it is unnecessary to 284 * get the power state by calling acpi_bus_get_power. 285 */ 286 acpi_bus_get_power(device->handle, &device->power.state); 287 //} 288 289 if ((state == device->power.state) && !device->flags.force_power_state) { 290 DPRINT1("Device is already at D%d\n", state); 291 return 0; 292 } 293 if (!device->power.states[state].flags.valid) { 294 DPRINT1( "Device does not support D%d\n", state); 295 return AE_NOT_FOUND; 296 } 297 if (device->parent && (state < device->parent->power.state)) { 298 DPRINT1( "Cannot set device to a higher-powered state than parent\n"); 299 return AE_NOT_FOUND; 300 } 301 302 /* 303 * Transition Power 304 * ---------------- 305 * On transitions to a high-powered state we first apply power (via 306 * power resources) then evalute _PSx. Conversely for transitions to 307 * a lower-powered state. 308 */ 309 if (state < device->power.state) { 310 if (device->power.flags.power_resources) { 311 result = acpi_power_transition(device, state); 312 if (result) 313 goto end; 314 } 315 if (device->power.states[state].flags.explicit_set) { 316 status = AcpiEvaluateObject(device->handle, 317 object_name, NULL, NULL); 318 if (ACPI_FAILURE(status)) { 319 result = AE_NOT_FOUND; 320 goto end; 321 } 322 } 323 } 324 else { 325 if (device->power.states[state].flags.explicit_set) { 326 status = AcpiEvaluateObject(device->handle, 327 object_name, NULL, NULL); 328 if (ACPI_FAILURE(status)) { 329 result = AE_NOT_FOUND; 330 goto end; 331 } 332 } 333 if (device->power.flags.power_resources) { 334 result = acpi_power_transition(device, state); 335 if (result) 336 goto end; 337 } 338 } 339 340 end: 341 if (result) 342 DPRINT( "Error transitioning device [%s] to D%d\n", 343 device->pnp.bus_id, state); 344 else 345 DPRINT("Device [%s] transitioned to D%d\n", 346 device->pnp.bus_id, state); 347 348 return result; 349 } 350 351 BOOLEAN acpi_bus_power_manageable(ACPI_HANDLE handle) 352 { 353 struct acpi_device *device; 354 int result; 355 356 result = acpi_bus_get_device(handle, &device); 357 return result ? 0 : device->flags.power_manageable; 358 } 359 360 BOOLEAN acpi_bus_can_wakeup(ACPI_HANDLE handle) 361 { 362 struct acpi_device *device; 363 int result; 364 365 result = acpi_bus_get_device(handle, &device); 366 return result ? 0 : device->wakeup.flags.valid; 367 } 368 369 static int 370 acpi_bus_get_power_flags ( 371 struct acpi_device *device) 372 { 373 ACPI_STATUS status = 0; 374 ACPI_HANDLE handle = 0; 375 UINT32 i = 0; 376 377 if (!device) 378 return AE_NOT_FOUND; 379 380 /* 381 * Power Management Flags 382 */ 383 status = AcpiGetHandle(device->handle, "_PSC", &handle); 384 if (ACPI_SUCCESS(status)) 385 device->power.flags.explicit_get = 1; 386 status = AcpiGetHandle(device->handle, "_IRC", &handle); 387 if (ACPI_SUCCESS(status)) 388 device->power.flags.inrush_current = 1; 389 status = AcpiGetHandle(device->handle, "_PRW", &handle); 390 if (ACPI_SUCCESS(status)) 391 device->flags.wake_capable = 1; 392 393 /* 394 * Enumerate supported power management states 395 */ 396 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { 397 struct acpi_device_power_state *ps = &device->power.states[i]; 398 char object_name[5] = {'_','P','R','0'+i,'\0'}; 399 400 /* Evaluate "_PRx" to se if power resources are referenced */ 401 status = acpi_evaluate_reference(device->handle, object_name, NULL, 402 &ps->resources); 403 if (ACPI_SUCCESS(status) && ps->resources.count) { 404 device->power.flags.power_resources = 1; 405 ps->flags.valid = 1; 406 } 407 408 /* Evaluate "_PSx" to see if we can do explicit sets */ 409 object_name[2] = 'S'; 410 status = AcpiGetHandle(device->handle, object_name, &handle); 411 if (ACPI_SUCCESS(status)) { 412 ps->flags.explicit_set = 1; 413 ps->flags.valid = 1; 414 } 415 416 /* State is valid if we have some power control */ 417 if (ps->resources.count || ps->flags.explicit_set) 418 ps->flags.valid = 1; 419 420 ps->power = -1; /* Unknown - driver assigned */ 421 ps->latency = -1; /* Unknown - driver assigned */ 422 } 423 424 /* Set defaults for D0 and D3 states (always valid) */ 425 device->power.states[ACPI_STATE_D0].flags.valid = 1; 426 device->power.states[ACPI_STATE_D0].power = 100; 427 device->power.states[ACPI_STATE_D3].flags.valid = 1; 428 device->power.states[ACPI_STATE_D3].power = 0; 429 430 device->power.state = ACPI_STATE_UNKNOWN; 431 432 return 0; 433 } 434 435 /* -------------------------------------------------------------------------- 436 Performance Management 437 -------------------------------------------------------------------------- */ 438 439 static int 440 acpi_bus_get_perf_flags ( 441 struct acpi_device *device) 442 { 443 if (!device) 444 return AE_NOT_FOUND; 445 446 device->performance.state = ACPI_STATE_UNKNOWN; 447 448 return 0; 449 } 450 451 452 /* -------------------------------------------------------------------------- 453 Event Management 454 -------------------------------------------------------------------------- */ 455 456 void 457 NTAPI 458 acpi_bus_generate_event_dpc(PKDPC Dpc, 459 PVOID DeferredContext, 460 PVOID SystemArgument1, 461 PVOID SystemArgument2) 462 { 463 struct acpi_bus_event *event; 464 struct acpi_device *device = SystemArgument1; 465 ULONG_PTR TypeData = (ULONG_PTR)SystemArgument2; 466 KIRQL OldIrql; 467 468 event = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct acpi_bus_event), 'epcA'); 469 if (!event) 470 return; 471 472 sprintf(event->device_class, "%s", device->pnp.device_class); 473 sprintf(event->bus_id, "%s", device->pnp.bus_id); 474 event->type = (TypeData & 0xFF000000) >> 24; 475 event->data = (TypeData & 0x00FFFFFF); 476 477 KeAcquireSpinLock(&acpi_bus_event_lock, &OldIrql); 478 list_add_tail(&event->node, &acpi_bus_event_list); 479 KeReleaseSpinLock(&acpi_bus_event_lock, OldIrql); 480 481 KeSetEvent(&AcpiEventQueue, IO_NO_INCREMENT, FALSE); 482 } 483 484 int 485 acpi_bus_generate_event ( 486 struct acpi_device *device, 487 UINT8 type, 488 int data) 489 { 490 ULONG_PTR TypeData = 0; 491 492 DPRINT("acpi_bus_generate_event\n"); 493 494 if (!device) 495 return_VALUE(AE_BAD_PARAMETER); 496 497 /* drop event on the floor if no one's listening */ 498 if (!event_is_open) 499 return_VALUE(0); 500 501 /* Data shouldn't even get near 24 bits */ 502 ASSERT(!(data & 0xFF000000)); 503 504 TypeData = data; 505 TypeData |= type << 24; 506 507 KeInsertQueueDpc(&event_dpc, device, (PVOID)TypeData); 508 509 return_VALUE(0); 510 } 511 512 int 513 acpi_bus_receive_event ( 514 struct acpi_bus_event *event) 515 { 516 // unsigned long flags = 0; 517 struct acpi_bus_event *entry = NULL; 518 KIRQL OldIrql; 519 520 //DECLARE_WAITQUEUE(wait, current); 521 522 DPRINT("acpi_bus_receive_event\n"); 523 524 if (!event) 525 return AE_BAD_PARAMETER; 526 527 event_is_open++; 528 KeWaitForSingleObject(&AcpiEventQueue, 529 Executive, 530 KernelMode, 531 FALSE, 532 NULL); 533 event_is_open--; 534 KeClearEvent(&AcpiEventQueue); 535 536 if (list_empty(&acpi_bus_event_list)) 537 return_VALUE(AE_NOT_FOUND); 538 539 // spin_lock_irqsave(&acpi_bus_event_lock, flags); 540 KeAcquireSpinLock(&acpi_bus_event_lock, &OldIrql); 541 entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node); 542 if (entry) 543 list_del(&entry->node); 544 KeReleaseSpinLock(&acpi_bus_event_lock, OldIrql); 545 // spin_unlock_irqrestore(&acpi_bus_event_lock, flags); 546 547 if (!entry) 548 return_VALUE(AE_NOT_FOUND); 549 550 memcpy(event, entry, sizeof(struct acpi_bus_event)); 551 552 ExFreePoolWithTag(entry, 'epcA'); 553 return_VALUE(0); 554 } 555 556 557 /* -------------------------------------------------------------------------- 558 Namespace Management 559 -------------------------------------------------------------------------- */ 560 561 562 /** 563 * acpi_bus_walk 564 * ------------- 565 * Used to walk the ACPI Bus's device namespace. Can walk down (depth-first) 566 * or up. Able to parse starting at any node in the namespace. Note that a 567 * callback return value of -249 will terminate the walk. 568 * 569 * @start: starting point 570 * callback: function to call for every device encountered while parsing 571 * direction: direction to parse (up or down) 572 * @data: context for this search operation 573 */ 574 static int 575 acpi_bus_walk ( 576 struct acpi_device *start, 577 acpi_bus_walk_callback callback, 578 int direction, 579 void *data) 580 { 581 int result = 0; 582 int level = 0; 583 struct acpi_device *device = NULL; 584 585 if (!start || !callback) 586 return AE_BAD_PARAMETER; 587 588 device = start; 589 590 /* 591 * Parse Namespace 592 * --------------- 593 * Parse a given subtree (specified by start) in the given direction. 594 * Walking 'up' simply means that we execute the callback on leaf 595 * devices prior to their parents (useful for things like removing 596 * or powering down a subtree). 597 */ 598 599 while (device) { 600 601 if (direction == WALK_DOWN) 602 if (-249 == callback(device, level, data)) 603 break; 604 605 /* Depth First */ 606 607 if (HAS_CHILDREN(device)) { 608 device = NODE_TO_DEVICE(device->children.next); 609 ++level; 610 continue; 611 } 612 613 if (direction == WALK_UP) 614 if (-249 == callback(device, level, data)) 615 break; 616 617 /* Now Breadth */ 618 619 if (HAS_SIBLINGS(device)) { 620 device = NODE_TO_DEVICE(device->node.next); 621 continue; 622 } 623 624 /* Scope Exhausted - Find Next */ 625 626 while ((device = device->parent)) { 627 --level; 628 if (HAS_SIBLINGS(device)) { 629 device = NODE_TO_DEVICE(device->node.next); 630 break; 631 } 632 } 633 } 634 635 if ((direction == WALK_UP) && (result == 0)) 636 callback(start, level, data); 637 638 return result; 639 } 640 641 642 /* -------------------------------------------------------------------------- 643 Notification Handling 644 -------------------------------------------------------------------------- */ 645 646 static void 647 acpi_bus_check_device (ACPI_HANDLE handle) 648 { 649 struct acpi_device *device; 650 ACPI_STATUS status = 0; 651 struct acpi_device_status old_status; 652 653 if (acpi_bus_get_device(handle, &device)) 654 return; 655 if (!device) 656 return; 657 658 old_status = device->status; 659 660 /* 661 * Make sure this device's parent is present before we go about 662 * messing with the device. 663 */ 664 if (device->parent && !device->parent->status.present) { 665 device->status = device->parent->status; 666 return; 667 } 668 669 status = acpi_bus_get_status(device); 670 if (ACPI_FAILURE(status)) 671 return; 672 673 if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) 674 return; 675 676 677 /* 678 * Device Insertion/Removal 679 */ 680 if ((device->status.present) && !(old_status.present)) { 681 DPRINT("Device insertion detected\n"); 682 /* TBD: Handle device insertion */ 683 } 684 else if (!(device->status.present) && (old_status.present)) { 685 DPRINT("Device removal detected\n"); 686 /* TBD: Handle device removal */ 687 } 688 689 } 690 691 692 static void 693 acpi_bus_check_scope (ACPI_HANDLE handle) 694 { 695 /* Status Change? */ 696 acpi_bus_check_device(handle); 697 698 /* 699 * TBD: Enumerate child devices within this device's scope and 700 * run acpi_bus_check_device()'s on them. 701 */ 702 } 703 704 705 /** 706 * acpi_bus_notify 707 * --------------- 708 * Callback for all 'system-level' device notifications (values 0x00-0x7F). 709 */ 710 static void 711 acpi_bus_notify ( 712 ACPI_HANDLE handle, 713 UINT32 type, 714 void *data) 715 { 716 struct acpi_device *device = NULL; 717 struct acpi_driver *driver; 718 719 DPRINT1("Notification %#02x to handle %p\n", type, handle); 720 721 //blocking_notifier_call_chain(&acpi_bus_notify_list, 722 // type, (void *)handle); 723 724 acpi_bus_get_device(handle, &device); 725 726 switch (type) { 727 728 case ACPI_NOTIFY_BUS_CHECK: 729 DPRINT("Received BUS CHECK notification for device [%s]\n", 730 device ? device->pnp.bus_id : "n/a"); 731 acpi_bus_check_scope(handle); 732 /* 733 * TBD: We'll need to outsource certain events to non-ACPI 734 * drivers via the device manager (device.c). 735 */ 736 break; 737 738 case ACPI_NOTIFY_DEVICE_CHECK: 739 DPRINT("Received DEVICE CHECK notification for device [%s]\n", 740 device ? device->pnp.bus_id : "n/a"); 741 acpi_bus_check_device(handle); 742 /* 743 * TBD: We'll need to outsource certain events to non-ACPI 744 * drivers via the device manager (device.c). 745 */ 746 break; 747 748 case ACPI_NOTIFY_DEVICE_WAKE: 749 DPRINT("Received DEVICE WAKE notification for device [%s]\n", 750 device ? device->pnp.bus_id : "n/a"); 751 acpi_bus_check_device(handle); 752 /* 753 * TBD: We'll need to outsource certain events to non-ACPI 754 * drivers via the device manager (device.c). 755 */ 756 break; 757 758 case ACPI_NOTIFY_EJECT_REQUEST: 759 DPRINT1("Received EJECT REQUEST notification for device [%s]\n", 760 device ? device->pnp.bus_id : "n/a"); 761 /* TBD */ 762 break; 763 764 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: 765 DPRINT1("Received DEVICE CHECK LIGHT notification for device [%s]\n", 766 device ? device->pnp.bus_id : "n/a"); 767 /* TBD: Exactly what does 'light' mean? */ 768 break; 769 770 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 771 DPRINT1("Received FREQUENCY MISMATCH notification for device [%s]\n", 772 device ? device->pnp.bus_id : "n/a"); 773 /* TBD */ 774 break; 775 776 case ACPI_NOTIFY_BUS_MODE_MISMATCH: 777 DPRINT1("Received BUS MODE MISMATCH notification for device [%s]\n", 778 device ? device->pnp.bus_id : "n/a"); 779 /* TBD */ 780 break; 781 782 case ACPI_NOTIFY_POWER_FAULT: 783 DPRINT1("Received POWER FAULT notification for device [%s]\n", 784 device ? device->pnp.bus_id : "n/a"); 785 /* TBD */ 786 break; 787 788 default: 789 DPRINT1("Received unknown/unsupported notification [%08x] for device [%s]\n", 790 type, device ? device->pnp.bus_id : "n/a"); 791 break; 792 } 793 794 if (device) { 795 driver = device->driver; 796 if (driver && driver->ops.notify && 797 (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) 798 driver->ops.notify(device, type); 799 } 800 } 801 802 803 /* -------------------------------------------------------------------------- 804 Driver Management 805 -------------------------------------------------------------------------- */ 806 807 808 static LIST_HEAD(acpi_bus_drivers); 809 //static DECLARE_MUTEX(acpi_bus_drivers_lock); 810 static FAST_MUTEX acpi_bus_drivers_lock; 811 812 813 /** 814 * acpi_bus_match 815 * -------------- 816 * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it 817 * matches the specified driver's criteria. 818 */ 819 static int 820 acpi_bus_match ( 821 struct acpi_device *device, 822 struct acpi_driver *driver) 823 { 824 int error = 0; 825 826 if (device->flags.hardware_id) 827 if (strstr(driver->ids, device->pnp.hardware_id)) 828 goto Done; 829 830 if (device->flags.compatible_ids) { 831 ACPI_PNP_DEVICE_ID_LIST *cid_list = device->pnp.cid_list; 832 int i; 833 834 /* compare multiple _CID entries against driver ids */ 835 for (i = 0; i < cid_list->Count; i++) 836 { 837 if (strstr(driver->ids, cid_list->Ids[i].String)) 838 goto Done; 839 } 840 } 841 error = -2; 842 843 Done: 844 845 return error; 846 } 847 848 849 /** 850 * acpi_bus_driver_init 851 * -------------------- 852 * Used to initialize a device via its device driver. Called whenever a 853 * driver is bound to a device. Invokes the driver's add() and start() ops. 854 */ 855 static int 856 acpi_bus_driver_init ( 857 struct acpi_device *device, 858 struct acpi_driver *driver) 859 { 860 int result = 0; 861 862 if (!device || !driver) 863 return_VALUE(AE_BAD_PARAMETER); 864 865 if (!driver->ops.add) 866 return_VALUE(-38); 867 868 result = driver->ops.add(device); 869 if (result) { 870 device->driver = NULL; 871 //acpi_driver_data(device) = NULL; 872 return_VALUE(result); 873 } 874 875 device->driver = driver; 876 877 /* 878 * TBD - Configuration Management: Assign resources to device based 879 * upon possible configuration and currently allocated resources. 880 */ 881 882 if (driver->ops.start) { 883 result = driver->ops.start(device); 884 if (result && driver->ops.remove) 885 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); 886 return_VALUE(result); 887 } 888 889 DPRINT("Driver successfully bound to device\n"); 890 891 if (driver->ops.scan) { 892 driver->ops.scan(device); 893 } 894 895 return_VALUE(0); 896 } 897 898 899 /** 900 * acpi_bus_attach 901 * ------------- 902 * Callback for acpi_bus_walk() used to find devices that match a specific 903 * driver's criteria and then attach the driver. 904 */ 905 static int 906 acpi_bus_attach ( 907 struct acpi_device *device, 908 int level, 909 void *data) 910 { 911 int result = 0; 912 struct acpi_driver *driver = NULL; 913 914 if (!device || !data) 915 return_VALUE(AE_BAD_PARAMETER); 916 917 driver = (struct acpi_driver *) data; 918 919 if (device->driver) 920 return_VALUE(-9); 921 922 if (!device->status.present) 923 return_VALUE(AE_NOT_FOUND); 924 925 result = acpi_bus_match(device, driver); 926 if (result) 927 return_VALUE(result); 928 929 DPRINT("Found driver [%s] for device [%s]\n", 930 driver->name, device->pnp.bus_id); 931 932 result = acpi_bus_driver_init(device, driver); 933 if (result) 934 return_VALUE(result); 935 936 down(&acpi_bus_drivers_lock); 937 ++driver->references; 938 up(&acpi_bus_drivers_lock); 939 940 return_VALUE(0); 941 } 942 943 944 /** 945 * acpi_bus_unattach 946 * ----------------- 947 * Callback for acpi_bus_walk() used to find devices that match a specific 948 * driver's criteria and unattach the driver. 949 */ 950 static int 951 acpi_bus_unattach ( 952 struct acpi_device *device, 953 int level, 954 void *data) 955 { 956 int result = 0; 957 struct acpi_driver *driver = (struct acpi_driver *) data; 958 959 if (!device || !driver) 960 return_VALUE(AE_BAD_PARAMETER); 961 962 if (device->driver != driver) 963 return_VALUE(-6); 964 965 if (!driver->ops.remove) 966 return_VALUE(-23); 967 968 result = driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); 969 if (result) 970 return_VALUE(result); 971 972 device->driver = NULL; 973 acpi_driver_data(device) = NULL; 974 975 down(&acpi_bus_drivers_lock); 976 driver->references--; 977 up(&acpi_bus_drivers_lock); 978 979 return_VALUE(0); 980 } 981 982 983 /** 984 * acpi_bus_find_driver 985 * -------------------- 986 * Parses the list of registered drivers looking for a driver applicable for 987 * the specified device. 988 */ 989 static int 990 acpi_bus_find_driver ( 991 struct acpi_device *device) 992 { 993 int result = AE_NOT_FOUND; 994 struct list_head *entry = NULL; 995 struct acpi_driver *driver = NULL; 996 997 if (!device || device->driver) 998 return_VALUE(AE_BAD_PARAMETER); 999 1000 down(&acpi_bus_drivers_lock); 1001 1002 list_for_each(entry, &acpi_bus_drivers) { 1003 1004 driver = list_entry(entry, struct acpi_driver, node); 1005 1006 if (acpi_bus_match(device, driver)) 1007 continue; 1008 1009 result = acpi_bus_driver_init(device, driver); 1010 if (!result) 1011 ++driver->references; 1012 1013 break; 1014 } 1015 1016 up(&acpi_bus_drivers_lock); 1017 1018 return_VALUE(result); 1019 } 1020 1021 1022 /** 1023 * acpi_bus_register_driver 1024 * ------------------------ 1025 * Registers a driver with the ACPI bus. Searches the namespace for all 1026 * devices that match the driver's criteria and binds. 1027 */ 1028 int 1029 acpi_bus_register_driver ( 1030 struct acpi_driver *driver) 1031 { 1032 if (!driver) 1033 return_VALUE(AE_BAD_PARAMETER); 1034 1035 //if (acpi_disabled) 1036 // return_VALUE(AE_NOT_FOUND); 1037 1038 down(&acpi_bus_drivers_lock); 1039 list_add_tail(&driver->node, &acpi_bus_drivers); 1040 up(&acpi_bus_drivers_lock); 1041 1042 acpi_bus_walk(acpi_root, acpi_bus_attach, 1043 WALK_DOWN, driver); 1044 1045 return_VALUE(driver->references); 1046 } 1047 1048 1049 /** 1050 * acpi_bus_unregister_driver 1051 * -------------------------- 1052 * Unregisters a driver with the ACPI bus. Searches the namespace for all 1053 * devices that match the driver's criteria and unbinds. 1054 */ 1055 void 1056 acpi_bus_unregister_driver ( 1057 struct acpi_driver *driver) 1058 { 1059 if (!driver) 1060 return; 1061 1062 acpi_bus_walk(acpi_root, acpi_bus_unattach, WALK_UP, driver); 1063 1064 if (driver->references) 1065 return; 1066 1067 down(&acpi_bus_drivers_lock); 1068 list_del(&driver->node); 1069 up(&acpi_bus_drivers_lock); 1070 1071 return; 1072 } 1073 1074 1075 /* -------------------------------------------------------------------------- 1076 Device Enumeration 1077 -------------------------------------------------------------------------- */ 1078 1079 static int 1080 acpi_bus_get_flags ( 1081 struct acpi_device *device) 1082 { 1083 ACPI_STATUS status = AE_OK; 1084 ACPI_HANDLE temp = NULL; 1085 1086 /* Presence of _STA indicates 'dynamic_status' */ 1087 status = AcpiGetHandle(device->handle, "_STA", &temp); 1088 if (ACPI_SUCCESS(status)) 1089 device->flags.dynamic_status = 1; 1090 1091 /* Presence of _CID indicates 'compatible_ids' */ 1092 status = AcpiGetHandle(device->handle, "_CID", &temp); 1093 if (ACPI_SUCCESS(status)) 1094 device->flags.compatible_ids = 1; 1095 1096 /* Presence of _RMV indicates 'removable' */ 1097 status = AcpiGetHandle(device->handle, "_RMV", &temp); 1098 if (ACPI_SUCCESS(status)) 1099 device->flags.removable = 1; 1100 1101 /* Presence of _EJD|_EJ0 indicates 'ejectable' */ 1102 status = AcpiGetHandle(device->handle, "_EJD", &temp); 1103 if (ACPI_SUCCESS(status)) 1104 device->flags.ejectable = 1; 1105 else { 1106 status = AcpiGetHandle(device->handle, "_EJ0", &temp); 1107 if (ACPI_SUCCESS(status)) 1108 device->flags.ejectable = 1; 1109 } 1110 1111 /* Presence of _LCK indicates 'lockable' */ 1112 status = AcpiGetHandle(device->handle, "_LCK", &temp); 1113 if (ACPI_SUCCESS(status)) 1114 device->flags.lockable = 1; 1115 1116 /* Presence of _PS0|_PR0 indicates 'power manageable' */ 1117 status = AcpiGetHandle(device->handle, "_PS0", &temp); 1118 if (ACPI_FAILURE(status)) 1119 status = AcpiGetHandle(device->handle, "_PR0", &temp); 1120 if (ACPI_SUCCESS(status)) 1121 device->flags.power_manageable = 1; 1122 1123 /* TBD: Performance management */ 1124 1125 return_VALUE(0); 1126 } 1127 1128 1129 int 1130 acpi_bus_add ( 1131 struct acpi_device **child, 1132 struct acpi_device *parent, 1133 ACPI_HANDLE handle, 1134 int type) 1135 { 1136 int result = 0; 1137 ACPI_STATUS status = AE_OK; 1138 struct acpi_device *device = NULL; 1139 char bus_id[5] = {'?',0}; 1140 ACPI_BUFFER buffer; 1141 ACPI_DEVICE_INFO *info = NULL; 1142 char *hid = NULL; 1143 char *uid = NULL; 1144 ACPI_PNP_DEVICE_ID_LIST *cid_list = NULL; 1145 int i = 0; 1146 acpi_unique_id static_uid_buffer; 1147 1148 if (!child) 1149 return_VALUE(AE_BAD_PARAMETER); 1150 1151 device = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct acpi_device), 'DpcA'); 1152 if (!device) { 1153 DPRINT1("Memory allocation error\n"); 1154 return_VALUE(-12); 1155 } 1156 memset(device, 0, sizeof(struct acpi_device)); 1157 1158 device->handle = handle; 1159 device->parent = parent; 1160 1161 /* 1162 * Bus ID 1163 * ------ 1164 * The device's Bus ID is simply the object name. 1165 * TBD: Shouldn't this value be unique (within the ACPI namespace)? 1166 */ 1167 switch (type) { 1168 case ACPI_BUS_TYPE_SYSTEM: 1169 snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", "ACPI"); 1170 break; 1171 case ACPI_BUS_TYPE_POWER_BUTTONF: 1172 case ACPI_BUS_TYPE_POWER_BUTTON: 1173 snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", "PWRF"); 1174 break; 1175 case ACPI_BUS_TYPE_SLEEP_BUTTONF: 1176 case ACPI_BUS_TYPE_SLEEP_BUTTON: 1177 snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", "SLPF"); 1178 break; 1179 default: 1180 buffer.Length = sizeof(bus_id); 1181 buffer.Pointer = bus_id; 1182 AcpiGetName(handle, ACPI_SINGLE_NAME, &buffer); 1183 1184 1185 /* Clean up trailing underscores (if any) */ 1186 for (i = 3; i > 1; i--) { 1187 if (bus_id[i] == '_') 1188 bus_id[i] = '\0'; 1189 else 1190 break; 1191 } 1192 snprintf(device->pnp.bus_id, sizeof(device->pnp.bus_id), "%s", bus_id); 1193 buffer.Pointer = NULL; 1194 1195 break; 1196 } 1197 1198 /* 1199 * Flags 1200 * ----- 1201 * Get prior to calling acpi_bus_get_status() so we know whether 1202 * or not _STA is present. Note that we only look for object 1203 * handles -- cannot evaluate objects until we know the device is 1204 * present and properly initialized. 1205 */ 1206 result = acpi_bus_get_flags(device); 1207 if (result) 1208 goto end; 1209 1210 /* 1211 * Status 1212 * ------ 1213 * See if the device is present. We always assume that non-Device() 1214 * objects (e.g. thermal zones, power resources, processors, etc.) are 1215 * present, functioning, etc. (at least when parent object is present). 1216 * Note that _STA has a different meaning for some objects (e.g. 1217 * power resources) so we need to be careful how we use it. 1218 */ 1219 switch (type) { 1220 case ACPI_BUS_TYPE_DEVICE: 1221 result = acpi_bus_get_status(device); 1222 if (result) 1223 goto end; 1224 break; 1225 default: 1226 STRUCT_TO_INT(device->status) = 0x0F; 1227 break; 1228 } 1229 if (!device->status.present) { 1230 result = -2; 1231 goto end; 1232 } 1233 1234 /* 1235 * Initialize Device 1236 * ----------------- 1237 * TBD: Synch with Core's enumeration/initialization process. 1238 */ 1239 1240 /* 1241 * Hardware ID, Unique ID, & Bus Address 1242 * ------------------------------------- 1243 */ 1244 switch (type) { 1245 case ACPI_BUS_TYPE_DEVICE: 1246 status = AcpiGetObjectInfo(handle,&info); 1247 if (ACPI_FAILURE(status)) { 1248 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1249 "Error reading device info\n")); 1250 result = AE_NOT_FOUND; 1251 info = NULL; 1252 goto end; 1253 } 1254 if (info->Valid & ACPI_VALID_HID) 1255 hid = info->HardwareId.String; 1256 if (info->Valid & ACPI_VALID_UID) 1257 uid = info->UniqueId.String; 1258 if (info->Valid & ACPI_VALID_CID) { 1259 cid_list = &info->CompatibleIdList; 1260 device->pnp.cid_list = ExAllocatePoolWithTag(NonPagedPool,cid_list->ListSize, 'DpcA'); 1261 if (device->pnp.cid_list) { 1262 char *p = (char *)&device->pnp.cid_list->Ids[cid_list->Count]; 1263 device->pnp.cid_list->Count = cid_list->Count; 1264 device->pnp.cid_list->ListSize = cid_list->ListSize; 1265 for (i = 0; i < cid_list->Count; i++) { 1266 device->pnp.cid_list->Ids[i].Length = cid_list->Ids[i].Length; 1267 device->pnp.cid_list->Ids[i].String = p; 1268 ASSERT(p + cid_list->Ids[i].Length <= (char *)device->pnp.cid_list + cid_list->ListSize); 1269 memcpy(device->pnp.cid_list->Ids[i].String, 1270 cid_list->Ids[i].String, cid_list->Ids[i].Length); 1271 p += cid_list->Ids[i].Length; 1272 } 1273 } 1274 else 1275 DPRINT("Memory allocation error\n"); 1276 } 1277 if (info->Valid & ACPI_VALID_ADR) { 1278 device->pnp.bus_address = info->Address; 1279 device->flags.bus_address = 1; 1280 } 1281 break; 1282 case ACPI_BUS_TYPE_POWER: 1283 hid = ACPI_POWER_HID; 1284 uid = static_uid_buffer; 1285 snprintf(uid, sizeof(static_uid_buffer), "%d", (PowerDeviceCount++)); 1286 break; 1287 case ACPI_BUS_TYPE_PROCESSOR: 1288 hid = ACPI_PROCESSOR_HID; 1289 uid = static_uid_buffer; 1290 snprintf(uid, sizeof(static_uid_buffer), "_%d", (ProcessorCount++)); 1291 break; 1292 case ACPI_BUS_TYPE_SYSTEM: 1293 hid = ACPI_SYSTEM_HID; 1294 break; 1295 case ACPI_BUS_TYPE_THERMAL: 1296 hid = ACPI_THERMAL_HID; 1297 uid = static_uid_buffer; 1298 snprintf(uid, sizeof(static_uid_buffer), "%d", (ThermalZoneCount++)); 1299 break; 1300 case ACPI_BUS_TYPE_POWER_BUTTON: 1301 hid = ACPI_BUTTON_HID_POWER; 1302 uid = static_uid_buffer; 1303 snprintf(uid, sizeof(static_uid_buffer), "%d", (PowerButtonCount++)); 1304 break; 1305 case ACPI_BUS_TYPE_POWER_BUTTONF: 1306 hid = ACPI_BUTTON_HID_POWERF; 1307 uid = static_uid_buffer; 1308 snprintf(uid, sizeof(static_uid_buffer), "%d", (FixedPowerButtonCount++)); 1309 break; 1310 case ACPI_BUS_TYPE_SLEEP_BUTTON: 1311 hid = ACPI_BUTTON_HID_SLEEP; 1312 uid = static_uid_buffer; 1313 snprintf(uid, sizeof(static_uid_buffer), "%d", (SleepButtonCount++)); 1314 break; 1315 case ACPI_BUS_TYPE_SLEEP_BUTTONF: 1316 hid = ACPI_BUTTON_HID_SLEEPF; 1317 uid = static_uid_buffer; 1318 snprintf(uid, sizeof(static_uid_buffer), "%d", (FixedSleepButtonCount++)); 1319 break; 1320 } 1321 1322 /* 1323 * \_SB 1324 * ---- 1325 * Fix for the system root bus device -- the only root-level device. 1326 */ 1327 if (((ACPI_HANDLE)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) { 1328 hid = ACPI_BUS_HID; 1329 snprintf(device->pnp.device_name, sizeof(device->pnp.device_name), "%s", ACPI_BUS_DEVICE_NAME); 1330 snprintf(device->pnp.device_class, sizeof(device->pnp.device_class), "%s", ACPI_BUS_CLASS); 1331 } 1332 1333 if (hid) { 1334 device->pnp.hardware_id = ExAllocatePoolWithTag(NonPagedPool, strlen(hid) + 1, 'DpcA'); 1335 if (device->pnp.hardware_id) { 1336 snprintf(device->pnp.hardware_id, strlen(hid) + 1, "%s", hid); 1337 device->flags.hardware_id = 1; 1338 } 1339 } 1340 if (uid) { 1341 snprintf(device->pnp.unique_id, sizeof(device->pnp.unique_id), "%s", uid); 1342 device->flags.unique_id = 1; 1343 } 1344 1345 /* 1346 * If we called get_object_info, we now are finished with the buffer, 1347 * so we can free it. 1348 */ 1349 //if (buffer.Pointer) 1350 //AcpiOsFree(buffer.Pointer); 1351 1352 /* 1353 * Power Management 1354 * ---------------- 1355 */ 1356 if (device->flags.power_manageable) { 1357 result = acpi_bus_get_power_flags(device); 1358 if (result) 1359 goto end; 1360 } 1361 1362 /* 1363 * Performance Management 1364 * ---------------------- 1365 */ 1366 if (device->flags.performance_manageable) { 1367 result = acpi_bus_get_perf_flags(device); 1368 if (result) 1369 goto end; 1370 } 1371 1372 /* 1373 * Context 1374 * ------- 1375 * Attach this 'struct acpi_device' to the ACPI object. This makes 1376 * resolutions from handle->device very efficient. Note that we need 1377 * to be careful with fixed-feature devices as they all attach to the 1378 * root object. 1379 */ 1380 switch (type) { 1381 case ACPI_BUS_TYPE_POWER_BUTTON: 1382 case ACPI_BUS_TYPE_POWER_BUTTONF: 1383 case ACPI_BUS_TYPE_SLEEP_BUTTON: 1384 case ACPI_BUS_TYPE_SLEEP_BUTTONF: 1385 break; 1386 default: 1387 status = AcpiAttachData(device->handle, 1388 acpi_bus_data_handler, device); 1389 break; 1390 } 1391 if (ACPI_FAILURE(status)) { 1392 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1393 "Error attaching device data\n")); 1394 result = AE_NOT_FOUND; 1395 goto end; 1396 } 1397 1398 /* 1399 * Linkage 1400 * ------- 1401 * Link this device to its parent and siblings. 1402 */ 1403 INIT_LIST_HEAD(&device->children); 1404 if (!device->parent) 1405 INIT_LIST_HEAD(&device->node); 1406 else 1407 list_add_tail(&device->node, &device->parent->children); 1408 1409 /* 1410 * Global Device Hierarchy: 1411 * ------------------------ 1412 * Register this device with the global device hierarchy. 1413 */ 1414 acpi_device_register(device, parent); 1415 1416 /* 1417 * Bind _ADR-Based Devices 1418 * ----------------------- 1419 * If there's a a bus address (_ADR) then we utilize the parent's 1420 * 'bind' function (if exists) to bind the ACPI- and natively- 1421 * enumerated device representations. 1422 */ 1423 if (device->flags.bus_address) { 1424 if (device->parent && device->parent->ops.bind) 1425 device->parent->ops.bind(device); 1426 } 1427 1428 /* 1429 * Locate & Attach Driver 1430 * ---------------------- 1431 * If there's a hardware id (_HID) or compatible ids (_CID) we check 1432 * to see if there's a driver installed for this kind of device. Note 1433 * that drivers can install before or after a device is enumerated. 1434 * 1435 * TBD: Assumes LDM provides driver hot-plug capability. 1436 */ 1437 if (device->flags.hardware_id || device->flags.compatible_ids) 1438 acpi_bus_find_driver(device); 1439 1440 end: 1441 if (info != NULL) 1442 ACPI_FREE(info); 1443 if (result) { 1444 if (device->pnp.cid_list) { 1445 ExFreePoolWithTag(device->pnp.cid_list, 'DpcA'); 1446 } 1447 if (device->pnp.hardware_id) { 1448 ExFreePoolWithTag(device->pnp.hardware_id, 'DpcA'); 1449 } 1450 ExFreePoolWithTag(device, 'DpcA'); 1451 return_VALUE(result); 1452 } 1453 *child = device; 1454 1455 return_VALUE(0); 1456 } 1457 1458 1459 static int 1460 acpi_bus_remove ( 1461 struct acpi_device *device, 1462 int type) 1463 { 1464 1465 if (!device) 1466 return_VALUE(AE_NOT_FOUND); 1467 1468 acpi_device_unregister(device); 1469 1470 if (device->pnp.cid_list) 1471 ExFreePoolWithTag(device->pnp.cid_list, 'DpcA'); 1472 1473 if (device->pnp.hardware_id) 1474 ExFreePoolWithTag(device->pnp.hardware_id, 'DpcA'); 1475 1476 if (device) 1477 ExFreePoolWithTag(device, 'DpcA'); 1478 1479 return_VALUE(0); 1480 } 1481 1482 1483 int 1484 acpi_bus_scan ( 1485 struct acpi_device *start) 1486 { 1487 ACPI_STATUS status = AE_OK; 1488 struct acpi_device *parent = NULL; 1489 struct acpi_device *child = NULL; 1490 ACPI_HANDLE phandle = 0; 1491 ACPI_HANDLE chandle = 0; 1492 ACPI_OBJECT_TYPE type = 0; 1493 UINT32 level = 1; 1494 1495 if (!start) 1496 return_VALUE(AE_BAD_PARAMETER); 1497 1498 parent = start; 1499 phandle = start->handle; 1500 1501 /* 1502 * Parse through the ACPI namespace, identify all 'devices', and 1503 * create a new 'struct acpi_device' for each. 1504 */ 1505 while ((level > 0) && parent) { 1506 1507 status = AcpiGetNextObject(ACPI_TYPE_ANY, phandle, 1508 chandle, &chandle); 1509 1510 /* 1511 * If this scope is exhausted then move our way back up. 1512 */ 1513 if (ACPI_FAILURE(status)) { 1514 level--; 1515 chandle = phandle; 1516 AcpiGetParent(phandle, &phandle); 1517 if (parent->parent) 1518 parent = parent->parent; 1519 continue; 1520 } 1521 1522 status = AcpiGetType(chandle, &type); 1523 if (ACPI_FAILURE(status)) 1524 continue; 1525 1526 /* 1527 * If this is a scope object then parse it (depth-first). 1528 */ 1529 if (type == ACPI_TYPE_LOCAL_SCOPE) { 1530 level++; 1531 phandle = chandle; 1532 chandle = 0; 1533 continue; 1534 } 1535 1536 /* 1537 * We're only interested in objects that we consider 'devices'. 1538 */ 1539 switch (type) { 1540 case ACPI_TYPE_DEVICE: 1541 type = ACPI_BUS_TYPE_DEVICE; 1542 break; 1543 case ACPI_TYPE_PROCESSOR: 1544 type = ACPI_BUS_TYPE_PROCESSOR; 1545 break; 1546 case ACPI_TYPE_THERMAL: 1547 type = ACPI_BUS_TYPE_THERMAL; 1548 break; 1549 case ACPI_TYPE_POWER: 1550 type = ACPI_BUS_TYPE_POWER; 1551 break; 1552 default: 1553 continue; 1554 } 1555 1556 status = acpi_bus_add(&child, parent, chandle, type); 1557 if (ACPI_FAILURE(status)) 1558 continue; 1559 1560 /* 1561 * If the device is present, enabled, and functioning then 1562 * parse its scope (depth-first). Note that we need to 1563 * represent absent devices to facilitate PnP notifications 1564 * -- but only the subtree head (not all of its children, 1565 * which will be enumerated when the parent is inserted). 1566 * 1567 * TBD: Need notifications and other detection mechanisms 1568 * in place before we can fully implement this. 1569 */ 1570 if (child->status.present) { 1571 status = AcpiGetNextObject(ACPI_TYPE_ANY, chandle, 1572 0, NULL); 1573 if (ACPI_SUCCESS(status)) { 1574 level++; 1575 phandle = chandle; 1576 chandle = 0; 1577 parent = child; 1578 } 1579 } 1580 } 1581 1582 return_VALUE(0); 1583 } 1584 1585 1586 static int 1587 acpi_bus_scan_fixed ( 1588 struct acpi_device *root) 1589 { 1590 int result = 0; 1591 struct acpi_device *device = NULL; 1592 1593 if (!root) 1594 return_VALUE(AE_NOT_FOUND); 1595 1596 /* If ACPI_FADT_POWER_BUTTON is set, then a control 1597 * method power button is present. Otherwise, a fixed 1598 * power button is present. 1599 */ 1600 if (AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) 1601 result = acpi_bus_add(&device, acpi_root, 1602 NULL, ACPI_BUS_TYPE_POWER_BUTTON); 1603 else 1604 { 1605 /* Enable the fixed power button so we get notified if it is pressed */ 1606 AcpiWriteBitRegister(ACPI_BITREG_POWER_BUTTON_ENABLE, 1); 1607 1608 result = acpi_bus_add(&device, acpi_root, 1609 NULL, ACPI_BUS_TYPE_POWER_BUTTONF); 1610 } 1611 1612 /* This one is a bit more complicated and we do it wrong 1613 * right now. If ACPI_FADT_SLEEP_BUTTON is set but no 1614 * device object is present then no sleep button is present, but 1615 * if the flags is clear and there is no device object then it is 1616 * a fixed sleep button. If the flag is set and there is a device object 1617 * the we have a control method button just like above. 1618 */ 1619 if (AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) 1620 result = acpi_bus_add(&device, acpi_root, 1621 NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); 1622 else 1623 { 1624 /* Enable the fixed sleep button so we get notified if it is pressed */ 1625 AcpiWriteBitRegister(ACPI_BITREG_SLEEP_BUTTON_ENABLE, 1); 1626 1627 result = acpi_bus_add(&device, acpi_root, 1628 NULL, ACPI_BUS_TYPE_SLEEP_BUTTONF); 1629 } 1630 1631 return_VALUE(result); 1632 } 1633 1634 1635 /* -------------------------------------------------------------------------- 1636 Initialization/Cleanup 1637 -------------------------------------------------------------------------- */ 1638 1639 int 1640 acpi_bus_init (void) 1641 { 1642 int result = 0; 1643 ACPI_STATUS status = AE_OK; 1644 1645 DPRINT("acpi_bus_init\n"); 1646 1647 KeInitializeDpc(&event_dpc, acpi_bus_generate_event_dpc, NULL); 1648 1649 status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION); 1650 if (ACPI_FAILURE(status)) { 1651 DPRINT1("Unable to start the ACPI Interpreter\n"); 1652 goto error1; 1653 } 1654 1655 /* 1656 * ACPI 2.0 requires the EC driver to be loaded and work before 1657 * the EC device is found in the namespace. This is accomplished 1658 * by looking for the ECDT table, and getting the EC parameters out 1659 * of that. 1660 */ 1661 //result = acpi_ec_ecdt_probe(); 1662 /* Ignore result. Not having an ECDT is not fatal. */ 1663 1664 status = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION); 1665 if (ACPI_FAILURE(status)) { 1666 DPRINT1("Unable to initialize ACPI objects\n"); 1667 goto error1; 1668 } 1669 1670 /* 1671 * Maybe EC region is required at bus_scan/acpi_get_devices. So it 1672 * is necessary to enable it as early as possible. 1673 */ 1674 //acpi_boot_ec_enable(); 1675 1676 /* Initialize sleep structures */ 1677 //acpi_sleep_init(); 1678 1679 /* 1680 * Register the for all standard device notifications. 1681 */ 1682 status = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, acpi_bus_notify, NULL); 1683 if (ACPI_FAILURE(status)) { 1684 DPRINT1("Unable to register for device notifications\n"); 1685 result = AE_NOT_FOUND; 1686 goto error1; 1687 } 1688 1689 /* 1690 * Create the root device in the bus's device tree 1691 */ 1692 result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 1693 ACPI_BUS_TYPE_SYSTEM); 1694 if (result) 1695 goto error2; 1696 1697 1698 /* 1699 * Enumerate devices in the ACPI namespace. 1700 */ 1701 result = acpi_bus_scan_fixed(acpi_root); 1702 if (result) 1703 DPRINT1("acpi_bus_scan_fixed failed\n"); 1704 result = acpi_bus_scan(acpi_root); 1705 if (result) 1706 DPRINT1("acpi_bus_scan failed\n"); 1707 1708 return_VALUE(0); 1709 1710 /* Mimic structured exception handling */ 1711 error2: 1712 AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT, 1713 ACPI_SYSTEM_NOTIFY, acpi_bus_notify); 1714 error1: 1715 AcpiTerminate(); 1716 return_VALUE(AE_NOT_FOUND); 1717 } 1718 1719 static void 1720 acpi_bus_exit (void) 1721 { 1722 ACPI_STATUS status = AE_OK; 1723 1724 DPRINT1("acpi_bus_exit\n"); 1725 1726 status = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT, 1727 ACPI_SYSTEM_NOTIFY, acpi_bus_notify); 1728 if (ACPI_FAILURE(status)) 1729 DPRINT1("Error removing notify handler\n"); 1730 1731 #ifdef CONFIG_ACPI_PCI 1732 acpi_pci_root_exit(); 1733 acpi_pci_link_exit(); 1734 #endif 1735 #ifdef CONFIG_ACPI_EC 1736 acpi_ec_exit(); 1737 #endif 1738 //acpi_power_exit(); 1739 acpi_system_exit(); 1740 1741 acpi_bus_remove(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1742 1743 status = AcpiTerminate(); 1744 if (ACPI_FAILURE(status)) 1745 DPRINT1("Unable to terminate the ACPI Interpreter\n"); 1746 else 1747 DPRINT1("Interpreter disabled\n"); 1748 1749 return_VOID; 1750 } 1751 1752 1753 int 1754 acpi_init (void) 1755 { 1756 int result = 0; 1757 1758 DPRINT("acpi_init\n"); 1759 1760 DPRINT("Subsystem revision %08x\n",ACPI_CA_VERSION); 1761 1762 KeInitializeSpinLock(&acpi_bus_event_lock); 1763 KeInitializeEvent(&AcpiEventQueue, NotificationEvent, FALSE); 1764 ExInitializeFastMutex(&acpi_bus_drivers_lock); 1765 1766 result = acpi_bus_init(); 1767 1768 //if (!result) { 1769 //pci_mmcfg_late_init(); 1770 //if (!(pm_flags & PM_APM)) 1771 // pm_flags |= PM_ACPI; 1772 //else { 1773 //DPRINT1("APM is already active, exiting\n"); 1774 //disable_acpi(); 1775 //result = -ENODEV; 1776 //} 1777 //} else 1778 // disable_acpi(); 1779 1780 /* 1781 * If the laptop falls into the DMI check table, the power state check 1782 * will be disabled in the course of device power transistion. 1783 */ 1784 //dmi_check_system(power_nocheck_dmi_table); 1785 1786 /* 1787 * Install drivers required for proper enumeration of the 1788 * ACPI namespace. 1789 */ 1790 acpi_system_init(); /* ACPI System */ 1791 acpi_power_init(); /* ACPI Bus Power Management */ 1792 acpi_button_init(); 1793 //acpi_ec_init(); /* ACPI Embedded Controller */ 1794 #ifdef CONFIG_ACPI_PCI 1795 if (!acpi_pci_disabled) { 1796 acpi_pci_link_init(); /* ACPI PCI Interrupt Link */ 1797 acpi_pci_root_init(); /* ACPI PCI Root Bridge */ 1798 } 1799 #endif 1800 1801 //acpi_scan_init(); 1802 //acpi_ec_init(); 1803 //acpi_power_init(); 1804 //acpi_system_init(); 1805 //acpi_debug_init(); 1806 //acpi_sleep_proc_init(); 1807 //acpi_wakeup_device_init(); 1808 1809 return result; 1810 } 1811 1812 1813 void 1814 acpi_exit (void) 1815 { 1816 DPRINT("acpi_exit\n"); 1817 1818 #ifdef CONFIG_PM 1819 pm_active = 0; 1820 #endif 1821 1822 acpi_bus_exit(); 1823 1824 return_VOID; 1825 } 1826 1827