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