The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/components/namespace/nsxfeval.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*******************************************************************************
    2  *
    3  * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
    4  *                         ACPI Object evaluation interfaces
    5  *
    6  ******************************************************************************/
    7 
    8 /******************************************************************************
    9  *
   10  * 1. Copyright Notice
   11  *
   12  * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp.
   13  * All rights reserved.
   14  *
   15  * 2. License
   16  *
   17  * 2.1. This is your license from Intel Corp. under its intellectual property
   18  * rights. You may have additional license terms from the party that provided
   19  * you this software, covering your right to use that party's intellectual
   20  * property rights.
   21  *
   22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
   23  * copy of the source code appearing in this file ("Covered Code") an
   24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
   25  * base code distributed originally by Intel ("Original Intel Code") to copy,
   26  * make derivatives, distribute, use and display any portion of the Covered
   27  * Code in any form, with the right to sublicense such rights; and
   28  *
   29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
   30  * license (with the right to sublicense), under only those claims of Intel
   31  * patents that are infringed by the Original Intel Code, to make, use, sell,
   32  * offer to sell, and import the Covered Code and derivative works thereof
   33  * solely to the minimum extent necessary to exercise the above copyright
   34  * license, and in no event shall the patent license extend to any additions
   35  * to or modifications of the Original Intel Code. No other license or right
   36  * is granted directly or by implication, estoppel or otherwise;
   37  *
   38  * The above copyright and patent license is granted only if the following
   39  * conditions are met:
   40  *
   41  * 3. Conditions
   42  *
   43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
   44  * Redistribution of source code of any substantial portion of the Covered
   45  * Code or modification with rights to further distribute source must include
   46  * the above Copyright Notice, the above License, this list of Conditions,
   47  * and the following Disclaimer and Export Compliance provision. In addition,
   48  * Licensee must cause all Covered Code to which Licensee contributes to
   49  * contain a file documenting the changes Licensee made to create that Covered
   50  * Code and the date of any change. Licensee must include in that file the
   51  * documentation of any changes made by any predecessor Licensee. Licensee
   52  * must include a prominent statement that the modification is derived,
   53  * directly or indirectly, from Original Intel Code.
   54  *
   55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
   56  * Redistribution of source code of any substantial portion of the Covered
   57  * Code or modification without rights to further distribute source must
   58  * include the following Disclaimer and Export Compliance provision in the
   59  * documentation and/or other materials provided with distribution. In
   60  * addition, Licensee may not authorize further sublicense of source of any
   61  * portion of the Covered Code, and must include terms to the effect that the
   62  * license from Licensee to its licensee is limited to the intellectual
   63  * property embodied in the software Licensee provides to its licensee, and
   64  * not to intellectual property embodied in modifications its licensee may
   65  * make.
   66  *
   67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
   68  * substantial portion of the Covered Code or modification must reproduce the
   69  * above Copyright Notice, and the following Disclaimer and Export Compliance
   70  * provision in the documentation and/or other materials provided with the
   71  * distribution.
   72  *
   73  * 3.4. Intel retains all right, title, and interest in and to the Original
   74  * Intel Code.
   75  *
   76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
   77  * Intel shall be used in advertising or otherwise to promote the sale, use or
   78  * other dealings in products derived from or relating to the Covered Code
   79  * without prior written authorization from Intel.
   80  *
   81  * 4. Disclaimer and Export Compliance
   82  *
   83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
   84  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
   85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
   86  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
   87  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
   88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
   89  * PARTICULAR PURPOSE.
   90  *
   91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
   92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
   93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
   94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
   95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
   96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
   97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
   98  * LIMITED REMEDY.
   99  *
  100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  101  * software or system incorporating such software without first obtaining any
  102  * required license or other approval from the U. S. Department of Commerce or
  103  * any other agency or department of the United States Government. In the
  104  * event Licensee exports any such software from the United States or
  105  * re-exports any such software from a foreign destination, Licensee shall
  106  * ensure that the distribution and export/re-export of the software is in
  107  * compliance with all laws, regulations, orders, or other restrictions of the
  108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  109  * any of its subsidiaries will export/re-export any technical data, process,
  110  * software, or service, directly or indirectly, to any country for which the
  111  * United States government or any agency thereof requires an export license,
  112  * other governmental approval, or letter of assurance, without first obtaining
  113  * such license, approval or letter.
  114  *
  115  *****************************************************************************
  116  *
  117  * Alternatively, you may choose to be licensed under the terms of the
  118  * following license:
  119  *
  120  * Redistribution and use in source and binary forms, with or without
  121  * modification, are permitted provided that the following conditions
  122  * are met:
  123  * 1. Redistributions of source code must retain the above copyright
  124  *    notice, this list of conditions, and the following disclaimer,
  125  *    without modification.
  126  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  127  *    substantially similar to the "NO WARRANTY" disclaimer below
  128  *    ("Disclaimer") and any redistribution must be conditioned upon
  129  *    including a substantially similar Disclaimer requirement for further
  130  *    binary redistribution.
  131  * 3. Neither the names of the above-listed copyright holders nor the names
  132  *    of any contributors may be used to endorse or promote products derived
  133  *    from this software without specific prior written permission.
  134  *
  135  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  136  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  137  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  138  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  139  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  140  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  141  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  142  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  143  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  144  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  145  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  146  *
  147  * Alternatively, you may choose to be licensed under the terms of the
  148  * GNU General Public License ("GPL") version 2 as published by the Free
  149  * Software Foundation.
  150  *
  151  *****************************************************************************/
  152 
  153 #define EXPORT_ACPI_INTERFACES
  154 
  155 #include <contrib/dev/acpica/include/acpi.h>
  156 #include <contrib/dev/acpica/include/accommon.h>
  157 #include <contrib/dev/acpica/include/acnamesp.h>
  158 #include <contrib/dev/acpica/include/acinterp.h>
  159 
  160 
  161 #define _COMPONENT          ACPI_NAMESPACE
  162         ACPI_MODULE_NAME    ("nsxfeval")
  163 
  164 /* Local prototypes */
  165 
  166 static void
  167 AcpiNsResolveReferences (
  168     ACPI_EVALUATE_INFO      *Info);
  169 
  170 
  171 /*******************************************************************************
  172  *
  173  * FUNCTION:    AcpiEvaluateObjectTyped
  174  *
  175  * PARAMETERS:  Handle              - Object handle (optional)
  176  *              Pathname            - Object pathname (optional)
  177  *              ExternalParams      - List of parameters to pass to a method,
  178  *                                    terminated by NULL. May be NULL
  179  *                                    if no parameters are being passed.
  180  *              ReturnBuffer        - Where to put the object return value (if
  181  *                                    any). Required.
  182  *              ReturnType          - Expected type of return object
  183  *
  184  * RETURN:      Status
  185  *
  186  * DESCRIPTION: Find and evaluate the given object, passing the given
  187  *              parameters if necessary. One of "Handle" or "Pathname" must
  188  *              be valid (non-null)
  189  *
  190  ******************************************************************************/
  191 
  192 ACPI_STATUS
  193 AcpiEvaluateObjectTyped (
  194     ACPI_HANDLE             Handle,
  195     ACPI_STRING             Pathname,
  196     ACPI_OBJECT_LIST        *ExternalParams,
  197     ACPI_BUFFER             *ReturnBuffer,
  198     ACPI_OBJECT_TYPE        ReturnType)
  199 {
  200     ACPI_STATUS             Status;
  201     BOOLEAN                 FreeBufferOnError = FALSE;
  202     ACPI_HANDLE             TargetHandle;
  203     char                    *FullPathname;
  204 
  205 
  206     ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
  207 
  208 
  209     /* Return buffer must be valid */
  210 
  211     if (!ReturnBuffer)
  212     {
  213         return_ACPI_STATUS (AE_BAD_PARAMETER);
  214     }
  215 
  216     if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
  217     {
  218         FreeBufferOnError = TRUE;
  219     }
  220 
  221     /* Get a handle here, in order to build an error message if needed */
  222 
  223     TargetHandle = Handle;
  224     if (Pathname)
  225     {
  226         Status = AcpiGetHandle (Handle, Pathname, &TargetHandle);
  227         if (ACPI_FAILURE (Status))
  228         {
  229             return_ACPI_STATUS (Status);
  230         }
  231     }
  232 
  233     FullPathname = AcpiNsGetExternalPathname (TargetHandle);
  234     if (!FullPathname)
  235     {
  236         return_ACPI_STATUS (AE_NO_MEMORY);
  237     }
  238 
  239     /* Evaluate the object */
  240 
  241     Status = AcpiEvaluateObject (TargetHandle, NULL, ExternalParams,
  242         ReturnBuffer);
  243     if (ACPI_FAILURE (Status))
  244     {
  245         goto Exit;
  246     }
  247 
  248     /* Type ANY means "don't care about return value type" */
  249 
  250     if (ReturnType == ACPI_TYPE_ANY)
  251     {
  252         goto Exit;
  253     }
  254 
  255     if (ReturnBuffer->Length == 0)
  256     {
  257         /* Error because caller specifically asked for a return value */
  258 
  259         ACPI_ERROR ((AE_INFO, "%s did not return any object",
  260             FullPathname));
  261         Status = AE_NULL_OBJECT;
  262         goto Exit;
  263     }
  264 
  265     /* Examine the object type returned from EvaluateObject */
  266 
  267     if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
  268     {
  269         goto Exit;
  270     }
  271 
  272     /* Return object type does not match requested type */
  273 
  274     ACPI_ERROR ((AE_INFO,
  275         "Incorrect return type from %s - received [%s], requested [%s]",
  276         FullPathname,
  277         AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
  278         AcpiUtGetTypeName (ReturnType)));
  279 
  280     if (FreeBufferOnError)
  281     {
  282         /*
  283          * Free a buffer created via ACPI_ALLOCATE_BUFFER.
  284          * Note: We use AcpiOsFree here because AcpiOsAllocate was used
  285          * to allocate the buffer. This purposefully bypasses the
  286          * (optionally enabled) allocation tracking mechanism since we
  287          * only want to track internal allocations.
  288          */
  289         AcpiOsFree (ReturnBuffer->Pointer);
  290         ReturnBuffer->Pointer = NULL;
  291     }
  292 
  293     ReturnBuffer->Length = 0;
  294     Status = AE_TYPE;
  295 
  296 Exit:
  297     ACPI_FREE (FullPathname);
  298     return_ACPI_STATUS (Status);
  299 }
  300 
  301 ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
  302 
  303 
  304 /*******************************************************************************
  305  *
  306  * FUNCTION:    AcpiEvaluateObject
  307  *
  308  * PARAMETERS:  Handle              - Object handle (optional)
  309  *              Pathname            - Object pathname (optional)
  310  *              ExternalParams      - List of parameters to pass to method,
  311  *                                    terminated by NULL. May be NULL
  312  *                                    if no parameters are being passed.
  313  *              ReturnBuffer        - Where to put method's return value (if
  314  *                                    any). If NULL, no value is returned.
  315  *
  316  * RETURN:      Status
  317  *
  318  * DESCRIPTION: Find and evaluate the given object, passing the given
  319  *              parameters if necessary. One of "Handle" or "Pathname" must
  320  *              be valid (non-null)
  321  *
  322  ******************************************************************************/
  323 
  324 ACPI_STATUS
  325 AcpiEvaluateObject (
  326     ACPI_HANDLE             Handle,
  327     ACPI_STRING             Pathname,
  328     ACPI_OBJECT_LIST        *ExternalParams,
  329     ACPI_BUFFER             *ReturnBuffer)
  330 {
  331     ACPI_STATUS             Status;
  332     ACPI_EVALUATE_INFO      *Info;
  333     ACPI_SIZE               BufferSpaceNeeded;
  334     UINT32                  i;
  335 
  336 
  337     ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
  338 
  339 
  340     /* Allocate and initialize the evaluation information block */
  341 
  342     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
  343     if (!Info)
  344     {
  345         return_ACPI_STATUS (AE_NO_MEMORY);
  346     }
  347 
  348     /* Convert and validate the device handle */
  349 
  350     Info->PrefixNode = AcpiNsValidateHandle (Handle);
  351     if (!Info->PrefixNode)
  352     {
  353         Status = AE_BAD_PARAMETER;
  354         goto Cleanup;
  355     }
  356 
  357     /*
  358      * Get the actual namespace node for the target object.
  359      * Handles these cases:
  360      *
  361      * 1) Null node, valid pathname from root (absolute path)
  362      * 2) Node and valid pathname (path relative to Node)
  363      * 3) Node, Null pathname
  364      */
  365     if ((Pathname) &&
  366         (ACPI_IS_ROOT_PREFIX (Pathname[0])))
  367     {
  368         /* The path is fully qualified, just evaluate by name */
  369 
  370         Info->PrefixNode = NULL;
  371     }
  372     else if (!Handle)
  373     {
  374         /*
  375          * A handle is optional iff a fully qualified pathname is specified.
  376          * Since we've already handled fully qualified names above, this is
  377          * an error.
  378          */
  379         if (!Pathname)
  380         {
  381             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  382                 "Both Handle and Pathname are NULL"));
  383         }
  384         else
  385         {
  386             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  387                 "Null Handle with relative pathname [%s]", Pathname));
  388         }
  389 
  390         Status = AE_BAD_PARAMETER;
  391         goto Cleanup;
  392     }
  393 
  394     Info->RelativePathname = Pathname;
  395 
  396     /*
  397      * Convert all external objects passed as arguments to the
  398      * internal version(s).
  399      */
  400     if (ExternalParams && ExternalParams->Count)
  401     {
  402         Info->ParamCount = (UINT16) ExternalParams->Count;
  403 
  404         /* Warn on impossible argument count */
  405 
  406         if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
  407         {
  408             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
  409                 "Excess arguments (%u) - using only %u",
  410                 Info->ParamCount, ACPI_METHOD_NUM_ARGS));
  411 
  412             Info->ParamCount = ACPI_METHOD_NUM_ARGS;
  413         }
  414 
  415         /*
  416          * Allocate a new parameter block for the internal objects
  417          * Add 1 to count to allow for null terminated internal list
  418          */
  419         Info->Parameters = ACPI_ALLOCATE_ZEROED (
  420             ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
  421         if (!Info->Parameters)
  422         {
  423             Status = AE_NO_MEMORY;
  424             goto Cleanup;
  425         }
  426 
  427         /* Convert each external object in the list to an internal object */
  428 
  429         for (i = 0; i < Info->ParamCount; i++)
  430         {
  431             Status = AcpiUtCopyEobjectToIobject (
  432                 &ExternalParams->Pointer[i], &Info->Parameters[i]);
  433             if (ACPI_FAILURE (Status))
  434             {
  435                 goto Cleanup;
  436             }
  437         }
  438 
  439         Info->Parameters[Info->ParamCount] = NULL;
  440     }
  441 
  442 
  443 #ifdef _FUTURE_FEATURE
  444 
  445     /*
  446      * Begin incoming argument count analysis. Check for too few args
  447      * and too many args.
  448      */
  449     switch (AcpiNsGetType (Info->Node))
  450     {
  451     case ACPI_TYPE_METHOD:
  452 
  453         /* Check incoming argument count against the method definition */
  454 
  455         if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)
  456         {
  457             ACPI_ERROR ((AE_INFO,
  458                 "Insufficient arguments (%u) - %u are required",
  459                 Info->ParamCount,
  460                 Info->ObjDesc->Method.ParamCount));
  461 
  462             Status = AE_MISSING_ARGUMENTS;
  463             goto Cleanup;
  464         }
  465 
  466         else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)
  467         {
  468             ACPI_WARNING ((AE_INFO,
  469                 "Excess arguments (%u) - only %u are required",
  470                 Info->ParamCount,
  471                 Info->ObjDesc->Method.ParamCount));
  472 
  473             /* Just pass the required number of arguments */
  474 
  475             Info->ParamCount = Info->ObjDesc->Method.ParamCount;
  476         }
  477 
  478         /*
  479          * Any incoming external objects to be passed as arguments to the
  480          * method must be converted to internal objects
  481          */
  482         if (Info->ParamCount)
  483         {
  484             /*
  485              * Allocate a new parameter block for the internal objects
  486              * Add 1 to count to allow for null terminated internal list
  487              */
  488             Info->Parameters = ACPI_ALLOCATE_ZEROED (
  489                 ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
  490             if (!Info->Parameters)
  491             {
  492                 Status = AE_NO_MEMORY;
  493                 goto Cleanup;
  494             }
  495 
  496             /* Convert each external object in the list to an internal object */
  497 
  498             for (i = 0; i < Info->ParamCount; i++)
  499             {
  500                 Status = AcpiUtCopyEobjectToIobject (
  501                     &ExternalParams->Pointer[i], &Info->Parameters[i]);
  502                 if (ACPI_FAILURE (Status))
  503                 {
  504                     goto Cleanup;
  505                 }
  506             }
  507 
  508             Info->Parameters[Info->ParamCount] = NULL;
  509         }
  510         break;
  511 
  512     default:
  513 
  514         /* Warn if arguments passed to an object that is not a method */
  515 
  516         if (Info->ParamCount)
  517         {
  518             ACPI_WARNING ((AE_INFO,
  519                 "%u arguments were passed to a non-method ACPI object",
  520                 Info->ParamCount));
  521         }
  522         break;
  523     }
  524 
  525 #endif
  526 
  527 
  528     /* Now we can evaluate the object */
  529 
  530     Status = AcpiNsEvaluate (Info);
  531 
  532     /*
  533      * If we are expecting a return value, and all went well above,
  534      * copy the return value to an external object.
  535      */
  536     if (!ReturnBuffer)
  537     {
  538         goto CleanupReturnObject;
  539     }
  540 
  541     if (!Info->ReturnObject)
  542     {
  543         ReturnBuffer->Length = 0;
  544         goto Cleanup;
  545     }
  546 
  547     if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
  548         ACPI_DESC_TYPE_NAMED)
  549     {
  550         /*
  551          * If we received a NS Node as a return object, this means that
  552          * the object we are evaluating has nothing interesting to
  553          * return (such as a mutex, etc.)  We return an error because
  554          * these types are essentially unsupported by this interface.
  555          * We don't check up front because this makes it easier to add
  556          * support for various types at a later date if necessary.
  557          */
  558         Status = AE_TYPE;
  559         Info->ReturnObject = NULL;   /* No need to delete a NS Node */
  560         ReturnBuffer->Length = 0;
  561     }
  562 
  563     if (ACPI_FAILURE (Status))
  564     {
  565         goto CleanupReturnObject;
  566     }
  567 
  568     /* Dereference Index and RefOf references */
  569 
  570     AcpiNsResolveReferences (Info);
  571 
  572     /* Get the size of the returned object */
  573 
  574     Status = AcpiUtGetObjectSize (Info->ReturnObject,
  575         &BufferSpaceNeeded);
  576     if (ACPI_SUCCESS (Status))
  577     {
  578         /* Validate/Allocate/Clear caller buffer */
  579 
  580         Status = AcpiUtInitializeBuffer (ReturnBuffer,
  581             BufferSpaceNeeded);
  582         if (ACPI_FAILURE (Status))
  583         {
  584             /*
  585              * Caller's buffer is too small or a new one can't
  586              * be allocated
  587              */
  588             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  589                 "Needed buffer size %X, %s\n",
  590                 (UINT32) BufferSpaceNeeded,
  591                 AcpiFormatException (Status)));
  592         }
  593         else
  594         {
  595             /* We have enough space for the object, build it */
  596 
  597             Status = AcpiUtCopyIobjectToEobject (
  598                 Info->ReturnObject, ReturnBuffer);
  599         }
  600     }
  601 
  602 CleanupReturnObject:
  603 
  604     if (Info->ReturnObject)
  605     {
  606         /*
  607          * Delete the internal return object. NOTE: Interpreter must be
  608          * locked to avoid race condition.
  609          */
  610         AcpiExEnterInterpreter ();
  611 
  612         /* Remove one reference on the return object (should delete it) */
  613 
  614         AcpiUtRemoveReference (Info->ReturnObject);
  615         AcpiExExitInterpreter ();
  616     }
  617 
  618 
  619 Cleanup:
  620 
  621     /* Free the input parameter list (if we created one) */
  622 
  623     if (Info->Parameters)
  624     {
  625         /* Free the allocated parameter block */
  626 
  627         AcpiUtDeleteInternalObjectList (Info->Parameters);
  628     }
  629 
  630     ACPI_FREE (Info);
  631     return_ACPI_STATUS (Status);
  632 }
  633 
  634 ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
  635 
  636 
  637 /*******************************************************************************
  638  *
  639  * FUNCTION:    AcpiNsResolveReferences
  640  *
  641  * PARAMETERS:  Info                    - Evaluation info block
  642  *
  643  * RETURN:      Info->ReturnObject is replaced with the dereferenced object
  644  *
  645  * DESCRIPTION: Dereference certain reference objects. Called before an
  646  *              internal return object is converted to an external ACPI_OBJECT.
  647  *
  648  * Performs an automatic dereference of Index and RefOf reference objects.
  649  * These reference objects are not supported by the ACPI_OBJECT, so this is a
  650  * last resort effort to return something useful. Also, provides compatibility
  651  * with other ACPI implementations.
  652  *
  653  * NOTE: does not handle references within returned package objects or nested
  654  * references, but this support could be added later if found to be necessary.
  655  *
  656  ******************************************************************************/
  657 
  658 static void
  659 AcpiNsResolveReferences (
  660     ACPI_EVALUATE_INFO      *Info)
  661 {
  662     ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
  663     ACPI_NAMESPACE_NODE     *Node;
  664 
  665 
  666     /* We are interested in reference objects only */
  667 
  668     if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
  669     {
  670         return;
  671     }
  672 
  673     /*
  674      * Two types of references are supported - those created by Index and
  675      * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
  676      * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
  677      * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
  678      * an ACPI_OBJECT.
  679      */
  680     switch (Info->ReturnObject->Reference.Class)
  681     {
  682     case ACPI_REFCLASS_INDEX:
  683 
  684         ObjDesc = *(Info->ReturnObject->Reference.Where);
  685         break;
  686 
  687     case ACPI_REFCLASS_REFOF:
  688 
  689         Node = Info->ReturnObject->Reference.Object;
  690         if (Node)
  691         {
  692             ObjDesc = Node->Object;
  693         }
  694         break;
  695 
  696     default:
  697 
  698         return;
  699     }
  700 
  701     /* Replace the existing reference object */
  702 
  703     if (ObjDesc)
  704     {
  705         AcpiUtAddReference (ObjDesc);
  706         AcpiUtRemoveReference (Info->ReturnObject);
  707         Info->ReturnObject = ObjDesc;
  708     }
  709 
  710     return;
  711 }
  712 
  713 
  714 /*******************************************************************************
  715  *
  716  * FUNCTION:    AcpiWalkNamespace
  717  *
  718  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
  719  *              StartObject         - Handle in namespace where search begins
  720  *              MaxDepth            - Depth to which search is to reach
  721  *              DescendingCallback  - Called during tree descent
  722  *                                    when an object of "Type" is found
  723  *              AscendingCallback   - Called during tree ascent
  724  *                                    when an object of "Type" is found
  725  *              Context             - Passed to user function(s) above
  726  *              ReturnValue         - Location where return value of
  727  *                                    UserFunction is put if terminated early
  728  *
  729  * RETURNS      Return value from the UserFunction if terminated early.
  730  *              Otherwise, returns NULL.
  731  *
  732  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  733  *              starting (and ending) at the object specified by StartHandle.
  734  *              The callback function is called whenever an object that matches
  735  *              the type parameter is found. If the callback function returns
  736  *              a non-zero value, the search is terminated immediately and this
  737  *              value is returned to the caller.
  738  *
  739  *              The point of this procedure is to provide a generic namespace
  740  *              walk routine that can be called from multiple places to
  741  *              provide multiple services; the callback function(s) can be
  742  *              tailored to each task, whether it is a print function,
  743  *              a compare function, etc.
  744  *
  745  ******************************************************************************/
  746 
  747 ACPI_STATUS
  748 AcpiWalkNamespace (
  749     ACPI_OBJECT_TYPE        Type,
  750     ACPI_HANDLE             StartObject,
  751     UINT32                  MaxDepth,
  752     ACPI_WALK_CALLBACK      DescendingCallback,
  753     ACPI_WALK_CALLBACK      AscendingCallback,
  754     void                    *Context,
  755     void                    **ReturnValue)
  756 {
  757     ACPI_STATUS             Status;
  758 
  759 
  760     ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
  761 
  762 
  763     /* Parameter validation */
  764 
  765     if ((Type > ACPI_TYPE_LOCAL_MAX) ||
  766         (!MaxDepth)                  ||
  767         (!DescendingCallback && !AscendingCallback))
  768     {
  769         return_ACPI_STATUS (AE_BAD_PARAMETER);
  770     }
  771 
  772     /*
  773      * Need to acquire the namespace reader lock to prevent interference
  774      * with any concurrent table unloads (which causes the deletion of
  775      * namespace objects). We cannot allow the deletion of a namespace node
  776      * while the user function is using it. The exception to this are the
  777      * nodes created and deleted during control method execution -- these
  778      * nodes are marked as temporary nodes and are ignored by the namespace
  779      * walk. Thus, control methods can be executed while holding the
  780      * namespace deletion lock (and the user function can execute control
  781      * methods.)
  782      */
  783     Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
  784     if (ACPI_FAILURE (Status))
  785     {
  786         return_ACPI_STATUS (Status);
  787     }
  788 
  789     /*
  790      * Lock the namespace around the walk. The namespace will be
  791      * unlocked/locked around each call to the user function - since the user
  792      * function must be allowed to make ACPICA calls itself (for example, it
  793      * will typically execute control methods during device enumeration.)
  794      */
  795     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  796     if (ACPI_FAILURE (Status))
  797     {
  798         goto UnlockAndExit;
  799     }
  800 
  801     /* Now we can validate the starting node */
  802 
  803     if (!AcpiNsValidateHandle (StartObject))
  804     {
  805         Status = AE_BAD_PARAMETER;
  806         goto UnlockAndExit2;
  807     }
  808 
  809     Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
  810         ACPI_NS_WALK_UNLOCK, DescendingCallback,
  811         AscendingCallback, Context, ReturnValue);
  812 
  813 UnlockAndExit2:
  814     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  815 
  816 UnlockAndExit:
  817     (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
  818     return_ACPI_STATUS (Status);
  819 }
  820 
  821 ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
  822 
  823 
  824 /*******************************************************************************
  825  *
  826  * FUNCTION:    AcpiNsGetDeviceCallback
  827  *
  828  * PARAMETERS:  Callback from AcpiGetDevice
  829  *
  830  * RETURN:      Status
  831  *
  832  * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
  833  *              present devices, or if they specified a HID, it filters based
  834  *              on that.
  835  *
  836  ******************************************************************************/
  837 
  838 static ACPI_STATUS
  839 AcpiNsGetDeviceCallback (
  840     ACPI_HANDLE             ObjHandle,
  841     UINT32                  NestingLevel,
  842     void                    *Context,
  843     void                    **ReturnValue)
  844 {
  845     ACPI_GET_DEVICES_INFO   *Info = Context;
  846     ACPI_STATUS             Status;
  847     ACPI_NAMESPACE_NODE     *Node;
  848     UINT32                  Flags;
  849     ACPI_PNP_DEVICE_ID      *Hid;
  850     ACPI_PNP_DEVICE_ID_LIST *Cid;
  851     UINT32                  i;
  852     BOOLEAN                 Found;
  853     int                     NoMatch;
  854 
  855 
  856     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  857     if (ACPI_FAILURE (Status))
  858     {
  859         return (Status);
  860     }
  861 
  862     Node = AcpiNsValidateHandle (ObjHandle);
  863     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  864     if (ACPI_FAILURE (Status))
  865     {
  866         return (Status);
  867     }
  868 
  869     if (!Node)
  870     {
  871         return (AE_BAD_PARAMETER);
  872     }
  873 
  874     /*
  875      * First, filter based on the device HID and CID.
  876      *
  877      * 01/2010: For this case where a specific HID is requested, we don't
  878      * want to run _STA until we have an actual HID match. Thus, we will
  879      * not unnecessarily execute _STA on devices for which the caller
  880      * doesn't care about. Previously, _STA was executed unconditionally
  881      * on all devices found here.
  882      *
  883      * A side-effect of this change is that now we will continue to search
  884      * for a matching HID even under device trees where the parent device
  885      * would have returned a _STA that indicates it is not present or
  886      * not functioning (thus aborting the search on that branch).
  887      */
  888     if (Info->Hid != NULL)
  889     {
  890         Status = AcpiUtExecute_HID (Node, &Hid);
  891         if (Status == AE_NOT_FOUND)
  892         {
  893             return (AE_OK);
  894         }
  895         else if (ACPI_FAILURE (Status))
  896         {
  897             return (AE_CTRL_DEPTH);
  898         }
  899 
  900         NoMatch = strcmp (Hid->String, Info->Hid);
  901         ACPI_FREE (Hid);
  902 
  903         if (NoMatch)
  904         {
  905             /*
  906              * HID does not match, attempt match within the
  907              * list of Compatible IDs (CIDs)
  908              */
  909             Status = AcpiUtExecute_CID (Node, &Cid);
  910             if (Status == AE_NOT_FOUND)
  911             {
  912                 return (AE_OK);
  913             }
  914             else if (ACPI_FAILURE (Status))
  915             {
  916                 return (AE_CTRL_DEPTH);
  917             }
  918 
  919             /* Walk the CID list */
  920 
  921             Found = FALSE;
  922             for (i = 0; i < Cid->Count; i++)
  923             {
  924                 if (strcmp (Cid->Ids[i].String, Info->Hid) == 0)
  925                 {
  926                     /* Found a matching CID */
  927 
  928                     Found = TRUE;
  929                     break;
  930                 }
  931             }
  932 
  933             ACPI_FREE (Cid);
  934             if (!Found)
  935             {
  936                 return (AE_OK);
  937             }
  938         }
  939     }
  940 
  941     /* Run _STA to determine if device is present */
  942 
  943     Status = AcpiUtExecute_STA (Node, &Flags);
  944     if (ACPI_FAILURE (Status))
  945     {
  946         return (AE_CTRL_DEPTH);
  947     }
  948 
  949     if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
  950         !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
  951     {
  952         /*
  953          * Don't examine the children of the device only when the
  954          * device is neither present nor functional. See ACPI spec,
  955          * description of _STA for more information.
  956          */
  957         return (AE_CTRL_DEPTH);
  958     }
  959 
  960     /* We have a valid device, invoke the user function */
  961 
  962     Status = Info->UserFunction (ObjHandle, NestingLevel,
  963         Info->Context, ReturnValue);
  964     return (Status);
  965 }
  966 
  967 
  968 /*******************************************************************************
  969  *
  970  * FUNCTION:    AcpiGetDevices
  971  *
  972  * PARAMETERS:  HID                 - HID to search for. Can be NULL.
  973  *              UserFunction        - Called when a matching object is found
  974  *              Context             - Passed to user function
  975  *              ReturnValue         - Location where return value of
  976  *                                    UserFunction is put if terminated early
  977  *
  978  * RETURNS      Return value from the UserFunction if terminated early.
  979  *              Otherwise, returns NULL.
  980  *
  981  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  982  *              starting (and ending) at the object specified by StartHandle.
  983  *              The UserFunction is called whenever an object of type
  984  *              Device is found. If the user function returns
  985  *              a non-zero value, the search is terminated immediately and this
  986  *              value is returned to the caller.
  987  *
  988  *              This is a wrapper for WalkNamespace, but the callback performs
  989  *              additional filtering. Please see AcpiNsGetDeviceCallback.
  990  *
  991  ******************************************************************************/
  992 
  993 ACPI_STATUS
  994 AcpiGetDevices (
  995     char                    *HID,
  996     ACPI_WALK_CALLBACK      UserFunction,
  997     void                    *Context,
  998     void                    **ReturnValue)
  999 {
 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)

Cache object: 69e16dcb8d3fe50de3a13d4fe39d3467


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.