Back to home page

LXR

 
 

    


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)