![]() |
|
|||
File indexing completed on 2025-05-11 08:24:03
0001 /******************************************************************************* 0002 * 0003 * Module Name: nsxfeval - Public interfaces to the ACPI subsystem 0004 * ACPI Object evaluation interfaces 0005 * 0006 ******************************************************************************/ 0007 0008 /****************************************************************************** 0009 * 0010 * 1. Copyright Notice 0011 * 0012 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 0013 * All rights reserved. 0014 * 0015 * 2. License 0016 * 0017 * 2.1. This is your license from Intel Corp. under its intellectual property 0018 * rights. You may have additional license terms from the party that provided 0019 * you this software, covering your right to use that party's intellectual 0020 * property rights. 0021 * 0022 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0023 * copy of the source code appearing in this file ("Covered Code") an 0024 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0025 * base code distributed originally by Intel ("Original Intel Code") to copy, 0026 * make derivatives, distribute, use and display any portion of the Covered 0027 * Code in any form, with the right to sublicense such rights; and 0028 * 0029 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0030 * license (with the right to sublicense), under only those claims of Intel 0031 * patents that are infringed by the Original Intel Code, to make, use, sell, 0032 * offer to sell, and import the Covered Code and derivative works thereof 0033 * solely to the minimum extent necessary to exercise the above copyright 0034 * license, and in no event shall the patent license extend to any additions 0035 * to or modifications of the Original Intel Code. No other license or right 0036 * is granted directly or by implication, estoppel or otherwise; 0037 * 0038 * The above copyright and patent license is granted only if the following 0039 * conditions are met: 0040 * 0041 * 3. Conditions 0042 * 0043 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0044 * Redistribution of source code of any substantial portion of the Covered 0045 * Code or modification with rights to further distribute source must include 0046 * the above Copyright Notice, the above License, this list of Conditions, 0047 * and the following Disclaimer and Export Compliance provision. In addition, 0048 * Licensee must cause all Covered Code to which Licensee contributes to 0049 * contain a file documenting the changes Licensee made to create that Covered 0050 * Code and the date of any change. Licensee must include in that file the 0051 * documentation of any changes made by any predecessor Licensee. Licensee 0052 * must include a prominent statement that the modification is derived, 0053 * directly or indirectly, from Original Intel Code. 0054 * 0055 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0056 * Redistribution of source code of any substantial portion of the Covered 0057 * Code or modification without rights to further distribute source must 0058 * include the following Disclaimer and Export Compliance provision in the 0059 * documentation and/or other materials provided with distribution. In 0060 * addition, Licensee may not authorize further sublicense of source of any 0061 * portion of the Covered Code, and must include terms to the effect that the 0062 * license from Licensee to its licensee is limited to the intellectual 0063 * property embodied in the software Licensee provides to its licensee, and 0064 * not to intellectual property embodied in modifications its licensee may 0065 * make. 0066 * 0067 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0068 * substantial portion of the Covered Code or modification must reproduce the 0069 * above Copyright Notice, and the following Disclaimer and Export Compliance 0070 * provision in the documentation and/or other materials provided with the 0071 * distribution. 0072 * 0073 * 3.4. Intel retains all right, title, and interest in and to the Original 0074 * Intel Code. 0075 * 0076 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0077 * Intel shall be used in advertising or otherwise to promote the sale, use or 0078 * other dealings in products derived from or relating to the Covered Code 0079 * without prior written authorization from Intel. 0080 * 0081 * 4. Disclaimer and Export Compliance 0082 * 0083 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0084 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0085 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0086 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0087 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0088 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0089 * PARTICULAR PURPOSE. 0090 * 0091 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0092 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0093 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0094 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0095 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0096 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0097 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0098 * LIMITED REMEDY. 0099 * 0100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0101 * software or system incorporating such software without first obtaining any 0102 * required license or other approval from the U. S. Department of Commerce or 0103 * any other agency or department of the United States Government. In the 0104 * event Licensee exports any such software from the United States or 0105 * re-exports any such software from a foreign destination, Licensee shall 0106 * ensure that the distribution and export/re-export of the software is in 0107 * compliance with all laws, regulations, orders, or other restrictions of the 0108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0109 * any of its subsidiaries will export/re-export any technical data, process, 0110 * software, or service, directly or indirectly, to any country for which the 0111 * United States government or any agency thereof requires an export license, 0112 * other governmental approval, or letter of assurance, without first obtaining 0113 * such license, approval or letter. 0114 * 0115 ***************************************************************************** 0116 * 0117 * Alternatively, you may choose to be licensed under the terms of the 0118 * following license: 0119 * 0120 * Redistribution and use in source and binary forms, with or without 0121 * modification, are permitted provided that the following conditions 0122 * are met: 0123 * 1. Redistributions of source code must retain the above copyright 0124 * notice, this list of conditions, and the following disclaimer, 0125 * without modification. 0126 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 0127 * substantially similar to the "NO WARRANTY" disclaimer below 0128 * ("Disclaimer") and any redistribution must be conditioned upon 0129 * including a substantially similar Disclaimer requirement for further 0130 * binary redistribution. 0131 * 3. Neither the names of the above-listed copyright holders nor the names 0132 * of any contributors may be used to endorse or promote products derived 0133 * from this software without specific prior written permission. 0134 * 0135 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0136 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0137 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0138 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0139 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0140 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0141 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0142 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0143 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0144 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0145 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0146 * 0147 * Alternatively, you may choose to be licensed under the terms of the 0148 * GNU General Public License ("GPL") version 2 as published by the Free 0149 * Software Foundation. 0150 * 0151 *****************************************************************************/ 0152 0153 #define EXPORT_ACPI_INTERFACES 0154 0155 #include "acpi.h" 0156 #include "accommon.h" 0157 #include "acnamesp.h" 0158 #include "acinterp.h" 0159 0160 0161 #define _COMPONENT ACPI_NAMESPACE 0162 ACPI_MODULE_NAME ("nsxfeval") 0163 0164 /* Local prototypes */ 0165 0166 static void 0167 AcpiNsResolveReferences ( 0168 ACPI_EVALUATE_INFO *Info); 0169 0170 0171 /******************************************************************************* 0172 * 0173 * FUNCTION: AcpiEvaluateObjectTyped 0174 * 0175 * PARAMETERS: Handle - Object handle (optional) 0176 * Pathname - Object pathname (optional) 0177 * ExternalParams - List of parameters to pass to a method, 0178 * terminated by NULL. May be NULL 0179 * if no parameters are being passed. 0180 * ReturnBuffer - Where to put the object return value (if 0181 * any). Required. 0182 * ReturnType - Expected type of return object 0183 * 0184 * RETURN: Status 0185 * 0186 * DESCRIPTION: Find and evaluate the given object, passing the given 0187 * parameters if necessary. One of "Handle" or "Pathname" must 0188 * be valid (non-null) 0189 * 0190 ******************************************************************************/ 0191 0192 ACPI_STATUS 0193 AcpiEvaluateObjectTyped ( 0194 ACPI_HANDLE Handle, 0195 ACPI_STRING Pathname, 0196 ACPI_OBJECT_LIST *ExternalParams, 0197 ACPI_BUFFER *ReturnBuffer, 0198 ACPI_OBJECT_TYPE ReturnType) 0199 { 0200 ACPI_STATUS Status; 0201 BOOLEAN FreeBufferOnError = FALSE; 0202 ACPI_HANDLE TargetHandle; 0203 char *FullPathname; 0204 0205 0206 ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); 0207 0208 0209 /* Return buffer must be valid */ 0210 0211 if (!ReturnBuffer) 0212 { 0213 return_ACPI_STATUS (AE_BAD_PARAMETER); 0214 } 0215 0216 if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) 0217 { 0218 FreeBufferOnError = TRUE; 0219 } 0220 0221 /* Get a handle here, in order to build an error message if needed */ 0222 0223 TargetHandle = Handle; 0224 if (Pathname) 0225 { 0226 Status = AcpiGetHandle (Handle, Pathname, &TargetHandle); 0227 if (ACPI_FAILURE (Status)) 0228 { 0229 return_ACPI_STATUS (Status); 0230 } 0231 } 0232 0233 FullPathname = AcpiNsGetExternalPathname (TargetHandle); 0234 if (!FullPathname) 0235 { 0236 return_ACPI_STATUS (AE_NO_MEMORY); 0237 } 0238 0239 /* Evaluate the object */ 0240 0241 Status = AcpiEvaluateObject (TargetHandle, NULL, ExternalParams, 0242 ReturnBuffer); 0243 if (ACPI_FAILURE (Status)) 0244 { 0245 goto Exit; 0246 } 0247 0248 /* Type ANY means "don't care about return value type" */ 0249 0250 if (ReturnType == ACPI_TYPE_ANY) 0251 { 0252 goto Exit; 0253 } 0254 0255 if (ReturnBuffer->Length == 0) 0256 { 0257 /* Error because caller specifically asked for a return value */ 0258 0259 ACPI_ERROR ((AE_INFO, "%s did not return any object", 0260 FullPathname)); 0261 Status = AE_NULL_OBJECT; 0262 goto Exit; 0263 } 0264 0265 /* Examine the object type returned from EvaluateObject */ 0266 0267 if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) 0268 { 0269 goto Exit; 0270 } 0271 0272 /* Return object type does not match requested type */ 0273 0274 ACPI_ERROR ((AE_INFO, 0275 "Incorrect return type from %s - received [%s], requested [%s]", 0276 FullPathname, 0277 AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), 0278 AcpiUtGetTypeName (ReturnType))); 0279 0280 if (FreeBufferOnError) 0281 { 0282 /* 0283 * Free a buffer created via ACPI_ALLOCATE_BUFFER. 0284 * Note: We use AcpiOsFree here because AcpiOsAllocate was used 0285 * to allocate the buffer. This purposefully bypasses the 0286 * (optionally enabled) allocation tracking mechanism since we 0287 * only want to track internal allocations. 0288 */ 0289 AcpiOsFree (ReturnBuffer->Pointer); 0290 ReturnBuffer->Pointer = NULL; 0291 } 0292 0293 ReturnBuffer->Length = 0; 0294 Status = AE_TYPE; 0295 0296 Exit: 0297 ACPI_FREE (FullPathname); 0298 return_ACPI_STATUS (Status); 0299 } 0300 0301 ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped) 0302 0303 0304 /******************************************************************************* 0305 * 0306 * FUNCTION: AcpiEvaluateObject 0307 * 0308 * PARAMETERS: Handle - Object handle (optional) 0309 * Pathname - Object pathname (optional) 0310 * ExternalParams - List of parameters to pass to method, 0311 * terminated by NULL. May be NULL 0312 * if no parameters are being passed. 0313 * ReturnBuffer - Where to put method's return value (if 0314 * any). If NULL, no value is returned. 0315 * 0316 * RETURN: Status 0317 * 0318 * DESCRIPTION: Find and evaluate the given object, passing the given 0319 * parameters if necessary. One of "Handle" or "Pathname" must 0320 * be valid (non-null) 0321 * 0322 ******************************************************************************/ 0323 0324 ACPI_STATUS 0325 AcpiEvaluateObject ( 0326 ACPI_HANDLE Handle, 0327 ACPI_STRING Pathname, 0328 ACPI_OBJECT_LIST *ExternalParams, 0329 ACPI_BUFFER *ReturnBuffer) 0330 { 0331 ACPI_STATUS Status; 0332 ACPI_EVALUATE_INFO *Info; 0333 ACPI_SIZE BufferSpaceNeeded; 0334 UINT32 i; 0335 0336 0337 ACPI_FUNCTION_TRACE (AcpiEvaluateObject); 0338 0339 0340 /* Allocate and initialize the evaluation information block */ 0341 0342 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 0343 if (!Info) 0344 { 0345 return_ACPI_STATUS (AE_NO_MEMORY); 0346 } 0347 0348 /* Convert and validate the device handle */ 0349 0350 Info->PrefixNode = AcpiNsValidateHandle (Handle); 0351 if (!Info->PrefixNode) 0352 { 0353 Status = AE_BAD_PARAMETER; 0354 goto Cleanup; 0355 } 0356 0357 /* 0358 * Get the actual namespace node for the target object. 0359 * Handles these cases: 0360 * 0361 * 1) Null node, valid pathname from root (absolute path) 0362 * 2) Node and valid pathname (path relative to Node) 0363 * 3) Node, Null pathname 0364 */ 0365 if ((Pathname) && 0366 (ACPI_IS_ROOT_PREFIX (Pathname[0]))) 0367 { 0368 /* The path is fully qualified, just evaluate by name */ 0369 0370 Info->PrefixNode = NULL; 0371 } 0372 else if (!Handle) 0373 { 0374 /* 0375 * A handle is optional iff a fully qualified pathname is specified. 0376 * Since we've already handled fully qualified names above, this is 0377 * an error. 0378 */ 0379 if (!Pathname) 0380 { 0381 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 0382 "Both Handle and Pathname are NULL")); 0383 } 0384 else 0385 { 0386 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 0387 "Null Handle with relative pathname [%s]", Pathname)); 0388 } 0389 0390 Status = AE_BAD_PARAMETER; 0391 goto Cleanup; 0392 } 0393 0394 Info->RelativePathname = Pathname; 0395 0396 /* 0397 * Convert all external objects passed as arguments to the 0398 * internal version(s). 0399 */ 0400 if (ExternalParams && ExternalParams->Count) 0401 { 0402 Info->ParamCount = (UINT16) ExternalParams->Count; 0403 0404 /* Warn on impossible argument count */ 0405 0406 if (Info->ParamCount > ACPI_METHOD_NUM_ARGS) 0407 { 0408 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 0409 "Excess arguments (%u) - using only %u", 0410 Info->ParamCount, ACPI_METHOD_NUM_ARGS)); 0411 0412 Info->ParamCount = ACPI_METHOD_NUM_ARGS; 0413 } 0414 0415 /* 0416 * Allocate a new parameter block for the internal objects 0417 * Add 1 to count to allow for null terminated internal list 0418 */ 0419 Info->Parameters = ACPI_ALLOCATE_ZEROED ( 0420 ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *)); 0421 if (!Info->Parameters) 0422 { 0423 Status = AE_NO_MEMORY; 0424 goto Cleanup; 0425 } 0426 0427 /* Convert each external object in the list to an internal object */ 0428 0429 for (i = 0; i < Info->ParamCount; i++) 0430 { 0431 Status = AcpiUtCopyEobjectToIobject ( 0432 &ExternalParams->Pointer[i], &Info->Parameters[i]); 0433 if (ACPI_FAILURE (Status)) 0434 { 0435 goto Cleanup; 0436 } 0437 } 0438 0439 Info->Parameters[Info->ParamCount] = NULL; 0440 } 0441 0442 0443 #ifdef _FUTURE_FEATURE 0444 0445 /* 0446 * Begin incoming argument count analysis. Check for too few args 0447 * and too many args. 0448 */ 0449 switch (AcpiNsGetType (Info->Node)) 0450 { 0451 case ACPI_TYPE_METHOD: 0452 0453 /* Check incoming argument count against the method definition */ 0454 0455 if (Info->ObjDesc->Method.ParamCount > Info->ParamCount) 0456 { 0457 ACPI_ERROR ((AE_INFO, 0458 "Insufficient arguments (%u) - %u are required", 0459 Info->ParamCount, 0460 Info->ObjDesc->Method.ParamCount)); 0461 0462 Status = AE_MISSING_ARGUMENTS; 0463 goto Cleanup; 0464 } 0465 0466 else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount) 0467 { 0468 ACPI_WARNING ((AE_INFO, 0469 "Excess arguments (%u) - only %u are required", 0470 Info->ParamCount, 0471 Info->ObjDesc->Method.ParamCount)); 0472 0473 /* Just pass the required number of arguments */ 0474 0475 Info->ParamCount = Info->ObjDesc->Method.ParamCount; 0476 } 0477 0478 /* 0479 * Any incoming external objects to be passed as arguments to the 0480 * method must be converted to internal objects 0481 */ 0482 if (Info->ParamCount) 0483 { 0484 /* 0485 * Allocate a new parameter block for the internal objects 0486 * Add 1 to count to allow for null terminated internal list 0487 */ 0488 Info->Parameters = ACPI_ALLOCATE_ZEROED ( 0489 ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *)); 0490 if (!Info->Parameters) 0491 { 0492 Status = AE_NO_MEMORY; 0493 goto Cleanup; 0494 } 0495 0496 /* Convert each external object in the list to an internal object */ 0497 0498 for (i = 0; i < Info->ParamCount; i++) 0499 { 0500 Status = AcpiUtCopyEobjectToIobject ( 0501 &ExternalParams->Pointer[i], &Info->Parameters[i]); 0502 if (ACPI_FAILURE (Status)) 0503 { 0504 goto Cleanup; 0505 } 0506 } 0507 0508 Info->Parameters[Info->ParamCount] = NULL; 0509 } 0510 break; 0511 0512 default: 0513 0514 /* Warn if arguments passed to an object that is not a method */ 0515 0516 if (Info->ParamCount) 0517 { 0518 ACPI_WARNING ((AE_INFO, 0519 "%u arguments were passed to a non-method ACPI object", 0520 Info->ParamCount)); 0521 } 0522 break; 0523 } 0524 0525 #endif 0526 0527 0528 /* Now we can evaluate the object */ 0529 0530 Status = AcpiNsEvaluate (Info); 0531 0532 /* 0533 * If we are expecting a return value, and all went well above, 0534 * copy the return value to an external object. 0535 */ 0536 if (!ReturnBuffer) 0537 { 0538 goto CleanupReturnObject; 0539 } 0540 0541 if (!Info->ReturnObject) 0542 { 0543 ReturnBuffer->Length = 0; 0544 goto Cleanup; 0545 } 0546 0547 if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) == 0548 ACPI_DESC_TYPE_NAMED) 0549 { 0550 /* 0551 * If we received a NS Node as a return object, this means that 0552 * the object we are evaluating has nothing interesting to 0553 * return (such as a mutex, etc.) We return an error because 0554 * these types are essentially unsupported by this interface. 0555 * We don't check up front because this makes it easier to add 0556 * support for various types at a later date if necessary. 0557 */ 0558 Status = AE_TYPE; 0559 Info->ReturnObject = NULL; /* No need to delete a NS Node */ 0560 ReturnBuffer->Length = 0; 0561 } 0562 0563 if (ACPI_FAILURE (Status)) 0564 { 0565 goto CleanupReturnObject; 0566 } 0567 0568 /* Dereference Index and RefOf references */ 0569 0570 AcpiNsResolveReferences (Info); 0571 0572 /* Get the size of the returned object */ 0573 0574 Status = AcpiUtGetObjectSize (Info->ReturnObject, 0575 &BufferSpaceNeeded); 0576 if (ACPI_SUCCESS (Status)) 0577 { 0578 /* Validate/Allocate/Clear caller buffer */ 0579 0580 Status = AcpiUtInitializeBuffer (ReturnBuffer, 0581 BufferSpaceNeeded); 0582 if (ACPI_FAILURE (Status)) 0583 { 0584 /* 0585 * Caller's buffer is too small or a new one can't 0586 * be allocated 0587 */ 0588 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 0589 "Needed buffer size %X, %s\n", 0590 (UINT32) BufferSpaceNeeded, 0591 AcpiFormatException (Status))); 0592 } 0593 else 0594 { 0595 /* We have enough space for the object, build it */ 0596 0597 Status = AcpiUtCopyIobjectToEobject ( 0598 Info->ReturnObject, ReturnBuffer); 0599 } 0600 } 0601 0602 CleanupReturnObject: 0603 0604 if (Info->ReturnObject) 0605 { 0606 /* 0607 * Delete the internal return object. NOTE: Interpreter must be 0608 * locked to avoid race condition. 0609 */ 0610 AcpiExEnterInterpreter (); 0611 0612 /* Remove one reference on the return object (should delete it) */ 0613 0614 AcpiUtRemoveReference (Info->ReturnObject); 0615 AcpiExExitInterpreter (); 0616 } 0617 0618 0619 Cleanup: 0620 0621 /* Free the input parameter list (if we created one) */ 0622 0623 if (Info->Parameters) 0624 { 0625 /* Free the allocated parameter block */ 0626 0627 AcpiUtDeleteInternalObjectList (Info->Parameters); 0628 } 0629 0630 ACPI_FREE (Info); 0631 return_ACPI_STATUS (Status); 0632 } 0633 0634 ACPI_EXPORT_SYMBOL (AcpiEvaluateObject) 0635 0636 0637 /******************************************************************************* 0638 * 0639 * FUNCTION: AcpiNsResolveReferences 0640 * 0641 * PARAMETERS: Info - Evaluation info block 0642 * 0643 * RETURN: Info->ReturnObject is replaced with the dereferenced object 0644 * 0645 * DESCRIPTION: Dereference certain reference objects. Called before an 0646 * internal return object is converted to an external ACPI_OBJECT. 0647 * 0648 * Performs an automatic dereference of Index and RefOf reference objects. 0649 * These reference objects are not supported by the ACPI_OBJECT, so this is a 0650 * last resort effort to return something useful. Also, provides compatibility 0651 * with other ACPI implementations. 0652 * 0653 * NOTE: does not handle references within returned package objects or nested 0654 * references, but this support could be added later if found to be necessary. 0655 * 0656 ******************************************************************************/ 0657 0658 static void 0659 AcpiNsResolveReferences ( 0660 ACPI_EVALUATE_INFO *Info) 0661 { 0662 ACPI_OPERAND_OBJECT *ObjDesc = NULL; 0663 ACPI_NAMESPACE_NODE *Node; 0664 0665 0666 /* We are interested in reference objects only */ 0667 0668 if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) 0669 { 0670 return; 0671 } 0672 0673 /* 0674 * Two types of references are supported - those created by Index and 0675 * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted 0676 * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle 0677 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to 0678 * an ACPI_OBJECT. 0679 */ 0680 switch (Info->ReturnObject->Reference.Class) 0681 { 0682 case ACPI_REFCLASS_INDEX: 0683 0684 ObjDesc = *(Info->ReturnObject->Reference.Where); 0685 break; 0686 0687 case ACPI_REFCLASS_REFOF: 0688 0689 Node = Info->ReturnObject->Reference.Object; 0690 if (Node) 0691 { 0692 ObjDesc = Node->Object; 0693 } 0694 break; 0695 0696 default: 0697 0698 return; 0699 } 0700 0701 /* Replace the existing reference object */ 0702 0703 if (ObjDesc) 0704 { 0705 AcpiUtAddReference (ObjDesc); 0706 AcpiUtRemoveReference (Info->ReturnObject); 0707 Info->ReturnObject = ObjDesc; 0708 } 0709 0710 return; 0711 } 0712 0713 0714 /******************************************************************************* 0715 * 0716 * FUNCTION: AcpiWalkNamespace 0717 * 0718 * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 0719 * StartObject - Handle in namespace where search begins 0720 * MaxDepth - Depth to which search is to reach 0721 * DescendingCallback - Called during tree descent 0722 * when an object of "Type" is found 0723 * AscendingCallback - Called during tree ascent 0724 * when an object of "Type" is found 0725 * Context - Passed to user function(s) above 0726 * ReturnValue - Location where return value of 0727 * UserFunction is put if terminated early 0728 * 0729 * RETURNS Return value from the UserFunction if terminated early. 0730 * Otherwise, returns NULL. 0731 * 0732 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 0733 * starting (and ending) at the object specified by StartHandle. 0734 * The callback function is called whenever an object that matches 0735 * the type parameter is found. If the callback function returns 0736 * a non-zero value, the search is terminated immediately and this 0737 * value is returned to the caller. 0738 * 0739 * The point of this procedure is to provide a generic namespace 0740 * walk routine that can be called from multiple places to 0741 * provide multiple services; the callback function(s) can be 0742 * tailored to each task, whether it is a print function, 0743 * a compare function, etc. 0744 * 0745 ******************************************************************************/ 0746 0747 ACPI_STATUS 0748 AcpiWalkNamespace ( 0749 ACPI_OBJECT_TYPE Type, 0750 ACPI_HANDLE StartObject, 0751 UINT32 MaxDepth, 0752 ACPI_WALK_CALLBACK DescendingCallback, 0753 ACPI_WALK_CALLBACK AscendingCallback, 0754 void *Context, 0755 void **ReturnValue) 0756 { 0757 ACPI_STATUS Status; 0758 0759 0760 ACPI_FUNCTION_TRACE (AcpiWalkNamespace); 0761 0762 0763 /* Parameter validation */ 0764 0765 if ((Type > ACPI_TYPE_LOCAL_MAX) || 0766 (!MaxDepth) || 0767 (!DescendingCallback && !AscendingCallback)) 0768 { 0769 return_ACPI_STATUS (AE_BAD_PARAMETER); 0770 } 0771 0772 /* 0773 * Need to acquire the namespace reader lock to prevent interference 0774 * with any concurrent table unloads (which causes the deletion of 0775 * namespace objects). We cannot allow the deletion of a namespace node 0776 * while the user function is using it. The exception to this are the 0777 * nodes created and deleted during control method execution -- these 0778 * nodes are marked as temporary nodes and are ignored by the namespace 0779 * walk. Thus, control methods can be executed while holding the 0780 * namespace deletion lock (and the user function can execute control 0781 * methods.) 0782 */ 0783 Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock); 0784 if (ACPI_FAILURE (Status)) 0785 { 0786 return_ACPI_STATUS (Status); 0787 } 0788 0789 /* 0790 * Lock the namespace around the walk. The namespace will be 0791 * unlocked/locked around each call to the user function - since the user 0792 * function must be allowed to make ACPICA calls itself (for example, it 0793 * will typically execute control methods during device enumeration.) 0794 */ 0795 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 0796 if (ACPI_FAILURE (Status)) 0797 { 0798 goto UnlockAndExit; 0799 } 0800 0801 /* Now we can validate the starting node */ 0802 0803 if (!AcpiNsValidateHandle (StartObject)) 0804 { 0805 Status = AE_BAD_PARAMETER; 0806 goto UnlockAndExit2; 0807 } 0808 0809 Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, 0810 ACPI_NS_WALK_UNLOCK, DescendingCallback, 0811 AscendingCallback, Context, ReturnValue); 0812 0813 UnlockAndExit2: 0814 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 0815 0816 UnlockAndExit: 0817 (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock); 0818 return_ACPI_STATUS (Status); 0819 } 0820 0821 ACPI_EXPORT_SYMBOL (AcpiWalkNamespace) 0822 0823 0824 /******************************************************************************* 0825 * 0826 * FUNCTION: AcpiNsGetDeviceCallback 0827 * 0828 * PARAMETERS: Callback from AcpiGetDevice 0829 * 0830 * RETURN: Status 0831 * 0832 * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 0833 * present devices, or if they specified a HID, it filters based 0834 * on that. 0835 * 0836 ******************************************************************************/ 0837 0838 static ACPI_STATUS 0839 AcpiNsGetDeviceCallback ( 0840 ACPI_HANDLE ObjHandle, 0841 UINT32 NestingLevel, 0842 void *Context, 0843 void **ReturnValue) 0844 { 0845 ACPI_GET_DEVICES_INFO *Info = Context; 0846 ACPI_STATUS Status; 0847 ACPI_NAMESPACE_NODE *Node; 0848 UINT32 Flags; 0849 ACPI_PNP_DEVICE_ID *Hid; 0850 ACPI_PNP_DEVICE_ID_LIST *Cid; 0851 UINT32 i; 0852 BOOLEAN Found; 0853 int NoMatch; 0854 0855 0856 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 0857 if (ACPI_FAILURE (Status)) 0858 { 0859 return (Status); 0860 } 0861 0862 Node = AcpiNsValidateHandle (ObjHandle); 0863 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 0864 if (ACPI_FAILURE (Status)) 0865 { 0866 return (Status); 0867 } 0868 0869 if (!Node) 0870 { 0871 return (AE_BAD_PARAMETER); 0872 } 0873 0874 /* 0875 * First, filter based on the device HID and CID. 0876 * 0877 * 01/2010: For this case where a specific HID is requested, we don't 0878 * want to run _STA until we have an actual HID match. Thus, we will 0879 * not unnecessarily execute _STA on devices for which the caller 0880 * doesn't care about. Previously, _STA was executed unconditionally 0881 * on all devices found here. 0882 * 0883 * A side-effect of this change is that now we will continue to search 0884 * for a matching HID even under device trees where the parent device 0885 * would have returned a _STA that indicates it is not present or 0886 * not functioning (thus aborting the search on that branch). 0887 */ 0888 if (Info->Hid != NULL) 0889 { 0890 Status = AcpiUtExecute_HID (Node, &Hid); 0891 if (Status == AE_NOT_FOUND) 0892 { 0893 return (AE_OK); 0894 } 0895 else if (ACPI_FAILURE (Status)) 0896 { 0897 return (AE_CTRL_DEPTH); 0898 } 0899 0900 NoMatch = strcmp (Hid->String, Info->Hid); 0901 ACPI_FREE (Hid); 0902 0903 if (NoMatch) 0904 { 0905 /* 0906 * HID does not match, attempt match within the 0907 * list of Compatible IDs (CIDs) 0908 */ 0909 Status = AcpiUtExecute_CID (Node, &Cid); 0910 if (Status == AE_NOT_FOUND) 0911 { 0912 return (AE_OK); 0913 } 0914 else if (ACPI_FAILURE (Status)) 0915 { 0916 return (AE_CTRL_DEPTH); 0917 } 0918 0919 /* Walk the CID list */ 0920 0921 Found = FALSE; 0922 for (i = 0; i < Cid->Count; i++) 0923 { 0924 if (strcmp (Cid->Ids[i].String, Info->Hid) == 0) 0925 { 0926 /* Found a matching CID */ 0927 0928 Found = TRUE; 0929 break; 0930 } 0931 } 0932 0933 ACPI_FREE (Cid); 0934 if (!Found) 0935 { 0936 return (AE_OK); 0937 } 0938 } 0939 } 0940 0941 /* Run _STA to determine if device is present */ 0942 0943 Status = AcpiUtExecute_STA (Node, &Flags); 0944 if (ACPI_FAILURE (Status)) 0945 { 0946 return (AE_CTRL_DEPTH); 0947 } 0948 0949 if (!(Flags & ACPI_STA_DEVICE_PRESENT) && 0950 !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) 0951 { 0952 /* 0953 * Don't examine the children of the device only when the 0954 * device is neither present nor functional. See ACPI spec, 0955 * description of _STA for more information. 0956 */ 0957 return (AE_CTRL_DEPTH); 0958 } 0959 0960 /* We have a valid device, invoke the user function */ 0961 0962 Status = Info->UserFunction (ObjHandle, NestingLevel, 0963 Info->Context, ReturnValue); 0964 return (Status); 0965 } 0966 0967 0968 /******************************************************************************* 0969 * 0970 * FUNCTION: AcpiGetDevices 0971 * 0972 * PARAMETERS: HID - HID to search for. Can be NULL. 0973 * UserFunction - Called when a matching object is found 0974 * Context - Passed to user function 0975 * ReturnValue - Location where return value of 0976 * UserFunction is put if terminated early 0977 * 0978 * RETURNS Return value from the UserFunction if terminated early. 0979 * Otherwise, returns NULL. 0980 * 0981 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 0982 * starting (and ending) at the object specified by StartHandle. 0983 * The UserFunction is called whenever an object of type 0984 * Device is found. If the user function returns 0985 * a non-zero value, the search is terminated immediately and this 0986 * value is returned to the caller. 0987 * 0988 * This is a wrapper for WalkNamespace, but the callback performs 0989 * additional filtering. Please see AcpiNsGetDeviceCallback. 0990 * 0991 ******************************************************************************/ 0992 0993 ACPI_STATUS 0994 AcpiGetDevices ( 0995 char *HID, 0996 ACPI_WALK_CALLBACK UserFunction, 0997 void *Context, 0998 void **ReturnValue) 0999 { 1000 ACPI_STATUS Status; 1001 ACPI_GET_DEVICES_INFO Info; 1002 1003 1004 ACPI_FUNCTION_TRACE (AcpiGetDevices); 1005 1006 1007 /* Parameter validation */ 1008 1009 if (!UserFunction) 1010 { 1011 return_ACPI_STATUS (AE_BAD_PARAMETER); 1012 } 1013 1014 /* 1015 * We're going to call their callback from OUR callback, so we need 1016 * to know what it is, and their context parameter. 1017 */ 1018 Info.Hid = HID; 1019 Info.Context = Context; 1020 Info.UserFunction = UserFunction; 1021 1022 /* 1023 * Lock the namespace around the walk. 1024 * The namespace will be unlocked/locked around each call 1025 * to the user function - since this function 1026 * must be allowed to make Acpi calls itself. 1027 */ 1028 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1029 if (ACPI_FAILURE (Status)) 1030 { 1031 return_ACPI_STATUS (Status); 1032 } 1033 1034 Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1035 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 1036 AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue); 1037 1038 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1039 return_ACPI_STATUS (Status); 1040 } 1041 1042 ACPI_EXPORT_SYMBOL (AcpiGetDevices) 1043 1044 1045 /******************************************************************************* 1046 * 1047 * FUNCTION: AcpiAttachData 1048 * 1049 * PARAMETERS: ObjHandle - Namespace node 1050 * Handler - Handler for this attachment 1051 * Data - Pointer to data to be attached 1052 * 1053 * RETURN: Status 1054 * 1055 * DESCRIPTION: Attach arbitrary data and handler to a namespace node. 1056 * 1057 ******************************************************************************/ 1058 1059 ACPI_STATUS 1060 AcpiAttachData ( 1061 ACPI_HANDLE ObjHandle, 1062 ACPI_OBJECT_HANDLER Handler, 1063 void *Data) 1064 { 1065 ACPI_NAMESPACE_NODE *Node; 1066 ACPI_STATUS Status; 1067 1068 1069 /* Parameter validation */ 1070 1071 if (!ObjHandle || 1072 !Handler || 1073 !Data) 1074 { 1075 return (AE_BAD_PARAMETER); 1076 } 1077 1078 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1079 if (ACPI_FAILURE (Status)) 1080 { 1081 return (Status); 1082 } 1083 1084 /* Convert and validate the handle */ 1085 1086 Node = AcpiNsValidateHandle (ObjHandle); 1087 if (!Node) 1088 { 1089 Status = AE_BAD_PARAMETER; 1090 goto UnlockAndExit; 1091 } 1092 1093 Status = AcpiNsAttachData (Node, Handler, Data); 1094 1095 UnlockAndExit: 1096 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1097 return (Status); 1098 } 1099 1100 ACPI_EXPORT_SYMBOL (AcpiAttachData) 1101 1102 1103 /******************************************************************************* 1104 * 1105 * FUNCTION: AcpiDetachData 1106 * 1107 * PARAMETERS: ObjHandle - Namespace node handle 1108 * Handler - Handler used in call to AcpiAttachData 1109 * 1110 * RETURN: Status 1111 * 1112 * DESCRIPTION: Remove data that was previously attached to a node. 1113 * 1114 ******************************************************************************/ 1115 1116 ACPI_STATUS 1117 AcpiDetachData ( 1118 ACPI_HANDLE ObjHandle, 1119 ACPI_OBJECT_HANDLER Handler) 1120 { 1121 ACPI_NAMESPACE_NODE *Node; 1122 ACPI_STATUS Status; 1123 1124 1125 /* Parameter validation */ 1126 1127 if (!ObjHandle || 1128 !Handler) 1129 { 1130 return (AE_BAD_PARAMETER); 1131 } 1132 1133 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1134 if (ACPI_FAILURE (Status)) 1135 { 1136 return (Status); 1137 } 1138 1139 /* Convert and validate the handle */ 1140 1141 Node = AcpiNsValidateHandle (ObjHandle); 1142 if (!Node) 1143 { 1144 Status = AE_BAD_PARAMETER; 1145 goto UnlockAndExit; 1146 } 1147 1148 Status = AcpiNsDetachData (Node, Handler); 1149 1150 UnlockAndExit: 1151 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1152 return (Status); 1153 } 1154 1155 ACPI_EXPORT_SYMBOL (AcpiDetachData) 1156 1157 1158 /******************************************************************************* 1159 * 1160 * FUNCTION: AcpiGetData 1161 * 1162 * PARAMETERS: ObjHandle - Namespace node 1163 * Handler - Handler used in call to AttachData 1164 * Data - Where the data is returned 1165 * 1166 * RETURN: Status 1167 * 1168 * DESCRIPTION: Retrieve data that was previously attached to a namespace node. 1169 * 1170 ******************************************************************************/ 1171 1172 ACPI_STATUS 1173 AcpiGetData ( 1174 ACPI_HANDLE ObjHandle, 1175 ACPI_OBJECT_HANDLER Handler, 1176 void **Data) 1177 { 1178 ACPI_NAMESPACE_NODE *Node; 1179 ACPI_STATUS Status; 1180 1181 1182 /* Parameter validation */ 1183 1184 if (!ObjHandle || 1185 !Handler || 1186 !Data) 1187 { 1188 return (AE_BAD_PARAMETER); 1189 } 1190 1191 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1192 if (ACPI_FAILURE (Status)) 1193 { 1194 return (Status); 1195 } 1196 1197 /* Convert and validate the handle */ 1198 1199 Node = AcpiNsValidateHandle (ObjHandle); 1200 if (!Node) 1201 { 1202 Status = AE_BAD_PARAMETER; 1203 goto UnlockAndExit; 1204 } 1205 1206 Status = AcpiNsGetAttachedData (Node, Handler, Data); 1207 1208 UnlockAndExit: 1209 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1210 return (Status); 1211 } 1212 1213 ACPI_EXPORT_SYMBOL (AcpiGetData)
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |