1 /****************************************************************************** 2 * 3 * Module Name: evregion - ACPI AddressSpace (OpRegion) handler dispatch 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 117 #define __EVREGION_C__ 118 119 #include "acpi.h" 120 #include "accommon.h" 121 #include "acevents.h" 122 #include "acnamesp.h" 123 #include "acinterp.h" 124 125 #define _COMPONENT ACPI_EVENTS 126 ACPI_MODULE_NAME ("evregion") 127 128 129 /* Local prototypes */ 130 131 static BOOLEAN 132 AcpiEvHasDefaultHandler ( 133 ACPI_NAMESPACE_NODE *Node, 134 ACPI_ADR_SPACE_TYPE SpaceId); 135 136 static void 137 AcpiEvOrphanEcRegMethod ( 138 void); 139 140 static ACPI_STATUS 141 AcpiEvRegRun ( 142 ACPI_HANDLE ObjHandle, 143 UINT32 Level, 144 void *Context, 145 void **ReturnValue); 146 147 static ACPI_STATUS 148 AcpiEvInstallHandler ( 149 ACPI_HANDLE ObjHandle, 150 UINT32 Level, 151 void *Context, 152 void **ReturnValue); 153 154 /* These are the address spaces that will get default handlers */ 155 156 #define ACPI_NUM_DEFAULT_SPACES 4 157 158 static UINT8 AcpiGbl_DefaultAddressSpaces[ACPI_NUM_DEFAULT_SPACES] = 159 { 160 ACPI_ADR_SPACE_SYSTEM_MEMORY, 161 ACPI_ADR_SPACE_SYSTEM_IO, 162 ACPI_ADR_SPACE_PCI_CONFIG, 163 ACPI_ADR_SPACE_DATA_TABLE 164 }; 165 166 167 /******************************************************************************* 168 * 169 * FUNCTION: AcpiEvInstallRegionHandlers 170 * 171 * PARAMETERS: None 172 * 173 * RETURN: Status 174 * 175 * DESCRIPTION: Installs the core subsystem default address space handlers. 176 * 177 ******************************************************************************/ 178 179 ACPI_STATUS 180 AcpiEvInstallRegionHandlers ( 181 void) 182 { 183 ACPI_STATUS Status; 184 UINT32 i; 185 186 187 ACPI_FUNCTION_TRACE (EvInstallRegionHandlers); 188 189 190 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 191 if (ACPI_FAILURE (Status)) 192 { 193 return_ACPI_STATUS (Status); 194 } 195 196 /* 197 * All address spaces (PCI Config, EC, SMBus) are scope dependent and 198 * registration must occur for a specific device. 199 * 200 * In the case of the system memory and IO address spaces there is 201 * currently no device associated with the address space. For these we 202 * use the root. 203 * 204 * We install the default PCI config space handler at the root so that 205 * this space is immediately available even though the we have not 206 * enumerated all the PCI Root Buses yet. This is to conform to the ACPI 207 * specification which states that the PCI config space must be always 208 * available -- even though we are nowhere near ready to find the PCI root 209 * buses at this point. 210 * 211 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler 212 * has already been installed (via AcpiInstallAddressSpaceHandler). 213 * Similar for AE_SAME_HANDLER. 214 */ 215 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) 216 { 217 Status = AcpiEvInstallSpaceHandler (AcpiGbl_RootNode, 218 AcpiGbl_DefaultAddressSpaces[i], 219 ACPI_DEFAULT_HANDLER, NULL, NULL); 220 switch (Status) 221 { 222 case AE_OK: 223 case AE_SAME_HANDLER: 224 case AE_ALREADY_EXISTS: 225 226 /* These exceptions are all OK */ 227 228 Status = AE_OK; 229 break; 230 231 default: 232 233 goto UnlockAndExit; 234 } 235 } 236 237 UnlockAndExit: 238 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 239 return_ACPI_STATUS (Status); 240 } 241 242 243 /******************************************************************************* 244 * 245 * FUNCTION: AcpiEvHasDefaultHandler 246 * 247 * PARAMETERS: Node - Namespace node for the device 248 * SpaceId - The address space ID 249 * 250 * RETURN: TRUE if default handler is installed, FALSE otherwise 251 * 252 * DESCRIPTION: Check if the default handler is installed for the requested 253 * space ID. 254 * 255 ******************************************************************************/ 256 257 static BOOLEAN 258 AcpiEvHasDefaultHandler ( 259 ACPI_NAMESPACE_NODE *Node, 260 ACPI_ADR_SPACE_TYPE SpaceId) 261 { 262 ACPI_OPERAND_OBJECT *ObjDesc; 263 ACPI_OPERAND_OBJECT *HandlerObj; 264 265 266 /* Must have an existing internal object */ 267 268 ObjDesc = AcpiNsGetAttachedObject (Node); 269 if (ObjDesc) 270 { 271 HandlerObj = ObjDesc->Device.Handler; 272 273 /* Walk the linked list of handlers for this object */ 274 275 while (HandlerObj) 276 { 277 if (HandlerObj->AddressSpace.SpaceId == SpaceId) 278 { 279 if (HandlerObj->AddressSpace.HandlerFlags & 280 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) 281 { 282 return (TRUE); 283 } 284 } 285 286 HandlerObj = HandlerObj->AddressSpace.Next; 287 } 288 } 289 290 return (FALSE); 291 } 292 293 294 /******************************************************************************* 295 * 296 * FUNCTION: AcpiEvInitializeOpRegions 297 * 298 * PARAMETERS: None 299 * 300 * RETURN: Status 301 * 302 * DESCRIPTION: Execute _REG methods for all Operation Regions that have 303 * an installed default region handler. 304 * 305 ******************************************************************************/ 306 307 ACPI_STATUS 308 AcpiEvInitializeOpRegions ( 309 void) 310 { 311 ACPI_STATUS Status; 312 UINT32 i; 313 314 315 ACPI_FUNCTION_TRACE (EvInitializeOpRegions); 316 317 318 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 319 if (ACPI_FAILURE (Status)) 320 { 321 return_ACPI_STATUS (Status); 322 } 323 324 /* Run the _REG methods for OpRegions in each default address space */ 325 326 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) 327 { 328 /* 329 * Make sure the installed handler is the DEFAULT handler. If not the 330 * default, the _REG methods will have already been run (when the 331 * handler was installed) 332 */ 333 if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode, 334 AcpiGbl_DefaultAddressSpaces[i])) 335 { 336 Status = AcpiEvExecuteRegMethods (AcpiGbl_RootNode, 337 AcpiGbl_DefaultAddressSpaces[i]); 338 } 339 } 340 341 AcpiGbl_RegMethodsExecuted = TRUE; 342 343 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 344 return_ACPI_STATUS (Status); 345 } 346 347 348 /******************************************************************************* 349 * 350 * FUNCTION: AcpiEvExecuteRegMethod 351 * 352 * PARAMETERS: RegionObj - Region object 353 * Function - Passed to _REG: On (1) or Off (0) 354 * 355 * RETURN: Status 356 * 357 * DESCRIPTION: Execute _REG method for a region 358 * 359 ******************************************************************************/ 360 361 ACPI_STATUS 362 AcpiEvExecuteRegMethod ( 363 ACPI_OPERAND_OBJECT *RegionObj, 364 UINT32 Function) 365 { 366 ACPI_EVALUATE_INFO *Info; 367 ACPI_OPERAND_OBJECT *Args[3]; 368 ACPI_OPERAND_OBJECT *RegionObj2; 369 ACPI_STATUS Status; 370 371 372 ACPI_FUNCTION_TRACE (EvExecuteRegMethod); 373 374 375 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 376 if (!RegionObj2) 377 { 378 return_ACPI_STATUS (AE_NOT_EXIST); 379 } 380 381 if (RegionObj2->Extra.Method_REG == NULL) 382 { 383 return_ACPI_STATUS (AE_OK); 384 } 385 386 /* Allocate and initialize the evaluation information block */ 387 388 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 389 if (!Info) 390 { 391 return_ACPI_STATUS (AE_NO_MEMORY); 392 } 393 394 Info->PrefixNode = RegionObj2->Extra.Method_REG; 395 Info->Pathname = NULL; 396 Info->Parameters = Args; 397 Info->Flags = ACPI_IGNORE_RETURN_VALUE; 398 399 /* 400 * The _REG method has two arguments: 401 * 402 * Arg0 - Integer: 403 * Operation region space ID Same value as RegionObj->Region.SpaceId 404 * 405 * Arg1 - Integer: 406 * connection status 1 for connecting the handler, 0 for disconnecting 407 * the handler (Passed as a parameter) 408 */ 409 Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId); 410 if (!Args[0]) 411 { 412 Status = AE_NO_MEMORY; 413 goto Cleanup1; 414 } 415 416 Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function); 417 if (!Args[1]) 418 { 419 Status = AE_NO_MEMORY; 420 goto Cleanup2; 421 } 422 423 Args[2] = NULL; /* Terminate list */ 424 425 /* Execute the method, no return value */ 426 427 ACPI_DEBUG_EXEC ( 428 AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL)); 429 430 Status = AcpiNsEvaluate (Info); 431 AcpiUtRemoveReference (Args[1]); 432 433 Cleanup2: 434 AcpiUtRemoveReference (Args[0]); 435 436 Cleanup1: 437 ACPI_FREE (Info); 438 return_ACPI_STATUS (Status); 439 } 440 441 442 /******************************************************************************* 443 * 444 * FUNCTION: AcpiEvAddressSpaceDispatch 445 * 446 * PARAMETERS: RegionObj - Internal region object 447 * FieldObj - Corresponding field. Can be NULL. 448 * Function - Read or Write operation 449 * RegionOffset - Where in the region to read or write 450 * BitWidth - Field width in bits (8, 16, 32, or 64) 451 * Value - Pointer to in or out value, must be 452 * a full 64-bit integer 453 * 454 * RETURN: Status 455 * 456 * DESCRIPTION: Dispatch an address space or operation region access to 457 * a previously installed handler. 458 * 459 ******************************************************************************/ 460 461 ACPI_STATUS 462 AcpiEvAddressSpaceDispatch ( 463 ACPI_OPERAND_OBJECT *RegionObj, 464 ACPI_OPERAND_OBJECT *FieldObj, 465 UINT32 Function, 466 UINT32 RegionOffset, 467 UINT32 BitWidth, 468 UINT64 *Value) 469 { 470 ACPI_STATUS Status; 471 ACPI_ADR_SPACE_HANDLER Handler; 472 ACPI_ADR_SPACE_SETUP RegionSetup; 473 ACPI_OPERAND_OBJECT *HandlerDesc; 474 ACPI_OPERAND_OBJECT *RegionObj2; 475 void *RegionContext = NULL; 476 ACPI_CONNECTION_INFO *Context; 477 478 479 ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch); 480 481 482 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 483 if (!RegionObj2) 484 { 485 return_ACPI_STATUS (AE_NOT_EXIST); 486 } 487 488 /* Ensure that there is a handler associated with this region */ 489 490 HandlerDesc = RegionObj->Region.Handler; 491 if (!HandlerDesc) 492 { 493 ACPI_ERROR ((AE_INFO, 494 "No handler for Region [%4.4s] (%p) [%s]", 495 AcpiUtGetNodeName (RegionObj->Region.Node), 496 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 497 498 return_ACPI_STATUS (AE_NOT_EXIST); 499 } 500 501 Context = HandlerDesc->AddressSpace.Context; 502 503 /* 504 * It may be the case that the region has never been initialized. 505 * Some types of regions require special init code 506 */ 507 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 508 { 509 /* This region has not been initialized yet, do it */ 510 511 RegionSetup = HandlerDesc->AddressSpace.Setup; 512 if (!RegionSetup) 513 { 514 /* No initialization routine, exit with error */ 515 516 ACPI_ERROR ((AE_INFO, 517 "No init routine for region(%p) [%s]", 518 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 519 return_ACPI_STATUS (AE_NOT_EXIST); 520 } 521 522 /* 523 * We must exit the interpreter because the region setup will 524 * potentially execute control methods (for example, the _REG method 525 * for this region) 526 */ 527 AcpiExExitInterpreter (); 528 529 Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE, 530 Context, &RegionContext); 531 532 /* Re-enter the interpreter */ 533 534 AcpiExEnterInterpreter (); 535 536 /* Check for failure of the Region Setup */ 537 538 if (ACPI_FAILURE (Status)) 539 { 540 ACPI_EXCEPTION ((AE_INFO, Status, 541 "During region initialization: [%s]", 542 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 543 return_ACPI_STATUS (Status); 544 } 545 546 /* Region initialization may have been completed by RegionSetup */ 547 548 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 549 { 550 RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE; 551 552 if (RegionObj2->Extra.RegionContext) 553 { 554 /* The handler for this region was already installed */ 555 556 ACPI_FREE (RegionContext); 557 } 558 else 559 { 560 /* 561 * Save the returned context for use in all accesses to 562 * this particular region 563 */ 564 RegionObj2->Extra.RegionContext = RegionContext; 565 } 566 } 567 } 568 569 /* We have everything we need, we can invoke the address space handler */ 570 571 Handler = HandlerDesc->AddressSpace.Handler; 572 573 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 574 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", 575 &RegionObj->Region.Handler->AddressSpace, Handler, 576 ACPI_FORMAT_NATIVE_UINT (RegionObj->Region.Address + RegionOffset), 577 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 578 579 580 /* 581 * Special handling for GenericSerialBus and GeneralPurposeIo: 582 * There are three extra parameters that must be passed to the 583 * handler via the context: 584 * 1) Connection buffer, a resource template from Connection() op. 585 * 2) Length of the above buffer. 586 * 3) Actual access length from the AccessAs() op. 587 */ 588 if (((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) || 589 (RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) && 590 Context && 591 FieldObj) 592 { 593 /* Get the Connection (ResourceTemplate) buffer */ 594 595 Context->Connection = FieldObj->Field.ResourceBuffer; 596 Context->Length = FieldObj->Field.ResourceLength; 597 Context->AccessLength = FieldObj->Field.AccessLength; 598 } 599 600 if (!(HandlerDesc->AddressSpace.HandlerFlags & 601 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 602 { 603 /* 604 * For handlers other than the default (supplied) handlers, we must 605 * exit the interpreter because the handler *might* block -- we don't 606 * know what it will do, so we can't hold the lock on the intepreter. 607 */ 608 AcpiExExitInterpreter(); 609 } 610 611 /* Call the handler */ 612 613 Status = Handler (Function, 614 (RegionObj->Region.Address + RegionOffset), BitWidth, Value, 615 Context, RegionObj2->Extra.RegionContext); 616 617 if (ACPI_FAILURE (Status)) 618 { 619 ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]", 620 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 621 } 622 623 if (!(HandlerDesc->AddressSpace.HandlerFlags & 624 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 625 { 626 /* 627 * We just returned from a non-default handler, we must re-enter the 628 * interpreter 629 */ 630 AcpiExEnterInterpreter (); 631 } 632 633 return_ACPI_STATUS (Status); 634 } 635 636 637 /******************************************************************************* 638 * 639 * FUNCTION: AcpiEvDetachRegion 640 * 641 * PARAMETERS: RegionObj - Region Object 642 * AcpiNsIsLocked - Namespace Region Already Locked? 643 * 644 * RETURN: None 645 * 646 * DESCRIPTION: Break the association between the handler and the region 647 * this is a two way association. 648 * 649 ******************************************************************************/ 650 651 void 652 AcpiEvDetachRegion( 653 ACPI_OPERAND_OBJECT *RegionObj, 654 BOOLEAN AcpiNsIsLocked) 655 { 656 ACPI_OPERAND_OBJECT *HandlerObj; 657 ACPI_OPERAND_OBJECT *ObjDesc; 658 ACPI_OPERAND_OBJECT **LastObjPtr; 659 ACPI_ADR_SPACE_SETUP RegionSetup; 660 void **RegionContext; 661 ACPI_OPERAND_OBJECT *RegionObj2; 662 ACPI_STATUS Status; 663 664 665 ACPI_FUNCTION_TRACE (EvDetachRegion); 666 667 668 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 669 if (!RegionObj2) 670 { 671 return_VOID; 672 } 673 RegionContext = &RegionObj2->Extra.RegionContext; 674 675 /* Get the address handler from the region object */ 676 677 HandlerObj = RegionObj->Region.Handler; 678 if (!HandlerObj) 679 { 680 /* This region has no handler, all done */ 681 682 return_VOID; 683 } 684 685 /* Find this region in the handler's list */ 686 687 ObjDesc = HandlerObj->AddressSpace.RegionList; 688 LastObjPtr = &HandlerObj->AddressSpace.RegionList; 689 690 while (ObjDesc) 691 { 692 /* Is this the correct Region? */ 693 694 if (ObjDesc == RegionObj) 695 { 696 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 697 "Removing Region %p from address handler %p\n", 698 RegionObj, HandlerObj)); 699 700 /* This is it, remove it from the handler's list */ 701 702 *LastObjPtr = ObjDesc->Region.Next; 703 ObjDesc->Region.Next = NULL; /* Must clear field */ 704 705 if (AcpiNsIsLocked) 706 { 707 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 708 if (ACPI_FAILURE (Status)) 709 { 710 return_VOID; 711 } 712 } 713 714 /* Now stop region accesses by executing the _REG method */ 715 716 Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT); 717 if (ACPI_FAILURE (Status)) 718 { 719 ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]", 720 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 721 } 722 723 if (AcpiNsIsLocked) 724 { 725 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 726 if (ACPI_FAILURE (Status)) 727 { 728 return_VOID; 729 } 730 } 731 732 /* 733 * If the region has been activated, call the setup handler with 734 * the deactivate notification 735 */ 736 if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE) 737 { 738 RegionSetup = HandlerObj->AddressSpace.Setup; 739 Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE, 740 HandlerObj->AddressSpace.Context, RegionContext); 741 742 /* Init routine may fail, Just ignore errors */ 743 744 if (ACPI_FAILURE (Status)) 745 { 746 ACPI_EXCEPTION ((AE_INFO, Status, 747 "from region handler - deactivate, [%s]", 748 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 749 } 750 751 RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE); 752 } 753 754 /* 755 * Remove handler reference in the region 756 * 757 * NOTE: this doesn't mean that the region goes away, the region 758 * is just inaccessible as indicated to the _REG method 759 * 760 * If the region is on the handler's list, this must be the 761 * region's handler 762 */ 763 RegionObj->Region.Handler = NULL; 764 AcpiUtRemoveReference (HandlerObj); 765 766 return_VOID; 767 } 768 769 /* Walk the linked list of handlers */ 770 771 LastObjPtr = &ObjDesc->Region.Next; 772 ObjDesc = ObjDesc->Region.Next; 773 } 774 775 /* If we get here, the region was not in the handler's region list */ 776 777 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 778 "Cannot remove region %p from address handler %p\n", 779 RegionObj, HandlerObj)); 780 781 return_VOID; 782 } 783 784 785 /******************************************************************************* 786 * 787 * FUNCTION: AcpiEvAttachRegion 788 * 789 * PARAMETERS: HandlerObj - Handler Object 790 * RegionObj - Region Object 791 * AcpiNsIsLocked - Namespace Region Already Locked? 792 * 793 * RETURN: None 794 * 795 * DESCRIPTION: Create the association between the handler and the region 796 * this is a two way association. 797 * 798 ******************************************************************************/ 799 800 ACPI_STATUS 801 AcpiEvAttachRegion ( 802 ACPI_OPERAND_OBJECT *HandlerObj, 803 ACPI_OPERAND_OBJECT *RegionObj, 804 BOOLEAN AcpiNsIsLocked) 805 { 806 807 ACPI_FUNCTION_TRACE (EvAttachRegion); 808 809 810 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 811 "Adding Region [%4.4s] %p to address handler %p [%s]\n", 812 AcpiUtGetNodeName (RegionObj->Region.Node), 813 RegionObj, HandlerObj, 814 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 815 816 /* Link this region to the front of the handler's list */ 817 818 RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList; 819 HandlerObj->AddressSpace.RegionList = RegionObj; 820 821 /* Install the region's handler */ 822 823 if (RegionObj->Region.Handler) 824 { 825 return_ACPI_STATUS (AE_ALREADY_EXISTS); 826 } 827 828 RegionObj->Region.Handler = HandlerObj; 829 AcpiUtAddReference (HandlerObj); 830 831 return_ACPI_STATUS (AE_OK); 832 } 833 834 835 /******************************************************************************* 836 * 837 * FUNCTION: AcpiEvInstallHandler 838 * 839 * PARAMETERS: WalkNamespace callback 840 * 841 * DESCRIPTION: This routine installs an address handler into objects that are 842 * of type Region or Device. 843 * 844 * If the Object is a Device, and the device has a handler of 845 * the same type then the search is terminated in that branch. 846 * 847 * This is because the existing handler is closer in proximity 848 * to any more regions than the one we are trying to install. 849 * 850 ******************************************************************************/ 851 852 static ACPI_STATUS 853 AcpiEvInstallHandler ( 854 ACPI_HANDLE ObjHandle, 855 UINT32 Level, 856 void *Context, 857 void **ReturnValue) 858 { 859 ACPI_OPERAND_OBJECT *HandlerObj; 860 ACPI_OPERAND_OBJECT *NextHandlerObj; 861 ACPI_OPERAND_OBJECT *ObjDesc; 862 ACPI_NAMESPACE_NODE *Node; 863 ACPI_STATUS Status; 864 865 866 ACPI_FUNCTION_NAME (EvInstallHandler); 867 868 869 HandlerObj = (ACPI_OPERAND_OBJECT *) Context; 870 871 /* Parameter validation */ 872 873 if (!HandlerObj) 874 { 875 return (AE_OK); 876 } 877 878 /* Convert and validate the device handle */ 879 880 Node = AcpiNsValidateHandle (ObjHandle); 881 if (!Node) 882 { 883 return (AE_BAD_PARAMETER); 884 } 885 886 /* 887 * We only care about regions and objects that are allowed to have 888 * address space handlers 889 */ 890 if ((Node->Type != ACPI_TYPE_DEVICE) && 891 (Node->Type != ACPI_TYPE_REGION) && 892 (Node != AcpiGbl_RootNode)) 893 { 894 return (AE_OK); 895 } 896 897 /* Check for an existing internal object */ 898 899 ObjDesc = AcpiNsGetAttachedObject (Node); 900 if (!ObjDesc) 901 { 902 /* No object, just exit */ 903 904 return (AE_OK); 905 } 906 907 /* Devices are handled different than regions */ 908 909 if (ObjDesc->Common.Type == ACPI_TYPE_DEVICE) 910 { 911 /* Check if this Device already has a handler for this address space */ 912 913 NextHandlerObj = ObjDesc->Device.Handler; 914 while (NextHandlerObj) 915 { 916 /* Found a handler, is it for the same address space? */ 917 918 if (NextHandlerObj->AddressSpace.SpaceId == 919 HandlerObj->AddressSpace.SpaceId) 920 { 921 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 922 "Found handler for region [%s] in device %p(%p) " 923 "handler %p\n", 924 AcpiUtGetRegionName (HandlerObj->AddressSpace.SpaceId), 925 ObjDesc, NextHandlerObj, HandlerObj)); 926 927 /* 928 * Since the object we found it on was a device, then it 929 * means that someone has already installed a handler for 930 * the branch of the namespace from this device on. Just 931 * bail out telling the walk routine to not traverse this 932 * branch. This preserves the scoping rule for handlers. 933 */ 934 return (AE_CTRL_DEPTH); 935 } 936 937 /* Walk the linked list of handlers attached to this device */ 938 939 NextHandlerObj = NextHandlerObj->AddressSpace.Next; 940 } 941 942 /* 943 * As long as the device didn't have a handler for this space we 944 * don't care about it. We just ignore it and proceed. 945 */ 946 return (AE_OK); 947 } 948 949 /* Object is a Region */ 950 951 if (ObjDesc->Region.SpaceId != HandlerObj->AddressSpace.SpaceId) 952 { 953 /* This region is for a different address space, just ignore it */ 954 955 return (AE_OK); 956 } 957 958 /* 959 * Now we have a region and it is for the handler's address space type. 960 * 961 * First disconnect region for any previous handler (if any) 962 */ 963 AcpiEvDetachRegion (ObjDesc, FALSE); 964 965 /* Connect the region to the new handler */ 966 967 Status = AcpiEvAttachRegion (HandlerObj, ObjDesc, FALSE); 968 return (Status); 969 } 970 971 972 /******************************************************************************* 973 * 974 * FUNCTION: AcpiEvInstallSpaceHandler 975 * 976 * PARAMETERS: Node - Namespace node for the device 977 * SpaceId - The address space ID 978 * Handler - Address of the handler 979 * Setup - Address of the setup function 980 * Context - Value passed to the handler on each access 981 * 982 * RETURN: Status 983 * 984 * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId. 985 * Assumes namespace is locked 986 * 987 ******************************************************************************/ 988 989 ACPI_STATUS 990 AcpiEvInstallSpaceHandler ( 991 ACPI_NAMESPACE_NODE *Node, 992 ACPI_ADR_SPACE_TYPE SpaceId, 993 ACPI_ADR_SPACE_HANDLER Handler, 994 ACPI_ADR_SPACE_SETUP Setup, 995 void *Context) 996 { 997 ACPI_OPERAND_OBJECT *ObjDesc; 998 ACPI_OPERAND_OBJECT *HandlerObj; 999 ACPI_STATUS Status; 1000 ACPI_OBJECT_TYPE Type; 1001 UINT8 Flags = 0; 1002 1003 1004 ACPI_FUNCTION_TRACE (EvInstallSpaceHandler); 1005 1006 1007 /* 1008 * This registration is valid for only the types below and the root. This 1009 * is where the default handlers get placed. 1010 */ 1011 if ((Node->Type != ACPI_TYPE_DEVICE) && 1012 (Node->Type != ACPI_TYPE_PROCESSOR) && 1013 (Node->Type != ACPI_TYPE_THERMAL) && 1014 (Node != AcpiGbl_RootNode)) 1015 { 1016 Status = AE_BAD_PARAMETER; 1017 goto UnlockAndExit; 1018 } 1019 1020 if (Handler == ACPI_DEFAULT_HANDLER) 1021 { 1022 Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED; 1023 1024 switch (SpaceId) 1025 { 1026 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 1027 Handler = AcpiExSystemMemorySpaceHandler; 1028 Setup = AcpiEvSystemMemoryRegionSetup; 1029 break; 1030 1031 case ACPI_ADR_SPACE_SYSTEM_IO: 1032 Handler = AcpiExSystemIoSpaceHandler; 1033 Setup = AcpiEvIoSpaceRegionSetup; 1034 break; 1035 1036 case ACPI_ADR_SPACE_PCI_CONFIG: 1037 Handler = AcpiExPciConfigSpaceHandler; 1038 Setup = AcpiEvPciConfigRegionSetup; 1039 break; 1040 1041 case ACPI_ADR_SPACE_CMOS: 1042 Handler = AcpiExCmosSpaceHandler; 1043 Setup = AcpiEvCmosRegionSetup; 1044 break; 1045 1046 case ACPI_ADR_SPACE_PCI_BAR_TARGET: 1047 Handler = AcpiExPciBarSpaceHandler; 1048 Setup = AcpiEvPciBarRegionSetup; 1049 break; 1050 1051 case ACPI_ADR_SPACE_DATA_TABLE: 1052 Handler = AcpiExDataTableSpaceHandler; 1053 Setup = NULL; 1054 break; 1055 1056 default: 1057 Status = AE_BAD_PARAMETER; 1058 goto UnlockAndExit; 1059 } 1060 } 1061 1062 /* If the caller hasn't specified a setup routine, use the default */ 1063 1064 if (!Setup) 1065 { 1066 Setup = AcpiEvDefaultRegionSetup; 1067 } 1068 1069 /* Check for an existing internal object */ 1070 1071 ObjDesc = AcpiNsGetAttachedObject (Node); 1072 if (ObjDesc) 1073 { 1074 /* 1075 * The attached device object already exists. Make sure the handler 1076 * is not already installed. 1077 */ 1078 HandlerObj = ObjDesc->Device.Handler; 1079 1080 /* Walk the handler list for this device */ 1081 1082 while (HandlerObj) 1083 { 1084 /* Same SpaceId indicates a handler already installed */ 1085 1086 if (HandlerObj->AddressSpace.SpaceId == SpaceId) 1087 { 1088 if (HandlerObj->AddressSpace.Handler == Handler) 1089 { 1090 /* 1091 * It is (relatively) OK to attempt to install the SAME 1092 * handler twice. This can easily happen with the 1093 * PCI_Config space. 1094 */ 1095 Status = AE_SAME_HANDLER; 1096 goto UnlockAndExit; 1097 } 1098 else 1099 { 1100 /* A handler is already installed */ 1101 1102 Status = AE_ALREADY_EXISTS; 1103 } 1104 goto UnlockAndExit; 1105 } 1106 1107 /* Walk the linked list of handlers */ 1108 1109 HandlerObj = HandlerObj->AddressSpace.Next; 1110 } 1111 } 1112 else 1113 { 1114 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 1115 "Creating object on Device %p while installing handler\n", Node)); 1116 1117 /* ObjDesc does not exist, create one */ 1118 1119 if (Node->Type == ACPI_TYPE_ANY) 1120 { 1121 Type = ACPI_TYPE_DEVICE; 1122 } 1123 else 1124 { 1125 Type = Node->Type; 1126 } 1127 1128 ObjDesc = AcpiUtCreateInternalObject (Type); 1129 if (!ObjDesc) 1130 { 1131 Status = AE_NO_MEMORY; 1132 goto UnlockAndExit; 1133 } 1134 1135 /* Init new descriptor */ 1136 1137 ObjDesc->Common.Type = (UINT8) Type; 1138 1139 /* Attach the new object to the Node */ 1140 1141 Status = AcpiNsAttachObject (Node, ObjDesc, Type); 1142 1143 /* Remove local reference to the object */ 1144 1145 AcpiUtRemoveReference (ObjDesc); 1146 1147 if (ACPI_FAILURE (Status)) 1148 { 1149 goto UnlockAndExit; 1150 } 1151 } 1152 1153 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 1154 "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n", 1155 AcpiUtGetRegionName (SpaceId), SpaceId, 1156 AcpiUtGetNodeName (Node), Node, ObjDesc)); 1157 1158 /* 1159 * Install the handler 1160 * 1161 * At this point there is no existing handler. Just allocate the object 1162 * for the handler and link it into the list. 1163 */ 1164 HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER); 1165 if (!HandlerObj) 1166 { 1167 Status = AE_NO_MEMORY; 1168 goto UnlockAndExit; 1169 } 1170 1171 /* Init handler obj */ 1172 1173 HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId; 1174 HandlerObj->AddressSpace.HandlerFlags = Flags; 1175 HandlerObj->AddressSpace.RegionList = NULL; 1176 HandlerObj->AddressSpace.Node = Node; 1177 HandlerObj->AddressSpace.Handler = Handler; 1178 HandlerObj->AddressSpace.Context = Context; 1179 HandlerObj->AddressSpace.Setup = Setup; 1180 1181 /* Install at head of Device.AddressSpace list */ 1182 1183 HandlerObj->AddressSpace.Next = ObjDesc->Device.Handler; 1184 1185 /* 1186 * The Device object is the first reference on the HandlerObj. 1187 * Each region that uses the handler adds a reference. 1188 */ 1189 ObjDesc->Device.Handler = HandlerObj; 1190 1191 /* 1192 * Walk the namespace finding all of the regions this 1193 * handler will manage. 1194 * 1195 * Start at the device and search the branch toward 1196 * the leaf nodes until either the leaf is encountered or 1197 * a device is detected that has an address handler of the 1198 * same type. 1199 * 1200 * In either case, back up and search down the remainder 1201 * of the branch 1202 */ 1203 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, 1204 ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, NULL, 1205 HandlerObj, NULL); 1206 1207 UnlockAndExit: 1208 return_ACPI_STATUS (Status); 1209 } 1210 1211 1212 /******************************************************************************* 1213 * 1214 * FUNCTION: AcpiEvExecuteRegMethods 1215 * 1216 * PARAMETERS: Node - Namespace node for the device 1217 * SpaceId - The address space ID 1218 * 1219 * RETURN: Status 1220 * 1221 * DESCRIPTION: Run all _REG methods for the input Space ID; 1222 * Note: assumes namespace is locked, or system init time. 1223 * 1224 ******************************************************************************/ 1225 1226 ACPI_STATUS 1227 AcpiEvExecuteRegMethods ( 1228 ACPI_NAMESPACE_NODE *Node, 1229 ACPI_ADR_SPACE_TYPE SpaceId) 1230 { 1231 ACPI_STATUS Status; 1232 1233 1234 ACPI_FUNCTION_TRACE (EvExecuteRegMethods); 1235 1236 1237 /* 1238 * Run all _REG methods for all Operation Regions for this space ID. This 1239 * is a separate walk in order to handle any interdependencies between 1240 * regions and _REG methods. (i.e. handlers must be installed for all 1241 * regions of this Space ID before we can run any _REG methods) 1242 */ 1243 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, 1244 ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, 1245 &SpaceId, NULL); 1246 1247 /* Special case for EC: handle "orphan" _REG methods with no region */ 1248 1249 if (SpaceId == ACPI_ADR_SPACE_EC) 1250 { 1251 AcpiEvOrphanEcRegMethod (); 1252 } 1253 1254 return_ACPI_STATUS (Status); 1255 } 1256 1257 1258 /******************************************************************************* 1259 * 1260 * FUNCTION: AcpiEvRegRun 1261 * 1262 * PARAMETERS: WalkNamespace callback 1263 * 1264 * DESCRIPTION: Run _REG method for region objects of the requested spaceID 1265 * 1266 ******************************************************************************/ 1267 1268 static ACPI_STATUS 1269 AcpiEvRegRun ( 1270 ACPI_HANDLE ObjHandle, 1271 UINT32 Level, 1272 void *Context, 1273 void **ReturnValue) 1274 { 1275 ACPI_OPERAND_OBJECT *ObjDesc; 1276 ACPI_NAMESPACE_NODE *Node; 1277 ACPI_ADR_SPACE_TYPE SpaceId; 1278 ACPI_STATUS Status; 1279 1280 1281 SpaceId = *ACPI_CAST_PTR (ACPI_ADR_SPACE_TYPE, Context); 1282 1283 /* Convert and validate the device handle */ 1284 1285 Node = AcpiNsValidateHandle (ObjHandle); 1286 if (!Node) 1287 { 1288 return (AE_BAD_PARAMETER); 1289 } 1290 1291 /* 1292 * We only care about regions.and objects that are allowed to have address 1293 * space handlers 1294 */ 1295 if ((Node->Type != ACPI_TYPE_REGION) && 1296 (Node != AcpiGbl_RootNode)) 1297 { 1298 return (AE_OK); 1299 } 1300 1301 /* Check for an existing internal object */ 1302 1303 ObjDesc = AcpiNsGetAttachedObject (Node); 1304 if (!ObjDesc) 1305 { 1306 /* No object, just exit */ 1307 1308 return (AE_OK); 1309 } 1310 1311 /* Object is a Region */ 1312 1313 if (ObjDesc->Region.SpaceId != SpaceId) 1314 { 1315 /* This region is for a different address space, just ignore it */ 1316 1317 return (AE_OK); 1318 } 1319 1320 Status = AcpiEvExecuteRegMethod (ObjDesc, ACPI_REG_CONNECT); 1321 return (Status); 1322 } 1323 1324 1325 /******************************************************************************* 1326 * 1327 * FUNCTION: AcpiEvOrphanEcRegMethod 1328 * 1329 * PARAMETERS: None 1330 * 1331 * RETURN: None 1332 * 1333 * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC 1334 * device. This is a _REG method that has no corresponding region 1335 * within the EC device scope. The orphan _REG method appears to 1336 * have been enabled by the description of the ECDT in the ACPI 1337 * specification: "The availability of the region space can be 1338 * detected by providing a _REG method object underneath the 1339 * Embedded Controller device." 1340 * 1341 * To quickly access the EC device, we use the EC_ID that appears 1342 * within the ECDT. Otherwise, we would need to perform a time- 1343 * consuming namespace walk, executing _HID methods to find the 1344 * EC device. 1345 * 1346 ******************************************************************************/ 1347 1348 static void 1349 AcpiEvOrphanEcRegMethod ( 1350 void) 1351 { 1352 ACPI_TABLE_ECDT *Table; 1353 ACPI_STATUS Status; 1354 ACPI_OBJECT_LIST Args; 1355 ACPI_OBJECT Objects[2]; 1356 ACPI_NAMESPACE_NODE *EcDeviceNode; 1357 ACPI_NAMESPACE_NODE *RegMethod; 1358 ACPI_NAMESPACE_NODE *NextNode; 1359 1360 1361 ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod); 1362 1363 1364 /* Get the ECDT (if present in system) */ 1365 1366 Status = AcpiGetTable (ACPI_SIG_ECDT, 0, 1367 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Table)); 1368 if (ACPI_FAILURE (Status)) 1369 { 1370 return_VOID; 1371 } 1372 1373 /* We need a valid EC_ID string */ 1374 1375 if (!(*Table->Id)) 1376 { 1377 return_VOID; 1378 } 1379 1380 /* Namespace is currently locked, must release */ 1381 1382 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1383 1384 /* Get a handle to the EC device referenced in the ECDT */ 1385 1386 Status = AcpiGetHandle (NULL, 1387 ACPI_CAST_PTR (char, Table->Id), 1388 ACPI_CAST_PTR (ACPI_HANDLE, &EcDeviceNode)); 1389 if (ACPI_FAILURE (Status)) 1390 { 1391 goto Exit; 1392 } 1393 1394 /* Get a handle to a _REG method immediately under the EC device */ 1395 1396 Status = AcpiGetHandle (EcDeviceNode, 1397 METHOD_NAME__REG, ACPI_CAST_PTR (ACPI_HANDLE, &RegMethod)); 1398 if (ACPI_FAILURE (Status)) 1399 { 1400 goto Exit; 1401 } 1402 1403 /* 1404 * Execute the _REG method only if there is no Operation Region in 1405 * this scope with the Embedded Controller space ID. Otherwise, it 1406 * will already have been executed. Note, this allows for Regions 1407 * with other space IDs to be present; but the code below will then 1408 * execute the _REG method with the EC space ID argument. 1409 */ 1410 NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL); 1411 while (NextNode) 1412 { 1413 if ((NextNode->Type == ACPI_TYPE_REGION) && 1414 (NextNode->Object) && 1415 (NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC)) 1416 { 1417 goto Exit; /* Do not execute _REG */ 1418 } 1419 NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode); 1420 } 1421 1422 /* Evaluate the _REG(EC,Connect) method */ 1423 1424 Args.Count = 2; 1425 Args.Pointer = Objects; 1426 Objects[0].Type = ACPI_TYPE_INTEGER; 1427 Objects[0].Integer.Value = ACPI_ADR_SPACE_EC; 1428 Objects[1].Type = ACPI_TYPE_INTEGER; 1429 Objects[1].Integer.Value = ACPI_REG_CONNECT; 1430 1431 Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL); 1432 1433 Exit: 1434 /* We ignore all errors from above, don't care */ 1435 1436 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1437 return_VOID; 1438 } 1439