Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenevregion.c
Go to the documentation of this file.
00001 /****************************************************************************** 00002 * 00003 * Module Name: evregion - ACPI AddressSpace (OpRegion) handler dispatch 00004 * 00005 *****************************************************************************/ 00006 00007 /****************************************************************************** 00008 * 00009 * 1. Copyright Notice 00010 * 00011 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. 00012 * All rights reserved. 00013 * 00014 * 2. License 00015 * 00016 * 2.1. This is your license from Intel Corp. under its intellectual property 00017 * rights. You may have additional license terms from the party that provided 00018 * you this software, covering your right to use that party's intellectual 00019 * property rights. 00020 * 00021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 00022 * copy of the source code appearing in this file ("Covered Code") an 00023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 00024 * base code distributed originally by Intel ("Original Intel Code") to copy, 00025 * make derivatives, distribute, use and display any portion of the Covered 00026 * Code in any form, with the right to sublicense such rights; and 00027 * 00028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 00029 * license (with the right to sublicense), under only those claims of Intel 00030 * patents that are infringed by the Original Intel Code, to make, use, sell, 00031 * offer to sell, and import the Covered Code and derivative works thereof 00032 * solely to the minimum extent necessary to exercise the above copyright 00033 * license, and in no event shall the patent license extend to any additions 00034 * to or modifications of the Original Intel Code. No other license or right 00035 * is granted directly or by implication, estoppel or otherwise; 00036 * 00037 * The above copyright and patent license is granted only if the following 00038 * conditions are met: 00039 * 00040 * 3. Conditions 00041 * 00042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 00043 * Redistribution of source code of any substantial portion of the Covered 00044 * Code or modification with rights to further distribute source must include 00045 * the above Copyright Notice, the above License, this list of Conditions, 00046 * and the following Disclaimer and Export Compliance provision. In addition, 00047 * Licensee must cause all Covered Code to which Licensee contributes to 00048 * contain a file documenting the changes Licensee made to create that Covered 00049 * Code and the date of any change. Licensee must include in that file the 00050 * documentation of any changes made by any predecessor Licensee. Licensee 00051 * must include a prominent statement that the modification is derived, 00052 * directly or indirectly, from Original Intel Code. 00053 * 00054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 00055 * Redistribution of source code of any substantial portion of the Covered 00056 * Code or modification without rights to further distribute source must 00057 * include the following Disclaimer and Export Compliance provision in the 00058 * documentation and/or other materials provided with distribution. In 00059 * addition, Licensee may not authorize further sublicense of source of any 00060 * portion of the Covered Code, and must include terms to the effect that the 00061 * license from Licensee to its licensee is limited to the intellectual 00062 * property embodied in the software Licensee provides to its licensee, and 00063 * not to intellectual property embodied in modifications its licensee may 00064 * make. 00065 * 00066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 00067 * substantial portion of the Covered Code or modification must reproduce the 00068 * above Copyright Notice, and the following Disclaimer and Export Compliance 00069 * provision in the documentation and/or other materials provided with the 00070 * distribution. 00071 * 00072 * 3.4. Intel retains all right, title, and interest in and to the Original 00073 * Intel Code. 00074 * 00075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 00076 * Intel shall be used in advertising or otherwise to promote the sale, use or 00077 * other dealings in products derived from or relating to the Covered Code 00078 * without prior written authorization from Intel. 00079 * 00080 * 4. Disclaimer and Export Compliance 00081 * 00082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 00083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 00084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 00085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 00086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 00087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 00088 * PARTICULAR PURPOSE. 00089 * 00090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 00091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 00092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 00093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 00094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 00095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 00096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 00097 * LIMITED REMEDY. 00098 * 00099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 00100 * software or system incorporating such software without first obtaining any 00101 * required license or other approval from the U. S. Department of Commerce or 00102 * any other agency or department of the United States Government. In the 00103 * event Licensee exports any such software from the United States or 00104 * re-exports any such software from a foreign destination, Licensee shall 00105 * ensure that the distribution and export/re-export of the software is in 00106 * compliance with all laws, regulations, orders, or other restrictions of the 00107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 00108 * any of its subsidiaries will export/re-export any technical data, process, 00109 * software, or service, directly or indirectly, to any country for which the 00110 * United States government or any agency thereof requires an export license, 00111 * other governmental approval, or letter of assurance, without first obtaining 00112 * such license, approval or letter. 00113 * 00114 *****************************************************************************/ 00115 00116 00117 #define __EVREGION_C__ 00118 00119 #include "acpi.h" 00120 #include "accommon.h" 00121 #include "acevents.h" 00122 #include "acnamesp.h" 00123 #include "acinterp.h" 00124 00125 #define _COMPONENT ACPI_EVENTS 00126 ACPI_MODULE_NAME ("evregion") 00127 00128 00129 /* Local prototypes */ 00130 00131 static BOOLEAN 00132 AcpiEvHasDefaultHandler ( 00133 ACPI_NAMESPACE_NODE *Node, 00134 ACPI_ADR_SPACE_TYPE SpaceId); 00135 00136 static void 00137 AcpiEvOrphanEcRegMethod ( 00138 void); 00139 00140 static ACPI_STATUS 00141 AcpiEvRegRun ( 00142 ACPI_HANDLE ObjHandle, 00143 UINT32 Level, 00144 void *Context, 00145 void **ReturnValue); 00146 00147 static ACPI_STATUS 00148 AcpiEvInstallHandler ( 00149 ACPI_HANDLE ObjHandle, 00150 UINT32 Level, 00151 void *Context, 00152 void **ReturnValue); 00153 00154 /* These are the address spaces that will get default handlers */ 00155 00156 #define ACPI_NUM_DEFAULT_SPACES 4 00157 00158 static UINT8 AcpiGbl_DefaultAddressSpaces[ACPI_NUM_DEFAULT_SPACES] = 00159 { 00160 ACPI_ADR_SPACE_SYSTEM_MEMORY, 00161 ACPI_ADR_SPACE_SYSTEM_IO, 00162 ACPI_ADR_SPACE_PCI_CONFIG, 00163 ACPI_ADR_SPACE_DATA_TABLE 00164 }; 00165 00166 00167 /******************************************************************************* 00168 * 00169 * FUNCTION: AcpiEvInstallRegionHandlers 00170 * 00171 * PARAMETERS: None 00172 * 00173 * RETURN: Status 00174 * 00175 * DESCRIPTION: Installs the core subsystem default address space handlers. 00176 * 00177 ******************************************************************************/ 00178 00179 ACPI_STATUS 00180 AcpiEvInstallRegionHandlers ( 00181 void) 00182 { 00183 ACPI_STATUS Status; 00184 UINT32 i; 00185 00186 00187 ACPI_FUNCTION_TRACE (EvInstallRegionHandlers); 00188 00189 00190 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00191 if (ACPI_FAILURE (Status)) 00192 { 00193 return_ACPI_STATUS (Status); 00194 } 00195 00196 /* 00197 * All address spaces (PCI Config, EC, SMBus) are scope dependent and 00198 * registration must occur for a specific device. 00199 * 00200 * In the case of the system memory and IO address spaces there is 00201 * currently no device associated with the address space. For these we 00202 * use the root. 00203 * 00204 * We install the default PCI config space handler at the root so that 00205 * this space is immediately available even though the we have not 00206 * enumerated all the PCI Root Buses yet. This is to conform to the ACPI 00207 * specification which states that the PCI config space must be always 00208 * available -- even though we are nowhere near ready to find the PCI root 00209 * buses at this point. 00210 * 00211 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler 00212 * has already been installed (via AcpiInstallAddressSpaceHandler). 00213 * Similar for AE_SAME_HANDLER. 00214 */ 00215 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) 00216 { 00217 Status = AcpiEvInstallSpaceHandler (AcpiGbl_RootNode, 00218 AcpiGbl_DefaultAddressSpaces[i], 00219 ACPI_DEFAULT_HANDLER, NULL, NULL); 00220 switch (Status) 00221 { 00222 case AE_OK: 00223 case AE_SAME_HANDLER: 00224 case AE_ALREADY_EXISTS: 00225 00226 /* These exceptions are all OK */ 00227 00228 Status = AE_OK; 00229 break; 00230 00231 default: 00232 00233 goto UnlockAndExit; 00234 } 00235 } 00236 00237 UnlockAndExit: 00238 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00239 return_ACPI_STATUS (Status); 00240 } 00241 00242 00243 /******************************************************************************* 00244 * 00245 * FUNCTION: AcpiEvHasDefaultHandler 00246 * 00247 * PARAMETERS: Node - Namespace node for the device 00248 * SpaceId - The address space ID 00249 * 00250 * RETURN: TRUE if default handler is installed, FALSE otherwise 00251 * 00252 * DESCRIPTION: Check if the default handler is installed for the requested 00253 * space ID. 00254 * 00255 ******************************************************************************/ 00256 00257 static BOOLEAN 00258 AcpiEvHasDefaultHandler ( 00259 ACPI_NAMESPACE_NODE *Node, 00260 ACPI_ADR_SPACE_TYPE SpaceId) 00261 { 00262 ACPI_OPERAND_OBJECT *ObjDesc; 00263 ACPI_OPERAND_OBJECT *HandlerObj; 00264 00265 00266 /* Must have an existing internal object */ 00267 00268 ObjDesc = AcpiNsGetAttachedObject (Node); 00269 if (ObjDesc) 00270 { 00271 HandlerObj = ObjDesc->Device.Handler; 00272 00273 /* Walk the linked list of handlers for this object */ 00274 00275 while (HandlerObj) 00276 { 00277 if (HandlerObj->AddressSpace.SpaceId == SpaceId) 00278 { 00279 if (HandlerObj->AddressSpace.HandlerFlags & 00280 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) 00281 { 00282 return (TRUE); 00283 } 00284 } 00285 00286 HandlerObj = HandlerObj->AddressSpace.Next; 00287 } 00288 } 00289 00290 return (FALSE); 00291 } 00292 00293 00294 /******************************************************************************* 00295 * 00296 * FUNCTION: AcpiEvInitializeOpRegions 00297 * 00298 * PARAMETERS: None 00299 * 00300 * RETURN: Status 00301 * 00302 * DESCRIPTION: Execute _REG methods for all Operation Regions that have 00303 * an installed default region handler. 00304 * 00305 ******************************************************************************/ 00306 00307 ACPI_STATUS 00308 AcpiEvInitializeOpRegions ( 00309 void) 00310 { 00311 ACPI_STATUS Status; 00312 UINT32 i; 00313 00314 00315 ACPI_FUNCTION_TRACE (EvInitializeOpRegions); 00316 00317 00318 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00319 if (ACPI_FAILURE (Status)) 00320 { 00321 return_ACPI_STATUS (Status); 00322 } 00323 00324 /* Run the _REG methods for OpRegions in each default address space */ 00325 00326 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) 00327 { 00328 /* 00329 * Make sure the installed handler is the DEFAULT handler. If not the 00330 * default, the _REG methods will have already been run (when the 00331 * handler was installed) 00332 */ 00333 if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode, 00334 AcpiGbl_DefaultAddressSpaces[i])) 00335 { 00336 Status = AcpiEvExecuteRegMethods (AcpiGbl_RootNode, 00337 AcpiGbl_DefaultAddressSpaces[i]); 00338 } 00339 } 00340 00341 AcpiGbl_RegMethodsExecuted = TRUE; 00342 00343 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00344 return_ACPI_STATUS (Status); 00345 } 00346 00347 00348 /******************************************************************************* 00349 * 00350 * FUNCTION: AcpiEvExecuteRegMethod 00351 * 00352 * PARAMETERS: RegionObj - Region object 00353 * Function - Passed to _REG: On (1) or Off (0) 00354 * 00355 * RETURN: Status 00356 * 00357 * DESCRIPTION: Execute _REG method for a region 00358 * 00359 ******************************************************************************/ 00360 00361 ACPI_STATUS 00362 AcpiEvExecuteRegMethod ( 00363 ACPI_OPERAND_OBJECT *RegionObj, 00364 UINT32 Function) 00365 { 00366 ACPI_EVALUATE_INFO *Info; 00367 ACPI_OPERAND_OBJECT *Args[3]; 00368 ACPI_OPERAND_OBJECT *RegionObj2; 00369 ACPI_STATUS Status; 00370 00371 00372 ACPI_FUNCTION_TRACE (EvExecuteRegMethod); 00373 00374 00375 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 00376 if (!RegionObj2) 00377 { 00378 return_ACPI_STATUS (AE_NOT_EXIST); 00379 } 00380 00381 if (RegionObj2->Extra.Method_REG == NULL) 00382 { 00383 return_ACPI_STATUS (AE_OK); 00384 } 00385 00386 /* Allocate and initialize the evaluation information block */ 00387 00388 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 00389 if (!Info) 00390 { 00391 return_ACPI_STATUS (AE_NO_MEMORY); 00392 } 00393 00394 Info->PrefixNode = RegionObj2->Extra.Method_REG; 00395 Info->Pathname = NULL; 00396 Info->Parameters = Args; 00397 Info->Flags = ACPI_IGNORE_RETURN_VALUE; 00398 00399 /* 00400 * The _REG method has two arguments: 00401 * 00402 * Arg0 - Integer: 00403 * Operation region space ID Same value as RegionObj->Region.SpaceId 00404 * 00405 * Arg1 - Integer: 00406 * connection status 1 for connecting the handler, 0 for disconnecting 00407 * the handler (Passed as a parameter) 00408 */ 00409 Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId); 00410 if (!Args[0]) 00411 { 00412 Status = AE_NO_MEMORY; 00413 goto Cleanup1; 00414 } 00415 00416 Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function); 00417 if (!Args[1]) 00418 { 00419 Status = AE_NO_MEMORY; 00420 goto Cleanup2; 00421 } 00422 00423 Args[2] = NULL; /* Terminate list */ 00424 00425 /* Execute the method, no return value */ 00426 00427 ACPI_DEBUG_EXEC ( 00428 AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL)); 00429 00430 Status = AcpiNsEvaluate (Info); 00431 AcpiUtRemoveReference (Args[1]); 00432 00433 Cleanup2: 00434 AcpiUtRemoveReference (Args[0]); 00435 00436 Cleanup1: 00437 ACPI_FREE (Info); 00438 return_ACPI_STATUS (Status); 00439 } 00440 00441 00442 /******************************************************************************* 00443 * 00444 * FUNCTION: AcpiEvAddressSpaceDispatch 00445 * 00446 * PARAMETERS: RegionObj - Internal region object 00447 * Function - Read or Write operation 00448 * RegionOffset - Where in the region to read or write 00449 * BitWidth - Field width in bits (8, 16, 32, or 64) 00450 * Value - Pointer to in or out value, must be 00451 * a full 64-bit integer 00452 * 00453 * RETURN: Status 00454 * 00455 * DESCRIPTION: Dispatch an address space or operation region access to 00456 * a previously installed handler. 00457 * 00458 ******************************************************************************/ 00459 00460 ACPI_STATUS 00461 AcpiEvAddressSpaceDispatch ( 00462 ACPI_OPERAND_OBJECT *RegionObj, 00463 UINT32 Function, 00464 UINT32 RegionOffset, 00465 UINT32 BitWidth, 00466 UINT64 *Value) 00467 { 00468 ACPI_STATUS Status; 00469 ACPI_ADR_SPACE_HANDLER Handler; 00470 ACPI_ADR_SPACE_SETUP RegionSetup; 00471 ACPI_OPERAND_OBJECT *HandlerDesc; 00472 ACPI_OPERAND_OBJECT *RegionObj2; 00473 void *RegionContext = NULL; 00474 00475 00476 ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch); 00477 00478 00479 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 00480 if (!RegionObj2) 00481 { 00482 return_ACPI_STATUS (AE_NOT_EXIST); 00483 } 00484 00485 /* Ensure that there is a handler associated with this region */ 00486 00487 HandlerDesc = RegionObj->Region.Handler; 00488 if (!HandlerDesc) 00489 { 00490 ACPI_ERROR ((AE_INFO, 00491 "No handler for Region [%4.4s] (%p) [%s]", 00492 AcpiUtGetNodeName (RegionObj->Region.Node), 00493 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 00494 00495 return_ACPI_STATUS (AE_NOT_EXIST); 00496 } 00497 00498 /* 00499 * It may be the case that the region has never been initialized. 00500 * Some types of regions require special init code 00501 */ 00502 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 00503 { 00504 /* This region has not been initialized yet, do it */ 00505 00506 RegionSetup = HandlerDesc->AddressSpace.Setup; 00507 if (!RegionSetup) 00508 { 00509 /* No initialization routine, exit with error */ 00510 00511 ACPI_ERROR ((AE_INFO, 00512 "No init routine for region(%p) [%s]", 00513 RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 00514 return_ACPI_STATUS (AE_NOT_EXIST); 00515 } 00516 00517 /* 00518 * We must exit the interpreter because the region setup will 00519 * potentially execute control methods (for example, the _REG method 00520 * for this region) 00521 */ 00522 AcpiExExitInterpreter (); 00523 00524 Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE, 00525 HandlerDesc->AddressSpace.Context, &RegionContext); 00526 00527 /* Re-enter the interpreter */ 00528 00529 AcpiExEnterInterpreter (); 00530 00531 /* Check for failure of the Region Setup */ 00532 00533 if (ACPI_FAILURE (Status)) 00534 { 00535 ACPI_EXCEPTION ((AE_INFO, Status, 00536 "During region initialization: [%s]", 00537 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 00538 return_ACPI_STATUS (Status); 00539 } 00540 00541 /* Region initialization may have been completed by RegionSetup */ 00542 00543 if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 00544 { 00545 RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE; 00546 00547 if (RegionObj2->Extra.RegionContext) 00548 { 00549 /* The handler for this region was already installed */ 00550 00551 ACPI_FREE (RegionContext); 00552 } 00553 else 00554 { 00555 /* 00556 * Save the returned context for use in all accesses to 00557 * this particular region 00558 */ 00559 RegionObj2->Extra.RegionContext = RegionContext; 00560 } 00561 } 00562 } 00563 00564 /* We have everything we need, we can invoke the address space handler */ 00565 00566 Handler = HandlerDesc->AddressSpace.Handler; 00567 00568 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 00569 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", 00570 &RegionObj->Region.Handler->AddressSpace, Handler, 00571 ACPI_FORMAT_NATIVE_UINT (RegionObj->Region.Address + RegionOffset), 00572 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 00573 00574 if (!(HandlerDesc->AddressSpace.HandlerFlags & 00575 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 00576 { 00577 /* 00578 * For handlers other than the default (supplied) handlers, we must 00579 * exit the interpreter because the handler *might* block -- we don't 00580 * know what it will do, so we can't hold the lock on the intepreter. 00581 */ 00582 AcpiExExitInterpreter(); 00583 } 00584 00585 /* Call the handler */ 00586 00587 Status = Handler (Function, 00588 (RegionObj->Region.Address + RegionOffset), BitWidth, Value, 00589 HandlerDesc->AddressSpace.Context, RegionObj2->Extra.RegionContext); 00590 00591 if (ACPI_FAILURE (Status)) 00592 { 00593 ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]", 00594 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 00595 } 00596 00597 if (!(HandlerDesc->AddressSpace.HandlerFlags & 00598 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 00599 { 00600 /* 00601 * We just returned from a non-default handler, we must re-enter the 00602 * interpreter 00603 */ 00604 AcpiExEnterInterpreter (); 00605 } 00606 00607 return_ACPI_STATUS (Status); 00608 } 00609 00610 00611 /******************************************************************************* 00612 * 00613 * FUNCTION: AcpiEvDetachRegion 00614 * 00615 * PARAMETERS: RegionObj - Region Object 00616 * AcpiNsIsLocked - Namespace Region Already Locked? 00617 * 00618 * RETURN: None 00619 * 00620 * DESCRIPTION: Break the association between the handler and the region 00621 * this is a two way association. 00622 * 00623 ******************************************************************************/ 00624 00625 void 00626 AcpiEvDetachRegion( 00627 ACPI_OPERAND_OBJECT *RegionObj, 00628 BOOLEAN AcpiNsIsLocked) 00629 { 00630 ACPI_OPERAND_OBJECT *HandlerObj; 00631 ACPI_OPERAND_OBJECT *ObjDesc; 00632 ACPI_OPERAND_OBJECT **LastObjPtr; 00633 ACPI_ADR_SPACE_SETUP RegionSetup; 00634 void **RegionContext; 00635 ACPI_OPERAND_OBJECT *RegionObj2; 00636 ACPI_STATUS Status; 00637 00638 00639 ACPI_FUNCTION_TRACE (EvDetachRegion); 00640 00641 00642 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 00643 if (!RegionObj2) 00644 { 00645 return_VOID; 00646 } 00647 RegionContext = &RegionObj2->Extra.RegionContext; 00648 00649 /* Get the address handler from the region object */ 00650 00651 HandlerObj = RegionObj->Region.Handler; 00652 if (!HandlerObj) 00653 { 00654 /* This region has no handler, all done */ 00655 00656 return_VOID; 00657 } 00658 00659 /* Find this region in the handler's list */ 00660 00661 ObjDesc = HandlerObj->AddressSpace.RegionList; 00662 LastObjPtr = &HandlerObj->AddressSpace.RegionList; 00663 00664 while (ObjDesc) 00665 { 00666 /* Is this the correct Region? */ 00667 00668 if (ObjDesc == RegionObj) 00669 { 00670 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 00671 "Removing Region %p from address handler %p\n", 00672 RegionObj, HandlerObj)); 00673 00674 /* This is it, remove it from the handler's list */ 00675 00676 *LastObjPtr = ObjDesc->Region.Next; 00677 ObjDesc->Region.Next = NULL; /* Must clear field */ 00678 00679 if (AcpiNsIsLocked) 00680 { 00681 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00682 if (ACPI_FAILURE (Status)) 00683 { 00684 return_VOID; 00685 } 00686 } 00687 00688 /* Now stop region accesses by executing the _REG method */ 00689 00690 Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT); 00691 if (ACPI_FAILURE (Status)) 00692 { 00693 ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]", 00694 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 00695 } 00696 00697 if (AcpiNsIsLocked) 00698 { 00699 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00700 if (ACPI_FAILURE (Status)) 00701 { 00702 return_VOID; 00703 } 00704 } 00705 00706 /* 00707 * If the region has been activated, call the setup handler with 00708 * the deactivate notification 00709 */ 00710 if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE) 00711 { 00712 RegionSetup = HandlerObj->AddressSpace.Setup; 00713 Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE, 00714 HandlerObj->AddressSpace.Context, RegionContext); 00715 00716 /* Init routine may fail, Just ignore errors */ 00717 00718 if (ACPI_FAILURE (Status)) 00719 { 00720 ACPI_EXCEPTION ((AE_INFO, Status, 00721 "from region handler - deactivate, [%s]", 00722 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 00723 } 00724 00725 RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE); 00726 } 00727 00728 /* 00729 * Remove handler reference in the region 00730 * 00731 * NOTE: this doesn't mean that the region goes away, the region 00732 * is just inaccessible as indicated to the _REG method 00733 * 00734 * If the region is on the handler's list, this must be the 00735 * region's handler 00736 */ 00737 RegionObj->Region.Handler = NULL; 00738 AcpiUtRemoveReference (HandlerObj); 00739 00740 return_VOID; 00741 } 00742 00743 /* Walk the linked list of handlers */ 00744 00745 LastObjPtr = &ObjDesc->Region.Next; 00746 ObjDesc = ObjDesc->Region.Next; 00747 } 00748 00749 /* If we get here, the region was not in the handler's region list */ 00750 00751 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 00752 "Cannot remove region %p from address handler %p\n", 00753 RegionObj, HandlerObj)); 00754 00755 return_VOID; 00756 } 00757 00758 00759 /******************************************************************************* 00760 * 00761 * FUNCTION: AcpiEvAttachRegion 00762 * 00763 * PARAMETERS: HandlerObj - Handler Object 00764 * RegionObj - Region Object 00765 * AcpiNsIsLocked - Namespace Region Already Locked? 00766 * 00767 * RETURN: None 00768 * 00769 * DESCRIPTION: Create the association between the handler and the region 00770 * this is a two way association. 00771 * 00772 ******************************************************************************/ 00773 00774 ACPI_STATUS 00775 AcpiEvAttachRegion ( 00776 ACPI_OPERAND_OBJECT *HandlerObj, 00777 ACPI_OPERAND_OBJECT *RegionObj, 00778 BOOLEAN AcpiNsIsLocked) 00779 { 00780 00781 ACPI_FUNCTION_TRACE (EvAttachRegion); 00782 00783 00784 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 00785 "Adding Region [%4.4s] %p to address handler %p [%s]\n", 00786 AcpiUtGetNodeName (RegionObj->Region.Node), 00787 RegionObj, HandlerObj, 00788 AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 00789 00790 /* Link this region to the front of the handler's list */ 00791 00792 RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList; 00793 HandlerObj->AddressSpace.RegionList = RegionObj; 00794 00795 /* Install the region's handler */ 00796 00797 if (RegionObj->Region.Handler) 00798 { 00799 return_ACPI_STATUS (AE_ALREADY_EXISTS); 00800 } 00801 00802 RegionObj->Region.Handler = HandlerObj; 00803 AcpiUtAddReference (HandlerObj); 00804 00805 return_ACPI_STATUS (AE_OK); 00806 } 00807 00808 00809 /******************************************************************************* 00810 * 00811 * FUNCTION: AcpiEvInstallHandler 00812 * 00813 * PARAMETERS: WalkNamespace callback 00814 * 00815 * DESCRIPTION: This routine installs an address handler into objects that are 00816 * of type Region or Device. 00817 * 00818 * If the Object is a Device, and the device has a handler of 00819 * the same type then the search is terminated in that branch. 00820 * 00821 * This is because the existing handler is closer in proximity 00822 * to any more regions than the one we are trying to install. 00823 * 00824 ******************************************************************************/ 00825 00826 static ACPI_STATUS 00827 AcpiEvInstallHandler ( 00828 ACPI_HANDLE ObjHandle, 00829 UINT32 Level, 00830 void *Context, 00831 void **ReturnValue) 00832 { 00833 ACPI_OPERAND_OBJECT *HandlerObj; 00834 ACPI_OPERAND_OBJECT *NextHandlerObj; 00835 ACPI_OPERAND_OBJECT *ObjDesc; 00836 ACPI_NAMESPACE_NODE *Node; 00837 ACPI_STATUS Status; 00838 00839 00840 ACPI_FUNCTION_NAME (EvInstallHandler); 00841 00842 00843 HandlerObj = (ACPI_OPERAND_OBJECT *) Context; 00844 00845 /* Parameter validation */ 00846 00847 if (!HandlerObj) 00848 { 00849 return (AE_OK); 00850 } 00851 00852 /* Convert and validate the device handle */ 00853 00854 Node = AcpiNsValidateHandle (ObjHandle); 00855 if (!Node) 00856 { 00857 return (AE_BAD_PARAMETER); 00858 } 00859 00860 /* 00861 * We only care about regions and objects that are allowed to have 00862 * address space handlers 00863 */ 00864 if ((Node->Type != ACPI_TYPE_DEVICE) && 00865 (Node->Type != ACPI_TYPE_REGION) && 00866 (Node != AcpiGbl_RootNode)) 00867 { 00868 return (AE_OK); 00869 } 00870 00871 /* Check for an existing internal object */ 00872 00873 ObjDesc = AcpiNsGetAttachedObject (Node); 00874 if (!ObjDesc) 00875 { 00876 /* No object, just exit */ 00877 00878 return (AE_OK); 00879 } 00880 00881 /* Devices are handled different than regions */ 00882 00883 if (ObjDesc->Common.Type == ACPI_TYPE_DEVICE) 00884 { 00885 /* Check if this Device already has a handler for this address space */ 00886 00887 NextHandlerObj = ObjDesc->Device.Handler; 00888 while (NextHandlerObj) 00889 { 00890 /* Found a handler, is it for the same address space? */ 00891 00892 if (NextHandlerObj->AddressSpace.SpaceId == 00893 HandlerObj->AddressSpace.SpaceId) 00894 { 00895 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 00896 "Found handler for region [%s] in device %p(%p) " 00897 "handler %p\n", 00898 AcpiUtGetRegionName (HandlerObj->AddressSpace.SpaceId), 00899 ObjDesc, NextHandlerObj, HandlerObj)); 00900 00901 /* 00902 * Since the object we found it on was a device, then it 00903 * means that someone has already installed a handler for 00904 * the branch of the namespace from this device on. Just 00905 * bail out telling the walk routine to not traverse this 00906 * branch. This preserves the scoping rule for handlers. 00907 */ 00908 return (AE_CTRL_DEPTH); 00909 } 00910 00911 /* Walk the linked list of handlers attached to this device */ 00912 00913 NextHandlerObj = NextHandlerObj->AddressSpace.Next; 00914 } 00915 00916 /* 00917 * As long as the device didn't have a handler for this space we 00918 * don't care about it. We just ignore it and proceed. 00919 */ 00920 return (AE_OK); 00921 } 00922 00923 /* Object is a Region */ 00924 00925 if (ObjDesc->Region.SpaceId != HandlerObj->AddressSpace.SpaceId) 00926 { 00927 /* This region is for a different address space, just ignore it */ 00928 00929 return (AE_OK); 00930 } 00931 00932 /* 00933 * Now we have a region and it is for the handler's address space type. 00934 * 00935 * First disconnect region for any previous handler (if any) 00936 */ 00937 AcpiEvDetachRegion (ObjDesc, FALSE); 00938 00939 /* Connect the region to the new handler */ 00940 00941 Status = AcpiEvAttachRegion (HandlerObj, ObjDesc, FALSE); 00942 return (Status); 00943 } 00944 00945 00946 /******************************************************************************* 00947 * 00948 * FUNCTION: AcpiEvInstallSpaceHandler 00949 * 00950 * PARAMETERS: Node - Namespace node for the device 00951 * SpaceId - The address space ID 00952 * Handler - Address of the handler 00953 * Setup - Address of the setup function 00954 * Context - Value passed to the handler on each access 00955 * 00956 * RETURN: Status 00957 * 00958 * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId. 00959 * Assumes namespace is locked 00960 * 00961 ******************************************************************************/ 00962 00963 ACPI_STATUS 00964 AcpiEvInstallSpaceHandler ( 00965 ACPI_NAMESPACE_NODE *Node, 00966 ACPI_ADR_SPACE_TYPE SpaceId, 00967 ACPI_ADR_SPACE_HANDLER Handler, 00968 ACPI_ADR_SPACE_SETUP Setup, 00969 void *Context) 00970 { 00971 ACPI_OPERAND_OBJECT *ObjDesc; 00972 ACPI_OPERAND_OBJECT *HandlerObj; 00973 ACPI_STATUS Status; 00974 ACPI_OBJECT_TYPE Type; 00975 UINT8 Flags = 0; 00976 00977 00978 ACPI_FUNCTION_TRACE (EvInstallSpaceHandler); 00979 00980 00981 /* 00982 * This registration is valid for only the types below and the root. This 00983 * is where the default handlers get placed. 00984 */ 00985 if ((Node->Type != ACPI_TYPE_DEVICE) && 00986 (Node->Type != ACPI_TYPE_PROCESSOR) && 00987 (Node->Type != ACPI_TYPE_THERMAL) && 00988 (Node != AcpiGbl_RootNode)) 00989 { 00990 Status = AE_BAD_PARAMETER; 00991 goto UnlockAndExit; 00992 } 00993 00994 if (Handler == ACPI_DEFAULT_HANDLER) 00995 { 00996 Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED; 00997 00998 switch (SpaceId) 00999 { 01000 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 01001 Handler = AcpiExSystemMemorySpaceHandler; 01002 Setup = AcpiEvSystemMemoryRegionSetup; 01003 break; 01004 01005 case ACPI_ADR_SPACE_SYSTEM_IO: 01006 Handler = AcpiExSystemIoSpaceHandler; 01007 Setup = AcpiEvIoSpaceRegionSetup; 01008 break; 01009 01010 case ACPI_ADR_SPACE_PCI_CONFIG: 01011 Handler = AcpiExPciConfigSpaceHandler; 01012 Setup = AcpiEvPciConfigRegionSetup; 01013 break; 01014 01015 case ACPI_ADR_SPACE_CMOS: 01016 Handler = AcpiExCmosSpaceHandler; 01017 Setup = AcpiEvCmosRegionSetup; 01018 break; 01019 01020 case ACPI_ADR_SPACE_PCI_BAR_TARGET: 01021 Handler = AcpiExPciBarSpaceHandler; 01022 Setup = AcpiEvPciBarRegionSetup; 01023 break; 01024 01025 case ACPI_ADR_SPACE_DATA_TABLE: 01026 Handler = AcpiExDataTableSpaceHandler; 01027 Setup = NULL; 01028 break; 01029 01030 default: 01031 Status = AE_BAD_PARAMETER; 01032 goto UnlockAndExit; 01033 } 01034 } 01035 01036 /* If the caller hasn't specified a setup routine, use the default */ 01037 01038 if (!Setup) 01039 { 01040 Setup = AcpiEvDefaultRegionSetup; 01041 } 01042 01043 /* Check for an existing internal object */ 01044 01045 ObjDesc = AcpiNsGetAttachedObject (Node); 01046 if (ObjDesc) 01047 { 01048 /* 01049 * The attached device object already exists. Make sure the handler 01050 * is not already installed. 01051 */ 01052 HandlerObj = ObjDesc->Device.Handler; 01053 01054 /* Walk the handler list for this device */ 01055 01056 while (HandlerObj) 01057 { 01058 /* Same SpaceId indicates a handler already installed */ 01059 01060 if (HandlerObj->AddressSpace.SpaceId == SpaceId) 01061 { 01062 if (HandlerObj->AddressSpace.Handler == Handler) 01063 { 01064 /* 01065 * It is (relatively) OK to attempt to install the SAME 01066 * handler twice. This can easily happen with the 01067 * PCI_Config space. 01068 */ 01069 Status = AE_SAME_HANDLER; 01070 goto UnlockAndExit; 01071 } 01072 else 01073 { 01074 /* A handler is already installed */ 01075 01076 Status = AE_ALREADY_EXISTS; 01077 } 01078 goto UnlockAndExit; 01079 } 01080 01081 /* Walk the linked list of handlers */ 01082 01083 HandlerObj = HandlerObj->AddressSpace.Next; 01084 } 01085 } 01086 else 01087 { 01088 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 01089 "Creating object on Device %p while installing handler\n", Node)); 01090 01091 /* ObjDesc does not exist, create one */ 01092 01093 if (Node->Type == ACPI_TYPE_ANY) 01094 { 01095 Type = ACPI_TYPE_DEVICE; 01096 } 01097 else 01098 { 01099 Type = Node->Type; 01100 } 01101 01102 ObjDesc = AcpiUtCreateInternalObject (Type); 01103 if (!ObjDesc) 01104 { 01105 Status = AE_NO_MEMORY; 01106 goto UnlockAndExit; 01107 } 01108 01109 /* Init new descriptor */ 01110 01111 ObjDesc->Common.Type = (UINT8) Type; 01112 01113 /* Attach the new object to the Node */ 01114 01115 Status = AcpiNsAttachObject (Node, ObjDesc, Type); 01116 01117 /* Remove local reference to the object */ 01118 01119 AcpiUtRemoveReference (ObjDesc); 01120 01121 if (ACPI_FAILURE (Status)) 01122 { 01123 goto UnlockAndExit; 01124 } 01125 } 01126 01127 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 01128 "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n", 01129 AcpiUtGetRegionName (SpaceId), SpaceId, 01130 AcpiUtGetNodeName (Node), Node, ObjDesc)); 01131 01132 /* 01133 * Install the handler 01134 * 01135 * At this point there is no existing handler. Just allocate the object 01136 * for the handler and link it into the list. 01137 */ 01138 HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER); 01139 if (!HandlerObj) 01140 { 01141 Status = AE_NO_MEMORY; 01142 goto UnlockAndExit; 01143 } 01144 01145 /* Init handler obj */ 01146 01147 HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId; 01148 HandlerObj->AddressSpace.HandlerFlags = Flags; 01149 HandlerObj->AddressSpace.RegionList = NULL; 01150 HandlerObj->AddressSpace.Node = Node; 01151 HandlerObj->AddressSpace.Handler = Handler; 01152 HandlerObj->AddressSpace.Context = Context; 01153 HandlerObj->AddressSpace.Setup = Setup; 01154 01155 /* Install at head of Device.AddressSpace list */ 01156 01157 HandlerObj->AddressSpace.Next = ObjDesc->Device.Handler; 01158 01159 /* 01160 * The Device object is the first reference on the HandlerObj. 01161 * Each region that uses the handler adds a reference. 01162 */ 01163 ObjDesc->Device.Handler = HandlerObj; 01164 01165 /* 01166 * Walk the namespace finding all of the regions this 01167 * handler will manage. 01168 * 01169 * Start at the device and search the branch toward 01170 * the leaf nodes until either the leaf is encountered or 01171 * a device is detected that has an address handler of the 01172 * same type. 01173 * 01174 * In either case, back up and search down the remainder 01175 * of the branch 01176 */ 01177 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, 01178 ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, NULL, 01179 HandlerObj, NULL); 01180 01181 UnlockAndExit: 01182 return_ACPI_STATUS (Status); 01183 } 01184 01185 01186 /******************************************************************************* 01187 * 01188 * FUNCTION: AcpiEvExecuteRegMethods 01189 * 01190 * PARAMETERS: Node - Namespace node for the device 01191 * SpaceId - The address space ID 01192 * 01193 * RETURN: Status 01194 * 01195 * DESCRIPTION: Run all _REG methods for the input Space ID; 01196 * Note: assumes namespace is locked, or system init time. 01197 * 01198 ******************************************************************************/ 01199 01200 ACPI_STATUS 01201 AcpiEvExecuteRegMethods ( 01202 ACPI_NAMESPACE_NODE *Node, 01203 ACPI_ADR_SPACE_TYPE SpaceId) 01204 { 01205 ACPI_STATUS Status; 01206 01207 01208 ACPI_FUNCTION_TRACE (EvExecuteRegMethods); 01209 01210 01211 /* 01212 * Run all _REG methods for all Operation Regions for this space ID. This 01213 * is a separate walk in order to handle any interdependencies between 01214 * regions and _REG methods. (i.e. handlers must be installed for all 01215 * regions of this Space ID before we can run any _REG methods) 01216 */ 01217 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, 01218 ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, 01219 &SpaceId, NULL); 01220 01221 /* Special case for EC: handle "orphan" _REG methods with no region */ 01222 01223 if (SpaceId == ACPI_ADR_SPACE_EC) 01224 { 01225 AcpiEvOrphanEcRegMethod (); 01226 } 01227 01228 return_ACPI_STATUS (Status); 01229 } 01230 01231 01232 /******************************************************************************* 01233 * 01234 * FUNCTION: AcpiEvRegRun 01235 * 01236 * PARAMETERS: WalkNamespace callback 01237 * 01238 * DESCRIPTION: Run _REG method for region objects of the requested spaceID 01239 * 01240 ******************************************************************************/ 01241 01242 static ACPI_STATUS 01243 AcpiEvRegRun ( 01244 ACPI_HANDLE ObjHandle, 01245 UINT32 Level, 01246 void *Context, 01247 void **ReturnValue) 01248 { 01249 ACPI_OPERAND_OBJECT *ObjDesc; 01250 ACPI_NAMESPACE_NODE *Node; 01251 ACPI_ADR_SPACE_TYPE SpaceId; 01252 ACPI_STATUS Status; 01253 01254 01255 SpaceId = *ACPI_CAST_PTR (ACPI_ADR_SPACE_TYPE, Context); 01256 01257 /* Convert and validate the device handle */ 01258 01259 Node = AcpiNsValidateHandle (ObjHandle); 01260 if (!Node) 01261 { 01262 return (AE_BAD_PARAMETER); 01263 } 01264 01265 /* 01266 * We only care about regions.and objects that are allowed to have address 01267 * space handlers 01268 */ 01269 if ((Node->Type != ACPI_TYPE_REGION) && 01270 (Node != AcpiGbl_RootNode)) 01271 { 01272 return (AE_OK); 01273 } 01274 01275 /* Check for an existing internal object */ 01276 01277 ObjDesc = AcpiNsGetAttachedObject (Node); 01278 if (!ObjDesc) 01279 { 01280 /* No object, just exit */ 01281 01282 return (AE_OK); 01283 } 01284 01285 /* Object is a Region */ 01286 01287 if (ObjDesc->Region.SpaceId != SpaceId) 01288 { 01289 /* This region is for a different address space, just ignore it */ 01290 01291 return (AE_OK); 01292 } 01293 01294 Status = AcpiEvExecuteRegMethod (ObjDesc, ACPI_REG_CONNECT); 01295 return (Status); 01296 } 01297 01298 01299 /******************************************************************************* 01300 * 01301 * FUNCTION: AcpiEvOrphanEcRegMethod 01302 * 01303 * PARAMETERS: None 01304 * 01305 * RETURN: None 01306 * 01307 * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC 01308 * device. This is a _REG method that has no corresponding region 01309 * within the EC device scope. The orphan _REG method appears to 01310 * have been enabled by the description of the ECDT in the ACPI 01311 * specification: "The availability of the region space can be 01312 * detected by providing a _REG method object underneath the 01313 * Embedded Controller device." 01314 * 01315 * To quickly access the EC device, we use the EC_ID that appears 01316 * within the ECDT. Otherwise, we would need to perform a time- 01317 * consuming namespace walk, executing _HID methods to find the 01318 * EC device. 01319 * 01320 ******************************************************************************/ 01321 01322 static void 01323 AcpiEvOrphanEcRegMethod ( 01324 void) 01325 { 01326 ACPI_TABLE_ECDT *Table; 01327 ACPI_STATUS Status; 01328 ACPI_OBJECT_LIST Args; 01329 ACPI_OBJECT Objects[2]; 01330 ACPI_NAMESPACE_NODE *EcDeviceNode; 01331 ACPI_NAMESPACE_NODE *RegMethod; 01332 ACPI_NAMESPACE_NODE *NextNode; 01333 01334 01335 ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod); 01336 01337 01338 /* Get the ECDT (if present in system) */ 01339 01340 Status = AcpiGetTable (ACPI_SIG_ECDT, 0, 01341 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Table)); 01342 if (ACPI_FAILURE (Status)) 01343 { 01344 return_VOID; 01345 } 01346 01347 /* We need a valid EC_ID string */ 01348 01349 if (!(*Table->Id)) 01350 { 01351 return_VOID; 01352 } 01353 01354 /* Namespace is currently locked, must release */ 01355 01356 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 01357 01358 /* Get a handle to the EC device referenced in the ECDT */ 01359 01360 Status = AcpiGetHandle (NULL, 01361 ACPI_CAST_PTR (char, Table->Id), 01362 ACPI_CAST_PTR (ACPI_HANDLE, &EcDeviceNode)); 01363 if (ACPI_FAILURE (Status)) 01364 { 01365 goto Exit; 01366 } 01367 01368 /* Get a handle to a _REG method immediately under the EC device */ 01369 01370 Status = AcpiGetHandle (EcDeviceNode, 01371 METHOD_NAME__REG, ACPI_CAST_PTR (ACPI_HANDLE, &RegMethod)); 01372 if (ACPI_FAILURE (Status)) 01373 { 01374 goto Exit; 01375 } 01376 01377 /* 01378 * Execute the _REG method only if there is no Operation Region in 01379 * this scope with the Embedded Controller space ID. Otherwise, it 01380 * will already have been executed. Note, this allows for Regions 01381 * with other space IDs to be present; but the code below will then 01382 * execute the _REG method with the EC space ID argument. 01383 */ 01384 NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL); 01385 while (NextNode) 01386 { 01387 if ((NextNode->Type == ACPI_TYPE_REGION) && 01388 (NextNode->Object) && 01389 (NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC)) 01390 { 01391 goto Exit; /* Do not execute _REG */ 01392 } 01393 NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode); 01394 } 01395 01396 /* Evaluate the _REG(EC,Connect) method */ 01397 01398 Args.Count = 2; 01399 Args.Pointer = Objects; 01400 Objects[0].Type = ACPI_TYPE_INTEGER; 01401 Objects[0].Integer.Value = ACPI_ADR_SPACE_EC; 01402 Objects[1].Type = ACPI_TYPE_INTEGER; 01403 Objects[1].Integer.Value = ACPI_REG_CONNECT; 01404 01405 Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL); 01406 01407 Exit: 01408 /* We ignore all errors from above, don't care */ 01409 01410 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 01411 return_VOID; 01412 } Generated on Sun May 27 2012 04:27:16 for ReactOS by
1.7.6.1
|