Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenevrgnini.c
Go to the documentation of this file.
00001 /****************************************************************************** 00002 * 00003 * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init 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 __EVRGNINI_C__ 00118 00119 #include "acpi.h" 00120 #include "accommon.h" 00121 #include "acevents.h" 00122 #include "acnamesp.h" 00123 00124 #define _COMPONENT ACPI_EVENTS 00125 ACPI_MODULE_NAME ("evrgnini") 00126 00127 /* Local prototypes */ 00128 00129 static BOOLEAN 00130 AcpiEvIsPciRootBridge ( 00131 ACPI_NAMESPACE_NODE *Node); 00132 00133 00134 /******************************************************************************* 00135 * 00136 * FUNCTION: AcpiEvSystemMemoryRegionSetup 00137 * 00138 * PARAMETERS: Handle - Region we are interested in 00139 * Function - Start or stop 00140 * HandlerContext - Address space handler context 00141 * RegionContext - Region specific context 00142 * 00143 * RETURN: Status 00144 * 00145 * DESCRIPTION: Setup a SystemMemory operation region 00146 * 00147 ******************************************************************************/ 00148 00149 ACPI_STATUS 00150 AcpiEvSystemMemoryRegionSetup ( 00151 ACPI_HANDLE Handle, 00152 UINT32 Function, 00153 void *HandlerContext, 00154 void **RegionContext) 00155 { 00156 ACPI_OPERAND_OBJECT *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle; 00157 ACPI_MEM_SPACE_CONTEXT *LocalRegionContext; 00158 00159 00160 ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup); 00161 00162 00163 if (Function == ACPI_REGION_DEACTIVATE) 00164 { 00165 if (*RegionContext) 00166 { 00167 LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext; 00168 00169 /* Delete a cached mapping if present */ 00170 00171 if (LocalRegionContext->MappedLength) 00172 { 00173 AcpiOsUnmapMemory (LocalRegionContext->MappedLogicalAddress, 00174 LocalRegionContext->MappedLength); 00175 } 00176 ACPI_FREE (LocalRegionContext); 00177 *RegionContext = NULL; 00178 } 00179 return_ACPI_STATUS (AE_OK); 00180 } 00181 00182 /* Create a new context */ 00183 00184 LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT)); 00185 if (!(LocalRegionContext)) 00186 { 00187 return_ACPI_STATUS (AE_NO_MEMORY); 00188 } 00189 00190 /* Save the region length and address for use in the handler */ 00191 00192 LocalRegionContext->Length = RegionDesc->Region.Length; 00193 LocalRegionContext->Address = RegionDesc->Region.Address; 00194 00195 *RegionContext = LocalRegionContext; 00196 return_ACPI_STATUS (AE_OK); 00197 } 00198 00199 00200 /******************************************************************************* 00201 * 00202 * FUNCTION: AcpiEvIoSpaceRegionSetup 00203 * 00204 * PARAMETERS: Handle - Region we are interested in 00205 * Function - Start or stop 00206 * HandlerContext - Address space handler context 00207 * RegionContext - Region specific context 00208 * 00209 * RETURN: Status 00210 * 00211 * DESCRIPTION: Setup a IO operation region 00212 * 00213 ******************************************************************************/ 00214 00215 ACPI_STATUS 00216 AcpiEvIoSpaceRegionSetup ( 00217 ACPI_HANDLE Handle, 00218 UINT32 Function, 00219 void *HandlerContext, 00220 void **RegionContext) 00221 { 00222 ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup); 00223 00224 00225 if (Function == ACPI_REGION_DEACTIVATE) 00226 { 00227 *RegionContext = NULL; 00228 } 00229 else 00230 { 00231 *RegionContext = HandlerContext; 00232 } 00233 00234 return_ACPI_STATUS (AE_OK); 00235 } 00236 00237 00238 /******************************************************************************* 00239 * 00240 * FUNCTION: AcpiEvPciConfigRegionSetup 00241 * 00242 * PARAMETERS: Handle - Region we are interested in 00243 * Function - Start or stop 00244 * HandlerContext - Address space handler context 00245 * RegionContext - Region specific context 00246 * 00247 * RETURN: Status 00248 * 00249 * DESCRIPTION: Setup a PCI_Config operation region 00250 * 00251 * MUTEX: Assumes namespace is not locked 00252 * 00253 ******************************************************************************/ 00254 00255 ACPI_STATUS 00256 AcpiEvPciConfigRegionSetup ( 00257 ACPI_HANDLE Handle, 00258 UINT32 Function, 00259 void *HandlerContext, 00260 void **RegionContext) 00261 { 00262 ACPI_STATUS Status = AE_OK; 00263 UINT64 PciValue; 00264 ACPI_PCI_ID *PciId = *RegionContext; 00265 ACPI_OPERAND_OBJECT *HandlerObj; 00266 ACPI_NAMESPACE_NODE *ParentNode; 00267 ACPI_NAMESPACE_NODE *PciRootNode; 00268 ACPI_NAMESPACE_NODE *PciDeviceNode; 00269 ACPI_OPERAND_OBJECT *RegionObj = (ACPI_OPERAND_OBJECT *) Handle; 00270 00271 00272 ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup); 00273 00274 00275 HandlerObj = RegionObj->Region.Handler; 00276 if (!HandlerObj) 00277 { 00278 /* 00279 * No installed handler. This shouldn't happen because the dispatch 00280 * routine checks before we get here, but we check again just in case. 00281 */ 00282 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 00283 "Attempting to init a region %p, with no handler\n", RegionObj)); 00284 return_ACPI_STATUS (AE_NOT_EXIST); 00285 } 00286 00287 *RegionContext = NULL; 00288 if (Function == ACPI_REGION_DEACTIVATE) 00289 { 00290 if (PciId) 00291 { 00292 ACPI_FREE (PciId); 00293 } 00294 return_ACPI_STATUS (Status); 00295 } 00296 00297 ParentNode = RegionObj->Region.Node->Parent; 00298 00299 /* 00300 * Get the _SEG and _BBN values from the device upon which the handler 00301 * is installed. 00302 * 00303 * We need to get the _SEG and _BBN objects relative to the PCI BUS device. 00304 * This is the device the handler has been registered to handle. 00305 */ 00306 00307 /* 00308 * If the AddressSpace.Node is still pointing to the root, we need 00309 * to scan upward for a PCI Root bridge and re-associate the OpRegion 00310 * handlers with that device. 00311 */ 00312 if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode) 00313 { 00314 /* Start search from the parent object */ 00315 00316 PciRootNode = ParentNode; 00317 while (PciRootNode != AcpiGbl_RootNode) 00318 { 00319 /* Get the _HID/_CID in order to detect a RootBridge */ 00320 00321 if (AcpiEvIsPciRootBridge (PciRootNode)) 00322 { 00323 /* Install a handler for this PCI root bridge */ 00324 00325 Status = AcpiInstallAddressSpaceHandler ( 00326 (ACPI_HANDLE) PciRootNode, 00327 ACPI_ADR_SPACE_PCI_CONFIG, 00328 ACPI_DEFAULT_HANDLER, NULL, NULL); 00329 if (ACPI_FAILURE (Status)) 00330 { 00331 if (Status == AE_SAME_HANDLER) 00332 { 00333 /* 00334 * It is OK if the handler is already installed on the 00335 * root bridge. Still need to return a context object 00336 * for the new PCI_Config operation region, however. 00337 */ 00338 Status = AE_OK; 00339 } 00340 else 00341 { 00342 ACPI_EXCEPTION ((AE_INFO, Status, 00343 "Could not install PciConfig handler " 00344 "for Root Bridge %4.4s", 00345 AcpiUtGetNodeName (PciRootNode))); 00346 } 00347 } 00348 break; 00349 } 00350 00351 PciRootNode = PciRootNode->Parent; 00352 } 00353 00354 /* PCI root bridge not found, use namespace root node */ 00355 } 00356 else 00357 { 00358 PciRootNode = HandlerObj->AddressSpace.Node; 00359 } 00360 00361 /* 00362 * If this region is now initialized, we are done. 00363 * (InstallAddressSpaceHandler could have initialized it) 00364 */ 00365 if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE) 00366 { 00367 return_ACPI_STATUS (AE_OK); 00368 } 00369 00370 /* Region is still not initialized. Create a new context */ 00371 00372 PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID)); 00373 if (!PciId) 00374 { 00375 return_ACPI_STATUS (AE_NO_MEMORY); 00376 } 00377 00378 /* 00379 * For PCI_Config space access, we need the segment, bus, device and 00380 * function numbers. Acquire them here. 00381 * 00382 * Find the parent device object. (This allows the operation region to be 00383 * within a subscope under the device, such as a control method.) 00384 */ 00385 PciDeviceNode = RegionObj->Region.Node; 00386 while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE)) 00387 { 00388 PciDeviceNode = PciDeviceNode->Parent; 00389 } 00390 00391 if (!PciDeviceNode) 00392 { 00393 ACPI_FREE (PciId); 00394 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 00395 } 00396 00397 /* 00398 * Get the PCI device and function numbers from the _ADR object 00399 * contained in the parent's scope. 00400 */ 00401 Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, 00402 PciDeviceNode, &PciValue); 00403 00404 /* 00405 * The default is zero, and since the allocation above zeroed the data, 00406 * just do nothing on failure. 00407 */ 00408 if (ACPI_SUCCESS (Status)) 00409 { 00410 PciId->Device = ACPI_HIWORD (ACPI_LODWORD (PciValue)); 00411 PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue)); 00412 } 00413 00414 /* The PCI segment number comes from the _SEG method */ 00415 00416 Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, 00417 PciRootNode, &PciValue); 00418 if (ACPI_SUCCESS (Status)) 00419 { 00420 PciId->Segment = ACPI_LOWORD (PciValue); 00421 } 00422 00423 /* The PCI bus number comes from the _BBN method */ 00424 00425 Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, 00426 PciRootNode, &PciValue); 00427 if (ACPI_SUCCESS (Status)) 00428 { 00429 PciId->Bus = ACPI_LOWORD (PciValue); 00430 } 00431 00432 /* Complete/update the PCI ID for this device */ 00433 00434 Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node); 00435 if (ACPI_FAILURE (Status)) 00436 { 00437 ACPI_FREE (PciId); 00438 return_ACPI_STATUS (Status); 00439 } 00440 00441 *RegionContext = PciId; 00442 return_ACPI_STATUS (AE_OK); 00443 } 00444 00445 00446 /******************************************************************************* 00447 * 00448 * FUNCTION: AcpiEvIsPciRootBridge 00449 * 00450 * PARAMETERS: Node - Device node being examined 00451 * 00452 * RETURN: TRUE if device is a PCI/PCI-Express Root Bridge 00453 * 00454 * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by 00455 * examining the _HID and _CID for the device. 00456 * 00457 ******************************************************************************/ 00458 00459 static BOOLEAN 00460 AcpiEvIsPciRootBridge ( 00461 ACPI_NAMESPACE_NODE *Node) 00462 { 00463 ACPI_STATUS Status; 00464 ACPI_DEVICE_ID *Hid; 00465 ACPI_DEVICE_ID_LIST *Cid; 00466 UINT32 i; 00467 BOOLEAN Match; 00468 00469 00470 /* Get the _HID and check for a PCI Root Bridge */ 00471 00472 Status = AcpiUtExecute_HID (Node, &Hid); 00473 if (ACPI_FAILURE (Status)) 00474 { 00475 return (FALSE); 00476 } 00477 00478 Match = AcpiUtIsPciRootBridge (Hid->String); 00479 ACPI_FREE (Hid); 00480 00481 if (Match) 00482 { 00483 return (TRUE); 00484 } 00485 00486 /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */ 00487 00488 Status = AcpiUtExecute_CID (Node, &Cid); 00489 if (ACPI_FAILURE (Status)) 00490 { 00491 return (FALSE); 00492 } 00493 00494 /* Check all _CIDs in the returned list */ 00495 00496 for (i = 0; i < Cid->Count; i++) 00497 { 00498 if (AcpiUtIsPciRootBridge (Cid->Ids[i].String)) 00499 { 00500 ACPI_FREE (Cid); 00501 return (TRUE); 00502 } 00503 } 00504 00505 ACPI_FREE (Cid); 00506 return (FALSE); 00507 } 00508 00509 00510 /******************************************************************************* 00511 * 00512 * FUNCTION: AcpiEvPciBarRegionSetup 00513 * 00514 * PARAMETERS: Handle - Region we are interested in 00515 * Function - Start or stop 00516 * HandlerContext - Address space handler context 00517 * RegionContext - Region specific context 00518 * 00519 * RETURN: Status 00520 * 00521 * DESCRIPTION: Setup a PciBAR operation region 00522 * 00523 * MUTEX: Assumes namespace is not locked 00524 * 00525 ******************************************************************************/ 00526 00527 ACPI_STATUS 00528 AcpiEvPciBarRegionSetup ( 00529 ACPI_HANDLE Handle, 00530 UINT32 Function, 00531 void *HandlerContext, 00532 void **RegionContext) 00533 { 00534 ACPI_FUNCTION_TRACE (EvPciBarRegionSetup); 00535 00536 00537 return_ACPI_STATUS (AE_OK); 00538 } 00539 00540 00541 /******************************************************************************* 00542 * 00543 * FUNCTION: AcpiEvCmosRegionSetup 00544 * 00545 * PARAMETERS: Handle - Region we are interested in 00546 * Function - Start or stop 00547 * HandlerContext - Address space handler context 00548 * RegionContext - Region specific context 00549 * 00550 * RETURN: Status 00551 * 00552 * DESCRIPTION: Setup a CMOS operation region 00553 * 00554 * MUTEX: Assumes namespace is not locked 00555 * 00556 ******************************************************************************/ 00557 00558 ACPI_STATUS 00559 AcpiEvCmosRegionSetup ( 00560 ACPI_HANDLE Handle, 00561 UINT32 Function, 00562 void *HandlerContext, 00563 void **RegionContext) 00564 { 00565 ACPI_FUNCTION_TRACE (EvCmosRegionSetup); 00566 00567 00568 return_ACPI_STATUS (AE_OK); 00569 } 00570 00571 00572 /******************************************************************************* 00573 * 00574 * FUNCTION: AcpiEvDefaultRegionSetup 00575 * 00576 * PARAMETERS: Handle - Region we are interested in 00577 * Function - Start or stop 00578 * HandlerContext - Address space handler context 00579 * RegionContext - Region specific context 00580 * 00581 * RETURN: Status 00582 * 00583 * DESCRIPTION: Default region initialization 00584 * 00585 ******************************************************************************/ 00586 00587 ACPI_STATUS 00588 AcpiEvDefaultRegionSetup ( 00589 ACPI_HANDLE Handle, 00590 UINT32 Function, 00591 void *HandlerContext, 00592 void **RegionContext) 00593 { 00594 ACPI_FUNCTION_TRACE (EvDefaultRegionSetup); 00595 00596 00597 if (Function == ACPI_REGION_DEACTIVATE) 00598 { 00599 *RegionContext = NULL; 00600 } 00601 else 00602 { 00603 *RegionContext = HandlerContext; 00604 } 00605 00606 return_ACPI_STATUS (AE_OK); 00607 } 00608 00609 00610 /******************************************************************************* 00611 * 00612 * FUNCTION: AcpiEvInitializeRegion 00613 * 00614 * PARAMETERS: RegionObj - Region we are initializing 00615 * AcpiNsLocked - Is namespace locked? 00616 * 00617 * RETURN: Status 00618 * 00619 * DESCRIPTION: Initializes the region, finds any _REG methods and saves them 00620 * for execution at a later time 00621 * 00622 * Get the appropriate address space handler for a newly 00623 * created region. 00624 * 00625 * This also performs address space specific initialization. For 00626 * example, PCI regions must have an _ADR object that contains 00627 * a PCI address in the scope of the definition. This address is 00628 * required to perform an access to PCI config space. 00629 * 00630 * MUTEX: Interpreter should be unlocked, because we may run the _REG 00631 * method for this region. 00632 * 00633 ******************************************************************************/ 00634 00635 ACPI_STATUS 00636 AcpiEvInitializeRegion ( 00637 ACPI_OPERAND_OBJECT *RegionObj, 00638 BOOLEAN AcpiNsLocked) 00639 { 00640 ACPI_OPERAND_OBJECT *HandlerObj; 00641 ACPI_OPERAND_OBJECT *ObjDesc; 00642 ACPI_ADR_SPACE_TYPE SpaceId; 00643 ACPI_NAMESPACE_NODE *Node; 00644 ACPI_STATUS Status; 00645 ACPI_NAMESPACE_NODE *MethodNode; 00646 ACPI_NAME *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG; 00647 ACPI_OPERAND_OBJECT *RegionObj2; 00648 00649 00650 ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked); 00651 00652 00653 if (!RegionObj) 00654 { 00655 return_ACPI_STATUS (AE_BAD_PARAMETER); 00656 } 00657 00658 if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED) 00659 { 00660 return_ACPI_STATUS (AE_OK); 00661 } 00662 00663 RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 00664 if (!RegionObj2) 00665 { 00666 return_ACPI_STATUS (AE_NOT_EXIST); 00667 } 00668 00669 Node = RegionObj->Region.Node->Parent; 00670 SpaceId = RegionObj->Region.SpaceId; 00671 00672 /* Setup defaults */ 00673 00674 RegionObj->Region.Handler = NULL; 00675 RegionObj2->Extra.Method_REG = NULL; 00676 RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE); 00677 RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED; 00678 00679 /* Find any "_REG" method associated with this region definition */ 00680 00681 Status = AcpiNsSearchOneScope ( 00682 *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode); 00683 if (ACPI_SUCCESS (Status)) 00684 { 00685 /* 00686 * The _REG method is optional and there can be only one per region 00687 * definition. This will be executed when the handler is attached 00688 * or removed 00689 */ 00690 RegionObj2->Extra.Method_REG = MethodNode; 00691 } 00692 00693 /* 00694 * The following loop depends upon the root Node having no parent 00695 * ie: AcpiGbl_RootNode->ParentEntry being set to NULL 00696 */ 00697 while (Node) 00698 { 00699 /* Check to see if a handler exists */ 00700 00701 HandlerObj = NULL; 00702 ObjDesc = AcpiNsGetAttachedObject (Node); 00703 if (ObjDesc) 00704 { 00705 /* Can only be a handler if the object exists */ 00706 00707 switch (Node->Type) 00708 { 00709 case ACPI_TYPE_DEVICE: 00710 00711 HandlerObj = ObjDesc->Device.Handler; 00712 break; 00713 00714 case ACPI_TYPE_PROCESSOR: 00715 00716 HandlerObj = ObjDesc->Processor.Handler; 00717 break; 00718 00719 case ACPI_TYPE_THERMAL: 00720 00721 HandlerObj = ObjDesc->ThermalZone.Handler; 00722 break; 00723 00724 case ACPI_TYPE_METHOD: 00725 /* 00726 * If we are executing module level code, the original 00727 * Node's object was replaced by this Method object and we 00728 * saved the handler in the method object. 00729 * 00730 * See AcpiNsExecModuleCode 00731 */ 00732 if (ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) 00733 { 00734 HandlerObj = ObjDesc->Method.Dispatch.Handler; 00735 } 00736 break; 00737 00738 default: 00739 /* Ignore other objects */ 00740 break; 00741 } 00742 00743 while (HandlerObj) 00744 { 00745 /* Is this handler of the correct type? */ 00746 00747 if (HandlerObj->AddressSpace.SpaceId == SpaceId) 00748 { 00749 /* Found correct handler */ 00750 00751 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 00752 "Found handler %p for region %p in obj %p\n", 00753 HandlerObj, RegionObj, ObjDesc)); 00754 00755 Status = AcpiEvAttachRegion (HandlerObj, RegionObj, 00756 AcpiNsLocked); 00757 00758 /* 00759 * Tell all users that this region is usable by 00760 * running the _REG method 00761 */ 00762 if (AcpiNsLocked) 00763 { 00764 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00765 if (ACPI_FAILURE (Status)) 00766 { 00767 return_ACPI_STATUS (Status); 00768 } 00769 } 00770 00771 Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT); 00772 00773 if (AcpiNsLocked) 00774 { 00775 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00776 if (ACPI_FAILURE (Status)) 00777 { 00778 return_ACPI_STATUS (Status); 00779 } 00780 } 00781 00782 return_ACPI_STATUS (AE_OK); 00783 } 00784 00785 /* Try next handler in the list */ 00786 00787 HandlerObj = HandlerObj->AddressSpace.Next; 00788 } 00789 } 00790 00791 /* This node does not have the handler we need; Pop up one level */ 00792 00793 Node = Node->Parent; 00794 } 00795 00796 /* If we get here, there is no handler for this region */ 00797 00798 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 00799 "No handler for RegionType %s(%X) (RegionObj %p)\n", 00800 AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj)); 00801 00802 return_ACPI_STATUS (AE_NOT_EXIST); 00803 } 00804 Generated on Mon May 28 2012 04:26:56 for ReactOS by
1.7.6.1
|