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