Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygennsxfeval.c
Go to the documentation of this file.
00001 /******************************************************************************* 00002 * 00003 * Module Name: nsxfeval - Public interfaces to the ACPI subsystem 00004 * ACPI Object evaluation interfaces 00005 * 00006 ******************************************************************************/ 00007 00008 /****************************************************************************** 00009 * 00010 * 1. Copyright Notice 00011 * 00012 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. 00013 * All rights reserved. 00014 * 00015 * 2. License 00016 * 00017 * 2.1. This is your license from Intel Corp. under its intellectual property 00018 * rights. You may have additional license terms from the party that provided 00019 * you this software, covering your right to use that party's intellectual 00020 * property rights. 00021 * 00022 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 00023 * copy of the source code appearing in this file ("Covered Code") an 00024 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 00025 * base code distributed originally by Intel ("Original Intel Code") to copy, 00026 * make derivatives, distribute, use and display any portion of the Covered 00027 * Code in any form, with the right to sublicense such rights; and 00028 * 00029 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 00030 * license (with the right to sublicense), under only those claims of Intel 00031 * patents that are infringed by the Original Intel Code, to make, use, sell, 00032 * offer to sell, and import the Covered Code and derivative works thereof 00033 * solely to the minimum extent necessary to exercise the above copyright 00034 * license, and in no event shall the patent license extend to any additions 00035 * to or modifications of the Original Intel Code. No other license or right 00036 * is granted directly or by implication, estoppel or otherwise; 00037 * 00038 * The above copyright and patent license is granted only if the following 00039 * conditions are met: 00040 * 00041 * 3. Conditions 00042 * 00043 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 00044 * Redistribution of source code of any substantial portion of the Covered 00045 * Code or modification with rights to further distribute source must include 00046 * the above Copyright Notice, the above License, this list of Conditions, 00047 * and the following Disclaimer and Export Compliance provision. In addition, 00048 * Licensee must cause all Covered Code to which Licensee contributes to 00049 * contain a file documenting the changes Licensee made to create that Covered 00050 * Code and the date of any change. Licensee must include in that file the 00051 * documentation of any changes made by any predecessor Licensee. Licensee 00052 * must include a prominent statement that the modification is derived, 00053 * directly or indirectly, from Original Intel Code. 00054 * 00055 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 00056 * Redistribution of source code of any substantial portion of the Covered 00057 * Code or modification without rights to further distribute source must 00058 * include the following Disclaimer and Export Compliance provision in the 00059 * documentation and/or other materials provided with distribution. In 00060 * addition, Licensee may not authorize further sublicense of source of any 00061 * portion of the Covered Code, and must include terms to the effect that the 00062 * license from Licensee to its licensee is limited to the intellectual 00063 * property embodied in the software Licensee provides to its licensee, and 00064 * not to intellectual property embodied in modifications its licensee may 00065 * make. 00066 * 00067 * 3.3. Redistribution of Executable. Redistribution in executable form of any 00068 * substantial portion of the Covered Code or modification must reproduce the 00069 * above Copyright Notice, and the following Disclaimer and Export Compliance 00070 * provision in the documentation and/or other materials provided with the 00071 * distribution. 00072 * 00073 * 3.4. Intel retains all right, title, and interest in and to the Original 00074 * Intel Code. 00075 * 00076 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 00077 * Intel shall be used in advertising or otherwise to promote the sale, use or 00078 * other dealings in products derived from or relating to the Covered Code 00079 * without prior written authorization from Intel. 00080 * 00081 * 4. Disclaimer and Export Compliance 00082 * 00083 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 00084 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 00085 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 00086 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 00087 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 00088 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 00089 * PARTICULAR PURPOSE. 00090 * 00091 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 00092 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 00093 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 00094 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 00095 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 00096 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 00097 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 00098 * LIMITED REMEDY. 00099 * 00100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 00101 * software or system incorporating such software without first obtaining any 00102 * required license or other approval from the U. S. Department of Commerce or 00103 * any other agency or department of the United States Government. In the 00104 * event Licensee exports any such software from the United States or 00105 * re-exports any such software from a foreign destination, Licensee shall 00106 * ensure that the distribution and export/re-export of the software is in 00107 * compliance with all laws, regulations, orders, or other restrictions of the 00108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 00109 * any of its subsidiaries will export/re-export any technical data, process, 00110 * software, or service, directly or indirectly, to any country for which the 00111 * United States government or any agency thereof requires an export license, 00112 * other governmental approval, or letter of assurance, without first obtaining 00113 * such license, approval or letter. 00114 * 00115 *****************************************************************************/ 00116 00117 00118 #define __NSXFEVAL_C__ 00119 00120 #include "acpi.h" 00121 #include "accommon.h" 00122 #include "acnamesp.h" 00123 #include "acinterp.h" 00124 00125 00126 #define _COMPONENT ACPI_NAMESPACE 00127 ACPI_MODULE_NAME ("nsxfeval") 00128 00129 /* Local prototypes */ 00130 00131 static void 00132 AcpiNsResolveReferences ( 00133 ACPI_EVALUATE_INFO *Info); 00134 00135 00136 /******************************************************************************* 00137 * 00138 * FUNCTION: AcpiEvaluateObjectTyped 00139 * 00140 * PARAMETERS: Handle - Object handle (optional) 00141 * Pathname - Object pathname (optional) 00142 * ExternalParams - List of parameters to pass to method, 00143 * terminated by NULL. May be NULL 00144 * if no parameters are being passed. 00145 * ReturnBuffer - Where to put method's return value (if 00146 * any). If NULL, no value is returned. 00147 * ReturnType - Expected type of return object 00148 * 00149 * RETURN: Status 00150 * 00151 * DESCRIPTION: Find and evaluate the given object, passing the given 00152 * parameters if necessary. One of "Handle" or "Pathname" must 00153 * be valid (non-null) 00154 * 00155 ******************************************************************************/ 00156 00157 ACPI_STATUS 00158 AcpiEvaluateObjectTyped ( 00159 ACPI_HANDLE Handle, 00160 ACPI_STRING Pathname, 00161 ACPI_OBJECT_LIST *ExternalParams, 00162 ACPI_BUFFER *ReturnBuffer, 00163 ACPI_OBJECT_TYPE ReturnType) 00164 { 00165 ACPI_STATUS Status; 00166 BOOLEAN MustFree = FALSE; 00167 00168 00169 ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); 00170 00171 00172 /* Return buffer must be valid */ 00173 00174 if (!ReturnBuffer) 00175 { 00176 return_ACPI_STATUS (AE_BAD_PARAMETER); 00177 } 00178 00179 if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) 00180 { 00181 MustFree = TRUE; 00182 } 00183 00184 /* Evaluate the object */ 00185 00186 Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer); 00187 if (ACPI_FAILURE (Status)) 00188 { 00189 return_ACPI_STATUS (Status); 00190 } 00191 00192 /* Type ANY means "don't care" */ 00193 00194 if (ReturnType == ACPI_TYPE_ANY) 00195 { 00196 return_ACPI_STATUS (AE_OK); 00197 } 00198 00199 if (ReturnBuffer->Length == 0) 00200 { 00201 /* Error because caller specifically asked for a return value */ 00202 00203 ACPI_ERROR ((AE_INFO, "No return value")); 00204 return_ACPI_STATUS (AE_NULL_OBJECT); 00205 } 00206 00207 /* Examine the object type returned from EvaluateObject */ 00208 00209 if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) 00210 { 00211 return_ACPI_STATUS (AE_OK); 00212 } 00213 00214 /* Return object type does not match requested type */ 00215 00216 ACPI_ERROR ((AE_INFO, 00217 "Incorrect return type [%s] requested [%s]", 00218 AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), 00219 AcpiUtGetTypeName (ReturnType))); 00220 00221 if (MustFree) 00222 { 00223 /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ 00224 00225 AcpiOsFree (ReturnBuffer->Pointer); 00226 ReturnBuffer->Pointer = NULL; 00227 } 00228 00229 ReturnBuffer->Length = 0; 00230 return_ACPI_STATUS (AE_TYPE); 00231 } 00232 00233 ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped) 00234 00235 00236 /******************************************************************************* 00237 * 00238 * FUNCTION: AcpiEvaluateObject 00239 * 00240 * PARAMETERS: Handle - Object handle (optional) 00241 * Pathname - Object pathname (optional) 00242 * ExternalParams - List of parameters to pass to method, 00243 * terminated by NULL. May be NULL 00244 * if no parameters are being passed. 00245 * ReturnBuffer - Where to put method's return value (if 00246 * any). If NULL, no value is returned. 00247 * 00248 * RETURN: Status 00249 * 00250 * DESCRIPTION: Find and evaluate the given object, passing the given 00251 * parameters if necessary. One of "Handle" or "Pathname" must 00252 * be valid (non-null) 00253 * 00254 ******************************************************************************/ 00255 00256 ACPI_STATUS 00257 AcpiEvaluateObject ( 00258 ACPI_HANDLE Handle, 00259 ACPI_STRING Pathname, 00260 ACPI_OBJECT_LIST *ExternalParams, 00261 ACPI_BUFFER *ReturnBuffer) 00262 { 00263 ACPI_STATUS Status; 00264 ACPI_EVALUATE_INFO *Info; 00265 ACPI_SIZE BufferSpaceNeeded; 00266 UINT32 i; 00267 00268 00269 ACPI_FUNCTION_TRACE (AcpiEvaluateObject); 00270 00271 00272 /* Allocate and initialize the evaluation information block */ 00273 00274 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 00275 if (!Info) 00276 { 00277 return_ACPI_STATUS (AE_NO_MEMORY); 00278 } 00279 00280 Info->Pathname = Pathname; 00281 00282 /* Convert and validate the device handle */ 00283 00284 Info->PrefixNode = AcpiNsValidateHandle (Handle); 00285 if (!Info->PrefixNode) 00286 { 00287 Status = AE_BAD_PARAMETER; 00288 goto Cleanup; 00289 } 00290 00291 /* 00292 * If there are parameters to be passed to a control method, the external 00293 * objects must all be converted to internal objects 00294 */ 00295 if (ExternalParams && ExternalParams->Count) 00296 { 00297 /* 00298 * Allocate a new parameter block for the internal objects 00299 * Add 1 to count to allow for null terminated internal list 00300 */ 00301 Info->Parameters = ACPI_ALLOCATE_ZEROED ( 00302 ((ACPI_SIZE) ExternalParams->Count + 1) * sizeof (void *)); 00303 if (!Info->Parameters) 00304 { 00305 Status = AE_NO_MEMORY; 00306 goto Cleanup; 00307 } 00308 00309 /* Convert each external object in the list to an internal object */ 00310 00311 for (i = 0; i < ExternalParams->Count; i++) 00312 { 00313 Status = AcpiUtCopyEobjectToIobject ( 00314 &ExternalParams->Pointer[i], &Info->Parameters[i]); 00315 if (ACPI_FAILURE (Status)) 00316 { 00317 goto Cleanup; 00318 } 00319 } 00320 Info->Parameters[ExternalParams->Count] = NULL; 00321 } 00322 00323 /* 00324 * Three major cases: 00325 * 1) Fully qualified pathname 00326 * 2) No handle, not fully qualified pathname (error) 00327 * 3) Valid handle 00328 */ 00329 if ((Pathname) && 00330 (AcpiNsValidRootPrefix (Pathname[0]))) 00331 { 00332 /* The path is fully qualified, just evaluate by name */ 00333 00334 Info->PrefixNode = NULL; 00335 Status = AcpiNsEvaluate (Info); 00336 } 00337 else if (!Handle) 00338 { 00339 /* 00340 * A handle is optional iff a fully qualified pathname is specified. 00341 * Since we've already handled fully qualified names above, this is 00342 * an error 00343 */ 00344 if (!Pathname) 00345 { 00346 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 00347 "Both Handle and Pathname are NULL")); 00348 } 00349 else 00350 { 00351 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 00352 "Null Handle with relative pathname [%s]", Pathname)); 00353 } 00354 00355 Status = AE_BAD_PARAMETER; 00356 } 00357 else 00358 { 00359 /* We have a namespace a node and a possible relative path */ 00360 00361 Status = AcpiNsEvaluate (Info); 00362 } 00363 00364 /* 00365 * If we are expecting a return value, and all went well above, 00366 * copy the return value to an external object. 00367 */ 00368 if (ReturnBuffer) 00369 { 00370 if (!Info->ReturnObject) 00371 { 00372 ReturnBuffer->Length = 0; 00373 } 00374 else 00375 { 00376 if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) == 00377 ACPI_DESC_TYPE_NAMED) 00378 { 00379 /* 00380 * If we received a NS Node as a return object, this means that 00381 * the object we are evaluating has nothing interesting to 00382 * return (such as a mutex, etc.) We return an error because 00383 * these types are essentially unsupported by this interface. 00384 * We don't check up front because this makes it easier to add 00385 * support for various types at a later date if necessary. 00386 */ 00387 Status = AE_TYPE; 00388 Info->ReturnObject = NULL; /* No need to delete a NS Node */ 00389 ReturnBuffer->Length = 0; 00390 } 00391 00392 if (ACPI_SUCCESS (Status)) 00393 { 00394 /* Dereference Index and RefOf references */ 00395 00396 AcpiNsResolveReferences (Info); 00397 00398 /* Get the size of the returned object */ 00399 00400 Status = AcpiUtGetObjectSize (Info->ReturnObject, 00401 &BufferSpaceNeeded); 00402 if (ACPI_SUCCESS (Status)) 00403 { 00404 /* Validate/Allocate/Clear caller buffer */ 00405 00406 Status = AcpiUtInitializeBuffer (ReturnBuffer, 00407 BufferSpaceNeeded); 00408 if (ACPI_FAILURE (Status)) 00409 { 00410 /* 00411 * Caller's buffer is too small or a new one can't 00412 * be allocated 00413 */ 00414 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 00415 "Needed buffer size %X, %s\n", 00416 (UINT32) BufferSpaceNeeded, 00417 AcpiFormatException (Status))); 00418 } 00419 else 00420 { 00421 /* We have enough space for the object, build it */ 00422 00423 Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject, 00424 ReturnBuffer); 00425 } 00426 } 00427 } 00428 } 00429 } 00430 00431 if (Info->ReturnObject) 00432 { 00433 /* 00434 * Delete the internal return object. NOTE: Interpreter must be 00435 * locked to avoid race condition. 00436 */ 00437 AcpiExEnterInterpreter (); 00438 00439 /* Remove one reference on the return object (should delete it) */ 00440 00441 AcpiUtRemoveReference (Info->ReturnObject); 00442 AcpiExExitInterpreter (); 00443 } 00444 00445 00446 Cleanup: 00447 00448 /* Free the input parameter list (if we created one) */ 00449 00450 if (Info->Parameters) 00451 { 00452 /* Free the allocated parameter block */ 00453 00454 AcpiUtDeleteInternalObjectList (Info->Parameters); 00455 } 00456 00457 ACPI_FREE (Info); 00458 return_ACPI_STATUS (Status); 00459 } 00460 00461 ACPI_EXPORT_SYMBOL (AcpiEvaluateObject) 00462 00463 00464 /******************************************************************************* 00465 * 00466 * FUNCTION: AcpiNsResolveReferences 00467 * 00468 * PARAMETERS: Info - Evaluation info block 00469 * 00470 * RETURN: Info->ReturnObject is replaced with the dereferenced object 00471 * 00472 * DESCRIPTION: Dereference certain reference objects. Called before an 00473 * internal return object is converted to an external ACPI_OBJECT. 00474 * 00475 * Performs an automatic dereference of Index and RefOf reference objects. 00476 * These reference objects are not supported by the ACPI_OBJECT, so this is a 00477 * last resort effort to return something useful. Also, provides compatibility 00478 * with other ACPI implementations. 00479 * 00480 * NOTE: does not handle references within returned package objects or nested 00481 * references, but this support could be added later if found to be necessary. 00482 * 00483 ******************************************************************************/ 00484 00485 static void 00486 AcpiNsResolveReferences ( 00487 ACPI_EVALUATE_INFO *Info) 00488 { 00489 ACPI_OPERAND_OBJECT *ObjDesc = NULL; 00490 ACPI_NAMESPACE_NODE *Node; 00491 00492 00493 /* We are interested in reference objects only */ 00494 00495 if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) 00496 { 00497 return; 00498 } 00499 00500 /* 00501 * Two types of references are supported - those created by Index and 00502 * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted 00503 * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle 00504 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to 00505 * an ACPI_OBJECT. 00506 */ 00507 switch (Info->ReturnObject->Reference.Class) 00508 { 00509 case ACPI_REFCLASS_INDEX: 00510 00511 ObjDesc = *(Info->ReturnObject->Reference.Where); 00512 break; 00513 00514 case ACPI_REFCLASS_REFOF: 00515 00516 Node = Info->ReturnObject->Reference.Object; 00517 if (Node) 00518 { 00519 ObjDesc = Node->Object; 00520 } 00521 break; 00522 00523 default: 00524 return; 00525 } 00526 00527 /* Replace the existing reference object */ 00528 00529 if (ObjDesc) 00530 { 00531 AcpiUtAddReference (ObjDesc); 00532 AcpiUtRemoveReference (Info->ReturnObject); 00533 Info->ReturnObject = ObjDesc; 00534 } 00535 00536 return; 00537 } 00538 00539 00540 /******************************************************************************* 00541 * 00542 * FUNCTION: AcpiWalkNamespace 00543 * 00544 * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 00545 * StartObject - Handle in namespace where search begins 00546 * MaxDepth - Depth to which search is to reach 00547 * PreOrderVisit - Called during tree pre-order visit 00548 * when an object of "Type" is found 00549 * PostOrderVisit - Called during tree post-order visit 00550 * when an object of "Type" is found 00551 * Context - Passed to user function(s) above 00552 * ReturnValue - Location where return value of 00553 * UserFunction is put if terminated early 00554 * 00555 * RETURNS Return value from the UserFunction if terminated early. 00556 * Otherwise, returns NULL. 00557 * 00558 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 00559 * starting (and ending) at the object specified by StartHandle. 00560 * The callback function is called whenever an object that matches 00561 * the type parameter is found. If the callback function returns 00562 * a non-zero value, the search is terminated immediately and this 00563 * value is returned to the caller. 00564 * 00565 * The point of this procedure is to provide a generic namespace 00566 * walk routine that can be called from multiple places to 00567 * provide multiple services; the callback function(s) can be 00568 * tailored to each task, whether it is a print function, 00569 * a compare function, etc. 00570 * 00571 ******************************************************************************/ 00572 00573 ACPI_STATUS 00574 AcpiWalkNamespace ( 00575 ACPI_OBJECT_TYPE Type, 00576 ACPI_HANDLE StartObject, 00577 UINT32 MaxDepth, 00578 ACPI_WALK_CALLBACK PreOrderVisit, 00579 ACPI_WALK_CALLBACK PostOrderVisit, 00580 void *Context, 00581 void **ReturnValue) 00582 { 00583 ACPI_STATUS Status; 00584 00585 00586 ACPI_FUNCTION_TRACE (AcpiWalkNamespace); 00587 00588 00589 /* Parameter validation */ 00590 00591 if ((Type > ACPI_TYPE_LOCAL_MAX) || 00592 (!MaxDepth) || 00593 (!PreOrderVisit && !PostOrderVisit)) 00594 { 00595 return_ACPI_STATUS (AE_BAD_PARAMETER); 00596 } 00597 00598 /* 00599 * Need to acquire the namespace reader lock to prevent interference 00600 * with any concurrent table unloads (which causes the deletion of 00601 * namespace objects). We cannot allow the deletion of a namespace node 00602 * while the user function is using it. The exception to this are the 00603 * nodes created and deleted during control method execution -- these 00604 * nodes are marked as temporary nodes and are ignored by the namespace 00605 * walk. Thus, control methods can be executed while holding the 00606 * namespace deletion lock (and the user function can execute control 00607 * methods.) 00608 */ 00609 Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock); 00610 if (ACPI_FAILURE (Status)) 00611 { 00612 return (Status); 00613 } 00614 00615 /* 00616 * Lock the namespace around the walk. The namespace will be 00617 * unlocked/locked around each call to the user function - since the user 00618 * function must be allowed to make ACPICA calls itself (for example, it 00619 * will typically execute control methods during device enumeration.) 00620 */ 00621 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00622 if (ACPI_FAILURE (Status)) 00623 { 00624 goto UnlockAndExit; 00625 } 00626 00627 Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, 00628 ACPI_NS_WALK_UNLOCK, PreOrderVisit, 00629 PostOrderVisit, Context, ReturnValue); 00630 00631 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00632 00633 UnlockAndExit: 00634 (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock); 00635 return_ACPI_STATUS (Status); 00636 } 00637 00638 ACPI_EXPORT_SYMBOL (AcpiWalkNamespace) 00639 00640 00641 /******************************************************************************* 00642 * 00643 * FUNCTION: AcpiNsGetDeviceCallback 00644 * 00645 * PARAMETERS: Callback from AcpiGetDevice 00646 * 00647 * RETURN: Status 00648 * 00649 * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 00650 * present devices, or if they specified a HID, it filters based 00651 * on that. 00652 * 00653 ******************************************************************************/ 00654 00655 static ACPI_STATUS 00656 AcpiNsGetDeviceCallback ( 00657 ACPI_HANDLE ObjHandle, 00658 UINT32 NestingLevel, 00659 void *Context, 00660 void **ReturnValue) 00661 { 00662 ACPI_GET_DEVICES_INFO *Info = Context; 00663 ACPI_STATUS Status; 00664 ACPI_NAMESPACE_NODE *Node; 00665 UINT32 Flags; 00666 ACPI_DEVICE_ID *Hid; 00667 ACPI_DEVICE_ID_LIST *Cid; 00668 UINT32 i; 00669 BOOLEAN Found; 00670 int NoMatch; 00671 00672 00673 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00674 if (ACPI_FAILURE (Status)) 00675 { 00676 return (Status); 00677 } 00678 00679 Node = AcpiNsValidateHandle (ObjHandle); 00680 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00681 if (ACPI_FAILURE (Status)) 00682 { 00683 return (Status); 00684 } 00685 00686 if (!Node) 00687 { 00688 return (AE_BAD_PARAMETER); 00689 } 00690 00691 /* 00692 * First, filter based on the device HID and CID. 00693 * 00694 * 01/2010: For this case where a specific HID is requested, we don't 00695 * want to run _STA until we have an actual HID match. Thus, we will 00696 * not unnecessarily execute _STA on devices for which the caller 00697 * doesn't care about. Previously, _STA was executed unconditionally 00698 * on all devices found here. 00699 * 00700 * A side-effect of this change is that now we will continue to search 00701 * for a matching HID even under device trees where the parent device 00702 * would have returned a _STA that indicates it is not present or 00703 * not functioning (thus aborting the search on that branch). 00704 */ 00705 if (Info->Hid != NULL) 00706 { 00707 Status = AcpiUtExecute_HID (Node, &Hid); 00708 if (Status == AE_NOT_FOUND) 00709 { 00710 return (AE_OK); 00711 } 00712 else if (ACPI_FAILURE (Status)) 00713 { 00714 return (AE_CTRL_DEPTH); 00715 } 00716 00717 NoMatch = ACPI_STRCMP (Hid->String, Info->Hid); 00718 ACPI_FREE (Hid); 00719 00720 if (NoMatch) 00721 { 00722 /* 00723 * HID does not match, attempt match within the 00724 * list of Compatible IDs (CIDs) 00725 */ 00726 Status = AcpiUtExecute_CID (Node, &Cid); 00727 if (Status == AE_NOT_FOUND) 00728 { 00729 return (AE_OK); 00730 } 00731 else if (ACPI_FAILURE (Status)) 00732 { 00733 return (AE_CTRL_DEPTH); 00734 } 00735 00736 /* Walk the CID list */ 00737 00738 Found = FALSE; 00739 for (i = 0; i < Cid->Count; i++) 00740 { 00741 if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0) 00742 { 00743 /* Found a matching CID */ 00744 00745 Found = TRUE; 00746 break; 00747 } 00748 } 00749 00750 ACPI_FREE (Cid); 00751 if (!Found) 00752 { 00753 return (AE_OK); 00754 } 00755 } 00756 } 00757 00758 /* Run _STA to determine if device is present */ 00759 00760 Status = AcpiUtExecute_STA (Node, &Flags); 00761 if (ACPI_FAILURE (Status)) 00762 { 00763 return (AE_CTRL_DEPTH); 00764 } 00765 00766 if (!(Flags & ACPI_STA_DEVICE_PRESENT) && 00767 !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) 00768 { 00769 /* 00770 * Don't examine the children of the device only when the 00771 * device is neither present nor functional. See ACPI spec, 00772 * description of _STA for more information. 00773 */ 00774 return (AE_CTRL_DEPTH); 00775 } 00776 00777 /* We have a valid device, invoke the user function */ 00778 00779 Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, 00780 ReturnValue); 00781 return (Status); 00782 } 00783 00784 00785 /******************************************************************************* 00786 * 00787 * FUNCTION: AcpiGetDevices 00788 * 00789 * PARAMETERS: HID - HID to search for. Can be NULL. 00790 * UserFunction - Called when a matching object is found 00791 * Context - Passed to user function 00792 * ReturnValue - Location where return value of 00793 * UserFunction is put if terminated early 00794 * 00795 * RETURNS Return value from the UserFunction if terminated early. 00796 * Otherwise, returns NULL. 00797 * 00798 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 00799 * starting (and ending) at the object specified by StartHandle. 00800 * The UserFunction is called whenever an object of type 00801 * Device is found. If the user function returns 00802 * a non-zero value, the search is terminated immediately and this 00803 * value is returned to the caller. 00804 * 00805 * This is a wrapper for WalkNamespace, but the callback performs 00806 * additional filtering. Please see AcpiNsGetDeviceCallback. 00807 * 00808 ******************************************************************************/ 00809 00810 ACPI_STATUS 00811 AcpiGetDevices ( 00812 char *HID, 00813 ACPI_WALK_CALLBACK UserFunction, 00814 void *Context, 00815 void **ReturnValue) 00816 { 00817 ACPI_STATUS Status; 00818 ACPI_GET_DEVICES_INFO Info; 00819 00820 00821 ACPI_FUNCTION_TRACE (AcpiGetDevices); 00822 00823 00824 /* Parameter validation */ 00825 00826 if (!UserFunction) 00827 { 00828 return_ACPI_STATUS (AE_BAD_PARAMETER); 00829 } 00830 00831 /* 00832 * We're going to call their callback from OUR callback, so we need 00833 * to know what it is, and their context parameter. 00834 */ 00835 Info.Hid = HID; 00836 Info.Context = Context; 00837 Info.UserFunction = UserFunction; 00838 00839 /* 00840 * Lock the namespace around the walk. 00841 * The namespace will be unlocked/locked around each call 00842 * to the user function - since this function 00843 * must be allowed to make Acpi calls itself. 00844 */ 00845 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00846 if (ACPI_FAILURE (Status)) 00847 { 00848 return_ACPI_STATUS (Status); 00849 } 00850 00851 Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 00852 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 00853 AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue); 00854 00855 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00856 return_ACPI_STATUS (Status); 00857 } 00858 00859 ACPI_EXPORT_SYMBOL (AcpiGetDevices) 00860 00861 00862 /******************************************************************************* 00863 * 00864 * FUNCTION: AcpiAttachData 00865 * 00866 * PARAMETERS: ObjHandle - Namespace node 00867 * Handler - Handler for this attachment 00868 * Data - Pointer to data to be attached 00869 * 00870 * RETURN: Status 00871 * 00872 * DESCRIPTION: Attach arbitrary data and handler to a namespace node. 00873 * 00874 ******************************************************************************/ 00875 00876 ACPI_STATUS 00877 AcpiAttachData ( 00878 ACPI_HANDLE ObjHandle, 00879 ACPI_OBJECT_HANDLER Handler, 00880 void *Data) 00881 { 00882 ACPI_NAMESPACE_NODE *Node; 00883 ACPI_STATUS Status; 00884 00885 00886 /* Parameter validation */ 00887 00888 if (!ObjHandle || 00889 !Handler || 00890 !Data) 00891 { 00892 return (AE_BAD_PARAMETER); 00893 } 00894 00895 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00896 if (ACPI_FAILURE (Status)) 00897 { 00898 return (Status); 00899 } 00900 00901 /* Convert and validate the handle */ 00902 00903 Node = AcpiNsValidateHandle (ObjHandle); 00904 if (!Node) 00905 { 00906 Status = AE_BAD_PARAMETER; 00907 goto UnlockAndExit; 00908 } 00909 00910 Status = AcpiNsAttachData (Node, Handler, Data); 00911 00912 UnlockAndExit: 00913 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00914 return (Status); 00915 } 00916 00917 ACPI_EXPORT_SYMBOL (AcpiAttachData) 00918 00919 00920 /******************************************************************************* 00921 * 00922 * FUNCTION: AcpiDetachData 00923 * 00924 * PARAMETERS: ObjHandle - Namespace node handle 00925 * Handler - Handler used in call to AcpiAttachData 00926 * 00927 * RETURN: Status 00928 * 00929 * DESCRIPTION: Remove data that was previously attached to a node. 00930 * 00931 ******************************************************************************/ 00932 00933 ACPI_STATUS 00934 AcpiDetachData ( 00935 ACPI_HANDLE ObjHandle, 00936 ACPI_OBJECT_HANDLER Handler) 00937 { 00938 ACPI_NAMESPACE_NODE *Node; 00939 ACPI_STATUS Status; 00940 00941 00942 /* Parameter validation */ 00943 00944 if (!ObjHandle || 00945 !Handler) 00946 { 00947 return (AE_BAD_PARAMETER); 00948 } 00949 00950 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 00951 if (ACPI_FAILURE (Status)) 00952 { 00953 return (Status); 00954 } 00955 00956 /* Convert and validate the handle */ 00957 00958 Node = AcpiNsValidateHandle (ObjHandle); 00959 if (!Node) 00960 { 00961 Status = AE_BAD_PARAMETER; 00962 goto UnlockAndExit; 00963 } 00964 00965 Status = AcpiNsDetachData (Node, Handler); 00966 00967 UnlockAndExit: 00968 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 00969 return (Status); 00970 } 00971 00972 ACPI_EXPORT_SYMBOL (AcpiDetachData) 00973 00974 00975 /******************************************************************************* 00976 * 00977 * FUNCTION: AcpiGetData 00978 * 00979 * PARAMETERS: ObjHandle - Namespace node 00980 * Handler - Handler used in call to AttachData 00981 * Data - Where the data is returned 00982 * 00983 * RETURN: Status 00984 * 00985 * DESCRIPTION: Retrieve data that was previously attached to a namespace node. 00986 * 00987 ******************************************************************************/ 00988 00989 ACPI_STATUS 00990 AcpiGetData ( 00991 ACPI_HANDLE ObjHandle, 00992 ACPI_OBJECT_HANDLER Handler, 00993 void **Data) 00994 { 00995 ACPI_NAMESPACE_NODE *Node; 00996 ACPI_STATUS Status; 00997 00998 00999 /* Parameter validation */ 01000 01001 if (!ObjHandle || 01002 !Handler || 01003 !Data) 01004 { 01005 return (AE_BAD_PARAMETER); 01006 } 01007 01008 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 01009 if (ACPI_FAILURE (Status)) 01010 { 01011 return (Status); 01012 } 01013 01014 /* Convert and validate the handle */ 01015 01016 Node = AcpiNsValidateHandle (ObjHandle); 01017 if (!Node) 01018 { 01019 Status = AE_BAD_PARAMETER; 01020 goto UnlockAndExit; 01021 } 01022 01023 Status = AcpiNsGetAttachedData (Node, Handler, Data); 01024 01025 UnlockAndExit: 01026 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 01027 return (Status); 01028 } 01029 01030 ACPI_EXPORT_SYMBOL (AcpiGetData) 01031 01032 Generated on Sun May 27 2012 04:27:21 for ReactOS by
1.7.6.1
|