nsxfeval.c revision 114237
1100966Siwasaki/*******************************************************************************
2100966Siwasaki *
3100966Siwasaki * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4100966Siwasaki *                         ACPI Object evaluation interfaces
5114237Snjl *              $Revision: 7 $
6100966Siwasaki *
7100966Siwasaki ******************************************************************************/
8100966Siwasaki
9100966Siwasaki/******************************************************************************
10100966Siwasaki *
11100966Siwasaki * 1. Copyright Notice
12100966Siwasaki *
13114237Snjl * Some or all of this work - Copyright (c) 1999 - 2003, 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"
123100966Siwasaki
124100966Siwasaki
125100966Siwasaki#define _COMPONENT          ACPI_NAMESPACE
126100966Siwasaki        ACPI_MODULE_NAME    ("nsxfeval")
127100966Siwasaki
128100966Siwasaki
129100966Siwasaki/*******************************************************************************
130100966Siwasaki *
131100966Siwasaki * FUNCTION:    AcpiEvaluateObjectTyped
132100966Siwasaki *
133100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
134100966Siwasaki *              *Pathname           - Object pathname (optional)
135100966Siwasaki *              **ExternalParams    - List of parameters to pass to method,
136100966Siwasaki *                                    terminated by NULL.  May be NULL
137100966Siwasaki *                                    if no parameters are being passed.
138100966Siwasaki *              *ReturnBuffer       - Where to put method's return value (if
139100966Siwasaki *                                    any).  If NULL, no value is returned.
140100966Siwasaki *              ReturnType          - Expected type of return object
141100966Siwasaki *
142100966Siwasaki * RETURN:      Status
143100966Siwasaki *
144100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
145100966Siwasaki *              parameters if necessary.  One of "Handle" or "Pathname" must
146100966Siwasaki *              be valid (non-null)
147100966Siwasaki *
148100966Siwasaki ******************************************************************************/
149100966Siwasaki
150100966SiwasakiACPI_STATUS
151100966SiwasakiAcpiEvaluateObjectTyped (
152100966Siwasaki    ACPI_HANDLE             Handle,
153100966Siwasaki    ACPI_STRING             Pathname,
154100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
155100966Siwasaki    ACPI_BUFFER             *ReturnBuffer,
156100966Siwasaki    ACPI_OBJECT_TYPE        ReturnType)
157100966Siwasaki{
158100966Siwasaki    ACPI_STATUS             Status;
159100966Siwasaki    BOOLEAN                 MustFree = FALSE;
160100966Siwasaki
161100966Siwasaki
162100966Siwasaki    ACPI_FUNCTION_TRACE ("AcpiEvaluateObjectTyped");
163100966Siwasaki
164100966Siwasaki
165100966Siwasaki    /* Return buffer must be valid */
166100966Siwasaki
167100966Siwasaki    if (!ReturnBuffer)
168100966Siwasaki    {
169100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
170100966Siwasaki    }
171100966Siwasaki
172100966Siwasaki    if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
173100966Siwasaki    {
174100966Siwasaki        MustFree = TRUE;
175100966Siwasaki    }
176100966Siwasaki
177100966Siwasaki    /* Evaluate the object */
178100966Siwasaki
179100966Siwasaki    Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
180100966Siwasaki    if (ACPI_FAILURE (Status))
181100966Siwasaki    {
182100966Siwasaki        return_ACPI_STATUS (Status);
183100966Siwasaki    }
184100966Siwasaki
185100966Siwasaki    /* Type ANY means "don't care" */
186100966Siwasaki
187100966Siwasaki    if (ReturnType == ACPI_TYPE_ANY)
188100966Siwasaki    {
189100966Siwasaki        return_ACPI_STATUS (AE_OK);
190100966Siwasaki    }
191100966Siwasaki
192100966Siwasaki    if (ReturnBuffer->Length == 0)
193100966Siwasaki    {
194100966Siwasaki        /* Error because caller specifically asked for a return value */
195100966Siwasaki
196100966Siwasaki        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
197100966Siwasaki            "No return value\n"));
198100966Siwasaki
199100966Siwasaki        return_ACPI_STATUS (AE_NULL_OBJECT);
200100966Siwasaki    }
201100966Siwasaki
202100966Siwasaki    /* Examine the object type returned from EvaluateObject */
203100966Siwasaki
204100966Siwasaki    if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
205100966Siwasaki    {
206100966Siwasaki        return_ACPI_STATUS (AE_OK);
207100966Siwasaki    }
208100966Siwasaki
209100966Siwasaki    /* Return object type does not match requested type */
210100966Siwasaki
211100966Siwasaki    ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
212100966Siwasaki        "Incorrect return type [%s] requested [%s]\n",
213100966Siwasaki        AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
214100966Siwasaki        AcpiUtGetTypeName (ReturnType)));
215100966Siwasaki
216100966Siwasaki    if (MustFree)
217100966Siwasaki    {
218100966Siwasaki        /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
219100966Siwasaki
220100966Siwasaki        AcpiOsFree (ReturnBuffer->Pointer);
221100966Siwasaki        ReturnBuffer->Pointer = NULL;
222100966Siwasaki    }
223100966Siwasaki
224100966Siwasaki    ReturnBuffer->Length = 0;
225100966Siwasaki    return_ACPI_STATUS (AE_TYPE);
226100966Siwasaki}
227100966Siwasaki
228100966Siwasaki
229100966Siwasaki/*******************************************************************************
230100966Siwasaki *
231100966Siwasaki * FUNCTION:    AcpiEvaluateObject
232100966Siwasaki *
233100966Siwasaki * PARAMETERS:  Handle              - Object handle (optional)
234100966Siwasaki *              *Pathname           - Object pathname (optional)
235100966Siwasaki *              **ExternalParams    - List of parameters to pass to method,
236100966Siwasaki *                                    terminated by NULL.  May be NULL
237100966Siwasaki *                                    if no parameters are being passed.
238100966Siwasaki *              *ReturnBuffer       - Where to put method's return value (if
239100966Siwasaki *                                    any).  If NULL, no value is returned.
240100966Siwasaki *
241100966Siwasaki * RETURN:      Status
242100966Siwasaki *
243100966Siwasaki * DESCRIPTION: Find and evaluate the given object, passing the given
244100966Siwasaki *              parameters if necessary.  One of "Handle" or "Pathname" must
245100966Siwasaki *              be valid (non-null)
246100966Siwasaki *
247100966Siwasaki ******************************************************************************/
248100966Siwasaki
249100966SiwasakiACPI_STATUS
250100966SiwasakiAcpiEvaluateObject (
251100966Siwasaki    ACPI_HANDLE             Handle,
252100966Siwasaki    ACPI_STRING             Pathname,
253100966Siwasaki    ACPI_OBJECT_LIST        *ExternalParams,
254100966Siwasaki    ACPI_BUFFER             *ReturnBuffer)
255100966Siwasaki{
256100966Siwasaki    ACPI_STATUS             Status;
257100966Siwasaki    ACPI_OPERAND_OBJECT     **InternalParams = NULL;
258100966Siwasaki    ACPI_OPERAND_OBJECT     *InternalReturnObj = NULL;
259100966Siwasaki    ACPI_SIZE               BufferSpaceNeeded;
260100966Siwasaki    UINT32                  i;
261100966Siwasaki
262100966Siwasaki
263100966Siwasaki    ACPI_FUNCTION_TRACE ("AcpiEvaluateObject");
264100966Siwasaki
265100966Siwasaki
266100966Siwasaki    /*
267100966Siwasaki     * If there are parameters to be passed to the object
268100966Siwasaki     * (which must be a control method), the external objects
269100966Siwasaki     * must be converted to internal objects
270100966Siwasaki     */
271100966Siwasaki    if (ExternalParams && ExternalParams->Count)
272100966Siwasaki    {
273100966Siwasaki        /*
274100966Siwasaki         * Allocate a new parameter block for the internal objects
275100966Siwasaki         * Add 1 to count to allow for null terminated internal list
276100966Siwasaki         */
277100966Siwasaki        InternalParams = ACPI_MEM_CALLOCATE (((ACPI_SIZE) ExternalParams->Count + 1) *
278100966Siwasaki                                                sizeof (void *));
279100966Siwasaki        if (!InternalParams)
280100966Siwasaki        {
281100966Siwasaki            return_ACPI_STATUS (AE_NO_MEMORY);
282100966Siwasaki        }
283100966Siwasaki
284100966Siwasaki        /*
285100966Siwasaki         * Convert each external object in the list to an
286100966Siwasaki         * internal object
287100966Siwasaki         */
288100966Siwasaki        for (i = 0; i < ExternalParams->Count; i++)
289100966Siwasaki        {
290100966Siwasaki            Status = AcpiUtCopyEobjectToIobject (&ExternalParams->Pointer[i],
291100966Siwasaki                                                &InternalParams[i]);
292100966Siwasaki            if (ACPI_FAILURE (Status))
293100966Siwasaki            {
294100966Siwasaki                AcpiUtDeleteInternalObjectList (InternalParams);
295100966Siwasaki                return_ACPI_STATUS (Status);
296100966Siwasaki            }
297100966Siwasaki        }
298100966Siwasaki        InternalParams[ExternalParams->Count] = NULL;
299100966Siwasaki    }
300100966Siwasaki
301100966Siwasaki    /*
302100966Siwasaki     * Three major cases:
303100966Siwasaki     * 1) Fully qualified pathname
304100966Siwasaki     * 2) No handle, not fully qualified pathname (error)
305100966Siwasaki     * 3) Valid handle
306100966Siwasaki     */
307100966Siwasaki    if ((Pathname) &&
308100966Siwasaki        (AcpiNsValidRootPrefix (Pathname[0])))
309100966Siwasaki    {
310100966Siwasaki        /*
311100966Siwasaki         *  The path is fully qualified, just evaluate by name
312100966Siwasaki         */
313100966Siwasaki        Status = AcpiNsEvaluateByName (Pathname, InternalParams,
314100966Siwasaki                    &InternalReturnObj);
315100966Siwasaki    }
316100966Siwasaki    else if (!Handle)
317100966Siwasaki    {
318100966Siwasaki        /*
319100966Siwasaki         * A handle is optional iff a fully qualified pathname
320100966Siwasaki         * is specified.  Since we've already handled fully
321100966Siwasaki         * qualified names above, this is an error
322100966Siwasaki         */
323100966Siwasaki        if (!Pathname)
324100966Siwasaki        {
325100966Siwasaki            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
326100966Siwasaki                "Both Handle and Pathname are NULL\n"));
327100966Siwasaki        }
328100966Siwasaki        else
329100966Siwasaki        {
330100966Siwasaki            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
331100966Siwasaki                "Handle is NULL and Pathname is relative\n"));
332100966Siwasaki        }
333100966Siwasaki
334100966Siwasaki        Status = AE_BAD_PARAMETER;
335100966Siwasaki    }
336100966Siwasaki    else
337100966Siwasaki    {
338100966Siwasaki        /*
339100966Siwasaki         * We get here if we have a handle -- and if we have a
340100966Siwasaki         * pathname it is relative.  The handle will be validated
341100966Siwasaki         * in the lower procedures
342100966Siwasaki         */
343100966Siwasaki        if (!Pathname)
344100966Siwasaki        {
345100966Siwasaki            /*
346100966Siwasaki             * The null pathname case means the handle is for
347100966Siwasaki             * the actual object to be evaluated
348100966Siwasaki             */
349100966Siwasaki            Status = AcpiNsEvaluateByHandle (Handle, InternalParams,
350100966Siwasaki                            &InternalReturnObj);
351100966Siwasaki        }
352100966Siwasaki        else
353100966Siwasaki        {
354100966Siwasaki           /*
355100966Siwasaki            * Both a Handle and a relative Pathname
356100966Siwasaki            */
357100966Siwasaki            Status = AcpiNsEvaluateRelative (Handle, Pathname, InternalParams,
358100966Siwasaki                            &InternalReturnObj);
359100966Siwasaki        }
360100966Siwasaki    }
361100966Siwasaki
362100966Siwasaki
363100966Siwasaki    /*
364100966Siwasaki     * If we are expecting a return value, and all went well above,
365100966Siwasaki     * copy the return value to an external object.
366100966Siwasaki     */
367100966Siwasaki    if (ReturnBuffer)
368100966Siwasaki    {
369100966Siwasaki        if (!InternalReturnObj)
370100966Siwasaki        {
371100966Siwasaki            ReturnBuffer->Length = 0;
372100966Siwasaki        }
373100966Siwasaki        else
374100966Siwasaki        {
375100966Siwasaki            if (ACPI_GET_DESCRIPTOR_TYPE (InternalReturnObj) == ACPI_DESC_TYPE_NAMED)
376100966Siwasaki            {
377100966Siwasaki                /*
378100966Siwasaki                 * If we received a NS Node as a return object, this means that
379100966Siwasaki                 * the object we are evaluating has nothing interesting to
380100966Siwasaki                 * return (such as a mutex, etc.)  We return an error because
381100966Siwasaki                 * these types are essentially unsupported by this interface.
382100966Siwasaki                 * We don't check up front because this makes it easier to add
383100966Siwasaki                 * support for various types at a later date if necessary.
384100966Siwasaki                 */
385100966Siwasaki                Status = AE_TYPE;
386100966Siwasaki                InternalReturnObj = NULL;   /* No need to delete a NS Node */
387100966Siwasaki                ReturnBuffer->Length = 0;
388100966Siwasaki            }
389100966Siwasaki
390100966Siwasaki            if (ACPI_SUCCESS (Status))
391100966Siwasaki            {
392100966Siwasaki                /*
393100966Siwasaki                 * Find out how large a buffer is needed
394100966Siwasaki                 * to contain the returned object
395100966Siwasaki                 */
396100966Siwasaki                Status = AcpiUtGetObjectSize (InternalReturnObj,
397100966Siwasaki                                                &BufferSpaceNeeded);
398100966Siwasaki                if (ACPI_SUCCESS (Status))
399100966Siwasaki                {
400100966Siwasaki                    /* Validate/Allocate/Clear caller buffer */
401100966Siwasaki
402100966Siwasaki                    Status = AcpiUtInitializeBuffer (ReturnBuffer, BufferSpaceNeeded);
403100966Siwasaki                    if (ACPI_FAILURE (Status))
404100966Siwasaki                    {
405100966Siwasaki                        /*
406100966Siwasaki                         * Caller's buffer is too small or a new one can't be allocated
407100966Siwasaki                         */
408100966Siwasaki                        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
409100966Siwasaki                            "Needed buffer size %X, %s\n",
410100966Siwasaki                            (UINT32) BufferSpaceNeeded, AcpiFormatException (Status)));
411100966Siwasaki                    }
412100966Siwasaki                    else
413100966Siwasaki                    {
414100966Siwasaki                        /*
415100966Siwasaki                         *  We have enough space for the object, build it
416100966Siwasaki                         */
417100966Siwasaki                        Status = AcpiUtCopyIobjectToEobject (InternalReturnObj,
418100966Siwasaki                                        ReturnBuffer);
419100966Siwasaki                    }
420100966Siwasaki                }
421100966Siwasaki            }
422100966Siwasaki        }
423100966Siwasaki    }
424100966Siwasaki
425100966Siwasaki    /* Delete the return and parameter objects */
426100966Siwasaki
427100966Siwasaki    if (InternalReturnObj)
428100966Siwasaki    {
429100966Siwasaki        /*
430100966Siwasaki         * Delete the internal return object. (Or at least
431100966Siwasaki         * decrement the reference count by one)
432100966Siwasaki         */
433100966Siwasaki        AcpiUtRemoveReference (InternalReturnObj);
434100966Siwasaki    }
435100966Siwasaki
436100966Siwasaki    /*
437100966Siwasaki     * Free the input parameter list (if we created one),
438100966Siwasaki     */
439100966Siwasaki    if (InternalParams)
440100966Siwasaki    {
441100966Siwasaki        /* Free the allocated parameter block */
442100966Siwasaki
443100966Siwasaki        AcpiUtDeleteInternalObjectList (InternalParams);
444100966Siwasaki    }
445100966Siwasaki
446100966Siwasaki    return_ACPI_STATUS (Status);
447100966Siwasaki}
448100966Siwasaki
449100966Siwasaki
450100966Siwasaki/*******************************************************************************
451100966Siwasaki *
452100966Siwasaki * FUNCTION:    AcpiWalkNamespace
453100966Siwasaki *
454100966Siwasaki * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
455100966Siwasaki *              StartObject         - Handle in namespace where search begins
456100966Siwasaki *              MaxDepth            - Depth to which search is to reach
457100966Siwasaki *              UserFunction        - Called when an object of "Type" is found
458100966Siwasaki *              Context             - Passed to user function
459100966Siwasaki *              ReturnValue         - Location where return value of
460100966Siwasaki *                                    UserFunction is put if terminated early
461100966Siwasaki *
462100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
463100966Siwasaki *              Otherwise, returns NULL.
464100966Siwasaki *
465100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
466100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
467100966Siwasaki *              The UserFunction is called whenever an object that matches
468100966Siwasaki *              the type parameter is found.  If the user function returns
469100966Siwasaki *              a non-zero value, the search is terminated immediately and this
470100966Siwasaki *              value is returned to the caller.
471100966Siwasaki *
472100966Siwasaki *              The point of this procedure is to provide a generic namespace
473100966Siwasaki *              walk routine that can be called from multiple places to
474100966Siwasaki *              provide multiple services;  the User Function can be tailored
475100966Siwasaki *              to each task, whether it is a print function, a compare
476100966Siwasaki *              function, etc.
477100966Siwasaki *
478100966Siwasaki ******************************************************************************/
479100966Siwasaki
480100966SiwasakiACPI_STATUS
481100966SiwasakiAcpiWalkNamespace (
482100966Siwasaki    ACPI_OBJECT_TYPE        Type,
483100966Siwasaki    ACPI_HANDLE             StartObject,
484100966Siwasaki    UINT32                  MaxDepth,
485100966Siwasaki    ACPI_WALK_CALLBACK      UserFunction,
486100966Siwasaki    void                    *Context,
487100966Siwasaki    void                    **ReturnValue)
488100966Siwasaki{
489100966Siwasaki    ACPI_STATUS             Status;
490100966Siwasaki
491100966Siwasaki
492100966Siwasaki    ACPI_FUNCTION_TRACE ("AcpiWalkNamespace");
493100966Siwasaki
494100966Siwasaki
495100966Siwasaki    /* Parameter validation */
496100966Siwasaki
497107325Siwasaki    if ((Type > ACPI_TYPE_EXTERNAL_MAX) ||
498107325Siwasaki        (!MaxDepth)                     ||
499100966Siwasaki        (!UserFunction))
500100966Siwasaki    {
501100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
502100966Siwasaki    }
503100966Siwasaki
504100966Siwasaki    /*
505100966Siwasaki     * Lock the namespace around the walk.
506100966Siwasaki     * The namespace will be unlocked/locked around each call
507100966Siwasaki     * to the user function - since this function
508100966Siwasaki     * must be allowed to make Acpi calls itself.
509100966Siwasaki     */
510100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
511100966Siwasaki    if (ACPI_FAILURE (Status))
512100966Siwasaki    {
513100966Siwasaki        return_ACPI_STATUS (Status);
514100966Siwasaki    }
515100966Siwasaki
516100966Siwasaki    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, ACPI_NS_WALK_UNLOCK,
517100966Siwasaki                    UserFunction, Context, ReturnValue);
518100966Siwasaki
519100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
520100966Siwasaki    return_ACPI_STATUS (Status);
521100966Siwasaki}
522100966Siwasaki
523100966Siwasaki
524100966Siwasaki/*******************************************************************************
525100966Siwasaki *
526100966Siwasaki * FUNCTION:    AcpiNsGetDeviceCallback
527100966Siwasaki *
528100966Siwasaki * PARAMETERS:  Callback from AcpiGetDevice
529100966Siwasaki *
530100966Siwasaki * RETURN:      Status
531100966Siwasaki *
532100966Siwasaki * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
533100966Siwasaki *              present devices, or if they specified a HID, it filters based
534100966Siwasaki *              on that.
535100966Siwasaki *
536100966Siwasaki ******************************************************************************/
537100966Siwasaki
538100966Siwasakistatic ACPI_STATUS
539100966SiwasakiAcpiNsGetDeviceCallback (
540100966Siwasaki    ACPI_HANDLE             ObjHandle,
541100966Siwasaki    UINT32                  NestingLevel,
542100966Siwasaki    void                    *Context,
543100966Siwasaki    void                    **ReturnValue)
544100966Siwasaki{
545100966Siwasaki    ACPI_STATUS             Status;
546100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
547100966Siwasaki    UINT32                  Flags;
548100966Siwasaki    ACPI_DEVICE_ID          Hid;
549100966Siwasaki    ACPI_DEVICE_ID          Cid;
550100966Siwasaki    ACPI_GET_DEVICES_INFO   *Info;
551100966Siwasaki
552100966Siwasaki
553100966Siwasaki    Info = Context;
554100966Siwasaki
555100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
556100966Siwasaki    if (ACPI_FAILURE (Status))
557100966Siwasaki    {
558100966Siwasaki        return (Status);
559100966Siwasaki    }
560100966Siwasaki
561100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
562100966Siwasaki    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
563100966Siwasaki    if (ACPI_FAILURE (Status))
564100966Siwasaki    {
565100966Siwasaki        return (Status);
566100966Siwasaki    }
567100966Siwasaki
568100966Siwasaki    if (!Node)
569100966Siwasaki    {
570100966Siwasaki        return (AE_BAD_PARAMETER);
571100966Siwasaki    }
572100966Siwasaki
573100966Siwasaki    /*
574100966Siwasaki     * Run _STA to determine if device is present
575100966Siwasaki     */
576100966Siwasaki    Status = AcpiUtExecute_STA (Node, &Flags);
577100966Siwasaki    if (ACPI_FAILURE (Status))
578100966Siwasaki    {
579100966Siwasaki        return (AE_CTRL_DEPTH);
580100966Siwasaki    }
581100966Siwasaki
582100966Siwasaki    if (!(Flags & 0x01))
583100966Siwasaki    {
584100966Siwasaki        /* Don't return at the device or children of the device if not there */
585100966Siwasaki        return (AE_CTRL_DEPTH);
586100966Siwasaki    }
587100966Siwasaki
588100966Siwasaki    /*
589100966Siwasaki     * Filter based on device HID & CID
590100966Siwasaki     */
591100966Siwasaki    if (Info->Hid != NULL)
592100966Siwasaki    {
593100966Siwasaki        Status = AcpiUtExecute_HID (Node, &Hid);
594100966Siwasaki        if (Status == AE_NOT_FOUND)
595100966Siwasaki        {
596100966Siwasaki            return (AE_OK);
597100966Siwasaki        }
598100966Siwasaki        else if (ACPI_FAILURE (Status))
599100966Siwasaki        {
600100966Siwasaki            return (AE_CTRL_DEPTH);
601100966Siwasaki        }
602100966Siwasaki
603100966Siwasaki        if (ACPI_STRNCMP (Hid.Buffer, Info->Hid, sizeof (Hid.Buffer)) != 0)
604100966Siwasaki        {
605100966Siwasaki            Status = AcpiUtExecute_CID (Node, &Cid);
606100966Siwasaki            if (Status == AE_NOT_FOUND)
607100966Siwasaki            {
608100966Siwasaki                return (AE_OK);
609100966Siwasaki            }
610100966Siwasaki            else if (ACPI_FAILURE (Status))
611100966Siwasaki            {
612100966Siwasaki                return (AE_CTRL_DEPTH);
613100966Siwasaki            }
614100966Siwasaki
615100966Siwasaki            /* TBD: Handle CID packages */
616100966Siwasaki
617100966Siwasaki            if (ACPI_STRNCMP (Cid.Buffer, Info->Hid, sizeof (Cid.Buffer)) != 0)
618100966Siwasaki            {
619100966Siwasaki                return (AE_OK);
620100966Siwasaki            }
621100966Siwasaki        }
622100966Siwasaki    }
623100966Siwasaki
624100966Siwasaki    Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue);
625100966Siwasaki    return (Status);
626100966Siwasaki}
627100966Siwasaki
628100966Siwasaki
629100966Siwasaki/*******************************************************************************
630100966Siwasaki *
631100966Siwasaki * FUNCTION:    AcpiGetDevices
632100966Siwasaki *
633100966Siwasaki * PARAMETERS:  HID                 - HID to search for. Can be NULL.
634100966Siwasaki *              UserFunction        - Called when a matching object is found
635100966Siwasaki *              Context             - Passed to user function
636100966Siwasaki *              ReturnValue         - Location where return value of
637100966Siwasaki *                                    UserFunction is put if terminated early
638100966Siwasaki *
639100966Siwasaki * RETURNS      Return value from the UserFunction if terminated early.
640100966Siwasaki *              Otherwise, returns NULL.
641100966Siwasaki *
642100966Siwasaki * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
643100966Siwasaki *              starting (and ending) at the object specified by StartHandle.
644100966Siwasaki *              The UserFunction is called whenever an object that matches
645100966Siwasaki *              the type parameter is found.  If the user function returns
646100966Siwasaki *              a non-zero value, the search is terminated immediately and this
647100966Siwasaki *              value is returned to the caller.
648100966Siwasaki *
649100966Siwasaki *              This is a wrapper for WalkNamespace, but the callback performs
650100966Siwasaki *              additional filtering. Please see AcpiGetDeviceCallback.
651100966Siwasaki *
652100966Siwasaki ******************************************************************************/
653100966Siwasaki
654100966SiwasakiACPI_STATUS
655100966SiwasakiAcpiGetDevices (
656114237Snjl    char                    *HID,
657100966Siwasaki    ACPI_WALK_CALLBACK      UserFunction,
658100966Siwasaki    void                    *Context,
659100966Siwasaki    void                    **ReturnValue)
660100966Siwasaki{
661100966Siwasaki    ACPI_STATUS             Status;
662100966Siwasaki    ACPI_GET_DEVICES_INFO   Info;
663100966Siwasaki
664100966Siwasaki
665100966Siwasaki    ACPI_FUNCTION_TRACE ("AcpiGetDevices");
666100966Siwasaki
667100966Siwasaki
668100966Siwasaki    /* Parameter validation */
669100966Siwasaki
670100966Siwasaki    if (!UserFunction)
671100966Siwasaki    {
672100966Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
673100966Siwasaki    }
674100966Siwasaki
675100966Siwasaki    /*
676100966Siwasaki     * We're going to call their callback from OUR callback, so we need
677100966Siwasaki     * to know what it is, and their context parameter.
678100966Siwasaki     */
679100966Siwasaki    Info.Context      = Context;
680100966Siwasaki    Info.UserFunction = UserFunction;
681100966Siwasaki    Info.Hid          = HID;
682100966Siwasaki
683100966Siwasaki    /*
684100966Siwasaki     * Lock the namespace around the walk.
685100966Siwasaki     * The namespace will be unlocked/locked around each call
686100966Siwasaki     * to the user function - since this function
687100966Siwasaki     * must be allowed to make Acpi calls itself.
688100966Siwasaki     */
689100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
690100966Siwasaki    if (ACPI_FAILURE (Status))
691100966Siwasaki    {
692100966Siwasaki        return_ACPI_STATUS (Status);
693100966Siwasaki    }
694100966Siwasaki
695100966Siwasaki    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE,
696100966Siwasaki                                    ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
697100966Siwasaki                                    ACPI_NS_WALK_UNLOCK,
698100966Siwasaki                                    AcpiNsGetDeviceCallback, &Info,
699100966Siwasaki                                    ReturnValue);
700100966Siwasaki
701100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
702100966Siwasaki    return_ACPI_STATUS (Status);
703100966Siwasaki}
704100966Siwasaki
705100966Siwasaki
706100966Siwasaki/*******************************************************************************
707100966Siwasaki *
708100966Siwasaki * FUNCTION:    AcpiAttachData
709100966Siwasaki *
710114237Snjl * PARAMETERS:  ObjHandle           - Namespace node
711107325Siwasaki *              Handler             - Handler for this attachment
712107325Siwasaki *              Data                - Pointer to data to be attached
713100966Siwasaki *
714100966Siwasaki * RETURN:      Status
715100966Siwasaki *
716107325Siwasaki * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
717100966Siwasaki *
718100966Siwasaki ******************************************************************************/
719100966Siwasaki
720100966SiwasakiACPI_STATUS
721100966SiwasakiAcpiAttachData (
722100966Siwasaki    ACPI_HANDLE             ObjHandle,
723100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
724100966Siwasaki    void                    *Data)
725100966Siwasaki{
726100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
727100966Siwasaki    ACPI_STATUS             Status;
728100966Siwasaki
729100966Siwasaki
730100966Siwasaki    /* Parameter validation */
731100966Siwasaki
732100966Siwasaki    if (!ObjHandle  ||
733100966Siwasaki        !Handler    ||
734100966Siwasaki        !Data)
735100966Siwasaki    {
736100966Siwasaki        return (AE_BAD_PARAMETER);
737100966Siwasaki    }
738100966Siwasaki
739100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
740100966Siwasaki    if (ACPI_FAILURE (Status))
741100966Siwasaki    {
742100966Siwasaki        return (Status);
743100966Siwasaki    }
744100966Siwasaki
745100966Siwasaki    /* Convert and validate the handle */
746100966Siwasaki
747100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
748100966Siwasaki    if (!Node)
749100966Siwasaki    {
750100966Siwasaki        Status = AE_BAD_PARAMETER;
751100966Siwasaki        goto UnlockAndExit;
752100966Siwasaki    }
753100966Siwasaki
754100966Siwasaki    Status = AcpiNsAttachData (Node, Handler, Data);
755100966Siwasaki
756100966SiwasakiUnlockAndExit:
757100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
758100966Siwasaki    return (Status);
759100966Siwasaki}
760100966Siwasaki
761100966Siwasaki
762100966Siwasaki/*******************************************************************************
763100966Siwasaki *
764100966Siwasaki * FUNCTION:    AcpiDetachData
765100966Siwasaki *
766107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node handle
767107325Siwasaki *              Handler             - Handler used in call to AcpiAttachData
768100966Siwasaki *
769100966Siwasaki * RETURN:      Status
770100966Siwasaki *
771107325Siwasaki * DESCRIPTION: Remove data that was previously attached to a node.
772100966Siwasaki *
773100966Siwasaki ******************************************************************************/
774100966Siwasaki
775100966SiwasakiACPI_STATUS
776100966SiwasakiAcpiDetachData (
777100966Siwasaki    ACPI_HANDLE             ObjHandle,
778100966Siwasaki    ACPI_OBJECT_HANDLER     Handler)
779100966Siwasaki{
780100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
781100966Siwasaki    ACPI_STATUS             Status;
782100966Siwasaki
783100966Siwasaki
784100966Siwasaki    /* Parameter validation */
785100966Siwasaki
786100966Siwasaki    if (!ObjHandle  ||
787100966Siwasaki        !Handler)
788100966Siwasaki    {
789100966Siwasaki        return (AE_BAD_PARAMETER);
790100966Siwasaki    }
791100966Siwasaki
792100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
793100966Siwasaki    if (ACPI_FAILURE (Status))
794100966Siwasaki    {
795100966Siwasaki        return (Status);
796100966Siwasaki    }
797100966Siwasaki
798100966Siwasaki    /* Convert and validate the handle */
799100966Siwasaki
800100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
801100966Siwasaki    if (!Node)
802100966Siwasaki    {
803100966Siwasaki        Status = AE_BAD_PARAMETER;
804100966Siwasaki        goto UnlockAndExit;
805100966Siwasaki    }
806100966Siwasaki
807100966Siwasaki    Status = AcpiNsDetachData (Node, Handler);
808100966Siwasaki
809100966SiwasakiUnlockAndExit:
810100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
811100966Siwasaki    return (Status);
812100966Siwasaki}
813100966Siwasaki
814100966Siwasaki
815100966Siwasaki/*******************************************************************************
816100966Siwasaki *
817100966Siwasaki * FUNCTION:    AcpiGetData
818100966Siwasaki *
819107325Siwasaki * PARAMETERS:  ObjHandle           - Namespace node
820107325Siwasaki *              Handler             - Handler used in call to AttachData
821107325Siwasaki *              Data                - Where the data is returned
822100966Siwasaki *
823100966Siwasaki * RETURN:      Status
824100966Siwasaki *
825107325Siwasaki * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
826100966Siwasaki *
827100966Siwasaki ******************************************************************************/
828100966Siwasaki
829100966SiwasakiACPI_STATUS
830100966SiwasakiAcpiGetData (
831100966Siwasaki    ACPI_HANDLE             ObjHandle,
832100966Siwasaki    ACPI_OBJECT_HANDLER     Handler,
833100966Siwasaki    void                    **Data)
834100966Siwasaki{
835100966Siwasaki    ACPI_NAMESPACE_NODE     *Node;
836100966Siwasaki    ACPI_STATUS             Status;
837100966Siwasaki
838100966Siwasaki
839100966Siwasaki    /* Parameter validation */
840100966Siwasaki
841100966Siwasaki    if (!ObjHandle  ||
842100966Siwasaki        !Handler    ||
843100966Siwasaki        !Data)
844100966Siwasaki    {
845100966Siwasaki        return (AE_BAD_PARAMETER);
846100966Siwasaki    }
847100966Siwasaki
848100966Siwasaki    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
849100966Siwasaki    if (ACPI_FAILURE (Status))
850100966Siwasaki    {
851100966Siwasaki        return (Status);
852100966Siwasaki    }
853100966Siwasaki
854100966Siwasaki    /* Convert and validate the handle */
855100966Siwasaki
856100966Siwasaki    Node = AcpiNsMapHandleToNode (ObjHandle);
857100966Siwasaki    if (!Node)
858100966Siwasaki    {
859100966Siwasaki        Status = AE_BAD_PARAMETER;
860100966Siwasaki        goto UnlockAndExit;
861100966Siwasaki    }
862100966Siwasaki
863100966Siwasaki    Status = AcpiNsGetAttachedData (Node, Handler, Data);
864100966Siwasaki
865100966SiwasakiUnlockAndExit:
866100966Siwasaki    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
867100966Siwasaki    return (Status);
868100966Siwasaki}
869100966Siwasaki
870100966Siwasaki
871