nsxfobj.c revision 67754
1/*******************************************************************************
2 *
3 * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
4 *                         ACPI Object oriented interfaces
5 *              $Revision: 74 $
6 *
7 ******************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999, Intel Corp.  All rights
14 * 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          NAMESPACE
128        MODULE_NAME         ("nsxfobj")
129
130
131/*******************************************************************************
132 *
133 * FUNCTION:    AcpiEvaluateObject
134 *
135 * PARAMETERS:  Handle              - Object handle (optional)
136 *              *Pathname           - Object pathname (optional)
137 *              **Params            - List of parameters to pass to
138 *                                    method, terminated by NULL.
139 *                                    Params itself may be NULL
140 *                                    if no parameters are being
141 *                                    passed.
142 *              *ReturnObject       - Where to put method's return value (if
143 *                                    any).  If NULL, no value is returned.
144 *
145 * RETURN:      Status
146 *
147 * DESCRIPTION: Find and evaluate the given object, passing the given
148 *              parameters if necessary.  One of "Handle" or "Pathname" must
149 *              be valid (non-null)
150 *
151 ******************************************************************************/
152
153ACPI_STATUS
154AcpiEvaluateObject (
155    ACPI_HANDLE             Handle,
156    ACPI_STRING             Pathname,
157    ACPI_OBJECT_LIST        *ParamObjects,
158    ACPI_BUFFER             *ReturnBuffer)
159{
160    ACPI_STATUS             Status;
161    ACPI_OPERAND_OBJECT     **ParamPtr = NULL;
162    ACPI_OPERAND_OBJECT     *ReturnObj = NULL;
163    ACPI_OPERAND_OBJECT     *ObjectPtr = NULL;
164    UINT32                  BufferSpaceNeeded;
165    UINT32                  UserBufferLength;
166    UINT32                  Count;
167    UINT32                  i;
168    UINT32                  ParamLength;
169    UINT32                  ObjectLength;
170
171
172    FUNCTION_TRACE ("AcpiEvaluateObject");
173
174
175    /*
176     * If there are parameters to be passed to the object
177     * (which must be a control method), the external objects
178     * must be converted to internal objects
179     */
180
181    if (ParamObjects && ParamObjects->Count)
182    {
183        /*
184         * Allocate a new parameter block for the internal objects
185         * Add 1 to count to allow for null terminated internal list
186         */
187
188        Count           = ParamObjects->Count;
189        ParamLength     = (Count + 1) * sizeof (void *);
190        ObjectLength    = Count * sizeof (ACPI_OPERAND_OBJECT);
191
192        ParamPtr = AcpiCmCallocate (ParamLength +   /* Parameter List part */
193                                    ObjectLength);  /* Actual objects */
194        if (!ParamPtr)
195        {
196            return_ACPI_STATUS (AE_NO_MEMORY);
197        }
198
199        ObjectPtr = (ACPI_OPERAND_OBJECT  *) ((UINT8 *) ParamPtr +
200                        ParamLength);
201
202        /*
203         * Init the param array of pointers and NULL terminate
204         * the list
205         */
206
207        for (i = 0; i < Count; i++)
208        {
209            ParamPtr[i] = &ObjectPtr[i];
210            AcpiCmInitStaticObject (&ObjectPtr[i]);
211        }
212        ParamPtr[Count] = NULL;
213
214        /*
215         * Convert each external object in the list to an
216         * internal object
217         */
218        for (i = 0; i < Count; i++)
219        {
220            Status =
221                AcpiCmBuildInternalObject (&ParamObjects->Pointer[i],
222                                            ParamPtr[i]);
223
224            if (ACPI_FAILURE (Status))
225            {
226                AcpiCmDeleteInternalObjectList (ParamPtr);
227                return_ACPI_STATUS (Status);
228            }
229        }
230    }
231
232
233    /*
234     * Three major cases:
235     * 1) Fully qualified pathname
236     * 2) No handle, not fully qualified pathname (error)
237     * 3) Valid handle
238     */
239
240    if ((Pathname) &&
241        (AcpiNsValidRootPrefix (Pathname[0])))
242    {
243        /*
244         *  The path is fully qualified, just evaluate by name
245         */
246        Status = AcpiNsEvaluateByName (Pathname, ParamPtr, &ReturnObj);
247    }
248
249    else if (!Handle)
250    {
251        /*
252         * A handle is optional iff a fully qualified pathname
253         * is specified.  Since we've already handled fully
254         * qualified names above, this is an error
255         */
256
257        if (!Pathname)
258        {
259            DEBUG_PRINT (ACPI_ERROR,
260                ("AcpiEvaluateObject: Both Handle and Pathname are NULL\n"));
261        }
262
263        else
264        {
265            DEBUG_PRINT (ACPI_ERROR,
266                ("AcpiEvaluateObject: Handle is NULL and Pathname is relative\n"));
267        }
268
269        Status = AE_BAD_PARAMETER;
270    }
271
272    else
273    {
274        /*
275         * We get here if we have a handle -- and if we have a
276         * pathname it is relative.  The handle will be validated
277         * in the lower procedures
278         */
279
280        if (!Pathname)
281        {
282            /*
283             * The null pathname case means the handle is for
284             * the actual object to be evaluated
285             */
286            Status = AcpiNsEvaluateByHandle (Handle, ParamPtr, &ReturnObj);
287        }
288
289        else
290        {
291           /*
292            * Both a Handle and a relative Pathname
293            */
294            Status = AcpiNsEvaluateRelative (Handle, Pathname, ParamPtr,
295                                                &ReturnObj);
296        }
297    }
298
299
300    /*
301     * If we are expecting a return value, and all went well above,
302     * copy the return value to an external object.
303     */
304
305    if (ReturnBuffer)
306    {
307        UserBufferLength = ReturnBuffer->Length;
308        ReturnBuffer->Length = 0;
309
310        if (ReturnObj)
311        {
312            if (VALID_DESCRIPTOR_TYPE (ReturnObj, ACPI_DESC_TYPE_NAMED))
313            {
314                /*
315                 * If we got an Node as a return object,
316                 * this means the object we are evaluating
317                 * has nothing interesting to return (such
318                 * as a mutex, etc.)  We return an error
319                 * because these types are essentially
320                 * unsupported by this interface.  We
321                 * don't check up front because this makes
322                 * it easier to add support for various
323                 * types at a later date if necessary.
324                 */
325                Status = AE_TYPE;
326                ReturnObj = NULL;   /* No need to delete an Node */
327            }
328
329            if (ACPI_SUCCESS (Status))
330            {
331                /*
332                 * Find out how large a buffer is needed
333                 * to contain the returned object
334                 */
335                Status = AcpiCmGetObjectSize (ReturnObj,
336                                                &BufferSpaceNeeded);
337                if (ACPI_SUCCESS (Status))
338                {
339                    /*
340                     * Check if there is enough room in the
341                     * caller's buffer
342                     */
343
344                    if (UserBufferLength < BufferSpaceNeeded)
345                    {
346                        /*
347                         * Caller's buffer is too small, can't
348                         * give him partial results fail the call
349                         * but return the buffer size needed
350                         */
351
352                        DEBUG_PRINT (ACPI_INFO,
353                            ("AcpiEvaluateObject: Needed buffer size %d, received %d\n",
354                            BufferSpaceNeeded, UserBufferLength));
355
356                        ReturnBuffer->Length = BufferSpaceNeeded;
357                        Status = AE_BUFFER_OVERFLOW;
358                    }
359
360                    else
361                    {
362                        /*
363                         *  We have enough space for the object, build it
364                         */
365                        Status = AcpiCmBuildExternalObject (ReturnObj,
366                                        ReturnBuffer);
367                        ReturnBuffer->Length = BufferSpaceNeeded;
368                    }
369                }
370            }
371        }
372    }
373
374
375    /* Delete the return and parameter objects */
376
377    if (ReturnObj)
378    {
379        /*
380         * Delete the internal return object. (Or at least
381         * decrement the reference count by one)
382         */
383        AcpiCmRemoveReference (ReturnObj);
384    }
385
386    /*
387     * Free the input parameter list (if we created one),
388     */
389
390    if (ParamPtr)
391    {
392        /* Free the allocated parameter block */
393
394        AcpiCmDeleteInternalObjectList (ParamPtr);
395    }
396
397    return_ACPI_STATUS (Status);
398}
399
400
401/*******************************************************************************
402 *
403 * FUNCTION:    AcpiGetNextObject
404 *
405 * PARAMETERS:  Type            - Type of object to be searched for
406 *              Parent          - Parent object whose children we are getting
407 *              LastChild       - Previous child that was found.
408 *                                The NEXT child will be returned
409 *              RetHandle       - Where handle to the next object is placed
410 *
411 * RETURN:      Status
412 *
413 * DESCRIPTION: Return the next peer object within the namespace.  If Handle is
414 *              valid, Scope is ignored.  Otherwise, the first object within
415 *              Scope is returned.
416 *
417 ******************************************************************************/
418
419ACPI_STATUS
420AcpiGetNextObject (
421    ACPI_OBJECT_TYPE        Type,
422    ACPI_HANDLE             Parent,
423    ACPI_HANDLE             Child,
424    ACPI_HANDLE             *RetHandle)
425{
426    ACPI_STATUS             Status = AE_OK;
427    ACPI_NAMESPACE_NODE     *Node;
428    ACPI_NAMESPACE_NODE     *ParentNode = NULL;
429    ACPI_NAMESPACE_NODE     *ChildNode = NULL;
430
431
432    /* Parameter validation */
433
434    if (Type > ACPI_TYPE_MAX)
435    {
436        return (AE_BAD_PARAMETER);
437    }
438
439    AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE);
440
441    /* If null handle, use the parent */
442
443    if (!Child)
444    {
445        /* Start search at the beginning of the specified scope */
446
447        ParentNode = AcpiNsConvertHandleToEntry (Parent);
448        if (!ParentNode)
449        {
450            Status = AE_BAD_PARAMETER;
451            goto UnlockAndExit;
452        }
453    }
454
455    /* Non-null handle, ignore the parent */
456
457    else
458    {
459        /* Convert and validate the handle */
460
461        ChildNode = AcpiNsConvertHandleToEntry (Child);
462        if (!ChildNode)
463        {
464            Status = AE_BAD_PARAMETER;
465            goto UnlockAndExit;
466        }
467    }
468
469
470    /* Internal function does the real work */
471
472    Node = AcpiNsGetNextObject ((OBJECT_TYPE_INTERNAL) Type,
473                                    ParentNode, ChildNode);
474    if (!Node)
475    {
476        Status = AE_NOT_FOUND;
477        goto UnlockAndExit;
478    }
479
480    if (RetHandle)
481    {
482        *RetHandle = AcpiNsConvertEntryToHandle (Node);
483    }
484
485
486UnlockAndExit:
487
488    AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
489    return (Status);
490}
491
492
493/*******************************************************************************
494 *
495 * FUNCTION:    AcpiGetType
496 *
497 * PARAMETERS:  Handle          - Handle of object whose type is desired
498 *              *RetType        - Where the type will be placed
499 *
500 * RETURN:      Status
501 *
502 * DESCRIPTION: This routine returns the type associatd with a particular handle
503 *
504 ******************************************************************************/
505
506ACPI_STATUS
507AcpiGetType (
508    ACPI_HANDLE             Handle,
509    ACPI_OBJECT_TYPE        *RetType)
510{
511    ACPI_NAMESPACE_NODE     *Node;
512
513
514    /* Parameter Validation */
515
516    if (!RetType)
517    {
518        return (AE_BAD_PARAMETER);
519    }
520
521    /*
522     * Special case for the predefined Root Node
523     * (return type ANY)
524     */
525    if (Handle == ACPI_ROOT_OBJECT)
526    {
527        *RetType = ACPI_TYPE_ANY;
528        return (AE_OK);
529    }
530
531    AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE);
532
533    /* Convert and validate the handle */
534
535    Node = AcpiNsConvertHandleToEntry (Handle);
536    if (!Node)
537    {
538        AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
539        return (AE_BAD_PARAMETER);
540    }
541
542    *RetType = Node->Type;
543
544
545    AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
546    return (AE_OK);
547}
548
549
550/*******************************************************************************
551 *
552 * FUNCTION:    AcpiGetParent
553 *
554 * PARAMETERS:  Handle          - Handle of object whose parent is desired
555 *              RetHandle       - Where the parent handle will be placed
556 *
557 * RETURN:      Status
558 *
559 * DESCRIPTION: Returns a handle to the parent of the object represented by
560 *              Handle.
561 *
562 ******************************************************************************/
563
564ACPI_STATUS
565AcpiGetParent (
566    ACPI_HANDLE             Handle,
567    ACPI_HANDLE             *RetHandle)
568{
569    ACPI_NAMESPACE_NODE     *Node;
570    ACPI_STATUS             Status = AE_OK;
571
572
573    /* No trace macro, too verbose */
574
575
576    if (!RetHandle)
577    {
578        return (AE_BAD_PARAMETER);
579    }
580
581    /* Special case for the predefined Root Node (no parent) */
582
583    if (Handle == ACPI_ROOT_OBJECT)
584    {
585        return (AE_NULL_ENTRY);
586    }
587
588
589    AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE);
590
591    /* Convert and validate the handle */
592
593    Node = AcpiNsConvertHandleToEntry (Handle);
594    if (!Node)
595    {
596        Status = AE_BAD_PARAMETER;
597        goto UnlockAndExit;
598    }
599
600
601    /* Get the parent entry */
602
603    *RetHandle =
604        AcpiNsConvertEntryToHandle (AcpiNsGetParentObject (Node));
605
606    /* Return exeption if parent is null */
607
608    if (!AcpiNsGetParentObject (Node))
609    {
610        Status = AE_NULL_ENTRY;
611    }
612
613
614UnlockAndExit:
615
616    AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
617    return (Status);
618}
619
620
621/*******************************************************************************
622 *
623 * FUNCTION:    AcpiWalkNamespace
624 *
625 * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
626 *              StartObject         - Handle in namespace where search begins
627 *              MaxDepth            - Depth to which search is to reach
628 *              UserFunction        - Called when an object of "Type" is found
629 *              Context             - Passed to user function
630 *              ReturnValue         - Location where return value of
631 *                                    UserFunction is put if terminated early
632 *
633 * RETURNS      Return value from the UserFunction if terminated early.
634 *              Otherwise, returns NULL.
635 *
636 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
637 *              starting (and ending) at the object specified by StartHandle.
638 *              The UserFunction is called whenever an object that matches
639 *              the type parameter is found.  If the user function returns
640 *              a non-zero value, the search is terminated immediately and this
641 *              value is returned to the caller.
642 *
643 *              The point of this procedure is to provide a generic namespace
644 *              walk routine that can be called from multiple places to
645 *              provide multiple services;  the User Function can be tailored
646 *              to each task, whether it is a print function, a compare
647 *              function, etc.
648 *
649 ******************************************************************************/
650
651ACPI_STATUS
652AcpiWalkNamespace (
653    ACPI_OBJECT_TYPE        Type,
654    ACPI_HANDLE             StartObject,
655    UINT32                  MaxDepth,
656    WALK_CALLBACK           UserFunction,
657    void                    *Context,
658    void                    **ReturnValue)
659{
660    ACPI_STATUS             Status;
661
662
663    FUNCTION_TRACE ("AcpiWalkNamespace");
664
665
666    /* Parameter validation */
667
668    if ((Type > ACPI_TYPE_MAX)  ||
669        (!MaxDepth)             ||
670        (!UserFunction))
671    {
672        return_ACPI_STATUS (AE_BAD_PARAMETER);
673    }
674
675    /*
676     * Lock the namespace around the walk.
677     * The namespace will be unlocked/locked around each call
678     * to the user function - since this function
679     * must be allowed to make Acpi calls itself.
680     */
681
682    AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE);
683    Status = AcpiNsWalkNamespace ((OBJECT_TYPE_INTERNAL) Type,
684                                    StartObject, MaxDepth,
685                                    NS_WALK_UNLOCK,
686                                    UserFunction, Context,
687                                    ReturnValue);
688
689    AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
690
691    return_ACPI_STATUS (Status);
692}
693
694
695/*******************************************************************************
696 *
697 * FUNCTION:    AcpiNsGetDeviceCallback
698 *
699 * PARAMETERS:  Callback from AcpiGetDevice
700 *
701 * RETURN:      Status
702 *
703 * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
704 *              present devices, or if they specified a HID, it filters based
705 *              on that.
706 *
707 ******************************************************************************/
708
709static ACPI_STATUS
710AcpiNsGetDeviceCallback (
711    ACPI_HANDLE             ObjHandle,
712    UINT32                  NestingLevel,
713    void                    *Context,
714    void                    **ReturnValue)
715{
716    ACPI_STATUS             Status;
717    ACPI_NAMESPACE_NODE     *Node;
718    UINT32                  Flags;
719    DEVICE_ID               DeviceId;
720    ACPI_GET_DEVICES_INFO   *Info;
721
722
723    Info = Context;
724
725    AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE);
726
727    Node = AcpiNsConvertHandleToEntry (ObjHandle);
728    if (!Node)
729    {
730        AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
731        return (AE_BAD_PARAMETER);
732    }
733
734    AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
735
736    /*
737     * Run _STA to determine if device is present
738     */
739
740    Status = AcpiCmExecute_STA (Node, &Flags);
741    if (ACPI_FAILURE (Status))
742    {
743        return (Status);
744    }
745
746    if (!(Flags & 0x01))
747    {
748        /* don't return at the device or children of the device if not there */
749
750        return (AE_CTRL_DEPTH);
751    }
752
753    /*
754     * Filter based on device HID
755     */
756    if (Info->Hid != NULL)
757    {
758        Status = AcpiCmExecute_HID (Node, &DeviceId);
759
760        if (Status == AE_NOT_FOUND)
761        {
762            return (AE_OK);
763        }
764
765        else if (ACPI_FAILURE (Status))
766        {
767            return (Status);
768        }
769
770        if (STRNCMP (DeviceId.Buffer, Info->Hid, sizeof (DeviceId.Buffer)) != 0)
771        {
772            return (AE_OK);
773        }
774    }
775
776    Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue);
777
778    return (AE_OK);
779}
780
781
782/*******************************************************************************
783 *
784 * FUNCTION:    AcpiGetDevices
785 *
786 * PARAMETERS:  HID                 - HID to search for. Can be NULL.
787 *              UserFunction        - Called when a matching object is found
788 *              Context             - Passed to user function
789 *              ReturnValue         - Location where return value of
790 *                                    UserFunction is put if terminated early
791 *
792 * RETURNS      Return value from the UserFunction if terminated early.
793 *              Otherwise, returns NULL.
794 *
795 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
796 *              starting (and ending) at the object specified by StartHandle.
797 *              The UserFunction is called whenever an object that matches
798 *              the type parameter is found.  If the user function returns
799 *              a non-zero value, the search is terminated immediately and this
800 *              value is returned to the caller.
801 *
802 *              This is a wrapper for WalkNamespace, but the callback performs
803 *              additional filtering. Please see AcpiGetDeviceCallback.
804 *
805 ******************************************************************************/
806
807ACPI_STATUS
808AcpiGetDevices (
809    NATIVE_CHAR             *HID,
810    WALK_CALLBACK           UserFunction,
811    void                    *Context,
812    void                    **ReturnValue)
813{
814    ACPI_STATUS             Status;
815    ACPI_GET_DEVICES_INFO   Info;
816
817
818    FUNCTION_TRACE ("AcpiGetDevices");
819
820
821    /* Parameter validation */
822
823    if (!UserFunction)
824    {
825        return_ACPI_STATUS (AE_BAD_PARAMETER);
826    }
827
828    /*
829     * We're going to call their callback from OUR callback, so we need
830     * to know what it is, and their context parameter.
831     */
832    Info.Context      = Context;
833    Info.UserFunction = UserFunction;
834    Info.Hid          = HID;
835
836    /*
837     * Lock the namespace around the walk.
838     * The namespace will be unlocked/locked around each call
839     * to the user function - since this function
840     * must be allowed to make Acpi calls itself.
841     */
842
843    AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE);
844    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE,
845                                    ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
846                                    NS_WALK_UNLOCK,
847                                    AcpiNsGetDeviceCallback, &Info,
848                                    ReturnValue);
849
850    AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
851
852    return_ACPI_STATUS (Status);
853}