nsxfeval.c revision 100966
1230557Sjimharris/*******************************************************************************
2230557Sjimharris *
3230557Sjimharris * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4230557Sjimharris *                         ACPI Object evaluation interfaces
5230557Sjimharris *              $Revision: 1 $
6230557Sjimharris *
7230557Sjimharris ******************************************************************************/
8230557Sjimharris
9230557Sjimharris/******************************************************************************
10230557Sjimharris *
11230557Sjimharris * 1. Copyright Notice
12230557Sjimharris *
13230557Sjimharris * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp.
14230557Sjimharris * All rights reserved.
15230557Sjimharris *
16230557Sjimharris * 2. License
17230557Sjimharris *
18230557Sjimharris * 2.1. This is your license from Intel Corp. under its intellectual property
19230557Sjimharris * rights.  You may have additional license terms from the party that provided
20230557Sjimharris * you this software, covering your right to use that party's intellectual
21230557Sjimharris * property rights.
22230557Sjimharris *
23230557Sjimharris * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24230557Sjimharris * copy of the source code appearing in this file ("Covered Code") an
25230557Sjimharris * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26230557Sjimharris * base code distributed originally by Intel ("Original Intel Code") to copy,
27230557Sjimharris * make derivatives, distribute, use and display any portion of the Covered
28230557Sjimharris * Code in any form, with the right to sublicense such rights; and
29230557Sjimharris *
30230557Sjimharris * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31230557Sjimharris * license (with the right to sublicense), under only those claims of Intel
32230557Sjimharris * patents that are infringed by the Original Intel Code, to make, use, sell,
33230557Sjimharris * offer to sell, and import the Covered Code and derivative works thereof
34230557Sjimharris * solely to the minimum extent necessary to exercise the above copyright
35230557Sjimharris * license, and in no event shall the patent license extend to any additions
36230557Sjimharris * to or modifications of the Original Intel Code.  No other license or right
37230557Sjimharris * is granted directly or by implication, estoppel or otherwise;
38230557Sjimharris *
39230557Sjimharris * The above copyright and patent license is granted only if the following
40230557Sjimharris * conditions are met:
41230557Sjimharris *
42230557Sjimharris * 3. Conditions
43230557Sjimharris *
44230557Sjimharris * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45230557Sjimharris * Redistribution of source code of any substantial portion of the Covered
46230557Sjimharris * Code or modification with rights to further distribute source must include
47230557Sjimharris * the above Copyright Notice, the above License, this list of Conditions,
48230557Sjimharris * and the following Disclaimer and Export Compliance provision.  In addition,
49230557Sjimharris * Licensee must cause all Covered Code to which Licensee contributes to
50230557Sjimharris * contain a file documenting the changes Licensee made to create that Covered
51230557Sjimharris * Code and the date of any change.  Licensee must include in that file the
52230557Sjimharris * documentation of any changes made by any predecessor Licensee.  Licensee
53230557Sjimharris * must include a prominent statement that the modification is derived,
54230557Sjimharris * directly or indirectly, from Original Intel Code.
55230557Sjimharris *
56230557Sjimharris * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57230557Sjimharris * Redistribution of source code of any substantial portion of the Covered
58230557Sjimharris * Code or modification without rights to further distribute source must
59230557Sjimharris * include the following Disclaimer and Export Compliance provision in the
60230557Sjimharris * documentation and/or other materials provided with distribution.  In
61230557Sjimharris * addition, Licensee may not authorize further sublicense of source of any
62230557Sjimharris * portion of the Covered Code, and must include terms to the effect that the
63230557Sjimharris * license from Licensee to its licensee is limited to the intellectual
64230557Sjimharris * property embodied in the software Licensee provides to its licensee, and
65230557Sjimharris * not to intellectual property embodied in modifications its licensee may
66230557Sjimharris * make.
67230557Sjimharris *
68230557Sjimharris * 3.3. Redistribution of Executable. Redistribution in executable form of any
69230557Sjimharris * substantial portion of the Covered Code or modification must reproduce the
70230557Sjimharris * above Copyright Notice, and the following Disclaimer and Export Compliance
71230557Sjimharris * provision in the documentation and/or other materials provided with the
72230557Sjimharris * distribution.
73230557Sjimharris *
74230557Sjimharris * 3.4. Intel retains all right, title, and interest in and to the Original
75230557Sjimharris * Intel Code.
76230557Sjimharris *
77230557Sjimharris * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78230557Sjimharris * Intel shall be used in advertising or otherwise to promote the sale, use or
79230557Sjimharris * other dealings in products derived from or relating to the Covered Code
80230557Sjimharris * without prior written authorization from Intel.
81230557Sjimharris *
82230557Sjimharris * 4. Disclaimer and Export Compliance
83230557Sjimharris *
84230557Sjimharris * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85230557Sjimharris * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86230557Sjimharris * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87230557Sjimharris * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88230557Sjimharris * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89230557Sjimharris * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90230557Sjimharris * PARTICULAR PURPOSE.
91230557Sjimharris *
92230557Sjimharris * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93230557Sjimharris * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94230557Sjimharris * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95230557Sjimharris * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96230557Sjimharris * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97230557Sjimharris * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98230557Sjimharris * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99230557Sjimharris * LIMITED REMEDY.
100230557Sjimharris *
101230557Sjimharris * 4.3. Licensee shall not export, either directly or indirectly, any of this
102230557Sjimharris * software or system incorporating such software without first obtaining any
103230557Sjimharris * required license or other approval from the U. S. Department of Commerce or
104230557Sjimharris * any other agency or department of the United States Government.  In the
105230557Sjimharris * event Licensee exports any such software from the United States or
106230557Sjimharris * re-exports any such software from a foreign destination, Licensee shall
107230557Sjimharris * ensure that the distribution and export/re-export of the software is in
108230557Sjimharris * compliance with all laws, regulations, orders, or other restrictions of the
109230557Sjimharris * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110230557Sjimharris * any of its subsidiaries will export/re-export any technical data, process,
111230557Sjimharris * software, or service, directly or indirectly, to any country for which the
112230557Sjimharris * United States government or any agency thereof requires an export license,
113230557Sjimharris * other governmental approval, or letter of assurance, without first obtaining
114230557Sjimharris * such license, approval or letter.
115230557Sjimharris *
116230557Sjimharris *****************************************************************************/
117230557Sjimharris
118230557Sjimharris
119230557Sjimharris#define __NSXFEVAL_C__
120230557Sjimharris
121230557Sjimharris#include "acpi.h"
122230557Sjimharris#include "acnamesp.h"
123230557Sjimharris
124230557Sjimharris
125230557Sjimharris#define _COMPONENT          ACPI_NAMESPACE
126230557Sjimharris        ACPI_MODULE_NAME    ("nsxfeval")
127230557Sjimharris
128230557Sjimharris
129230557Sjimharris/*******************************************************************************
130230557Sjimharris *
131230557Sjimharris * FUNCTION:    AcpiEvaluateObjectTyped
132230557Sjimharris *
133230557Sjimharris * PARAMETERS:  Handle              - Object handle (optional)
134230557Sjimharris *              *Pathname           - Object pathname (optional)
135230557Sjimharris *              **ExternalParams    - List of parameters to pass to method,
136230557Sjimharris *                                    terminated by NULL.  May be NULL
137230557Sjimharris *                                    if no parameters are being passed.
138230557Sjimharris *              *ReturnBuffer       - Where to put method's return value (if
139230557Sjimharris *                                    any).  If NULL, no value is returned.
140230557Sjimharris *              ReturnType          - Expected type of return object
141230557Sjimharris *
142230557Sjimharris * RETURN:      Status
143230557Sjimharris *
144230557Sjimharris * DESCRIPTION: Find and evaluate the given object, passing the given
145230557Sjimharris *              parameters if necessary.  One of "Handle" or "Pathname" must
146230557Sjimharris *              be valid (non-null)
147230557Sjimharris *
148230557Sjimharris ******************************************************************************/
149230557Sjimharris
150230557SjimharrisACPI_STATUS
151230557SjimharrisAcpiEvaluateObjectTyped (
152230557Sjimharris    ACPI_HANDLE             Handle,
153230557Sjimharris    ACPI_STRING             Pathname,
154230557Sjimharris    ACPI_OBJECT_LIST        *ExternalParams,
155230557Sjimharris    ACPI_BUFFER             *ReturnBuffer,
156230557Sjimharris    ACPI_OBJECT_TYPE        ReturnType)
157230557Sjimharris{
158230557Sjimharris    ACPI_STATUS             Status;
159230557Sjimharris    BOOLEAN                 MustFree = FALSE;
160230557Sjimharris
161230557Sjimharris
162230557Sjimharris    ACPI_FUNCTION_TRACE ("AcpiEvaluateObjectTyped");
163230557Sjimharris
164230557Sjimharris
165230557Sjimharris    /* Return buffer must be valid */
166230557Sjimharris
167230557Sjimharris    if (!ReturnBuffer)
168230557Sjimharris    {
169        return_ACPI_STATUS (AE_BAD_PARAMETER);
170    }
171
172    if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
173    {
174        MustFree = TRUE;
175    }
176
177    /* Evaluate the object */
178
179    Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
180    if (ACPI_FAILURE (Status))
181    {
182        return_ACPI_STATUS (Status);
183    }
184
185    /* Type ANY means "don't care" */
186
187    if (ReturnType == ACPI_TYPE_ANY)
188    {
189        return_ACPI_STATUS (AE_OK);
190    }
191
192    if (ReturnBuffer->Length == 0)
193    {
194        /* Error because caller specifically asked for a return value */
195
196        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
197            "No return value\n"));
198
199        return_ACPI_STATUS (AE_NULL_OBJECT);
200    }
201
202    /* Examine the object type returned from EvaluateObject */
203
204    if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
205    {
206        return_ACPI_STATUS (AE_OK);
207    }
208
209    /* Return object type does not match requested type */
210
211    ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
212        "Incorrect return type [%s] requested [%s]\n",
213        AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
214        AcpiUtGetTypeName (ReturnType)));
215
216    if (MustFree)
217    {
218        /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
219
220        AcpiOsFree (ReturnBuffer->Pointer);
221        ReturnBuffer->Pointer = NULL;
222    }
223
224    ReturnBuffer->Length = 0;
225    return_ACPI_STATUS (AE_TYPE);
226}
227
228
229/*******************************************************************************
230 *
231 * FUNCTION:    AcpiEvaluateObject
232 *
233 * PARAMETERS:  Handle              - Object handle (optional)
234 *              *Pathname           - Object pathname (optional)
235 *              **ExternalParams    - List of parameters to pass to method,
236 *                                    terminated by NULL.  May be NULL
237 *                                    if no parameters are being passed.
238 *              *ReturnBuffer       - Where to put method's return value (if
239 *                                    any).  If NULL, no value is returned.
240 *
241 * RETURN:      Status
242 *
243 * DESCRIPTION: Find and evaluate the given object, passing the given
244 *              parameters if necessary.  One of "Handle" or "Pathname" must
245 *              be valid (non-null)
246 *
247 ******************************************************************************/
248
249ACPI_STATUS
250AcpiEvaluateObject (
251    ACPI_HANDLE             Handle,
252    ACPI_STRING             Pathname,
253    ACPI_OBJECT_LIST        *ExternalParams,
254    ACPI_BUFFER             *ReturnBuffer)
255{
256    ACPI_STATUS             Status;
257    ACPI_OPERAND_OBJECT     **InternalParams = NULL;
258    ACPI_OPERAND_OBJECT     *InternalReturnObj = NULL;
259    ACPI_SIZE               BufferSpaceNeeded;
260    UINT32                  i;
261
262
263    ACPI_FUNCTION_TRACE ("AcpiEvaluateObject");
264
265
266    /*
267     * If there are parameters to be passed to the object
268     * (which must be a control method), the external objects
269     * must be converted to internal objects
270     */
271    if (ExternalParams && ExternalParams->Count)
272    {
273        /*
274         * Allocate a new parameter block for the internal objects
275         * Add 1 to count to allow for null terminated internal list
276         */
277        InternalParams = ACPI_MEM_CALLOCATE (((ACPI_SIZE) ExternalParams->Count + 1) *
278                                                sizeof (void *));
279        if (!InternalParams)
280        {
281            return_ACPI_STATUS (AE_NO_MEMORY);
282        }
283
284        /*
285         * Convert each external object in the list to an
286         * internal object
287         */
288        for (i = 0; i < ExternalParams->Count; i++)
289        {
290            Status = AcpiUtCopyEobjectToIobject (&ExternalParams->Pointer[i],
291                                                &InternalParams[i]);
292            if (ACPI_FAILURE (Status))
293            {
294                AcpiUtDeleteInternalObjectList (InternalParams);
295                return_ACPI_STATUS (Status);
296            }
297        }
298        InternalParams[ExternalParams->Count] = NULL;
299    }
300
301    /*
302     * Three major cases:
303     * 1) Fully qualified pathname
304     * 2) No handle, not fully qualified pathname (error)
305     * 3) Valid handle
306     */
307    if ((Pathname) &&
308        (AcpiNsValidRootPrefix (Pathname[0])))
309    {
310        /*
311         *  The path is fully qualified, just evaluate by name
312         */
313        Status = AcpiNsEvaluateByName (Pathname, InternalParams,
314                    &InternalReturnObj);
315    }
316    else if (!Handle)
317    {
318        /*
319         * A handle is optional iff a fully qualified pathname
320         * is specified.  Since we've already handled fully
321         * qualified names above, this is an error
322         */
323        if (!Pathname)
324        {
325            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
326                "Both Handle and Pathname are NULL\n"));
327        }
328        else
329        {
330            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
331                "Handle is NULL and Pathname is relative\n"));
332        }
333
334        Status = AE_BAD_PARAMETER;
335    }
336    else
337    {
338        /*
339         * We get here if we have a handle -- and if we have a
340         * pathname it is relative.  The handle will be validated
341         * in the lower procedures
342         */
343        if (!Pathname)
344        {
345            /*
346             * The null pathname case means the handle is for
347             * the actual object to be evaluated
348             */
349            Status = AcpiNsEvaluateByHandle (Handle, InternalParams,
350                            &InternalReturnObj);
351        }
352        else
353        {
354           /*
355            * Both a Handle and a relative Pathname
356            */
357            Status = AcpiNsEvaluateRelative (Handle, Pathname, InternalParams,
358                            &InternalReturnObj);
359        }
360    }
361
362
363    /*
364     * If we are expecting a return value, and all went well above,
365     * copy the return value to an external object.
366     */
367    if (ReturnBuffer)
368    {
369        if (!InternalReturnObj)
370        {
371            ReturnBuffer->Length = 0;
372        }
373        else
374        {
375            if (ACPI_GET_DESCRIPTOR_TYPE (InternalReturnObj) == ACPI_DESC_TYPE_NAMED)
376            {
377                /*
378                 * If we received a NS Node as a return object, this means that
379                 * the object we are evaluating has nothing interesting to
380                 * return (such as a mutex, etc.)  We return an error because
381                 * these types are essentially unsupported by this interface.
382                 * We don't check up front because this makes it easier to add
383                 * support for various types at a later date if necessary.
384                 */
385                Status = AE_TYPE;
386                InternalReturnObj = NULL;   /* No need to delete a NS Node */
387                ReturnBuffer->Length = 0;
388            }
389
390            if (ACPI_SUCCESS (Status))
391            {
392                /*
393                 * Find out how large a buffer is needed
394                 * to contain the returned object
395                 */
396                Status = AcpiUtGetObjectSize (InternalReturnObj,
397                                                &BufferSpaceNeeded);
398                if (ACPI_SUCCESS (Status))
399                {
400                    /* Validate/Allocate/Clear caller buffer */
401
402                    Status = AcpiUtInitializeBuffer (ReturnBuffer, BufferSpaceNeeded);
403                    if (ACPI_FAILURE (Status))
404                    {
405                        /*
406                         * Caller's buffer is too small or a new one can't be allocated
407                         */
408                        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
409                            "Needed buffer size %X, %s\n",
410                            (UINT32) BufferSpaceNeeded, AcpiFormatException (Status)));
411                    }
412                    else
413                    {
414                        /*
415                         *  We have enough space for the object, build it
416                         */
417                        Status = AcpiUtCopyIobjectToEobject (InternalReturnObj,
418                                        ReturnBuffer);
419                    }
420                }
421            }
422        }
423    }
424
425    /* Delete the return and parameter objects */
426
427    if (InternalReturnObj)
428    {
429        /*
430         * Delete the internal return object. (Or at least
431         * decrement the reference count by one)
432         */
433        AcpiUtRemoveReference (InternalReturnObj);
434    }
435
436    /*
437     * Free the input parameter list (if we created one),
438     */
439    if (InternalParams)
440    {
441        /* Free the allocated parameter block */
442
443        AcpiUtDeleteInternalObjectList (InternalParams);
444    }
445
446    return_ACPI_STATUS (Status);
447}
448
449
450
451/*******************************************************************************
452 *
453 * FUNCTION:    AcpiWalkNamespace
454 *
455 * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
456 *              StartObject         - Handle in namespace where search begins
457 *              MaxDepth            - Depth to which search is to reach
458 *              UserFunction        - Called when an object of "Type" is found
459 *              Context             - Passed to user function
460 *              ReturnValue         - Location where return value of
461 *                                    UserFunction is put if terminated early
462 *
463 * RETURNS      Return value from the UserFunction if terminated early.
464 *              Otherwise, returns NULL.
465 *
466 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
467 *              starting (and ending) at the object specified by StartHandle.
468 *              The UserFunction is called whenever an object that matches
469 *              the type parameter is found.  If the user function returns
470 *              a non-zero value, the search is terminated immediately and this
471 *              value is returned to the caller.
472 *
473 *              The point of this procedure is to provide a generic namespace
474 *              walk routine that can be called from multiple places to
475 *              provide multiple services;  the User Function can be tailored
476 *              to each task, whether it is a print function, a compare
477 *              function, etc.
478 *
479 ******************************************************************************/
480
481ACPI_STATUS
482AcpiWalkNamespace (
483    ACPI_OBJECT_TYPE        Type,
484    ACPI_HANDLE             StartObject,
485    UINT32                  MaxDepth,
486    ACPI_WALK_CALLBACK      UserFunction,
487    void                    *Context,
488    void                    **ReturnValue)
489{
490    ACPI_STATUS             Status;
491
492
493    ACPI_FUNCTION_TRACE ("AcpiWalkNamespace");
494
495
496    /* Parameter validation */
497
498    if ((Type > ACPI_TYPE_MAX)  ||
499        (!MaxDepth)             ||
500        (!UserFunction))
501    {
502        return_ACPI_STATUS (AE_BAD_PARAMETER);
503    }
504
505    /*
506     * Lock the namespace around the walk.
507     * The namespace will be unlocked/locked around each call
508     * to the user function - since this function
509     * must be allowed to make Acpi calls itself.
510     */
511    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
512    if (ACPI_FAILURE (Status))
513    {
514        return_ACPI_STATUS (Status);
515    }
516
517    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, ACPI_NS_WALK_UNLOCK,
518                    UserFunction, Context, ReturnValue);
519
520    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
521    return_ACPI_STATUS (Status);
522}
523
524
525/*******************************************************************************
526 *
527 * FUNCTION:    AcpiNsGetDeviceCallback
528 *
529 * PARAMETERS:  Callback from AcpiGetDevice
530 *
531 * RETURN:      Status
532 *
533 * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
534 *              present devices, or if they specified a HID, it filters based
535 *              on that.
536 *
537 ******************************************************************************/
538
539static ACPI_STATUS
540AcpiNsGetDeviceCallback (
541    ACPI_HANDLE             ObjHandle,
542    UINT32                  NestingLevel,
543    void                    *Context,
544    void                    **ReturnValue)
545{
546    ACPI_STATUS             Status;
547    ACPI_NAMESPACE_NODE     *Node;
548    UINT32                  Flags;
549    ACPI_DEVICE_ID          Hid;
550    ACPI_DEVICE_ID          Cid;
551    ACPI_GET_DEVICES_INFO   *Info;
552
553
554    Info = Context;
555
556    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
557    if (ACPI_FAILURE (Status))
558    {
559        return (Status);
560    }
561
562    Node = AcpiNsMapHandleToNode (ObjHandle);
563    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
564    if (ACPI_FAILURE (Status))
565    {
566        return (Status);
567    }
568
569    if (!Node)
570    {
571        return (AE_BAD_PARAMETER);
572    }
573
574    /*
575     * Run _STA to determine if device is present
576     */
577    Status = AcpiUtExecute_STA (Node, &Flags);
578    if (ACPI_FAILURE (Status))
579    {
580        return (AE_CTRL_DEPTH);
581    }
582
583    if (!(Flags & 0x01))
584    {
585        /* Don't return at the device or children of the device if not there */
586        return (AE_CTRL_DEPTH);
587    }
588
589    /*
590     * Filter based on device HID & CID
591     */
592    if (Info->Hid != NULL)
593    {
594        Status = AcpiUtExecute_HID (Node, &Hid);
595        if (Status == AE_NOT_FOUND)
596        {
597            return (AE_OK);
598        }
599        else if (ACPI_FAILURE (Status))
600        {
601            return (AE_CTRL_DEPTH);
602        }
603
604        if (ACPI_STRNCMP (Hid.Buffer, Info->Hid, sizeof (Hid.Buffer)) != 0)
605        {
606            Status = AcpiUtExecute_CID (Node, &Cid);
607            if (Status == AE_NOT_FOUND)
608            {
609                return (AE_OK);
610            }
611            else if (ACPI_FAILURE (Status))
612            {
613                return (AE_CTRL_DEPTH);
614            }
615
616            /* TBD: Handle CID packages */
617
618            if (ACPI_STRNCMP (Cid.Buffer, Info->Hid, sizeof (Cid.Buffer)) != 0)
619            {
620                return (AE_OK);
621            }
622        }
623    }
624
625    Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue);
626    return (Status);
627}
628
629
630/*******************************************************************************
631 *
632 * FUNCTION:    AcpiGetDevices
633 *
634 * PARAMETERS:  HID                 - HID to search for. Can be NULL.
635 *              UserFunction        - Called when a matching object is found
636 *              Context             - Passed to user function
637 *              ReturnValue         - Location where return value of
638 *                                    UserFunction is put if terminated early
639 *
640 * RETURNS      Return value from the UserFunction if terminated early.
641 *              Otherwise, returns NULL.
642 *
643 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
644 *              starting (and ending) at the object specified by StartHandle.
645 *              The UserFunction is called whenever an object that matches
646 *              the type parameter is found.  If the user function returns
647 *              a non-zero value, the search is terminated immediately and this
648 *              value is returned to the caller.
649 *
650 *              This is a wrapper for WalkNamespace, but the callback performs
651 *              additional filtering. Please see AcpiGetDeviceCallback.
652 *
653 ******************************************************************************/
654
655ACPI_STATUS
656AcpiGetDevices (
657    NATIVE_CHAR             *HID,
658    ACPI_WALK_CALLBACK      UserFunction,
659    void                    *Context,
660    void                    **ReturnValue)
661{
662    ACPI_STATUS             Status;
663    ACPI_GET_DEVICES_INFO   Info;
664
665
666    ACPI_FUNCTION_TRACE ("AcpiGetDevices");
667
668
669    /* Parameter validation */
670
671    if (!UserFunction)
672    {
673        return_ACPI_STATUS (AE_BAD_PARAMETER);
674    }
675
676    /*
677     * We're going to call their callback from OUR callback, so we need
678     * to know what it is, and their context parameter.
679     */
680    Info.Context      = Context;
681    Info.UserFunction = UserFunction;
682    Info.Hid          = HID;
683
684    /*
685     * Lock the namespace around the walk.
686     * The namespace will be unlocked/locked around each call
687     * to the user function - since this function
688     * must be allowed to make Acpi calls itself.
689     */
690    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
691    if (ACPI_FAILURE (Status))
692    {
693        return_ACPI_STATUS (Status);
694    }
695
696    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE,
697                                    ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
698                                    ACPI_NS_WALK_UNLOCK,
699                                    AcpiNsGetDeviceCallback, &Info,
700                                    ReturnValue);
701
702    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
703    return_ACPI_STATUS (Status);
704}
705
706
707/*******************************************************************************
708 *
709 * FUNCTION:    AcpiAttachData
710 *
711 * PARAMETERS:
712 *
713 * RETURN:      Status
714 *
715 * DESCRIPTION:
716 *
717 ******************************************************************************/
718
719ACPI_STATUS
720AcpiAttachData (
721    ACPI_HANDLE             ObjHandle,
722    ACPI_OBJECT_HANDLER     Handler,
723    void                    *Data)
724{
725    ACPI_NAMESPACE_NODE     *Node;
726    ACPI_STATUS             Status;
727
728
729    /* Parameter validation */
730
731    if (!ObjHandle  ||
732        !Handler    ||
733        !Data)
734    {
735        return (AE_BAD_PARAMETER);
736    }
737
738    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
739    if (ACPI_FAILURE (Status))
740    {
741        return (Status);
742    }
743
744    /* Convert and validate the handle */
745
746    Node = AcpiNsMapHandleToNode (ObjHandle);
747    if (!Node)
748    {
749        Status = AE_BAD_PARAMETER;
750        goto UnlockAndExit;
751    }
752
753    Status = AcpiNsAttachData (Node, Handler, Data);
754
755UnlockAndExit:
756    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
757    return (Status);
758}
759
760
761/*******************************************************************************
762 *
763 * FUNCTION:    AcpiDetachData
764 *
765 * PARAMETERS:
766 *
767 * RETURN:      Status
768 *
769 * DESCRIPTION:
770 *
771 ******************************************************************************/
772
773ACPI_STATUS
774AcpiDetachData (
775    ACPI_HANDLE             ObjHandle,
776    ACPI_OBJECT_HANDLER     Handler)
777{
778    ACPI_NAMESPACE_NODE     *Node;
779    ACPI_STATUS             Status;
780
781
782    /* Parameter validation */
783
784    if (!ObjHandle  ||
785        !Handler)
786    {
787        return (AE_BAD_PARAMETER);
788    }
789
790    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
791    if (ACPI_FAILURE (Status))
792    {
793        return (Status);
794    }
795
796    /* Convert and validate the handle */
797
798    Node = AcpiNsMapHandleToNode (ObjHandle);
799    if (!Node)
800    {
801        Status = AE_BAD_PARAMETER;
802        goto UnlockAndExit;
803    }
804
805    Status = AcpiNsDetachData (Node, Handler);
806
807UnlockAndExit:
808    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
809    return (Status);
810}
811
812
813/*******************************************************************************
814 *
815 * FUNCTION:    AcpiGetData
816 *
817 * PARAMETERS:
818 *
819 * RETURN:      Status
820 *
821 * DESCRIPTION:
822 *
823 ******************************************************************************/
824
825ACPI_STATUS
826AcpiGetData (
827    ACPI_HANDLE             ObjHandle,
828    ACPI_OBJECT_HANDLER     Handler,
829    void                    **Data)
830{
831    ACPI_NAMESPACE_NODE     *Node;
832    ACPI_STATUS             Status;
833
834
835    /* Parameter validation */
836
837    if (!ObjHandle  ||
838        !Handler    ||
839        !Data)
840    {
841        return (AE_BAD_PARAMETER);
842    }
843
844    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
845    if (ACPI_FAILURE (Status))
846    {
847        return (Status);
848    }
849
850    /* Convert and validate the handle */
851
852    Node = AcpiNsMapHandleToNode (ObjHandle);
853    if (!Node)
854    {
855        Status = AE_BAD_PARAMETER;
856        goto UnlockAndExit;
857    }
858
859    Status = AcpiNsGetAttachedData (Node, Handler, Data);
860
861UnlockAndExit:
862    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
863    return (Status);
864}
865
866
867