nsxfeval.c revision 128212
1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4100966Siwasaki *                         ACPI Object evaluation interfaces
5128212Snjl *              $Revision: 12 $
6100966Siwasaki *
7100966Siwasaki ******************************************************************************/
8100966Siwasaki
9100966Siwasaki/******************************************************************************
10100966Siwasaki *
11100966Siwasaki * 1. Copyright Notice
12100966Siwasaki *
13126372Snjl * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
14100966Siwasaki * All rights reserved.
15100966Siwasaki *
16100966Siwasaki * 2. License
17100966Siwasaki *
18100966Siwasaki * 2.1. This is your license from Intel Corp. under its intellectual property
19100966Siwasaki * rights.  You may have additional license terms from the party that provided
20100966Siwasaki * you this software, covering your right to use that party's intellectual
21100966Siwasaki * property rights.
22100966Siwasaki *
23100966Siwasaki * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24100966Siwasaki * copy of the source code appearing in this file ("Covered Code") an
25100966Siwasaki * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26100966Siwasaki * base code distributed originally by Intel ("Original Intel Code") to copy,
27100966Siwasaki * make derivatives, distribute, use and display any portion of the Covered
28100966Siwasaki * Code in any form, with the right to sublicense such rights; and
29100966Siwasaki *
30100966Siwasaki * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31100966Siwasaki * license (with the right to sublicense), under only those claims of Intel
32100966Siwasaki * patents that are infringed by the Original Intel Code, to make, use, sell,
33100966Siwasaki * offer to sell, and import the Covered Code and derivative works thereof
34100966Siwasaki * solely to the minimum extent necessary to exercise the above copyright
35100966Siwasaki * license, and in no event shall the patent license extend to any additions
36100966Siwasaki * to or modifications of the Original Intel Code.  No other license or right
37100966Siwasaki * is granted directly or by implication, estoppel or otherwise;
38100966Siwasaki *
39100966Siwasaki * The above copyright and patent license is granted only if the following
40100966Siwasaki * conditions are met:
41100966Siwasaki *
42100966Siwasaki * 3. Conditions
43100966Siwasaki *
44100966Siwasaki * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45100966Siwasaki * Redistribution of source code of any substantial portion of the Covered
46100966Siwasaki * Code or modification with rights to further distribute source must include
47100966Siwasaki * the above Copyright Notice, the above License, this list of Conditions,
48100966Siwasaki * and the following Disclaimer and Export Compliance provision.  In addition,
49100966Siwasaki * Licensee must cause all Covered Code to which Licensee contributes to
50100966Siwasaki * contain a file documenting the changes Licensee made to create that Covered
51100966Siwasaki * Code and the date of any change.  Licensee must include in that file the
52100966Siwasaki * documentation of any changes made by any predecessor Licensee.  Licensee
53100966Siwasaki * must include a prominent statement that the modification is derived,
54100966Siwasaki * directly or indirectly, from Original Intel Code.
55100966Siwasaki *
56100966Siwasaki * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57100966Siwasaki * Redistribution of source code of any substantial portion of the Covered
58100966Siwasaki * Code or modification without rights to further distribute source must
59100966Siwasaki * include the following Disclaimer and Export Compliance provision in the
60100966Siwasaki * documentation and/or other materials provided with distribution.  In
61100966Siwasaki * addition, Licensee may not authorize further sublicense of source of any
62100966Siwasaki * portion of the Covered Code, and must include terms to the effect that the
63100966Siwasaki * license from Licensee to its licensee is limited to the intellectual
64100966Siwasaki * property embodied in the software Licensee provides to its licensee, and
65100966Siwasaki * not to intellectual property embodied in modifications its licensee may
66100966Siwasaki * make.
67100966Siwasaki *
68100966Siwasaki * 3.3. Redistribution of Executable. Redistribution in executable form of any
69100966Siwasaki * substantial portion of the Covered Code or modification must reproduce the
70100966Siwasaki * above Copyright Notice, and the following Disclaimer and Export Compliance
71100966Siwasaki * provision in the documentation and/or other materials provided with the
72100966Siwasaki * distribution.
73100966Siwasaki *
74100966Siwasaki * 3.4. Intel retains all right, title, and interest in and to the Original
75100966Siwasaki * Intel Code.
76100966Siwasaki *
77100966Siwasaki * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78100966Siwasaki * Intel shall be used in advertising or otherwise to promote the sale, use or
79100966Siwasaki * other dealings in products derived from or relating to the Covered Code
80100966Siwasaki * without prior written authorization from Intel.
81100966Siwasaki *
82100966Siwasaki * 4. Disclaimer and Export Compliance
83100966Siwasaki *
84100966Siwasaki * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85100966Siwasaki * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86100966Siwasaki * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87100966Siwasaki * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88100966Siwasaki * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89100966Siwasaki * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90100966Siwasaki * PARTICULAR PURPOSE.
91100966Siwasaki *
92100966Siwasaki * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93100966Siwasaki * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94100966Siwasaki * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95100966Siwasaki * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96100966Siwasaki * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97100966Siwasaki * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98100966Siwasaki * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99100966Siwasaki * LIMITED REMEDY.
100100966Siwasaki *
101100966Siwasaki * 4.3. Licensee shall not export, either directly or indirectly, any of this
102100966Siwasaki * software or system incorporating such software without first obtaining any
103100966Siwasaki * required license or other approval from the U. S. Department of Commerce or
104100966Siwasaki * any other agency or department of the United States Government.  In the
105100966Siwasaki * event Licensee exports any such software from the United States or
106100966Siwasaki * re-exports any such software from a foreign destination, Licensee shall
107100966Siwasaki * ensure that the distribution and export/re-export of the software is in
108100966Siwasaki * compliance with all laws, regulations, orders, or other restrictions of the
109100966Siwasaki * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110100966Siwasaki * any of its subsidiaries will export/re-export any technical data, process,
111100966Siwasaki * software, or service, directly or indirectly, to any country for which the
112100966Siwasaki * United States government or any agency thereof requires an export license,
113100966Siwasaki * other governmental approval, or letter of assurance, without first obtaining
114100966Siwasaki * such license, approval or letter.
115100966Siwasaki *
116100966Siwasaki *****************************************************************************/
117100966Siwasaki
118100966Siwasaki
119100966Siwasaki#define __NSXFEVAL_C__
120100966Siwasaki
121100966Siwasaki#include "acpi.h"
122100966Siwasaki#include "acnamesp.h"
123128212Snjl#include "acinterp.h"
124100966Siwasaki
125100966Siwasaki
126100966Siwasaki#define _COMPONENT          ACPI_NAMESPACE
127100966Siwasaki        ACPI_MODULE_NAME    ("nsxfeval")
128100966Siwasaki
129100966Siwasaki
130100966Siwasaki/*******************************************************************************
131100966Siwasaki *
132100966Siwasaki * FUNCTION:    AcpiEvaluateObjectTyped
133100966Siwasaki *
134100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
135100966Siwasaki *              *Pathname           - Object pathname (optional)
136100966Siwasaki *              **ExternalParams    - List of parameters to pass to method,
137100966Siwasaki *                                    terminated by NULL.  May be NULL
138100966Siwasaki *                                    if no parameters are being passed.
139100966Siwasaki *              *ReturnBuffer       - Where to put method's return value (if
140100966Siwasaki *                                    any).  If NULL, no value is returned.
141100966Siwasaki *              ReturnType          - Expected type of return object
142100966Siwasaki *
143100966Siwasaki * RETURN:      Status
144100966Siwasaki *
145100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
146100966Siwasaki *              parameters if necessary.  One of "Handle" or "Pathname" must
147100966Siwasaki *              be valid (non-null)
148100966Siwasaki *
149100966Siwasaki ******************************************************************************/
150100966Siwasaki
151100966SiwasakiACPI_STATUS
152100966SiwasakiAcpiEvaluateObjectTyped (
153100966Siwasaki    ACPI_HANDLE             Handle,
154100966Siwasaki    ACPI_STRING             Pathname,
155100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
156100966Siwasaki    ACPI_BUFFER             *ReturnBuffer,
157100966Siwasaki    ACPI_OBJECT_TYPE        ReturnType)
158100966Siwasaki{
159100966Siwasaki    ACPI_STATUS             Status;
160100966Siwasaki    BOOLEAN                 MustFree = FALSE;
161100966Siwasaki
162100966Siwasaki
163100966Siwasaki    ACPI_FUNCTION_TRACE ("AcpiEvaluateObjectTyped");
164100966Siwasaki
165100966Siwasaki
166100966Siwasaki    /* Return buffer must be valid */
167100966Siwasaki
168100966Siwasaki    if (!ReturnBuffer)
169100966Siwasaki    {
170100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
171100966Siwasaki    }
172100966Siwasaki
173100966Siwasaki    if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
174100966Siwasaki    {
175100966Siwasaki        MustFree = TRUE;
176100966Siwasaki    }
177100966Siwasaki
178100966Siwasaki    /* Evaluate the object */
179100966Siwasaki
180100966Siwasaki    Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
181100966Siwasaki    if (ACPI_FAILURE (Status))
182100966Siwasaki    {
183100966Siwasaki        return_ACPI_STATUS (Status);
184100966Siwasaki    }
185100966Siwasaki
186100966Siwasaki    /* Type ANY means "don't care" */
187100966Siwasaki
188100966Siwasaki    if (ReturnType == ACPI_TYPE_ANY)
189100966Siwasaki    {
190100966Siwasaki        return_ACPI_STATUS (AE_OK);
191100966Siwasaki    }
192100966Siwasaki
193100966Siwasaki    if (ReturnBuffer->Length == 0)
194100966Siwasaki    {
195100966Siwasaki        /* Error because caller specifically asked for a return value */
196100966Siwasaki
197100966Siwasaki        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
198100966Siwasaki            "No return value\n"));
199100966Siwasaki
200100966Siwasaki        return_ACPI_STATUS (AE_NULL_OBJECT);
201100966Siwasaki    }
202100966Siwasaki
203100966Siwasaki    /* Examine the object type returned from EvaluateObject */
204100966Siwasaki
205100966Siwasaki    if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
206100966Siwasaki    {
207100966Siwasaki        return_ACPI_STATUS (AE_OK);
208100966Siwasaki    }
209100966Siwasaki
210100966Siwasaki    /* Return object type does not match requested type */
211100966Siwasaki
212100966Siwasaki    ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
213100966Siwasaki        "Incorrect return type [%s] requested [%s]\n",
214100966Siwasaki        AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
215100966Siwasaki        AcpiUtGetTypeName (ReturnType)));
216100966Siwasaki
217100966Siwasaki    if (MustFree)
218100966Siwasaki    {
219100966Siwasaki        /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
220100966Siwasaki
221100966Siwasaki        AcpiOsFree (ReturnBuffer->Pointer);
222100966Siwasaki        ReturnBuffer->Pointer = NULL;
223100966Siwasaki    }
224100966Siwasaki
225100966Siwasaki    ReturnBuffer->Length = 0;
226100966Siwasaki    return_ACPI_STATUS (AE_TYPE);
227100966Siwasaki}
228100966Siwasaki
229100966Siwasaki
230100966Siwasaki/*******************************************************************************
231100966Siwasaki *
232100966Siwasaki * FUNCTION:    AcpiEvaluateObject
233100966Siwasaki *
234100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
235128212Snjl *              Pathname            - Object pathname (optional)
236128212Snjl *              ExternalParams      - List of parameters to pass to method,
237100966Siwasaki *                                    terminated by NULL.  May be NULL
238100966Siwasaki *                                    if no parameters are being passed.
239128212Snjl *              ReturnBuffer        - Where to put method's return value (if
240100966Siwasaki *                                    any).  If NULL, no value is returned.
241100966Siwasaki *
242100966Siwasaki * RETURN:      Status
243100966Siwasaki *
244100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
245100966Siwasaki *              parameters if necessary.  One of "Handle" or "Pathname" must
246100966Siwasaki *              be valid (non-null)
247100966Siwasaki *
248100966Siwasaki ******************************************************************************/
249100966Siwasaki
250100966SiwasakiACPI_STATUS
251100966SiwasakiAcpiEvaluateObject (
252100966Siwasaki    ACPI_HANDLE             Handle,
253100966Siwasaki    ACPI_STRING             Pathname,
254100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
255100966Siwasaki    ACPI_BUFFER             *ReturnBuffer)
256100966Siwasaki{
257100966Siwasaki    ACPI_STATUS             Status;
258128212Snjl    ACPI_STATUS             Status2;
259100966Siwasaki    ACPI_OPERAND_OBJECT     **InternalParams = NULL;
260100966Siwasaki    ACPI_OPERAND_OBJECT     *InternalReturnObj = NULL;
261100966Siwasaki    ACPI_SIZE               BufferSpaceNeeded;
262100966Siwasaki    UINT32                  i;
263100966Siwasaki
264100966Siwasaki
265100966Siwasaki    ACPI_FUNCTION_TRACE ("AcpiEvaluateObject");
266100966Siwasaki
267100966Siwasaki
268100966Siwasaki    /*
269100966Siwasaki     * If there are parameters to be passed to the object
270100966Siwasaki     * (which must be a control method), the external objects
271100966Siwasaki     * must be converted to internal objects
272100966Siwasaki     */
273100966Siwasaki    if (ExternalParams && ExternalParams->Count)
274100966Siwasaki    {
275100966Siwasaki        /*
276100966Siwasaki         * Allocate a new parameter block for the internal objects
277100966Siwasaki         * Add 1 to count to allow for null terminated internal list
278100966Siwasaki         */
279100966Siwasaki        InternalParams = ACPI_MEM_CALLOCATE (((ACPI_SIZE) ExternalParams->Count + 1) *
280100966Siwasaki                                                sizeof (void *));
281100966Siwasaki        if (!InternalParams)
282100966Siwasaki        {
283100966Siwasaki            return_ACPI_STATUS (AE_NO_MEMORY);
284100966Siwasaki        }
285100966Siwasaki
286100966Siwasaki        /*
287100966Siwasaki         * Convert each external object in the list to an
288100966Siwasaki         * internal object
289100966Siwasaki         */
290100966Siwasaki        for (i = 0; i < ExternalParams->Count; i++)
291100966Siwasaki        {
292100966Siwasaki            Status = AcpiUtCopyEobjectToIobject (&ExternalParams->Pointer[i],
293128212Snjl                                                 &InternalParams[i]);
294100966Siwasaki            if (ACPI_FAILURE (Status))
295100966Siwasaki            {
296100966Siwasaki                AcpiUtDeleteInternalObjectList (InternalParams);
297100966Siwasaki                return_ACPI_STATUS (Status);
298100966Siwasaki            }
299100966Siwasaki        }
300100966Siwasaki        InternalParams[ExternalParams->Count] = NULL;
301100966Siwasaki    }
302100966Siwasaki
303100966Siwasaki    /*
304100966Siwasaki     * Three major cases:
305100966Siwasaki     * 1) Fully qualified pathname
306100966Siwasaki     * 2) No handle, not fully qualified pathname (error)
307100966Siwasaki     * 3) Valid handle
308100966Siwasaki     */
309100966Siwasaki    if ((Pathname) &&
310100966Siwasaki        (AcpiNsValidRootPrefix (Pathname[0])))
311100966Siwasaki    {
312100966Siwasaki        /*
313100966Siwasaki         *  The path is fully qualified, just evaluate by name
314100966Siwasaki         */
315100966Siwasaki        Status = AcpiNsEvaluateByName (Pathname, InternalParams,
316100966Siwasaki                    &InternalReturnObj);
317100966Siwasaki    }
318100966Siwasaki    else if (!Handle)
319100966Siwasaki    {
320100966Siwasaki        /*
321100966Siwasaki         * A handle is optional iff a fully qualified pathname
322100966Siwasaki         * is specified.  Since we've already handled fully
323100966Siwasaki         * qualified names above, this is an error
324100966Siwasaki         */
325100966Siwasaki        if (!Pathname)
326100966Siwasaki        {
327100966Siwasaki            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
328100966Siwasaki                "Both Handle and Pathname are NULL\n"));
329100966Siwasaki        }
330100966Siwasaki        else
331100966Siwasaki        {
332100966Siwasaki            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
333100966Siwasaki                "Handle is NULL and Pathname is relative\n"));
334100966Siwasaki        }
335100966Siwasaki
336100966Siwasaki        Status = AE_BAD_PARAMETER;
337100966Siwasaki    }
338100966Siwasaki    else
339100966Siwasaki    {
340100966Siwasaki        /*
341100966Siwasaki         * We get here if we have a handle -- and if we have a
342100966Siwasaki         * pathname it is relative.  The handle will be validated
343100966Siwasaki         * in the lower procedures
344100966Siwasaki         */
345100966Siwasaki        if (!Pathname)
346100966Siwasaki        {
347100966Siwasaki            /*
348100966Siwasaki             * The null pathname case means the handle is for
349100966Siwasaki             * the actual object to be evaluated
350100966Siwasaki             */
351100966Siwasaki            Status = AcpiNsEvaluateByHandle (Handle, InternalParams,
352100966Siwasaki                            &InternalReturnObj);
353100966Siwasaki        }
354100966Siwasaki        else
355100966Siwasaki        {
356100966Siwasaki           /*
357100966Siwasaki            * Both a Handle and a relative Pathname
358100966Siwasaki            */
359100966Siwasaki            Status = AcpiNsEvaluateRelative (Handle, Pathname, InternalParams,
360100966Siwasaki                            &InternalReturnObj);
361100966Siwasaki        }
362100966Siwasaki    }
363100966Siwasaki
364100966Siwasaki
365100966Siwasaki    /*
366100966Siwasaki     * If we are expecting a return value, and all went well above,
367100966Siwasaki     * copy the return value to an external object.
368100966Siwasaki     */
369100966Siwasaki    if (ReturnBuffer)
370100966Siwasaki    {
371100966Siwasaki        if (!InternalReturnObj)
372100966Siwasaki        {
373100966Siwasaki            ReturnBuffer->Length = 0;
374100966Siwasaki        }
375100966Siwasaki        else
376100966Siwasaki        {
377100966Siwasaki            if (ACPI_GET_DESCRIPTOR_TYPE (InternalReturnObj) == ACPI_DESC_TYPE_NAMED)
378100966Siwasaki            {
379100966Siwasaki                /*
380100966Siwasaki                 * If we received a NS Node as a return object, this means that
381100966Siwasaki                 * the object we are evaluating has nothing interesting to
382100966Siwasaki                 * return (such as a mutex, etc.)  We return an error because
383100966Siwasaki                 * these types are essentially unsupported by this interface.
384100966Siwasaki                 * We don't check up front because this makes it easier to add
385100966Siwasaki                 * support for various types at a later date if necessary.
386100966Siwasaki                 */
387100966Siwasaki                Status = AE_TYPE;
388100966Siwasaki                InternalReturnObj = NULL;   /* No need to delete a NS Node */
389100966Siwasaki                ReturnBuffer->Length = 0;
390100966Siwasaki            }
391100966Siwasaki
392100966Siwasaki            if (ACPI_SUCCESS (Status))
393100966Siwasaki            {
394100966Siwasaki                /*
395100966Siwasaki                 * Find out how large a buffer is needed
396100966Siwasaki                 * to contain the returned object
397100966Siwasaki                 */
398100966Siwasaki                Status = AcpiUtGetObjectSize (InternalReturnObj,
399100966Siwasaki                                                &BufferSpaceNeeded);
400100966Siwasaki                if (ACPI_SUCCESS (Status))
401100966Siwasaki                {
402100966Siwasaki                    /* Validate/Allocate/Clear caller buffer */
403100966Siwasaki
404100966Siwasaki                    Status = AcpiUtInitializeBuffer (ReturnBuffer, BufferSpaceNeeded);
405100966Siwasaki                    if (ACPI_FAILURE (Status))
406100966Siwasaki                    {
407100966Siwasaki                        /*
408100966Siwasaki                         * Caller's buffer is too small or a new one can't be allocated
409100966Siwasaki                         */
410100966Siwasaki                        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
411100966Siwasaki                            "Needed buffer size %X, %s\n",
412100966Siwasaki                            (UINT32) BufferSpaceNeeded, AcpiFormatException (Status)));
413100966Siwasaki                    }
414100966Siwasaki                    else
415100966Siwasaki                    {
416100966Siwasaki                        /*
417100966Siwasaki                         *  We have enough space for the object, build it
418100966Siwasaki                         */
419100966Siwasaki                        Status = AcpiUtCopyIobjectToEobject (InternalReturnObj,
420100966Siwasaki                                        ReturnBuffer);
421100966Siwasaki                    }
422100966Siwasaki                }
423100966Siwasaki            }
424100966Siwasaki        }
425100966Siwasaki    }
426100966Siwasaki
427100966Siwasaki    if (InternalReturnObj)
428100966Siwasaki    {
429128212Snjl        /*
430128212Snjl         * Delete the internal return object.  NOTE: Interpreter
431128212Snjl         * must be locked to avoid race condition.
432100966Siwasaki         */
433128212Snjl        Status2 = AcpiExEnterInterpreter ();
434128212Snjl        if (ACPI_SUCCESS (Status2))
435128212Snjl        {
436128212Snjl            /*
437128212Snjl             * Delete the internal return object. (Or at least
438128212Snjl             * decrement the reference count by one)
439128212Snjl             */
440128212Snjl            AcpiUtRemoveReference (InternalReturnObj);
441128212Snjl            AcpiExExitInterpreter ();
442128212Snjl        }
443100966Siwasaki    }
444100966Siwasaki
445100966Siwasaki    /*
446100966Siwasaki     * Free the input parameter list (if we created one),
447100966Siwasaki     */
448100966Siwasaki    if (InternalParams)
449100966Siwasaki    {
450100966Siwasaki        /* Free the allocated parameter block */
451100966Siwasaki
452100966Siwasaki        AcpiUtDeleteInternalObjectList (InternalParams);
453100966Siwasaki    }
454100966Siwasaki
455100966Siwasaki    return_ACPI_STATUS (Status);
456100966Siwasaki}
457100966Siwasaki
458100966Siwasaki
459100966Siwasaki/*******************************************************************************
460100966Siwasaki *
461100966Siwasaki * FUNCTION:    AcpiWalkNamespace
462100966Siwasaki *
463100966Siwasaki * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
464100966Siwasaki *              StartObject         - Handle in namespace where search begins
465100966Siwasaki *              MaxDepth            - Depth to which search is to reach
466100966Siwasaki *              UserFunction        - Called when an object of "Type" is found
467100966Siwasaki *              Context             - Passed to user function
468100966Siwasaki *              ReturnValue         - Location where return value of
469100966Siwasaki *                                    UserFunction is put if terminated early
470100966Siwasaki *
471100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
472100966Siwasaki *              Otherwise, returns NULL.
473100966Siwasaki *
474100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
475100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
476100966Siwasaki *              The UserFunction is called whenever an object that matches
477100966Siwasaki *              the type parameter is found.  If the user function returns
478100966Siwasaki *              a non-zero value, the search is terminated immediately and this
479100966Siwasaki *              value is returned to the caller.
480100966Siwasaki *
481100966Siwasaki *              The point of this procedure is to provide a generic namespace
482100966Siwasaki *              walk routine that can be called from multiple places to
483100966Siwasaki *              provide multiple services;  the User Function can be tailored
484100966Siwasaki *              to each task, whether it is a print function, a compare
485100966Siwasaki *              function, etc.
486100966Siwasaki *
487100966Siwasaki ******************************************************************************/
488100966Siwasaki
489100966SiwasakiACPI_STATUS
490100966SiwasakiAcpiWalkNamespace (
491100966Siwasaki    ACPI_OBJECT_TYPE        Type,
492100966Siwasaki    ACPI_HANDLE             StartObject,
493100966Siwasaki    UINT32                  MaxDepth,
494100966Siwasaki    ACPI_WALK_CALLBACK      UserFunction,
495100966Siwasaki    void                    *Context,
496100966Siwasaki    void                    **ReturnValue)
497100966Siwasaki{
498100966Siwasaki    ACPI_STATUS             Status;
499100966Siwasaki
500100966Siwasaki
501100966Siwasaki    ACPI_FUNCTION_TRACE ("AcpiWalkNamespace");
502100966Siwasaki
503100966Siwasaki
504100966Siwasaki    /* Parameter validation */
505100966Siwasaki
506107325Siwasaki    if ((Type > ACPI_TYPE_EXTERNAL_MAX) ||
507107325Siwasaki        (!MaxDepth)                     ||
508100966Siwasaki        (!UserFunction))
509100966Siwasaki    {
510100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
511100966Siwasaki    }
512100966Siwasaki
513100966Siwasaki    /*
514100966Siwasaki     * Lock the namespace around the walk.
515100966Siwasaki     * The namespace will be unlocked/locked around each call
516100966Siwasaki     * to the user function - since this function
517100966Siwasaki     * must be allowed to make Acpi calls itself.
518100966Siwasaki     */
519100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
520100966Siwasaki    if (ACPI_FAILURE (Status))
521100966Siwasaki    {
522100966Siwasaki        return_ACPI_STATUS (Status);
523100966Siwasaki    }
524100966Siwasaki
525100966Siwasaki    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, ACPI_NS_WALK_UNLOCK,
526100966Siwasaki                    UserFunction, Context, ReturnValue);
527100966Siwasaki
528100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
529100966Siwasaki    return_ACPI_STATUS (Status);
530100966Siwasaki}
531100966Siwasaki
532100966Siwasaki
533100966Siwasaki/*******************************************************************************
534100966Siwasaki *
535100966Siwasaki * FUNCTION:    AcpiNsGetDeviceCallback
536100966Siwasaki *
537100966Siwasaki * PARAMETERS:  Callback from AcpiGetDevice
538100966Siwasaki *
539100966Siwasaki * RETURN:      Status
540100966Siwasaki *
541100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
542100966Siwasaki *              present devices, or if they specified a HID, it filters based
543100966Siwasaki *              on that.
544100966Siwasaki *
545100966Siwasaki ******************************************************************************/
546100966Siwasaki
547100966Siwasakistatic ACPI_STATUS
548100966SiwasakiAcpiNsGetDeviceCallback (
549100966Siwasaki    ACPI_HANDLE             ObjHandle,
550100966Siwasaki    UINT32                  NestingLevel,
551100966Siwasaki    void                    *Context,
552100966Siwasaki    void                    **ReturnValue)
553100966Siwasaki{
554117521Snjl    ACPI_GET_DEVICES_INFO   *Info = Context;
555100966Siwasaki    ACPI_STATUS             Status;
556100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
557100966Siwasaki    UINT32                  Flags;
558100966Siwasaki    ACPI_DEVICE_ID          Hid;
559117521Snjl    ACPI_COMPATIBLE_ID_LIST *Cid;
560117521Snjl    ACPI_NATIVE_UINT        i;
561100966Siwasaki
562100966Siwasaki
563100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
564100966Siwasaki    if (ACPI_FAILURE (Status))
565100966Siwasaki    {
566100966Siwasaki        return (Status);
567100966Siwasaki    }
568100966Siwasaki
569100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
570100966Siwasaki    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
571100966Siwasaki    if (ACPI_FAILURE (Status))
572100966Siwasaki    {
573100966Siwasaki        return (Status);
574100966Siwasaki    }
575100966Siwasaki
576100966Siwasaki    if (!Node)
577100966Siwasaki    {
578100966Siwasaki        return (AE_BAD_PARAMETER);
579100966Siwasaki    }
580100966Siwasaki
581117521Snjl    /* Run _STA to determine if device is present */
582117521Snjl
583100966Siwasaki    Status = AcpiUtExecute_STA (Node, &Flags);
584100966Siwasaki    if (ACPI_FAILURE (Status))
585100966Siwasaki    {
586100966Siwasaki        return (AE_CTRL_DEPTH);
587100966Siwasaki    }
588100966Siwasaki
589100966Siwasaki    if (!(Flags & 0x01))
590100966Siwasaki    {
591100966Siwasaki        /* Don't return at the device or children of the device if not there */
592117521Snjl
593100966Siwasaki        return (AE_CTRL_DEPTH);
594100966Siwasaki    }
595100966Siwasaki
596117521Snjl    /* Filter based on device HID & CID */
597117521Snjl
598100966Siwasaki    if (Info->Hid != NULL)
599100966Siwasaki    {
600100966Siwasaki        Status = AcpiUtExecute_HID (Node, &Hid);
601100966Siwasaki        if (Status == AE_NOT_FOUND)
602100966Siwasaki        {
603100966Siwasaki            return (AE_OK);
604100966Siwasaki        }
605100966Siwasaki        else if (ACPI_FAILURE (Status))
606100966Siwasaki        {
607100966Siwasaki            return (AE_CTRL_DEPTH);
608100966Siwasaki        }
609100966Siwasaki
610117521Snjl        if (ACPI_STRNCMP (Hid.Value, Info->Hid, sizeof (Hid.Value)) != 0)
611100966Siwasaki        {
612117521Snjl            /* Get the list of Compatible IDs */
613117521Snjl
614100966Siwasaki            Status = AcpiUtExecute_CID (Node, &Cid);
615100966Siwasaki            if (Status == AE_NOT_FOUND)
616100966Siwasaki            {
617100966Siwasaki                return (AE_OK);
618100966Siwasaki            }
619100966Siwasaki            else if (ACPI_FAILURE (Status))
620100966Siwasaki            {
621100966Siwasaki                return (AE_CTRL_DEPTH);
622100966Siwasaki            }
623100966Siwasaki
624117521Snjl            /* Walk the CID list */
625100966Siwasaki
626117521Snjl            for (i = 0; i < Cid->Count; i++)
627100966Siwasaki            {
628117521Snjl                if (ACPI_STRNCMP (Cid->Id[i].Value, Info->Hid,
629117521Snjl                                        sizeof (ACPI_COMPATIBLE_ID)) != 0)
630117521Snjl                {
631117521Snjl                    ACPI_MEM_FREE (Cid);
632117521Snjl                    return (AE_OK);
633117521Snjl                }
634100966Siwasaki            }
635117521Snjl            ACPI_MEM_FREE (Cid);
636100966Siwasaki        }
637100966Siwasaki    }
638100966Siwasaki
639100966Siwasaki    Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue);
640100966Siwasaki    return (Status);
641100966Siwasaki}
642100966Siwasaki
643100966Siwasaki
644100966Siwasaki/*******************************************************************************
645100966Siwasaki *
646100966Siwasaki * FUNCTION:    AcpiGetDevices
647100966Siwasaki *
648100966Siwasaki * PARAMETERS:  HID                 - HID to search for. Can be NULL.
649100966Siwasaki *              UserFunction        - Called when a matching object is found
650100966Siwasaki *              Context             - Passed to user function
651100966Siwasaki *              ReturnValue         - Location where return value of
652100966Siwasaki *                                    UserFunction is put if terminated early
653100966Siwasaki *
654100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
655100966Siwasaki *              Otherwise, returns NULL.
656100966Siwasaki *
657100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
658100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
659117521Snjl *              The UserFunction is called whenever an object of type
660117521Snjl *              Device is found.  If the user function returns
661100966Siwasaki *              a non-zero value, the search is terminated immediately and this
662100966Siwasaki *              value is returned to the caller.
663100966Siwasaki *
664100966Siwasaki *              This is a wrapper for WalkNamespace, but the callback performs
665100966Siwasaki *              additional filtering. Please see AcpiGetDeviceCallback.
666100966Siwasaki *
667100966Siwasaki ******************************************************************************/
668100966Siwasaki
669100966SiwasakiACPI_STATUS
670100966SiwasakiAcpiGetDevices (
671114237Snjl    char                    *HID,
672100966Siwasaki    ACPI_WALK_CALLBACK      UserFunction,
673100966Siwasaki    void                    *Context,
674100966Siwasaki    void                    **ReturnValue)
675100966Siwasaki{
676100966Siwasaki    ACPI_STATUS             Status;
677100966Siwasaki    ACPI_GET_DEVICES_INFO   Info;
678100966Siwasaki
679100966Siwasaki
680100966Siwasaki    ACPI_FUNCTION_TRACE ("AcpiGetDevices");
681100966Siwasaki
682100966Siwasaki
683100966Siwasaki    /* Parameter validation */
684100966Siwasaki
685100966Siwasaki    if (!UserFunction)
686100966Siwasaki    {
687100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
688100966Siwasaki    }
689100966Siwasaki
690100966Siwasaki    /*
691100966Siwasaki     * We're going to call their callback from OUR callback, so we need
692100966Siwasaki     * to know what it is, and their context parameter.
693100966Siwasaki     */
694100966Siwasaki    Info.Context      = Context;
695100966Siwasaki    Info.UserFunction = UserFunction;
696100966Siwasaki    Info.Hid          = HID;
697100966Siwasaki
698100966Siwasaki    /*
699100966Siwasaki     * Lock the namespace around the walk.
700100966Siwasaki     * The namespace will be unlocked/locked around each call
701100966Siwasaki     * to the user function - since this function
702100966Siwasaki     * must be allowed to make Acpi calls itself.
703100966Siwasaki     */
704100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
705100966Siwasaki    if (ACPI_FAILURE (Status))
706100966Siwasaki    {
707100966Siwasaki        return_ACPI_STATUS (Status);
708100966Siwasaki    }
709100966Siwasaki
710100966Siwasaki    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE,
711100966Siwasaki                                    ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
712100966Siwasaki                                    ACPI_NS_WALK_UNLOCK,
713100966Siwasaki                                    AcpiNsGetDeviceCallback, &Info,
714100966Siwasaki                                    ReturnValue);
715100966Siwasaki
716100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
717100966Siwasaki    return_ACPI_STATUS (Status);
718100966Siwasaki}
719100966Siwasaki
720100966Siwasaki
721100966Siwasaki/*******************************************************************************
722100966Siwasaki *
723100966Siwasaki * FUNCTION:    AcpiAttachData
724100966Siwasaki *
725114237Snjl * PARAMETERS:  ObjHandle           - Namespace node
726107325Siwasaki *              Handler             - Handler for this attachment
727107325Siwasaki *              Data                - Pointer to data to be attached
728100966Siwasaki *
729100966Siwasaki * RETURN:      Status
730100966Siwasaki *
731107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
732100966Siwasaki *
733100966Siwasaki ******************************************************************************/
734100966Siwasaki
735100966SiwasakiACPI_STATUS
736100966SiwasakiAcpiAttachData (
737100966Siwasaki    ACPI_HANDLE             ObjHandle,
738100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
739100966Siwasaki    void                    *Data)
740100966Siwasaki{
741100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
742100966Siwasaki    ACPI_STATUS             Status;
743100966Siwasaki
744100966Siwasaki
745100966Siwasaki    /* Parameter validation */
746100966Siwasaki
747100966Siwasaki    if (!ObjHandle  ||
748100966Siwasaki        !Handler    ||
749100966Siwasaki        !Data)
750100966Siwasaki    {
751100966Siwasaki        return (AE_BAD_PARAMETER);
752100966Siwasaki    }
753100966Siwasaki
754100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
755100966Siwasaki    if (ACPI_FAILURE (Status))
756100966Siwasaki    {
757100966Siwasaki        return (Status);
758100966Siwasaki    }
759100966Siwasaki
760100966Siwasaki    /* Convert and validate the handle */
761100966Siwasaki
762100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
763100966Siwasaki    if (!Node)
764100966Siwasaki    {
765100966Siwasaki        Status = AE_BAD_PARAMETER;
766100966Siwasaki        goto UnlockAndExit;
767100966Siwasaki    }
768100966Siwasaki
769100966Siwasaki    Status = AcpiNsAttachData (Node, Handler, Data);
770100966Siwasaki
771100966SiwasakiUnlockAndExit:
772100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
773100966Siwasaki    return (Status);
774100966Siwasaki}
775100966Siwasaki
776100966Siwasaki
777100966Siwasaki/*******************************************************************************
778100966Siwasaki *
779100966Siwasaki * FUNCTION:    AcpiDetachData
780100966Siwasaki *
781107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node handle
782107325Siwasaki *              Handler             - Handler used in call to AcpiAttachData
783100966Siwasaki *
784100966Siwasaki * RETURN:      Status
785100966Siwasaki *
786107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node.
787100966Siwasaki *
788100966Siwasaki ******************************************************************************/
789100966Siwasaki
790100966SiwasakiACPI_STATUS
791100966SiwasakiAcpiDetachData (
792100966Siwasaki    ACPI_HANDLE             ObjHandle,
793100966Siwasaki    ACPI_OBJECT_HANDLER     Handler)
794100966Siwasaki{
795100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
796100966Siwasaki    ACPI_STATUS             Status;
797100966Siwasaki
798100966Siwasaki
799100966Siwasaki    /* Parameter validation */
800100966Siwasaki
801100966Siwasaki    if (!ObjHandle  ||
802100966Siwasaki        !Handler)
803100966Siwasaki    {
804100966Siwasaki        return (AE_BAD_PARAMETER);
805100966Siwasaki    }
806100966Siwasaki
807100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
808100966Siwasaki    if (ACPI_FAILURE (Status))
809100966Siwasaki    {
810100966Siwasaki        return (Status);
811100966Siwasaki    }
812100966Siwasaki
813100966Siwasaki    /* Convert and validate the handle */
814100966Siwasaki
815100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
816100966Siwasaki    if (!Node)
817100966Siwasaki    {
818100966Siwasaki        Status = AE_BAD_PARAMETER;
819100966Siwasaki        goto UnlockAndExit;
820100966Siwasaki    }
821100966Siwasaki
822100966Siwasaki    Status = AcpiNsDetachData (Node, Handler);
823100966Siwasaki
824100966SiwasakiUnlockAndExit:
825100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
826100966Siwasaki    return (Status);
827100966Siwasaki}
828100966Siwasaki
829100966Siwasaki
830100966Siwasaki/*******************************************************************************
831100966Siwasaki *
832100966Siwasaki * FUNCTION:    AcpiGetData
833100966Siwasaki *
834107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node
835107325Siwasaki *              Handler             - Handler used in call to AttachData
836107325Siwasaki *              Data                - Where the data is returned
837100966Siwasaki *
838100966Siwasaki * RETURN:      Status
839100966Siwasaki *
840107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
841100966Siwasaki *
842100966Siwasaki ******************************************************************************/
843100966Siwasaki
844100966SiwasakiACPI_STATUS
845100966SiwasakiAcpiGetData (
846100966Siwasaki    ACPI_HANDLE             ObjHandle,
847100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
848100966Siwasaki    void                    **Data)
849100966Siwasaki{
850100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
851100966Siwasaki    ACPI_STATUS             Status;
852100966Siwasaki
853100966Siwasaki
854100966Siwasaki    /* Parameter validation */
855100966Siwasaki
856100966Siwasaki    if (!ObjHandle  ||
857100966Siwasaki        !Handler    ||
858100966Siwasaki        !Data)
859100966Siwasaki    {
860100966Siwasaki        return (AE_BAD_PARAMETER);
861100966Siwasaki    }
862100966Siwasaki
863100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
864100966Siwasaki    if (ACPI_FAILURE (Status))
865100966Siwasaki    {
866100966Siwasaki        return (Status);
867100966Siwasaki    }
868100966Siwasaki
869100966Siwasaki    /* Convert and validate the handle */
870100966Siwasaki
871100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
872100966Siwasaki    if (!Node)
873100966Siwasaki    {
874100966Siwasaki        Status = AE_BAD_PARAMETER;
875100966Siwasaki        goto UnlockAndExit;
876100966Siwasaki    }
877100966Siwasaki
878100966Siwasaki    Status = AcpiNsGetAttachedData (Node, Handler, Data);
879100966Siwasaki
880100966SiwasakiUnlockAndExit:
881100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
882100966Siwasaki    return (Status);
883100966Siwasaki}
884100966Siwasaki
885100966Siwasaki
886