1 /****************************************************************************** 2 * 3 * Module Name: evregion - Operation Region support 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2016, 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 #include "acpi.h" 117 #include "accommon.h" 118 #include "acevents.h" 119 #include "acnamesp.h" 120 #include "acinterp.h" 121 122 #define _COMPONENT ACPI_EVENTS 123 ACPI_MODULE_NAME ("evregion") 124 125 126 extern UINT8 AcpiGbl_DefaultAddressSpaces[]; 127 128 /* Local prototypes */ 129 130 static void 131 AcpiEvOrphanEcRegMethod ( 132 ACPI_NAMESPACE_NODE *EcDeviceNode); 133 134 static ACPI_STATUS 135 AcpiEvRegRun ( 136 ACPI_HANDLE ObjHandle, 137 UINT32 Level, 138 void *Context, 139 void **ReturnValue); 140 141 142 /******************************************************************************* 143 * 144 * FUNCTION: AcpiEvInitializeOpRegions 145 * 146 * PARAMETERS: None 147 * 148 * RETURN: Status 149 * 150 * DESCRIPTION: Execute _REG methods for all Operation Regions that have 151 * an installed default region handler. 152 * 153 ******************************************************************************/ 154 155 ACPI_STATUS 156 AcpiEvInitializeOpRegions ( 157 void) 158 { 159 ACPI_STATUS Status; 160 UINT32 i; 161 162 163 ACPI_FUNCTION_TRACE (EvInitializeOpRegions); 164 165 166 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 167 if (ACPI_FAILURE (Status)) 168 { 169 return_ACPI_STATUS (Status); 170 } 171 172 /* Run the _REG methods for OpRegions in each default address space */ 173 174 AcpiGbl_RegMethodsEnabled = TRUE; 175 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) 176 { 177 /* 178 * Make sure the installed handler is the DEFAULT handler. If not the 179 * default, the _REG methods will have already been run (when the 180 * handler was installed) 181 */ 182 if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode, 183 AcpiGbl_DefaultAddressSpaces[i])) 184 { 185 AcpiEvExecuteRegMethods (AcpiGbl_RootNode, 186 AcpiGbl_DefaultAddressSpaces[i], ACPI_REG_CONNECT); 187 } 188 } 189 190 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 191 return_ACPI_STATUS (Status); 192 } 193 194 195 /******************************************************************************* 196 * 197 * FUNCTION: AcpiEvAddressSpaceDispatch 198 * 199 * PARAMETERS: RegionObj - Internal region object 200 * FieldObj - Corresponding field. Can be NULL. 201 * Function - Read or Write operation 202 * RegionOffset - Where in the region to read or write 203 * BitWidth - Field width in bits (8, 16, 32, or 64) 204 * Value - Pointer to in or out value, must be 205 * a full 64-bit integer 206 * 207 * RETURN: Status 208 * 209 * DESCRIPTION: Dispatch an address space or operation region access to 210 * a previously installed handler. 211 * 212 * NOTE: During early initialization, we always install the default region 213 * handlers for Memory, I/O and PCI_Config. This ensures that these operation 214 * region address spaces are always available as per the ACPI specification. 215 * This is especially needed in order to support the execution of 216 * module-level AML code during loading of the ACPI tables. 217 * 218 ******************************************************************************/ 219 220 ACPI_STATUS 221 AcpiEvAddressSpaceDispatch ( 222 ACPI_OPERAND_OBJECT *RegionObj, 223 ACPI_OPERAND_OBJECT *FieldObj, 224 UINT32 Function, 225 UINT32 RegionOffset, 226 UINT32 BitWidth, 227 UINT64 *Value) 228 { 229 ACPI_STATUS Status; 230 ACPI_ADR_SPACE_HANDLER Handler; 231 ACPI_ADR_SPACE_SETUP RegionSetup; 232 ACPI_OPERAND_OBJECT *HandlerDesc; 233 ACPI_OPERAND_OBJECT *RegionObj2; 234 void *RegionContext = NULL; 235 ACPI_CONNECTION_INFO *Context; 236 ACPI_PHYSICAL_ADDRESS Address; 237 238 239 ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch); 240 241 242 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 243 if (!RegionObj2) 244 { 245 return_ACPI_STATUS (AE_NOT_EXIST); 246 } 247 248 /* Ensure that there is a handler associated with this region */ 249 250 HandlerDesc = RegionObj->Region.Handler; 251 if (!HandlerDesc) 252 { 253 ACPI_ERROR ((AE_INFO, 254 "No handler for Region [%4.4s] (%p) [%s]", 255 AcpiUtGetNodeName (RegionObj->Region.Node), 256 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 257 258 return_ACPI_STATUS (AE_NOT_EXIST); 259 } 260 261 Context = HandlerDesc->AddressSpace.Context; 262 263 /* 264 * It may be the case that the region has never been initialized. 265 * Some types of regions require special init code 266 */ 267 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 268 { 269 /* This region has not been initialized yet, do it */ 270 271 RegionSetup = HandlerDesc->AddressSpace.Setup; 272 if (!RegionSetup) 273 { 274 /* No initialization routine, exit with error */ 275 276 ACPI_ERROR ((AE_INFO, 277 "No init routine for region(%p) [%s]", 278 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 279 return_ACPI_STATUS (AE_NOT_EXIST); 280 } 281 282 /* 283 * We must exit the interpreter because the region setup will 284 * potentially execute control methods (for example, the _REG method 285 * for this region) 286 */ 287 AcpiExExitInterpreter (); 288 289 Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE, 290 Context, &RegionContext); 291 292 /* Re-enter the interpreter */ 293 294 AcpiExEnterInterpreter (); 295 296 /* Check for failure of the Region Setup */ 297 298 if (ACPI_FAILURE (Status)) 299 { 300 ACPI_EXCEPTION ((AE_INFO, Status, 301 "During region initialization: [%s]", 302 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 303 return_ACPI_STATUS (Status); 304 } 305 306 /* Region initialization may have been completed by RegionSetup */ 307 308 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 309 { 310 RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE; 311 312 /* 313 * Save the returned context for use in all accesses to 314 * the handler for this particular region 315 */ 316 if (!(RegionObj2->Extra.RegionContext)) 317 { 318 RegionObj2->Extra.RegionContext = RegionContext; 319 } 320 } 321 } 322 323 /* We have everything we need, we can invoke the address space handler */ 324 325 Handler = HandlerDesc->AddressSpace.Handler; 326 Address = (RegionObj->Region.Address + RegionOffset); 327 328 /* 329 * Special handling for GenericSerialBus and GeneralPurposeIo: 330 * There are three extra parameters that must be passed to the 331 * handler via the context: 332 * 1) Connection buffer, a resource template from Connection() op 333 * 2) Length of the above buffer 334 * 3) Actual access length from the AccessAs() op 335 * 336 * In addition, for GeneralPurposeIo, the Address and BitWidth fields 337 * are defined as follows: 338 * 1) Address is the pin number index of the field (bit offset from 339 * the previous Connection) 340 * 2) BitWidth is the actual bit length of the field (number of pins) 341 */ 342 if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) && 343 Context && 344 FieldObj) 345 { 346 /* Get the Connection (ResourceTemplate) buffer */ 347 348 Context->Connection = FieldObj->Field.ResourceBuffer; 349 Context->Length = FieldObj->Field.ResourceLength; 350 Context->AccessLength = FieldObj->Field.AccessLength; 351 } 352 if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO) && 353 Context && 354 FieldObj) 355 { 356 /* Get the Connection (ResourceTemplate) buffer */ 357 358 Context->Connection = FieldObj->Field.ResourceBuffer; 359 Context->Length = FieldObj->Field.ResourceLength; 360 Context->AccessLength = FieldObj->Field.AccessLength; 361 Address = FieldObj->Field.PinNumberIndex; 362 BitWidth = FieldObj->Field.BitLength; 363 } 364 365 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 366 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", 367 &RegionObj->Region.Handler->AddressSpace, Handler, 368 ACPI_FORMAT_UINT64 (Address), 369 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 370 371 if (!(HandlerDesc->AddressSpace.HandlerFlags & 372 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 373 { 374 /* 375 * For handlers other than the default (supplied) handlers, we must 376 * exit the interpreter because the handler *might* block -- we don't 377 * know what it will do, so we can't hold the lock on the intepreter. 378 */ 379 AcpiExExitInterpreter(); 380 } 381 382 /* Call the handler */ 383 384 Status = Handler (Function, Address, BitWidth, Value, Context, 385 RegionObj2->Extra.RegionContext); 386 387 if (ACPI_FAILURE (Status)) 388 { 389 ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]", 390 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 391 } 392 393 if (!(HandlerDesc->AddressSpace.HandlerFlags & 394 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 395 { 396 /* 397 * We just returned from a non-default handler, we must re-enter the 398 * interpreter 399 */ 400 AcpiExEnterInterpreter (); 401 } 402 403 return_ACPI_STATUS (Status); 404 } 405 406 407 /******************************************************************************* 408 * 409 * FUNCTION: AcpiEvDetachRegion 410 * 411 * PARAMETERS: RegionObj - Region Object 412 * AcpiNsIsLocked - Namespace Region Already Locked? 413 * 414 * RETURN: None 415 * 416 * DESCRIPTION: Break the association between the handler and the region 417 * this is a two way association. 418 * 419 ******************************************************************************/ 420 421 void 422 AcpiEvDetachRegion ( 423 ACPI_OPERAND_OBJECT *RegionObj, 424 BOOLEAN AcpiNsIsLocked) 425 { 426 ACPI_OPERAND_OBJECT *HandlerObj; 427 ACPI_OPERAND_OBJECT *ObjDesc; 428 ACPI_OPERAND_OBJECT *StartDesc; 429 ACPI_OPERAND_OBJECT **LastObjPtr; 430 ACPI_ADR_SPACE_SETUP RegionSetup; 431 void **RegionContext; 432 ACPI_OPERAND_OBJECT *RegionObj2; 433 ACPI_STATUS Status; 434 435 436 ACPI_FUNCTION_TRACE (EvDetachRegion); 437 438 439 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 440 if (!RegionObj2) 441 { 442 return_VOID; 443 } 444 RegionContext = &RegionObj2->Extra.RegionContext; 445 446 /* Get the address handler from the region object */ 447 448 HandlerObj = RegionObj->Region.Handler; 449 if (!HandlerObj) 450 { 451 /* This region has no handler, all done */ 452 453 return_VOID; 454 } 455 456 /* Find this region in the handler's list */ 457 458 ObjDesc = HandlerObj->AddressSpace.RegionList; 459 StartDesc = ObjDesc; 460 LastObjPtr = &HandlerObj->AddressSpace.RegionList; 461 462 while (ObjDesc) 463 { 464 /* Is this the correct Region? */ 465 466 if (ObjDesc == RegionObj) 467 { 468 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 469 "Removing Region %p from address handler %p\n", 470 RegionObj, HandlerObj)); 471 472 /* This is it, remove it from the handler's list */ 473 474 *LastObjPtr = ObjDesc->Region.Next; 475 ObjDesc->Region.Next = NULL; /* Must clear field */ 476 477 if (AcpiNsIsLocked) 478 { 479 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 480 if (ACPI_FAILURE (Status)) 481 { 482 return_VOID; 483 } 484 } 485 486 /* Now stop region accesses by executing the _REG method */ 487 488 Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT); 489 if (ACPI_FAILURE (Status)) 490 { 491 ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]", 492 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 493 } 494 495 if (AcpiNsIsLocked) 496 { 497 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 498 if (ACPI_FAILURE (Status)) 499 { 500 return_VOID; 501 } 502 } 503 504 /* 505 * If the region has been activated, call the setup handler with 506 * the deactivate notification 507 */ 508 if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE) 509 { 510 RegionSetup = HandlerObj->AddressSpace.Setup; 511 Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE, 512 HandlerObj->AddressSpace.Context, RegionContext); 513 514 /* 515 * RegionContext should have been released by the deactivate 516 * operation. We don't need access to it anymore here. 517 */ 518 if (RegionContext) 519 { 520 *RegionContext = NULL; 521 } 522 523 /* Init routine may fail, Just ignore errors */ 524 525 if (ACPI_FAILURE (Status)) 526 { 527 ACPI_EXCEPTION ((AE_INFO, Status, 528 "from region handler - deactivate, [%s]", 529 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 530 } 531 532 RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE); 533 } 534 535 /* 536 * Remove handler reference in the region 537 * 538 * NOTE: this doesn't mean that the region goes away, the region 539 * is just inaccessible as indicated to the _REG method 540 * 541 * If the region is on the handler's list, this must be the 542 * region's handler 543 */ 544 RegionObj->Region.Handler = NULL; 545 AcpiUtRemoveReference (HandlerObj); 546 547 return_VOID; 548 } 549 550 /* Walk the linked list of handlers */ 551 552 LastObjPtr = &ObjDesc->Region.Next; 553 ObjDesc = ObjDesc->Region.Next; 554 555 /* Prevent infinite loop if list is corrupted */ 556 557 if (ObjDesc == StartDesc) 558 { 559 ACPI_ERROR ((AE_INFO, 560 "Circular handler list in region object %p", 561 RegionObj)); 562 return_VOID; 563 } 564 } 565 566 /* If we get here, the region was not in the handler's region list */ 567 568 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 569 "Cannot remove region %p from address handler %p\n", 570 RegionObj, HandlerObj)); 571 572 return_VOID; 573 } 574 575 576 /******************************************************************************* 577 * 578 * FUNCTION: AcpiEvAttachRegion 579 * 580 * PARAMETERS: HandlerObj - Handler Object 581 * RegionObj - Region Object 582 * AcpiNsIsLocked - Namespace Region Already Locked? 583 * 584 * RETURN: None 585 * 586 * DESCRIPTION: Create the association between the handler and the region 587 * this is a two way association. 588 * 589 ******************************************************************************/ 590 591 ACPI_STATUS 592 AcpiEvAttachRegion ( 593 ACPI_OPERAND_OBJECT *HandlerObj, 594 ACPI_OPERAND_OBJECT *RegionObj, 595 BOOLEAN AcpiNsIsLocked) 596 { 597 598 ACPI_FUNCTION_TRACE (EvAttachRegion); 599 600 601 /* Install the region's handler */ 602 603 if (RegionObj->Region.Handler) 604 { 605 return_ACPI_STATUS (AE_ALREADY_EXISTS); 606 } 607 608 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 609 "Adding Region [%4.4s] %p to address handler %p [%s]\n", 610 AcpiUtGetNodeName (RegionObj->Region.Node), 611 RegionObj, HandlerObj, 612 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 613 614 /* Link this region to the front of the handler's list */ 615 616 RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList; 617 HandlerObj->AddressSpace.RegionList = RegionObj; 618 RegionObj->Region.Handler = HandlerObj; 619 AcpiUtAddReference (HandlerObj); 620 621 return_ACPI_STATUS (AE_OK); 622 } 623 624 625 /******************************************************************************* 626 * 627 * FUNCTION: AcpiEvAssociateRegMethod 628 * 629 * PARAMETERS: RegionObj - Region object 630 * 631 * RETURN: Status 632 * 633 * DESCRIPTION: Find and associate _REG method to a region 634 * 635 ******************************************************************************/ 636 637 void 638 AcpiEvAssociateRegMethod ( 639 ACPI_OPERAND_OBJECT *RegionObj) 640 { 641 ACPI_NAME *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG; 642 ACPI_NAMESPACE_NODE *MethodNode; 643 ACPI_NAMESPACE_NODE *Node; 644 ACPI_OPERAND_OBJECT *RegionObj2; 645 ACPI_STATUS Status; 646 647 648 ACPI_FUNCTION_TRACE (EvAssociateRegMethod); 649 650 651 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 652 if (!RegionObj2) 653 { 654 return_VOID; 655 } 656 657 Node = RegionObj->Region.Node->Parent; 658 659 /* Find any "_REG" method associated with this region definition */ 660 661 Status = AcpiNsSearchOneScope ( 662 *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode); 663 if (ACPI_SUCCESS (Status)) 664 { 665 /* 666 * The _REG method is optional and there can be only one per region 667 * definition. This will be executed when the handler is attached 668 * or removed 669 */ 670 RegionObj2->Extra.Method_REG = MethodNode; 671 } 672 673 return_VOID; 674 } 675 676 677 /******************************************************************************* 678 * 679 * FUNCTION: AcpiEvExecuteRegMethod 680 * 681 * PARAMETERS: RegionObj - Region object 682 * Function - Passed to _REG: On (1) or Off (0) 683 * 684 * RETURN: Status 685 * 686 * DESCRIPTION: Execute _REG method for a region 687 * 688 ******************************************************************************/ 689 690 ACPI_STATUS 691 AcpiEvExecuteRegMethod ( 692 ACPI_OPERAND_OBJECT *RegionObj, 693 UINT32 Function) 694 { 695 ACPI_EVALUATE_INFO *Info; 696 ACPI_OPERAND_OBJECT *Args[3]; 697 ACPI_OPERAND_OBJECT *RegionObj2; 698 ACPI_STATUS Status; 699 700 701 ACPI_FUNCTION_TRACE (EvExecuteRegMethod); 702 703 704 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 705 if (!RegionObj2) 706 { 707 return_ACPI_STATUS (AE_NOT_EXIST); 708 } 709 710 if (RegionObj2->Extra.Method_REG == NULL || 711 RegionObj->Region.Handler == NULL || 712 !AcpiGbl_RegMethodsEnabled) 713 { 714 return_ACPI_STATUS (AE_OK); 715 } 716 717 /* _REG(DISCONNECT) should be paired with _REG(CONNECT) */ 718 719 if ((Function == ACPI_REG_CONNECT && 720 RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED) || 721 (Function == ACPI_REG_DISCONNECT && 722 !(RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED))) 723 { 724 return_ACPI_STATUS (AE_OK); 725 } 726 727 /* Allocate and initialize the evaluation information block */ 728 729 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 730 if (!Info) 731 { 732 return_ACPI_STATUS (AE_NO_MEMORY); 733 } 734 735 Info->PrefixNode = RegionObj2->Extra.Method_REG; 736 Info->RelativePathname = NULL; 737 Info->Parameters = Args; 738 Info->Flags = ACPI_IGNORE_RETURN_VALUE; 739 740 /* 741 * The _REG method has two arguments: 742 * 743 * Arg0 - Integer: 744 * Operation region space ID Same value as RegionObj->Region.SpaceId 745 * 746 * Arg1 - Integer: 747 * connection status 1 for connecting the handler, 0 for disconnecting 748 * the handler (Passed as a parameter) 749 */ 750 Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId); 751 if (!Args[0]) 752 { 753 Status = AE_NO_MEMORY; 754 goto Cleanup1; 755 } 756 757 Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function); 758 if (!Args[1]) 759 { 760 Status = AE_NO_MEMORY; 761 goto Cleanup2; 762 } 763 764 Args[2] = NULL; /* Terminate list */ 765 766 /* Execute the method, no return value */ 767 768 ACPI_DEBUG_EXEC ( 769 AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL)); 770 771 Status = AcpiNsEvaluate (Info); 772 AcpiUtRemoveReference (Args[1]); 773 774 if (ACPI_FAILURE (Status)) 775 { 776 goto Cleanup2; 777 } 778 779 if (Function == ACPI_REG_CONNECT) 780 { 781 RegionObj->Common.Flags |= AOPOBJ_REG_CONNECTED; 782 } 783 else 784 { 785 RegionObj->Common.Flags &= ~AOPOBJ_REG_CONNECTED; 786 } 787 788 Cleanup2: 789 AcpiUtRemoveReference (Args[0]); 790 791 Cleanup1: 792 ACPI_FREE (Info); 793 return_ACPI_STATUS (Status); 794 } 795 796 797 /******************************************************************************* 798 * 799 * FUNCTION: AcpiEvExecuteRegMethods 800 * 801 * PARAMETERS: Node - Namespace node for the device 802 * SpaceId - The address space ID 803 * Function - Passed to _REG: On (1) or Off (0) 804 * 805 * RETURN: None 806 * 807 * DESCRIPTION: Run all _REG methods for the input Space ID; 808 * Note: assumes namespace is locked, or system init time. 809 * 810 ******************************************************************************/ 811 812 void 813 AcpiEvExecuteRegMethods ( 814 ACPI_NAMESPACE_NODE *Node, 815 ACPI_ADR_SPACE_TYPE SpaceId, 816 UINT32 Function) 817 { 818 ACPI_REG_WALK_INFO Info; 819 820 821 ACPI_FUNCTION_TRACE (EvExecuteRegMethods); 822 823 Info.SpaceId = SpaceId; 824 Info.Function = Function; 825 Info.RegRunCount = 0; 826 827 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, 828 " Running _REG methods for SpaceId %s\n", 829 AcpiUtGetRegionName (Info.SpaceId))); 830 831 /* 832 * Run all _REG methods for all Operation Regions for this space ID. This 833 * is a separate walk in order to handle any interdependencies between 834 * regions and _REG methods. (i.e. handlers must be installed for all 835 * regions of this Space ID before we can run any _REG methods) 836 */ 837 (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, 838 ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &Info, NULL); 839 840 /* Special case for EC: handle "orphan" _REG methods with no region */ 841 842 if (SpaceId == ACPI_ADR_SPACE_EC) 843 { 844 AcpiEvOrphanEcRegMethod (Node); 845 } 846 847 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, 848 " Executed %u _REG methods for SpaceId %s\n", 849 Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId))); 850 851 return_VOID; 852 } 853 854 855 /******************************************************************************* 856 * 857 * FUNCTION: AcpiEvRegRun 858 * 859 * PARAMETERS: WalkNamespace callback 860 * 861 * DESCRIPTION: Run _REG method for region objects of the requested spaceID 862 * 863 ******************************************************************************/ 864 865 static ACPI_STATUS 866 AcpiEvRegRun ( 867 ACPI_HANDLE ObjHandle, 868 UINT32 Level, 869 void *Context, 870 void **ReturnValue) 871 { 872 ACPI_OPERAND_OBJECT *ObjDesc; 873 ACPI_NAMESPACE_NODE *Node; 874 ACPI_STATUS Status; 875 ACPI_REG_WALK_INFO *Info; 876 877 878 Info = ACPI_CAST_PTR (ACPI_REG_WALK_INFO, Context); 879 880 /* Convert and validate the device handle */ 881 882 Node = AcpiNsValidateHandle (ObjHandle); 883 if (!Node) 884 { 885 return (AE_BAD_PARAMETER); 886 } 887 888 /* 889 * We only care about regions.and objects that are allowed to have address 890 * space handlers 891 */ 892 if ((Node->Type != ACPI_TYPE_REGION) && 893 (Node != AcpiGbl_RootNode)) 894 { 895 return (AE_OK); 896 } 897 898 /* Check for an existing internal object */ 899 900 ObjDesc = AcpiNsGetAttachedObject (Node); 901 if (!ObjDesc) 902 { 903 /* No object, just exit */ 904 905 return (AE_OK); 906 } 907 908 /* Object is a Region */ 909 910 if (ObjDesc->Region.SpaceId != Info->SpaceId) 911 { 912 /* This region is for a different address space, just ignore it */ 913 914 return (AE_OK); 915 } 916 917 Info->RegRunCount++; 918 Status = AcpiEvExecuteRegMethod (ObjDesc, Info->Function); 919 return (Status); 920 } 921 922 923 /******************************************************************************* 924 * 925 * FUNCTION: AcpiEvOrphanEcRegMethod 926 * 927 * PARAMETERS: EcDeviceNode - Namespace node for an EC device 928 * 929 * RETURN: None 930 * 931 * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC 932 * device. This is a _REG method that has no corresponding region 933 * within the EC device scope. The orphan _REG method appears to 934 * have been enabled by the description of the ECDT in the ACPI 935 * specification: "The availability of the region space can be 936 * detected by providing a _REG method object underneath the 937 * Embedded Controller device." 938 * 939 * To quickly access the EC device, we use the EcDeviceNode used 940 * during EC handler installation. Otherwise, we would need to 941 * perform a time consuming namespace walk, executing _HID 942 * methods to find the EC device. 943 * 944 * MUTEX: Assumes the namespace is locked 945 * 946 ******************************************************************************/ 947 948 static void 949 AcpiEvOrphanEcRegMethod ( 950 ACPI_NAMESPACE_NODE *EcDeviceNode) 951 { 952 ACPI_HANDLE RegMethod; 953 ACPI_NAMESPACE_NODE *NextNode; 954 ACPI_STATUS Status; 955 ACPI_OBJECT_LIST Args; 956 ACPI_OBJECT Objects[2]; 957 958 959 ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod); 960 961 962 if (!EcDeviceNode) 963 { 964 return_VOID; 965 } 966 967 /* Namespace is currently locked, must release */ 968 969 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 970 971 /* Get a handle to a _REG method immediately under the EC device */ 972 973 Status = AcpiGetHandle (EcDeviceNode, METHOD_NAME__REG, &RegMethod); 974 if (ACPI_FAILURE (Status)) 975 { 976 goto Exit; /* There is no _REG method present */ 977 } 978 979 /* 980 * Execute the _REG method only if there is no Operation Region in 981 * this scope with the Embedded Controller space ID. Otherwise, it 982 * will already have been executed. Note, this allows for Regions 983 * with other space IDs to be present; but the code below will then 984 * execute the _REG method with the EmbeddedControl SpaceID argument. 985 */ 986 NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL); 987 while (NextNode) 988 { 989 if ((NextNode->Type == ACPI_TYPE_REGION) && 990 (NextNode->Object) && 991 (NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC)) 992 { 993 goto Exit; /* Do not execute the _REG */ 994 } 995 996 NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode); 997 } 998 999 /* Evaluate the _REG(EmbeddedControl,Connect) method */ 1000 1001 Args.Count = 2; 1002 Args.Pointer = Objects; 1003 Objects[0].Type = ACPI_TYPE_INTEGER; 1004 Objects[0].Integer.Value = ACPI_ADR_SPACE_EC; 1005 Objects[1].Type = ACPI_TYPE_INTEGER; 1006 Objects[1].Integer.Value = ACPI_REG_CONNECT; 1007 1008 Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL); 1009 1010 Exit: 1011 /* We ignore all errors from above, don't care */ 1012 1013 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1014 return_VOID; 1015 } 1016