xref: /freebsd-src/sys/contrib/dev/acpica/components/namespace/nsxfeval.c (revision 804fe2660352e090f4481f2c1d646b508859e79a)
1a159c266SJung-uk Kim /*******************************************************************************
2a159c266SJung-uk Kim  *
3a159c266SJung-uk Kim  * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4a159c266SJung-uk Kim  *                         ACPI Object evaluation interfaces
5a159c266SJung-uk Kim  *
6a159c266SJung-uk Kim  ******************************************************************************/
7a159c266SJung-uk Kim 
80d84335fSJung-uk Kim /******************************************************************************
90d84335fSJung-uk Kim  *
100d84335fSJung-uk Kim  * 1. Copyright Notice
110d84335fSJung-uk Kim  *
12*804fe266SJung-uk Kim  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
13a159c266SJung-uk Kim  * All rights reserved.
14a159c266SJung-uk Kim  *
150d84335fSJung-uk Kim  * 2. License
160d84335fSJung-uk Kim  *
170d84335fSJung-uk Kim  * 2.1. This is your license from Intel Corp. under its intellectual property
180d84335fSJung-uk Kim  * rights. You may have additional license terms from the party that provided
190d84335fSJung-uk Kim  * you this software, covering your right to use that party's intellectual
200d84335fSJung-uk Kim  * property rights.
210d84335fSJung-uk Kim  *
220d84335fSJung-uk Kim  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
230d84335fSJung-uk Kim  * copy of the source code appearing in this file ("Covered Code") an
240d84335fSJung-uk Kim  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
250d84335fSJung-uk Kim  * base code distributed originally by Intel ("Original Intel Code") to copy,
260d84335fSJung-uk Kim  * make derivatives, distribute, use and display any portion of the Covered
270d84335fSJung-uk Kim  * Code in any form, with the right to sublicense such rights; and
280d84335fSJung-uk Kim  *
290d84335fSJung-uk Kim  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
300d84335fSJung-uk Kim  * license (with the right to sublicense), under only those claims of Intel
310d84335fSJung-uk Kim  * patents that are infringed by the Original Intel Code, to make, use, sell,
320d84335fSJung-uk Kim  * offer to sell, and import the Covered Code and derivative works thereof
330d84335fSJung-uk Kim  * solely to the minimum extent necessary to exercise the above copyright
340d84335fSJung-uk Kim  * license, and in no event shall the patent license extend to any additions
350d84335fSJung-uk Kim  * to or modifications of the Original Intel Code. No other license or right
360d84335fSJung-uk Kim  * is granted directly or by implication, estoppel or otherwise;
370d84335fSJung-uk Kim  *
380d84335fSJung-uk Kim  * The above copyright and patent license is granted only if the following
390d84335fSJung-uk Kim  * conditions are met:
400d84335fSJung-uk Kim  *
410d84335fSJung-uk Kim  * 3. Conditions
420d84335fSJung-uk Kim  *
430d84335fSJung-uk Kim  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
440d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
450d84335fSJung-uk Kim  * Code or modification with rights to further distribute source must include
460d84335fSJung-uk Kim  * the above Copyright Notice, the above License, this list of Conditions,
470d84335fSJung-uk Kim  * and the following Disclaimer and Export Compliance provision. In addition,
480d84335fSJung-uk Kim  * Licensee must cause all Covered Code to which Licensee contributes to
490d84335fSJung-uk Kim  * contain a file documenting the changes Licensee made to create that Covered
500d84335fSJung-uk Kim  * Code and the date of any change. Licensee must include in that file the
510d84335fSJung-uk Kim  * documentation of any changes made by any predecessor Licensee. Licensee
520d84335fSJung-uk Kim  * must include a prominent statement that the modification is derived,
530d84335fSJung-uk Kim  * directly or indirectly, from Original Intel Code.
540d84335fSJung-uk Kim  *
550d84335fSJung-uk Kim  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
560d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
570d84335fSJung-uk Kim  * Code or modification without rights to further distribute source must
580d84335fSJung-uk Kim  * include the following Disclaimer and Export Compliance provision in the
590d84335fSJung-uk Kim  * documentation and/or other materials provided with distribution. In
600d84335fSJung-uk Kim  * addition, Licensee may not authorize further sublicense of source of any
610d84335fSJung-uk Kim  * portion of the Covered Code, and must include terms to the effect that the
620d84335fSJung-uk Kim  * license from Licensee to its licensee is limited to the intellectual
630d84335fSJung-uk Kim  * property embodied in the software Licensee provides to its licensee, and
640d84335fSJung-uk Kim  * not to intellectual property embodied in modifications its licensee may
650d84335fSJung-uk Kim  * make.
660d84335fSJung-uk Kim  *
670d84335fSJung-uk Kim  * 3.3. Redistribution of Executable. Redistribution in executable form of any
680d84335fSJung-uk Kim  * substantial portion of the Covered Code or modification must reproduce the
690d84335fSJung-uk Kim  * above Copyright Notice, and the following Disclaimer and Export Compliance
700d84335fSJung-uk Kim  * provision in the documentation and/or other materials provided with the
710d84335fSJung-uk Kim  * distribution.
720d84335fSJung-uk Kim  *
730d84335fSJung-uk Kim  * 3.4. Intel retains all right, title, and interest in and to the Original
740d84335fSJung-uk Kim  * Intel Code.
750d84335fSJung-uk Kim  *
760d84335fSJung-uk Kim  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
770d84335fSJung-uk Kim  * Intel shall be used in advertising or otherwise to promote the sale, use or
780d84335fSJung-uk Kim  * other dealings in products derived from or relating to the Covered Code
790d84335fSJung-uk Kim  * without prior written authorization from Intel.
800d84335fSJung-uk Kim  *
810d84335fSJung-uk Kim  * 4. Disclaimer and Export Compliance
820d84335fSJung-uk Kim  *
830d84335fSJung-uk Kim  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
840d84335fSJung-uk Kim  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
850d84335fSJung-uk Kim  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
860d84335fSJung-uk Kim  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
870d84335fSJung-uk Kim  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
880d84335fSJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
890d84335fSJung-uk Kim  * PARTICULAR PURPOSE.
900d84335fSJung-uk Kim  *
910d84335fSJung-uk Kim  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
920d84335fSJung-uk Kim  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
930d84335fSJung-uk Kim  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
940d84335fSJung-uk Kim  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
950d84335fSJung-uk Kim  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
960d84335fSJung-uk Kim  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
970d84335fSJung-uk Kim  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
980d84335fSJung-uk Kim  * LIMITED REMEDY.
990d84335fSJung-uk Kim  *
1000d84335fSJung-uk Kim  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1010d84335fSJung-uk Kim  * software or system incorporating such software without first obtaining any
1020d84335fSJung-uk Kim  * required license or other approval from the U. S. Department of Commerce or
1030d84335fSJung-uk Kim  * any other agency or department of the United States Government. In the
1040d84335fSJung-uk Kim  * event Licensee exports any such software from the United States or
1050d84335fSJung-uk Kim  * re-exports any such software from a foreign destination, Licensee shall
1060d84335fSJung-uk Kim  * ensure that the distribution and export/re-export of the software is in
1070d84335fSJung-uk Kim  * compliance with all laws, regulations, orders, or other restrictions of the
1080d84335fSJung-uk Kim  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1090d84335fSJung-uk Kim  * any of its subsidiaries will export/re-export any technical data, process,
1100d84335fSJung-uk Kim  * software, or service, directly or indirectly, to any country for which the
1110d84335fSJung-uk Kim  * United States government or any agency thereof requires an export license,
1120d84335fSJung-uk Kim  * other governmental approval, or letter of assurance, without first obtaining
1130d84335fSJung-uk Kim  * such license, approval or letter.
1140d84335fSJung-uk Kim  *
1150d84335fSJung-uk Kim  *****************************************************************************
1160d84335fSJung-uk Kim  *
1170d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
1180d84335fSJung-uk Kim  * following license:
1190d84335fSJung-uk Kim  *
120a159c266SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
121a159c266SJung-uk Kim  * modification, are permitted provided that the following conditions
122a159c266SJung-uk Kim  * are met:
123a159c266SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
124a159c266SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
125a159c266SJung-uk Kim  *    without modification.
126a159c266SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127a159c266SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
128a159c266SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
129a159c266SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
130a159c266SJung-uk Kim  *    binary redistribution.
131a159c266SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
132a159c266SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
133a159c266SJung-uk Kim  *    from this software without specific prior written permission.
134a159c266SJung-uk Kim  *
1350d84335fSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1360d84335fSJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1370d84335fSJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1380d84335fSJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1390d84335fSJung-uk Kim  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1400d84335fSJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1410d84335fSJung-uk Kim  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1420d84335fSJung-uk Kim  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1430d84335fSJung-uk Kim  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1440d84335fSJung-uk Kim  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1450d84335fSJung-uk Kim  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1460d84335fSJung-uk Kim  *
1470d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
148a159c266SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
149a159c266SJung-uk Kim  * Software Foundation.
150a159c266SJung-uk Kim  *
1510d84335fSJung-uk Kim  *****************************************************************************/
152a159c266SJung-uk Kim 
153313a0c13SJung-uk Kim #define EXPORT_ACPI_INTERFACES
154a159c266SJung-uk Kim 
155a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
156a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
157a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
158a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acinterp.h>
159a159c266SJung-uk Kim 
160a159c266SJung-uk Kim 
161a159c266SJung-uk Kim #define _COMPONENT          ACPI_NAMESPACE
162a159c266SJung-uk Kim         ACPI_MODULE_NAME    ("nsxfeval")
163a159c266SJung-uk Kim 
164a159c266SJung-uk Kim /* Local prototypes */
165a159c266SJung-uk Kim 
166a159c266SJung-uk Kim static void
167a159c266SJung-uk Kim AcpiNsResolveReferences (
168a159c266SJung-uk Kim     ACPI_EVALUATE_INFO      *Info);
169a159c266SJung-uk Kim 
170a159c266SJung-uk Kim 
171a159c266SJung-uk Kim /*******************************************************************************
172a159c266SJung-uk Kim  *
173a159c266SJung-uk Kim  * FUNCTION:    AcpiEvaluateObjectTyped
174a159c266SJung-uk Kim  *
175a159c266SJung-uk Kim  * PARAMETERS:  Handle              - Object handle (optional)
176a159c266SJung-uk Kim  *              Pathname            - Object pathname (optional)
177f1db5ef7SJung-uk Kim  *              ExternalParams      - List of parameters to pass to a method,
178a159c266SJung-uk Kim  *                                    terminated by NULL. May be NULL
179a159c266SJung-uk Kim  *                                    if no parameters are being passed.
180f1db5ef7SJung-uk Kim  *              ReturnBuffer        - Where to put the object return value (if
181f1db5ef7SJung-uk Kim  *                                    any). Required.
182a159c266SJung-uk Kim  *              ReturnType          - Expected type of return object
183a159c266SJung-uk Kim  *
184a159c266SJung-uk Kim  * RETURN:      Status
185a159c266SJung-uk Kim  *
186a159c266SJung-uk Kim  * DESCRIPTION: Find and evaluate the given object, passing the given
187a159c266SJung-uk Kim  *              parameters if necessary. One of "Handle" or "Pathname" must
188a159c266SJung-uk Kim  *              be valid (non-null)
189a159c266SJung-uk Kim  *
190a159c266SJung-uk Kim  ******************************************************************************/
191a159c266SJung-uk Kim 
192a159c266SJung-uk Kim ACPI_STATUS
193a159c266SJung-uk Kim AcpiEvaluateObjectTyped (
194a159c266SJung-uk Kim     ACPI_HANDLE             Handle,
195a159c266SJung-uk Kim     ACPI_STRING             Pathname,
196a159c266SJung-uk Kim     ACPI_OBJECT_LIST        *ExternalParams,
197a159c266SJung-uk Kim     ACPI_BUFFER             *ReturnBuffer,
198a159c266SJung-uk Kim     ACPI_OBJECT_TYPE        ReturnType)
199a159c266SJung-uk Kim {
200a159c266SJung-uk Kim     ACPI_STATUS             Status;
201313a0c13SJung-uk Kim     BOOLEAN                 FreeBufferOnError = FALSE;
202af051161SJung-uk Kim     ACPI_HANDLE             TargetHandle;
203af051161SJung-uk Kim     char                    *FullPathname;
204a159c266SJung-uk Kim 
205a159c266SJung-uk Kim 
206a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
207a159c266SJung-uk Kim 
208a159c266SJung-uk Kim 
209a159c266SJung-uk Kim     /* Return buffer must be valid */
210a159c266SJung-uk Kim 
211a159c266SJung-uk Kim     if (!ReturnBuffer)
212a159c266SJung-uk Kim     {
213a159c266SJung-uk Kim         return_ACPI_STATUS (AE_BAD_PARAMETER);
214a159c266SJung-uk Kim     }
215a159c266SJung-uk Kim 
216a159c266SJung-uk Kim     if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
217a159c266SJung-uk Kim     {
218313a0c13SJung-uk Kim         FreeBufferOnError = TRUE;
219a159c266SJung-uk Kim     }
220a159c266SJung-uk Kim 
221f1db5ef7SJung-uk Kim     /* Get a handle here, in order to build an error message if needed */
222f1db5ef7SJung-uk Kim 
223f1db5ef7SJung-uk Kim     TargetHandle = Handle;
224f1db5ef7SJung-uk Kim     if (Pathname)
225f1db5ef7SJung-uk Kim     {
226af051161SJung-uk Kim         Status = AcpiGetHandle (Handle, Pathname, &TargetHandle);
227a159c266SJung-uk Kim         if (ACPI_FAILURE (Status))
228a159c266SJung-uk Kim         {
229a159c266SJung-uk Kim             return_ACPI_STATUS (Status);
230a159c266SJung-uk Kim         }
231f1db5ef7SJung-uk Kim     }
232a159c266SJung-uk Kim 
233af051161SJung-uk Kim     FullPathname = AcpiNsGetExternalPathname (TargetHandle);
234af051161SJung-uk Kim     if (!FullPathname)
235af051161SJung-uk Kim     {
236af051161SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
237af051161SJung-uk Kim     }
238af051161SJung-uk Kim 
239af051161SJung-uk Kim     /* Evaluate the object */
240af051161SJung-uk Kim 
241af051161SJung-uk Kim     Status = AcpiEvaluateObject (TargetHandle, NULL, ExternalParams,
242af051161SJung-uk Kim         ReturnBuffer);
243af051161SJung-uk Kim     if (ACPI_FAILURE (Status))
244af051161SJung-uk Kim     {
245af051161SJung-uk Kim         goto Exit;
246af051161SJung-uk Kim     }
247af051161SJung-uk Kim 
248af051161SJung-uk Kim     /* Type ANY means "don't care about return value type" */
249a159c266SJung-uk Kim 
250a159c266SJung-uk Kim     if (ReturnType == ACPI_TYPE_ANY)
251a159c266SJung-uk Kim     {
252af051161SJung-uk Kim         goto Exit;
253a159c266SJung-uk Kim     }
254a159c266SJung-uk Kim 
255a159c266SJung-uk Kim     if (ReturnBuffer->Length == 0)
256a159c266SJung-uk Kim     {
257a159c266SJung-uk Kim         /* Error because caller specifically asked for a return value */
258a159c266SJung-uk Kim 
259af051161SJung-uk Kim         ACPI_ERROR ((AE_INFO, "%s did not return any object",
260af051161SJung-uk Kim             FullPathname));
261af051161SJung-uk Kim         Status = AE_NULL_OBJECT;
262af051161SJung-uk Kim         goto Exit;
263a159c266SJung-uk Kim     }
264a159c266SJung-uk Kim 
265a159c266SJung-uk Kim     /* Examine the object type returned from EvaluateObject */
266a159c266SJung-uk Kim 
267a159c266SJung-uk Kim     if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
268a159c266SJung-uk Kim     {
269af051161SJung-uk Kim         goto Exit;
270a159c266SJung-uk Kim     }
271a159c266SJung-uk Kim 
272a159c266SJung-uk Kim     /* Return object type does not match requested type */
273a159c266SJung-uk Kim 
274a159c266SJung-uk Kim     ACPI_ERROR ((AE_INFO,
275af051161SJung-uk Kim         "Incorrect return type from %s - received [%s], requested [%s]",
276af051161SJung-uk Kim         FullPathname,
277a159c266SJung-uk Kim         AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
278a159c266SJung-uk Kim         AcpiUtGetTypeName (ReturnType)));
279a159c266SJung-uk Kim 
280313a0c13SJung-uk Kim     if (FreeBufferOnError)
281a159c266SJung-uk Kim     {
282313a0c13SJung-uk Kim         /*
283313a0c13SJung-uk Kim          * Free a buffer created via ACPI_ALLOCATE_BUFFER.
284313a0c13SJung-uk Kim          * Note: We use AcpiOsFree here because AcpiOsAllocate was used
285313a0c13SJung-uk Kim          * to allocate the buffer. This purposefully bypasses the
286313a0c13SJung-uk Kim          * (optionally enabled) allocation tracking mechanism since we
287313a0c13SJung-uk Kim          * only want to track internal allocations.
288313a0c13SJung-uk Kim          */
289a159c266SJung-uk Kim         AcpiOsFree (ReturnBuffer->Pointer);
290a159c266SJung-uk Kim         ReturnBuffer->Pointer = NULL;
291a159c266SJung-uk Kim     }
292a159c266SJung-uk Kim 
293a159c266SJung-uk Kim     ReturnBuffer->Length = 0;
294af051161SJung-uk Kim     Status = AE_TYPE;
295af051161SJung-uk Kim 
296af051161SJung-uk Kim Exit:
297af051161SJung-uk Kim     ACPI_FREE (FullPathname);
298af051161SJung-uk Kim     return_ACPI_STATUS (Status);
299a159c266SJung-uk Kim }
300a159c266SJung-uk Kim 
301a159c266SJung-uk Kim ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
302a159c266SJung-uk Kim 
303a159c266SJung-uk Kim 
304a159c266SJung-uk Kim /*******************************************************************************
305a159c266SJung-uk Kim  *
306a159c266SJung-uk Kim  * FUNCTION:    AcpiEvaluateObject
307a159c266SJung-uk Kim  *
308a159c266SJung-uk Kim  * PARAMETERS:  Handle              - Object handle (optional)
309a159c266SJung-uk Kim  *              Pathname            - Object pathname (optional)
310a159c266SJung-uk Kim  *              ExternalParams      - List of parameters to pass to method,
311a159c266SJung-uk Kim  *                                    terminated by NULL. May be NULL
312a159c266SJung-uk Kim  *                                    if no parameters are being passed.
313a159c266SJung-uk Kim  *              ReturnBuffer        - Where to put method's return value (if
314a159c266SJung-uk Kim  *                                    any). If NULL, no value is returned.
315a159c266SJung-uk Kim  *
316a159c266SJung-uk Kim  * RETURN:      Status
317a159c266SJung-uk Kim  *
318a159c266SJung-uk Kim  * DESCRIPTION: Find and evaluate the given object, passing the given
319a159c266SJung-uk Kim  *              parameters if necessary. One of "Handle" or "Pathname" must
320a159c266SJung-uk Kim  *              be valid (non-null)
321a159c266SJung-uk Kim  *
322a159c266SJung-uk Kim  ******************************************************************************/
323a159c266SJung-uk Kim 
324a159c266SJung-uk Kim ACPI_STATUS
325a159c266SJung-uk Kim AcpiEvaluateObject (
326a159c266SJung-uk Kim     ACPI_HANDLE             Handle,
327a159c266SJung-uk Kim     ACPI_STRING             Pathname,
328a159c266SJung-uk Kim     ACPI_OBJECT_LIST        *ExternalParams,
329a159c266SJung-uk Kim     ACPI_BUFFER             *ReturnBuffer)
330a159c266SJung-uk Kim {
331a159c266SJung-uk Kim     ACPI_STATUS             Status;
332a159c266SJung-uk Kim     ACPI_EVALUATE_INFO      *Info;
333a159c266SJung-uk Kim     ACPI_SIZE               BufferSpaceNeeded;
334a159c266SJung-uk Kim     UINT32                  i;
335a159c266SJung-uk Kim 
336a159c266SJung-uk Kim 
337a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
338a159c266SJung-uk Kim 
339a159c266SJung-uk Kim 
340a159c266SJung-uk Kim     /* Allocate and initialize the evaluation information block */
341a159c266SJung-uk Kim 
342a159c266SJung-uk Kim     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
343a159c266SJung-uk Kim     if (!Info)
344a159c266SJung-uk Kim     {
345a159c266SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
346a159c266SJung-uk Kim     }
347a159c266SJung-uk Kim 
348a159c266SJung-uk Kim     /* Convert and validate the device handle */
349a159c266SJung-uk Kim 
350a159c266SJung-uk Kim     Info->PrefixNode = AcpiNsValidateHandle (Handle);
351a159c266SJung-uk Kim     if (!Info->PrefixNode)
352a159c266SJung-uk Kim     {
353a159c266SJung-uk Kim         Status = AE_BAD_PARAMETER;
354a159c266SJung-uk Kim         goto Cleanup;
355a159c266SJung-uk Kim     }
356a159c266SJung-uk Kim 
357a159c266SJung-uk Kim     /*
358895f26a9SJung-uk Kim      * Get the actual namespace node for the target object.
359895f26a9SJung-uk Kim      * Handles these cases:
360895f26a9SJung-uk Kim      *
361895f26a9SJung-uk Kim      * 1) Null node, valid pathname from root (absolute path)
362895f26a9SJung-uk Kim      * 2) Node and valid pathname (path relative to Node)
363895f26a9SJung-uk Kim      * 3) Node, Null pathname
364a159c266SJung-uk Kim      */
365a159c266SJung-uk Kim     if ((Pathname) &&
366efcc2a30SJung-uk Kim         (ACPI_IS_ROOT_PREFIX (Pathname[0])))
367a159c266SJung-uk Kim     {
368a159c266SJung-uk Kim         /* The path is fully qualified, just evaluate by name */
369a159c266SJung-uk Kim 
370a159c266SJung-uk Kim         Info->PrefixNode = NULL;
371a159c266SJung-uk Kim     }
372a159c266SJung-uk Kim     else if (!Handle)
373a159c266SJung-uk Kim     {
374a159c266SJung-uk Kim         /*
375a159c266SJung-uk Kim          * A handle is optional iff a fully qualified pathname is specified.
376a159c266SJung-uk Kim          * Since we've already handled fully qualified names above, this is
377895f26a9SJung-uk Kim          * an error.
378a159c266SJung-uk Kim          */
379a159c266SJung-uk Kim         if (!Pathname)
380a159c266SJung-uk Kim         {
381a159c266SJung-uk Kim             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
382a159c266SJung-uk Kim                 "Both Handle and Pathname are NULL"));
383a159c266SJung-uk Kim         }
384a159c266SJung-uk Kim         else
385a159c266SJung-uk Kim         {
386a159c266SJung-uk Kim             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
387a159c266SJung-uk Kim                 "Null Handle with relative pathname [%s]", Pathname));
388a159c266SJung-uk Kim         }
389a159c266SJung-uk Kim 
390a159c266SJung-uk Kim         Status = AE_BAD_PARAMETER;
391895f26a9SJung-uk Kim         goto Cleanup;
392a159c266SJung-uk Kim     }
393895f26a9SJung-uk Kim 
394895f26a9SJung-uk Kim     Info->RelativePathname = Pathname;
395895f26a9SJung-uk Kim 
396895f26a9SJung-uk Kim     /*
397895f26a9SJung-uk Kim      * Convert all external objects passed as arguments to the
398895f26a9SJung-uk Kim      * internal version(s).
399895f26a9SJung-uk Kim      */
400895f26a9SJung-uk Kim     if (ExternalParams && ExternalParams->Count)
401a159c266SJung-uk Kim     {
402895f26a9SJung-uk Kim         Info->ParamCount = (UINT16) ExternalParams->Count;
403895f26a9SJung-uk Kim 
404895f26a9SJung-uk Kim         /* Warn on impossible argument count */
405895f26a9SJung-uk Kim 
406895f26a9SJung-uk Kim         if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
407895f26a9SJung-uk Kim         {
408895f26a9SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
409895f26a9SJung-uk Kim                 "Excess arguments (%u) - using only %u",
410895f26a9SJung-uk Kim                 Info->ParamCount, ACPI_METHOD_NUM_ARGS));
411895f26a9SJung-uk Kim 
412895f26a9SJung-uk Kim             Info->ParamCount = ACPI_METHOD_NUM_ARGS;
413895f26a9SJung-uk Kim         }
414895f26a9SJung-uk Kim 
415895f26a9SJung-uk Kim         /*
416895f26a9SJung-uk Kim          * Allocate a new parameter block for the internal objects
417895f26a9SJung-uk Kim          * Add 1 to count to allow for null terminated internal list
418895f26a9SJung-uk Kim          */
419895f26a9SJung-uk Kim         Info->Parameters = ACPI_ALLOCATE_ZEROED (
420895f26a9SJung-uk Kim             ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
421895f26a9SJung-uk Kim         if (!Info->Parameters)
422895f26a9SJung-uk Kim         {
423895f26a9SJung-uk Kim             Status = AE_NO_MEMORY;
424895f26a9SJung-uk Kim             goto Cleanup;
425895f26a9SJung-uk Kim         }
426895f26a9SJung-uk Kim 
427895f26a9SJung-uk Kim         /* Convert each external object in the list to an internal object */
428895f26a9SJung-uk Kim 
429895f26a9SJung-uk Kim         for (i = 0; i < Info->ParamCount; i++)
430895f26a9SJung-uk Kim         {
431895f26a9SJung-uk Kim             Status = AcpiUtCopyEobjectToIobject (
432895f26a9SJung-uk Kim                 &ExternalParams->Pointer[i], &Info->Parameters[i]);
433895f26a9SJung-uk Kim             if (ACPI_FAILURE (Status))
434895f26a9SJung-uk Kim             {
435895f26a9SJung-uk Kim                 goto Cleanup;
436895f26a9SJung-uk Kim             }
437895f26a9SJung-uk Kim         }
438895f26a9SJung-uk Kim 
439895f26a9SJung-uk Kim         Info->Parameters[Info->ParamCount] = NULL;
440895f26a9SJung-uk Kim     }
441895f26a9SJung-uk Kim 
442895f26a9SJung-uk Kim 
443f8146b88SJung-uk Kim #ifdef _FUTURE_FEATURE
444895f26a9SJung-uk Kim 
445895f26a9SJung-uk Kim     /*
446895f26a9SJung-uk Kim      * Begin incoming argument count analysis. Check for too few args
447895f26a9SJung-uk Kim      * and too many args.
448895f26a9SJung-uk Kim      */
449895f26a9SJung-uk Kim     switch (AcpiNsGetType (Info->Node))
450895f26a9SJung-uk Kim     {
451895f26a9SJung-uk Kim     case ACPI_TYPE_METHOD:
452895f26a9SJung-uk Kim 
453895f26a9SJung-uk Kim         /* Check incoming argument count against the method definition */
454895f26a9SJung-uk Kim 
455895f26a9SJung-uk Kim         if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)
456895f26a9SJung-uk Kim         {
457895f26a9SJung-uk Kim             ACPI_ERROR ((AE_INFO,
458895f26a9SJung-uk Kim                 "Insufficient arguments (%u) - %u are required",
459895f26a9SJung-uk Kim                 Info->ParamCount,
460895f26a9SJung-uk Kim                 Info->ObjDesc->Method.ParamCount));
461895f26a9SJung-uk Kim 
462895f26a9SJung-uk Kim             Status = AE_MISSING_ARGUMENTS;
463895f26a9SJung-uk Kim             goto Cleanup;
464895f26a9SJung-uk Kim         }
465895f26a9SJung-uk Kim 
466895f26a9SJung-uk Kim         else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)
467895f26a9SJung-uk Kim         {
468895f26a9SJung-uk Kim             ACPI_WARNING ((AE_INFO,
469895f26a9SJung-uk Kim                 "Excess arguments (%u) - only %u are required",
470895f26a9SJung-uk Kim                 Info->ParamCount,
471895f26a9SJung-uk Kim                 Info->ObjDesc->Method.ParamCount));
472895f26a9SJung-uk Kim 
473895f26a9SJung-uk Kim             /* Just pass the required number of arguments */
474895f26a9SJung-uk Kim 
475895f26a9SJung-uk Kim             Info->ParamCount = Info->ObjDesc->Method.ParamCount;
476895f26a9SJung-uk Kim         }
477895f26a9SJung-uk Kim 
478895f26a9SJung-uk Kim         /*
479895f26a9SJung-uk Kim          * Any incoming external objects to be passed as arguments to the
480895f26a9SJung-uk Kim          * method must be converted to internal objects
481895f26a9SJung-uk Kim          */
482895f26a9SJung-uk Kim         if (Info->ParamCount)
483895f26a9SJung-uk Kim         {
484895f26a9SJung-uk Kim             /*
485895f26a9SJung-uk Kim              * Allocate a new parameter block for the internal objects
486895f26a9SJung-uk Kim              * Add 1 to count to allow for null terminated internal list
487895f26a9SJung-uk Kim              */
488895f26a9SJung-uk Kim             Info->Parameters = ACPI_ALLOCATE_ZEROED (
489895f26a9SJung-uk Kim                 ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
490895f26a9SJung-uk Kim             if (!Info->Parameters)
491895f26a9SJung-uk Kim             {
492895f26a9SJung-uk Kim                 Status = AE_NO_MEMORY;
493895f26a9SJung-uk Kim                 goto Cleanup;
494895f26a9SJung-uk Kim             }
495895f26a9SJung-uk Kim 
496895f26a9SJung-uk Kim             /* Convert each external object in the list to an internal object */
497895f26a9SJung-uk Kim 
498895f26a9SJung-uk Kim             for (i = 0; i < Info->ParamCount; i++)
499895f26a9SJung-uk Kim             {
500895f26a9SJung-uk Kim                 Status = AcpiUtCopyEobjectToIobject (
501895f26a9SJung-uk Kim                     &ExternalParams->Pointer[i], &Info->Parameters[i]);
502895f26a9SJung-uk Kim                 if (ACPI_FAILURE (Status))
503895f26a9SJung-uk Kim                 {
504895f26a9SJung-uk Kim                     goto Cleanup;
505895f26a9SJung-uk Kim                 }
506895f26a9SJung-uk Kim             }
507895f26a9SJung-uk Kim 
508895f26a9SJung-uk Kim             Info->Parameters[Info->ParamCount] = NULL;
509895f26a9SJung-uk Kim         }
510895f26a9SJung-uk Kim         break;
511895f26a9SJung-uk Kim 
512895f26a9SJung-uk Kim     default:
513895f26a9SJung-uk Kim 
514895f26a9SJung-uk Kim         /* Warn if arguments passed to an object that is not a method */
515895f26a9SJung-uk Kim 
516895f26a9SJung-uk Kim         if (Info->ParamCount)
517895f26a9SJung-uk Kim         {
518895f26a9SJung-uk Kim             ACPI_WARNING ((AE_INFO,
519895f26a9SJung-uk Kim                 "%u arguments were passed to a non-method ACPI object",
520895f26a9SJung-uk Kim                 Info->ParamCount));
521895f26a9SJung-uk Kim         }
522895f26a9SJung-uk Kim         break;
523895f26a9SJung-uk Kim     }
524895f26a9SJung-uk Kim 
525895f26a9SJung-uk Kim #endif
526895f26a9SJung-uk Kim 
527895f26a9SJung-uk Kim 
528895f26a9SJung-uk Kim     /* Now we can evaluate the object */
529a159c266SJung-uk Kim 
530a159c266SJung-uk Kim     Status = AcpiNsEvaluate (Info);
531a159c266SJung-uk Kim 
532a159c266SJung-uk Kim     /*
533a159c266SJung-uk Kim      * If we are expecting a return value, and all went well above,
534a159c266SJung-uk Kim      * copy the return value to an external object.
535a159c266SJung-uk Kim      */
536f8146b88SJung-uk Kim     if (!ReturnBuffer)
537a159c266SJung-uk Kim     {
538f8146b88SJung-uk Kim         goto CleanupReturnObject;
539f8146b88SJung-uk Kim     }
540f8146b88SJung-uk Kim 
541a159c266SJung-uk Kim     if (!Info->ReturnObject)
542a159c266SJung-uk Kim     {
543a159c266SJung-uk Kim         ReturnBuffer->Length = 0;
544f8146b88SJung-uk Kim         goto Cleanup;
545a159c266SJung-uk Kim     }
546f8146b88SJung-uk Kim 
547a159c266SJung-uk Kim     if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
548a159c266SJung-uk Kim         ACPI_DESC_TYPE_NAMED)
549a159c266SJung-uk Kim     {
550a159c266SJung-uk Kim         /*
551a159c266SJung-uk Kim          * If we received a NS Node as a return object, this means that
552a159c266SJung-uk Kim          * the object we are evaluating has nothing interesting to
553a159c266SJung-uk Kim          * return (such as a mutex, etc.)  We return an error because
554a159c266SJung-uk Kim          * these types are essentially unsupported by this interface.
555a159c266SJung-uk Kim          * We don't check up front because this makes it easier to add
556a159c266SJung-uk Kim          * support for various types at a later date if necessary.
557a159c266SJung-uk Kim          */
558a159c266SJung-uk Kim         Status = AE_TYPE;
559a159c266SJung-uk Kim         Info->ReturnObject = NULL;   /* No need to delete a NS Node */
560a159c266SJung-uk Kim         ReturnBuffer->Length = 0;
561a159c266SJung-uk Kim     }
562a159c266SJung-uk Kim 
563f8146b88SJung-uk Kim     if (ACPI_FAILURE (Status))
564a159c266SJung-uk Kim     {
565f8146b88SJung-uk Kim         goto CleanupReturnObject;
566f8146b88SJung-uk Kim     }
567f8146b88SJung-uk Kim 
568a159c266SJung-uk Kim     /* Dereference Index and RefOf references */
569a159c266SJung-uk Kim 
570a159c266SJung-uk Kim     AcpiNsResolveReferences (Info);
571a159c266SJung-uk Kim 
572a159c266SJung-uk Kim     /* Get the size of the returned object */
573a159c266SJung-uk Kim 
574a159c266SJung-uk Kim     Status = AcpiUtGetObjectSize (Info->ReturnObject,
575a159c266SJung-uk Kim         &BufferSpaceNeeded);
576a159c266SJung-uk Kim     if (ACPI_SUCCESS (Status))
577a159c266SJung-uk Kim     {
578a159c266SJung-uk Kim         /* Validate/Allocate/Clear caller buffer */
579a159c266SJung-uk Kim 
580a159c266SJung-uk Kim         Status = AcpiUtInitializeBuffer (ReturnBuffer,
581a159c266SJung-uk Kim             BufferSpaceNeeded);
582a159c266SJung-uk Kim         if (ACPI_FAILURE (Status))
583a159c266SJung-uk Kim         {
584a159c266SJung-uk Kim             /*
585a159c266SJung-uk Kim              * Caller's buffer is too small or a new one can't
586a159c266SJung-uk Kim              * be allocated
587a159c266SJung-uk Kim              */
588a159c266SJung-uk Kim             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
589a159c266SJung-uk Kim                 "Needed buffer size %X, %s\n",
590a159c266SJung-uk Kim                 (UINT32) BufferSpaceNeeded,
591a159c266SJung-uk Kim                 AcpiFormatException (Status)));
592a159c266SJung-uk Kim         }
593a159c266SJung-uk Kim         else
594a159c266SJung-uk Kim         {
595a159c266SJung-uk Kim             /* We have enough space for the object, build it */
596a159c266SJung-uk Kim 
597f8146b88SJung-uk Kim             Status = AcpiUtCopyIobjectToEobject (
598f8146b88SJung-uk Kim                 Info->ReturnObject, ReturnBuffer);
599a159c266SJung-uk Kim         }
600a159c266SJung-uk Kim     }
601f8146b88SJung-uk Kim 
602f8146b88SJung-uk Kim CleanupReturnObject:
603a159c266SJung-uk Kim 
604a159c266SJung-uk Kim     if (Info->ReturnObject)
605a159c266SJung-uk Kim     {
606a159c266SJung-uk Kim         /*
607a159c266SJung-uk Kim          * Delete the internal return object. NOTE: Interpreter must be
608a159c266SJung-uk Kim          * locked to avoid race condition.
609a159c266SJung-uk Kim          */
610a159c266SJung-uk Kim         AcpiExEnterInterpreter ();
611a159c266SJung-uk Kim 
612a159c266SJung-uk Kim         /* Remove one reference on the return object (should delete it) */
613a159c266SJung-uk Kim 
614a159c266SJung-uk Kim         AcpiUtRemoveReference (Info->ReturnObject);
615a159c266SJung-uk Kim         AcpiExExitInterpreter ();
616a159c266SJung-uk Kim     }
617a159c266SJung-uk Kim 
618a159c266SJung-uk Kim 
619a159c266SJung-uk Kim Cleanup:
620a159c266SJung-uk Kim 
621a159c266SJung-uk Kim     /* Free the input parameter list (if we created one) */
622a159c266SJung-uk Kim 
623a159c266SJung-uk Kim     if (Info->Parameters)
624a159c266SJung-uk Kim     {
625a159c266SJung-uk Kim         /* Free the allocated parameter block */
626a159c266SJung-uk Kim 
627a159c266SJung-uk Kim         AcpiUtDeleteInternalObjectList (Info->Parameters);
628a159c266SJung-uk Kim     }
629a159c266SJung-uk Kim 
630a159c266SJung-uk Kim     ACPI_FREE (Info);
631a159c266SJung-uk Kim     return_ACPI_STATUS (Status);
632a159c266SJung-uk Kim }
633a159c266SJung-uk Kim 
634a159c266SJung-uk Kim ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
635a159c266SJung-uk Kim 
636a159c266SJung-uk Kim 
637a159c266SJung-uk Kim /*******************************************************************************
638a159c266SJung-uk Kim  *
639a159c266SJung-uk Kim  * FUNCTION:    AcpiNsResolveReferences
640a159c266SJung-uk Kim  *
641a159c266SJung-uk Kim  * PARAMETERS:  Info                    - Evaluation info block
642a159c266SJung-uk Kim  *
643a159c266SJung-uk Kim  * RETURN:      Info->ReturnObject is replaced with the dereferenced object
644a159c266SJung-uk Kim  *
645a159c266SJung-uk Kim  * DESCRIPTION: Dereference certain reference objects. Called before an
646a159c266SJung-uk Kim  *              internal return object is converted to an external ACPI_OBJECT.
647a159c266SJung-uk Kim  *
648a159c266SJung-uk Kim  * Performs an automatic dereference of Index and RefOf reference objects.
649a159c266SJung-uk Kim  * These reference objects are not supported by the ACPI_OBJECT, so this is a
650a159c266SJung-uk Kim  * last resort effort to return something useful. Also, provides compatibility
651a159c266SJung-uk Kim  * with other ACPI implementations.
652a159c266SJung-uk Kim  *
653a159c266SJung-uk Kim  * NOTE: does not handle references within returned package objects or nested
654a159c266SJung-uk Kim  * references, but this support could be added later if found to be necessary.
655a159c266SJung-uk Kim  *
656a159c266SJung-uk Kim  ******************************************************************************/
657a159c266SJung-uk Kim 
658a159c266SJung-uk Kim static void
659a159c266SJung-uk Kim AcpiNsResolveReferences (
660a159c266SJung-uk Kim     ACPI_EVALUATE_INFO      *Info)
661a159c266SJung-uk Kim {
662a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
663a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
664a159c266SJung-uk Kim 
665a159c266SJung-uk Kim 
666a159c266SJung-uk Kim     /* We are interested in reference objects only */
667a159c266SJung-uk Kim 
668a159c266SJung-uk Kim     if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
669a159c266SJung-uk Kim     {
670a159c266SJung-uk Kim         return;
671a159c266SJung-uk Kim     }
672a159c266SJung-uk Kim 
673a159c266SJung-uk Kim     /*
674a159c266SJung-uk Kim      * Two types of references are supported - those created by Index and
675a159c266SJung-uk Kim      * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
676a159c266SJung-uk Kim      * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
677a159c266SJung-uk Kim      * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
678a159c266SJung-uk Kim      * an ACPI_OBJECT.
679a159c266SJung-uk Kim      */
680a159c266SJung-uk Kim     switch (Info->ReturnObject->Reference.Class)
681a159c266SJung-uk Kim     {
682a159c266SJung-uk Kim     case ACPI_REFCLASS_INDEX:
683a159c266SJung-uk Kim 
684a159c266SJung-uk Kim         ObjDesc = *(Info->ReturnObject->Reference.Where);
685a159c266SJung-uk Kim         break;
686a159c266SJung-uk Kim 
687a159c266SJung-uk Kim     case ACPI_REFCLASS_REFOF:
688a159c266SJung-uk Kim 
689a159c266SJung-uk Kim         Node = Info->ReturnObject->Reference.Object;
690a159c266SJung-uk Kim         if (Node)
691a159c266SJung-uk Kim         {
692a159c266SJung-uk Kim             ObjDesc = Node->Object;
693a159c266SJung-uk Kim         }
694a159c266SJung-uk Kim         break;
695a159c266SJung-uk Kim 
696a159c266SJung-uk Kim     default:
697a9d8d09cSJung-uk Kim 
698a159c266SJung-uk Kim         return;
699a159c266SJung-uk Kim     }
700a159c266SJung-uk Kim 
701a159c266SJung-uk Kim     /* Replace the existing reference object */
702a159c266SJung-uk Kim 
703a159c266SJung-uk Kim     if (ObjDesc)
704a159c266SJung-uk Kim     {
705a159c266SJung-uk Kim         AcpiUtAddReference (ObjDesc);
706a159c266SJung-uk Kim         AcpiUtRemoveReference (Info->ReturnObject);
707a159c266SJung-uk Kim         Info->ReturnObject = ObjDesc;
708a159c266SJung-uk Kim     }
709a159c266SJung-uk Kim 
710a159c266SJung-uk Kim     return;
711a159c266SJung-uk Kim }
712a159c266SJung-uk Kim 
713a159c266SJung-uk Kim 
714a159c266SJung-uk Kim /*******************************************************************************
715a159c266SJung-uk Kim  *
716a159c266SJung-uk Kim  * FUNCTION:    AcpiWalkNamespace
717a159c266SJung-uk Kim  *
718a159c266SJung-uk Kim  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
719a159c266SJung-uk Kim  *              StartObject         - Handle in namespace where search begins
720a159c266SJung-uk Kim  *              MaxDepth            - Depth to which search is to reach
721bf6fac21SJung-uk Kim  *              DescendingCallback  - Called during tree descent
722a159c266SJung-uk Kim  *                                    when an object of "Type" is found
723bf6fac21SJung-uk Kim  *              AscendingCallback   - Called during tree ascent
724a159c266SJung-uk Kim  *                                    when an object of "Type" is found
725a159c266SJung-uk Kim  *              Context             - Passed to user function(s) above
726a159c266SJung-uk Kim  *              ReturnValue         - Location where return value of
727a159c266SJung-uk Kim  *                                    UserFunction is put if terminated early
728a159c266SJung-uk Kim  *
729a159c266SJung-uk Kim  * RETURNS      Return value from the UserFunction if terminated early.
730a159c266SJung-uk Kim  *              Otherwise, returns NULL.
731a159c266SJung-uk Kim  *
732a159c266SJung-uk Kim  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
733a159c266SJung-uk Kim  *              starting (and ending) at the object specified by StartHandle.
734a159c266SJung-uk Kim  *              The callback function is called whenever an object that matches
735a159c266SJung-uk Kim  *              the type parameter is found. If the callback function returns
736a159c266SJung-uk Kim  *              a non-zero value, the search is terminated immediately and this
737a159c266SJung-uk Kim  *              value is returned to the caller.
738a159c266SJung-uk Kim  *
739a159c266SJung-uk Kim  *              The point of this procedure is to provide a generic namespace
740a159c266SJung-uk Kim  *              walk routine that can be called from multiple places to
741a159c266SJung-uk Kim  *              provide multiple services; the callback function(s) can be
742a159c266SJung-uk Kim  *              tailored to each task, whether it is a print function,
743a159c266SJung-uk Kim  *              a compare function, etc.
744a159c266SJung-uk Kim  *
745a159c266SJung-uk Kim  ******************************************************************************/
746a159c266SJung-uk Kim 
747a159c266SJung-uk Kim ACPI_STATUS
748a159c266SJung-uk Kim AcpiWalkNamespace (
749a159c266SJung-uk Kim     ACPI_OBJECT_TYPE        Type,
750a159c266SJung-uk Kim     ACPI_HANDLE             StartObject,
751a159c266SJung-uk Kim     UINT32                  MaxDepth,
752bf6fac21SJung-uk Kim     ACPI_WALK_CALLBACK      DescendingCallback,
753bf6fac21SJung-uk Kim     ACPI_WALK_CALLBACK      AscendingCallback,
754a159c266SJung-uk Kim     void                    *Context,
755a159c266SJung-uk Kim     void                    **ReturnValue)
756a159c266SJung-uk Kim {
757a159c266SJung-uk Kim     ACPI_STATUS             Status;
758a159c266SJung-uk Kim 
759a159c266SJung-uk Kim 
760a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
761a159c266SJung-uk Kim 
762a159c266SJung-uk Kim 
763a159c266SJung-uk Kim     /* Parameter validation */
764a159c266SJung-uk Kim 
765a159c266SJung-uk Kim     if ((Type > ACPI_TYPE_LOCAL_MAX) ||
766a159c266SJung-uk Kim         (!MaxDepth)                  ||
767bf6fac21SJung-uk Kim         (!DescendingCallback && !AscendingCallback))
768a159c266SJung-uk Kim     {
769a159c266SJung-uk Kim         return_ACPI_STATUS (AE_BAD_PARAMETER);
770a159c266SJung-uk Kim     }
771a159c266SJung-uk Kim 
772a159c266SJung-uk Kim     /*
773a159c266SJung-uk Kim      * Need to acquire the namespace reader lock to prevent interference
774a159c266SJung-uk Kim      * with any concurrent table unloads (which causes the deletion of
775a159c266SJung-uk Kim      * namespace objects). We cannot allow the deletion of a namespace node
776a159c266SJung-uk Kim      * while the user function is using it. The exception to this are the
777a159c266SJung-uk Kim      * nodes created and deleted during control method execution -- these
778a159c266SJung-uk Kim      * nodes are marked as temporary nodes and are ignored by the namespace
779a159c266SJung-uk Kim      * walk. Thus, control methods can be executed while holding the
780a159c266SJung-uk Kim      * namespace deletion lock (and the user function can execute control
781a159c266SJung-uk Kim      * methods.)
782a159c266SJung-uk Kim      */
783a159c266SJung-uk Kim     Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
784a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
785a159c266SJung-uk Kim     {
7868ef1a331SJung-uk Kim         return_ACPI_STATUS (Status);
787a159c266SJung-uk Kim     }
788a159c266SJung-uk Kim 
789a159c266SJung-uk Kim     /*
790a159c266SJung-uk Kim      * Lock the namespace around the walk. The namespace will be
791a159c266SJung-uk Kim      * unlocked/locked around each call to the user function - since the user
792a159c266SJung-uk Kim      * function must be allowed to make ACPICA calls itself (for example, it
793a159c266SJung-uk Kim      * will typically execute control methods during device enumeration.)
794a159c266SJung-uk Kim      */
795a159c266SJung-uk Kim     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
796a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
797a159c266SJung-uk Kim     {
798a159c266SJung-uk Kim         goto UnlockAndExit;
799a159c266SJung-uk Kim     }
800a159c266SJung-uk Kim 
80179c6d946SJung-uk Kim     /* Now we can validate the starting node */
80279c6d946SJung-uk Kim 
80379c6d946SJung-uk Kim     if (!AcpiNsValidateHandle (StartObject))
80479c6d946SJung-uk Kim     {
80579c6d946SJung-uk Kim         Status = AE_BAD_PARAMETER;
80679c6d946SJung-uk Kim         goto UnlockAndExit2;
80779c6d946SJung-uk Kim     }
80879c6d946SJung-uk Kim 
809a159c266SJung-uk Kim     Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
810bf6fac21SJung-uk Kim         ACPI_NS_WALK_UNLOCK, DescendingCallback,
811bf6fac21SJung-uk Kim         AscendingCallback, Context, ReturnValue);
812a159c266SJung-uk Kim 
81379c6d946SJung-uk Kim UnlockAndExit2:
814a159c266SJung-uk Kim     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
815a159c266SJung-uk Kim 
816a159c266SJung-uk Kim UnlockAndExit:
817a159c266SJung-uk Kim     (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
818a159c266SJung-uk Kim     return_ACPI_STATUS (Status);
819a159c266SJung-uk Kim }
820a159c266SJung-uk Kim 
821a159c266SJung-uk Kim ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
822a159c266SJung-uk Kim 
823a159c266SJung-uk Kim 
824a159c266SJung-uk Kim /*******************************************************************************
825a159c266SJung-uk Kim  *
826a159c266SJung-uk Kim  * FUNCTION:    AcpiNsGetDeviceCallback
827a159c266SJung-uk Kim  *
828a159c266SJung-uk Kim  * PARAMETERS:  Callback from AcpiGetDevice
829a159c266SJung-uk Kim  *
830a159c266SJung-uk Kim  * RETURN:      Status
831a159c266SJung-uk Kim  *
832a159c266SJung-uk Kim  * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
833a159c266SJung-uk Kim  *              present devices, or if they specified a HID, it filters based
834a159c266SJung-uk Kim  *              on that.
835a159c266SJung-uk Kim  *
836a159c266SJung-uk Kim  ******************************************************************************/
837a159c266SJung-uk Kim 
838a159c266SJung-uk Kim static ACPI_STATUS
839a159c266SJung-uk Kim AcpiNsGetDeviceCallback (
840a159c266SJung-uk Kim     ACPI_HANDLE             ObjHandle,
841a159c266SJung-uk Kim     UINT32                  NestingLevel,
842a159c266SJung-uk Kim     void                    *Context,
843a159c266SJung-uk Kim     void                    **ReturnValue)
844a159c266SJung-uk Kim {
845a159c266SJung-uk Kim     ACPI_GET_DEVICES_INFO   *Info = Context;
846a159c266SJung-uk Kim     ACPI_STATUS             Status;
847a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
848a159c266SJung-uk Kim     UINT32                  Flags;
8498ef1a331SJung-uk Kim     ACPI_PNP_DEVICE_ID      *Hid;
8508ef1a331SJung-uk Kim     ACPI_PNP_DEVICE_ID_LIST *Cid;
851a159c266SJung-uk Kim     UINT32                  i;
852a159c266SJung-uk Kim     BOOLEAN                 Found;
853a159c266SJung-uk Kim     int                     NoMatch;
854a159c266SJung-uk Kim 
855a159c266SJung-uk Kim 
856a159c266SJung-uk Kim     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
857a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
858a159c266SJung-uk Kim     {
859a159c266SJung-uk Kim         return (Status);
860a159c266SJung-uk Kim     }
861a159c266SJung-uk Kim 
862a159c266SJung-uk Kim     Node = AcpiNsValidateHandle (ObjHandle);
863a159c266SJung-uk Kim     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
864a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
865a159c266SJung-uk Kim     {
866a159c266SJung-uk Kim         return (Status);
867a159c266SJung-uk Kim     }
868a159c266SJung-uk Kim 
869a159c266SJung-uk Kim     if (!Node)
870a159c266SJung-uk Kim     {
871a159c266SJung-uk Kim         return (AE_BAD_PARAMETER);
872a159c266SJung-uk Kim     }
873a159c266SJung-uk Kim 
874a159c266SJung-uk Kim     /*
875a159c266SJung-uk Kim      * First, filter based on the device HID and CID.
876a159c266SJung-uk Kim      *
877a159c266SJung-uk Kim      * 01/2010: For this case where a specific HID is requested, we don't
878a159c266SJung-uk Kim      * want to run _STA until we have an actual HID match. Thus, we will
879a159c266SJung-uk Kim      * not unnecessarily execute _STA on devices for which the caller
880a159c266SJung-uk Kim      * doesn't care about. Previously, _STA was executed unconditionally
881a159c266SJung-uk Kim      * on all devices found here.
882a159c266SJung-uk Kim      *
883a159c266SJung-uk Kim      * A side-effect of this change is that now we will continue to search
884a159c266SJung-uk Kim      * for a matching HID even under device trees where the parent device
885a159c266SJung-uk Kim      * would have returned a _STA that indicates it is not present or
886a159c266SJung-uk Kim      * not functioning (thus aborting the search on that branch).
887a159c266SJung-uk Kim      */
888a159c266SJung-uk Kim     if (Info->Hid != NULL)
889a159c266SJung-uk Kim     {
890a159c266SJung-uk Kim         Status = AcpiUtExecute_HID (Node, &Hid);
891a159c266SJung-uk Kim         if (Status == AE_NOT_FOUND)
892a159c266SJung-uk Kim         {
893a159c266SJung-uk Kim             return (AE_OK);
894a159c266SJung-uk Kim         }
895a159c266SJung-uk Kim         else if (ACPI_FAILURE (Status))
896a159c266SJung-uk Kim         {
897a159c266SJung-uk Kim             return (AE_CTRL_DEPTH);
898a159c266SJung-uk Kim         }
899a159c266SJung-uk Kim 
9005ef50723SJung-uk Kim         NoMatch = strcmp (Hid->String, Info->Hid);
901a159c266SJung-uk Kim         ACPI_FREE (Hid);
902a159c266SJung-uk Kim 
903a159c266SJung-uk Kim         if (NoMatch)
904a159c266SJung-uk Kim         {
905a159c266SJung-uk Kim             /*
906a159c266SJung-uk Kim              * HID does not match, attempt match within the
907a159c266SJung-uk Kim              * list of Compatible IDs (CIDs)
908a159c266SJung-uk Kim              */
909a159c266SJung-uk Kim             Status = AcpiUtExecute_CID (Node, &Cid);
910a159c266SJung-uk Kim             if (Status == AE_NOT_FOUND)
911a159c266SJung-uk Kim             {
912a159c266SJung-uk Kim                 return (AE_OK);
913a159c266SJung-uk Kim             }
914a159c266SJung-uk Kim             else if (ACPI_FAILURE (Status))
915a159c266SJung-uk Kim             {
916a159c266SJung-uk Kim                 return (AE_CTRL_DEPTH);
917a159c266SJung-uk Kim             }
918a159c266SJung-uk Kim 
919a159c266SJung-uk Kim             /* Walk the CID list */
920a159c266SJung-uk Kim 
921a159c266SJung-uk Kim             Found = FALSE;
922a159c266SJung-uk Kim             for (i = 0; i < Cid->Count; i++)
923a159c266SJung-uk Kim             {
9245ef50723SJung-uk Kim                 if (strcmp (Cid->Ids[i].String, Info->Hid) == 0)
925a159c266SJung-uk Kim                 {
926a159c266SJung-uk Kim                     /* Found a matching CID */
927a159c266SJung-uk Kim 
928a159c266SJung-uk Kim                     Found = TRUE;
929a159c266SJung-uk Kim                     break;
930a159c266SJung-uk Kim                 }
931a159c266SJung-uk Kim             }
932a159c266SJung-uk Kim 
933a159c266SJung-uk Kim             ACPI_FREE (Cid);
934a159c266SJung-uk Kim             if (!Found)
935a159c266SJung-uk Kim             {
936a159c266SJung-uk Kim                 return (AE_OK);
937a159c266SJung-uk Kim             }
938a159c266SJung-uk Kim         }
939a159c266SJung-uk Kim     }
940a159c266SJung-uk Kim 
941a159c266SJung-uk Kim     /* Run _STA to determine if device is present */
942a159c266SJung-uk Kim 
943a159c266SJung-uk Kim     Status = AcpiUtExecute_STA (Node, &Flags);
944a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
945a159c266SJung-uk Kim     {
946a159c266SJung-uk Kim         return (AE_CTRL_DEPTH);
947a159c266SJung-uk Kim     }
948a159c266SJung-uk Kim 
949a159c266SJung-uk Kim     if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
950a159c266SJung-uk Kim         !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
951a159c266SJung-uk Kim     {
952a159c266SJung-uk Kim         /*
953a159c266SJung-uk Kim          * Don't examine the children of the device only when the
954a159c266SJung-uk Kim          * device is neither present nor functional. See ACPI spec,
955a159c266SJung-uk Kim          * description of _STA for more information.
956a159c266SJung-uk Kim          */
957a159c266SJung-uk Kim         return (AE_CTRL_DEPTH);
958a159c266SJung-uk Kim     }
959a159c266SJung-uk Kim 
960a159c266SJung-uk Kim     /* We have a valid device, invoke the user function */
961a159c266SJung-uk Kim 
962f8146b88SJung-uk Kim     Status = Info->UserFunction (ObjHandle, NestingLevel,
963f8146b88SJung-uk Kim         Info->Context, ReturnValue);
964a159c266SJung-uk Kim     return (Status);
965a159c266SJung-uk Kim }
966a159c266SJung-uk Kim 
967a159c266SJung-uk Kim 
968a159c266SJung-uk Kim /*******************************************************************************
969a159c266SJung-uk Kim  *
970a159c266SJung-uk Kim  * FUNCTION:    AcpiGetDevices
971a159c266SJung-uk Kim  *
972a159c266SJung-uk Kim  * PARAMETERS:  HID                 - HID to search for. Can be NULL.
973a159c266SJung-uk Kim  *              UserFunction        - Called when a matching object is found
974a159c266SJung-uk Kim  *              Context             - Passed to user function
975a159c266SJung-uk Kim  *              ReturnValue         - Location where return value of
976a159c266SJung-uk Kim  *                                    UserFunction is put if terminated early
977a159c266SJung-uk Kim  *
978a159c266SJung-uk Kim  * RETURNS      Return value from the UserFunction if terminated early.
979a159c266SJung-uk Kim  *              Otherwise, returns NULL.
980a159c266SJung-uk Kim  *
981a159c266SJung-uk Kim  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
982a159c266SJung-uk Kim  *              starting (and ending) at the object specified by StartHandle.
983a159c266SJung-uk Kim  *              The UserFunction is called whenever an object of type
984a159c266SJung-uk Kim  *              Device is found. If the user function returns
985a159c266SJung-uk Kim  *              a non-zero value, the search is terminated immediately and this
986a159c266SJung-uk Kim  *              value is returned to the caller.
987a159c266SJung-uk Kim  *
988a159c266SJung-uk Kim  *              This is a wrapper for WalkNamespace, but the callback performs
989a159c266SJung-uk Kim  *              additional filtering. Please see AcpiNsGetDeviceCallback.
990a159c266SJung-uk Kim  *
991a159c266SJung-uk Kim  ******************************************************************************/
992a159c266SJung-uk Kim 
993a159c266SJung-uk Kim ACPI_STATUS
994a159c266SJung-uk Kim AcpiGetDevices (
995a159c266SJung-uk Kim     char                    *HID,
996a159c266SJung-uk Kim     ACPI_WALK_CALLBACK      UserFunction,
997a159c266SJung-uk Kim     void                    *Context,
998a159c266SJung-uk Kim     void                    **ReturnValue)
999a159c266SJung-uk Kim {
1000a159c266SJung-uk Kim     ACPI_STATUS             Status;
1001a159c266SJung-uk Kim     ACPI_GET_DEVICES_INFO   Info;
1002a159c266SJung-uk Kim 
1003a159c266SJung-uk Kim 
1004a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE (AcpiGetDevices);
1005a159c266SJung-uk Kim 
1006a159c266SJung-uk Kim 
1007a159c266SJung-uk Kim     /* Parameter validation */
1008a159c266SJung-uk Kim 
1009a159c266SJung-uk Kim     if (!UserFunction)
1010a159c266SJung-uk Kim     {
1011a159c266SJung-uk Kim         return_ACPI_STATUS (AE_BAD_PARAMETER);
1012a159c266SJung-uk Kim     }
1013a159c266SJung-uk Kim 
1014a159c266SJung-uk Kim     /*
1015a159c266SJung-uk Kim      * We're going to call their callback from OUR callback, so we need
1016a159c266SJung-uk Kim      * to know what it is, and their context parameter.
1017a159c266SJung-uk Kim      */
1018a159c266SJung-uk Kim     Info.Hid = HID;
1019a159c266SJung-uk Kim     Info.Context = Context;
1020a159c266SJung-uk Kim     Info.UserFunction = UserFunction;
1021a159c266SJung-uk Kim 
1022a159c266SJung-uk Kim     /*
1023a159c266SJung-uk Kim      * Lock the namespace around the walk.
1024a159c266SJung-uk Kim      * The namespace will be unlocked/locked around each call
1025a159c266SJung-uk Kim      * to the user function - since this function
1026a159c266SJung-uk Kim      * must be allowed to make Acpi calls itself.
1027a159c266SJung-uk Kim      */
1028a159c266SJung-uk Kim     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1029a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
1030a159c266SJung-uk Kim     {
1031a159c266SJung-uk Kim         return_ACPI_STATUS (Status);
1032a159c266SJung-uk Kim     }
1033a159c266SJung-uk Kim 
1034a159c266SJung-uk Kim     Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1035a159c266SJung-uk Kim         ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
1036a159c266SJung-uk Kim         AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
1037a159c266SJung-uk Kim 
1038a159c266SJung-uk Kim     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1039a159c266SJung-uk Kim     return_ACPI_STATUS (Status);
1040a159c266SJung-uk Kim }
1041a159c266SJung-uk Kim 
1042a159c266SJung-uk Kim ACPI_EXPORT_SYMBOL (AcpiGetDevices)
1043a159c266SJung-uk Kim 
1044a159c266SJung-uk Kim 
1045a159c266SJung-uk Kim /*******************************************************************************
1046a159c266SJung-uk Kim  *
1047a159c266SJung-uk Kim  * FUNCTION:    AcpiAttachData
1048a159c266SJung-uk Kim  *
1049a159c266SJung-uk Kim  * PARAMETERS:  ObjHandle           - Namespace node
1050a159c266SJung-uk Kim  *              Handler             - Handler for this attachment
1051a159c266SJung-uk Kim  *              Data                - Pointer to data to be attached
1052a159c266SJung-uk Kim  *
1053a159c266SJung-uk Kim  * RETURN:      Status
1054a159c266SJung-uk Kim  *
1055a159c266SJung-uk Kim  * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
1056a159c266SJung-uk Kim  *
1057a159c266SJung-uk Kim  ******************************************************************************/
1058a159c266SJung-uk Kim 
1059a159c266SJung-uk Kim ACPI_STATUS
1060a159c266SJung-uk Kim AcpiAttachData (
1061a159c266SJung-uk Kim     ACPI_HANDLE             ObjHandle,
1062a159c266SJung-uk Kim     ACPI_OBJECT_HANDLER     Handler,
1063a159c266SJung-uk Kim     void                    *Data)
1064a159c266SJung-uk Kim {
1065a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
1066a159c266SJung-uk Kim     ACPI_STATUS             Status;
1067a159c266SJung-uk Kim 
1068a159c266SJung-uk Kim 
1069a159c266SJung-uk Kim     /* Parameter validation */
1070a159c266SJung-uk Kim 
1071a159c266SJung-uk Kim     if (!ObjHandle  ||
1072a159c266SJung-uk Kim         !Handler    ||
1073a159c266SJung-uk Kim         !Data)
1074a159c266SJung-uk Kim     {
1075a159c266SJung-uk Kim         return (AE_BAD_PARAMETER);
1076a159c266SJung-uk Kim     }
1077a159c266SJung-uk Kim 
1078a159c266SJung-uk Kim     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1079a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
1080a159c266SJung-uk Kim     {
1081a159c266SJung-uk Kim         return (Status);
1082a159c266SJung-uk Kim     }
1083a159c266SJung-uk Kim 
1084a159c266SJung-uk Kim     /* Convert and validate the handle */
1085a159c266SJung-uk Kim 
1086a159c266SJung-uk Kim     Node = AcpiNsValidateHandle (ObjHandle);
1087a159c266SJung-uk Kim     if (!Node)
1088a159c266SJung-uk Kim     {
1089a159c266SJung-uk Kim         Status = AE_BAD_PARAMETER;
1090a159c266SJung-uk Kim         goto UnlockAndExit;
1091a159c266SJung-uk Kim     }
1092a159c266SJung-uk Kim 
1093a159c266SJung-uk Kim     Status = AcpiNsAttachData (Node, Handler, Data);
1094a159c266SJung-uk Kim 
1095a159c266SJung-uk Kim UnlockAndExit:
1096a159c266SJung-uk Kim     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1097a159c266SJung-uk Kim     return (Status);
1098a159c266SJung-uk Kim }
1099a159c266SJung-uk Kim 
1100a159c266SJung-uk Kim ACPI_EXPORT_SYMBOL (AcpiAttachData)
1101a159c266SJung-uk Kim 
1102a159c266SJung-uk Kim 
1103a159c266SJung-uk Kim /*******************************************************************************
1104a159c266SJung-uk Kim  *
1105a159c266SJung-uk Kim  * FUNCTION:    AcpiDetachData
1106a159c266SJung-uk Kim  *
1107a159c266SJung-uk Kim  * PARAMETERS:  ObjHandle           - Namespace node handle
1108a159c266SJung-uk Kim  *              Handler             - Handler used in call to AcpiAttachData
1109a159c266SJung-uk Kim  *
1110a159c266SJung-uk Kim  * RETURN:      Status
1111a159c266SJung-uk Kim  *
1112a159c266SJung-uk Kim  * DESCRIPTION: Remove data that was previously attached to a node.
1113a159c266SJung-uk Kim  *
1114a159c266SJung-uk Kim  ******************************************************************************/
1115a159c266SJung-uk Kim 
1116a159c266SJung-uk Kim ACPI_STATUS
1117a159c266SJung-uk Kim AcpiDetachData (
1118a159c266SJung-uk Kim     ACPI_HANDLE             ObjHandle,
1119a159c266SJung-uk Kim     ACPI_OBJECT_HANDLER     Handler)
1120a159c266SJung-uk Kim {
1121a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
1122a159c266SJung-uk Kim     ACPI_STATUS             Status;
1123a159c266SJung-uk Kim 
1124a159c266SJung-uk Kim 
1125a159c266SJung-uk Kim     /* Parameter validation */
1126a159c266SJung-uk Kim 
1127a159c266SJung-uk Kim     if (!ObjHandle  ||
1128a159c266SJung-uk Kim         !Handler)
1129a159c266SJung-uk Kim     {
1130a159c266SJung-uk Kim         return (AE_BAD_PARAMETER);
1131a159c266SJung-uk Kim     }
1132a159c266SJung-uk Kim 
1133a159c266SJung-uk Kim     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1134a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
1135a159c266SJung-uk Kim     {
1136a159c266SJung-uk Kim         return (Status);
1137a159c266SJung-uk Kim     }
1138a159c266SJung-uk Kim 
1139a159c266SJung-uk Kim     /* Convert and validate the handle */
1140a159c266SJung-uk Kim 
1141a159c266SJung-uk Kim     Node = AcpiNsValidateHandle (ObjHandle);
1142a159c266SJung-uk Kim     if (!Node)
1143a159c266SJung-uk Kim     {
1144a159c266SJung-uk Kim         Status = AE_BAD_PARAMETER;
1145a159c266SJung-uk Kim         goto UnlockAndExit;
1146a159c266SJung-uk Kim     }
1147a159c266SJung-uk Kim 
1148a159c266SJung-uk Kim     Status = AcpiNsDetachData (Node, Handler);
1149a159c266SJung-uk Kim 
1150a159c266SJung-uk Kim UnlockAndExit:
1151a159c266SJung-uk Kim     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1152a159c266SJung-uk Kim     return (Status);
1153a159c266SJung-uk Kim }
1154a159c266SJung-uk Kim 
1155a159c266SJung-uk Kim ACPI_EXPORT_SYMBOL (AcpiDetachData)
1156a159c266SJung-uk Kim 
1157a159c266SJung-uk Kim 
1158a159c266SJung-uk Kim /*******************************************************************************
1159a159c266SJung-uk Kim  *
1160b4b4b530SBaptiste Daroussin  * FUNCTION:    AcpiGetData
1161a159c266SJung-uk Kim  *
1162a159c266SJung-uk Kim  * PARAMETERS:  ObjHandle           - Namespace node
1163b4b4b530SBaptiste Daroussin  *              Handler             - Handler used in call to AttachData
1164a159c266SJung-uk Kim  *              Data                - Where the data is returned
1165a159c266SJung-uk Kim  *
1166a159c266SJung-uk Kim  * RETURN:      Status
1167a159c266SJung-uk Kim  *
1168b4b4b530SBaptiste Daroussin  * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
1169a159c266SJung-uk Kim  *
1170a159c266SJung-uk Kim  ******************************************************************************/
1171b4b4b530SBaptiste Daroussin 
1172a159c266SJung-uk Kim ACPI_STATUS
1173b4b4b530SBaptiste Daroussin AcpiGetData (
1174a159c266SJung-uk Kim     ACPI_HANDLE             ObjHandle,
1175a159c266SJung-uk Kim     ACPI_OBJECT_HANDLER     Handler,
1176b4b4b530SBaptiste Daroussin     void                    **Data)
1177a159c266SJung-uk Kim {
1178a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
1179a159c266SJung-uk Kim     ACPI_STATUS             Status;
1180a159c266SJung-uk Kim 
1181a159c266SJung-uk Kim 
1182a159c266SJung-uk Kim     /* Parameter validation */
1183a159c266SJung-uk Kim 
1184a159c266SJung-uk Kim     if (!ObjHandle  ||
1185a159c266SJung-uk Kim         !Handler    ||
1186a159c266SJung-uk Kim         !Data)
1187a159c266SJung-uk Kim     {
1188a159c266SJung-uk Kim         return (AE_BAD_PARAMETER);
1189a159c266SJung-uk Kim     }
1190a159c266SJung-uk Kim 
1191a159c266SJung-uk Kim     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1192a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
1193a159c266SJung-uk Kim     {
1194a159c266SJung-uk Kim         return (Status);
1195a159c266SJung-uk Kim     }
1196a159c266SJung-uk Kim 
1197a159c266SJung-uk Kim     /* Convert and validate the handle */
1198a159c266SJung-uk Kim 
1199a159c266SJung-uk Kim     Node = AcpiNsValidateHandle (ObjHandle);
1200a159c266SJung-uk Kim     if (!Node)
1201a159c266SJung-uk Kim     {
1202a159c266SJung-uk Kim         Status = AE_BAD_PARAMETER;
1203a159c266SJung-uk Kim         goto UnlockAndExit;
1204a159c266SJung-uk Kim     }
1205a159c266SJung-uk Kim 
1206a159c266SJung-uk Kim     Status = AcpiNsGetAttachedData (Node, Handler, Data);
1207b4b4b530SBaptiste Daroussin 
1208a159c266SJung-uk Kim UnlockAndExit:
1209a159c266SJung-uk Kim     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1210a159c266SJung-uk Kim     return (Status);
1211a159c266SJung-uk Kim }
1212a159c266SJung-uk Kim 
1213a159c266SJung-uk Kim ACPI_EXPORT_SYMBOL (AcpiGetData)
1214