nsxfobj.c revision 67754
12SN/A/*******************************************************************************
26SN/A *
32SN/A * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
42SN/A *                         ACPI Object oriented interfaces
52SN/A *              $Revision: 74 $
62SN/A *
72SN/A ******************************************************************************/
82SN/A
92SN/A/******************************************************************************
102SN/A *
112SN/A * 1. Copyright Notice
122SN/A *
132SN/A * Some or all of this work - Copyright (c) 1999, Intel Corp.  All rights
142SN/A * reserved.
152SN/A *
162SN/A * 2. License
172SN/A *
182SN/A * 2.1. This is your license from Intel Corp. under its intellectual property
192SN/A * rights.  You may have additional license terms from the party that provided
202SN/A * you this software, covering your right to use that party's intellectual
212SN/A * property rights.
222SN/A *
232SN/A * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
242SN/A * copy of the source code appearing in this file ("Covered Code") an
252SN/A * irrevocable, perpetual, worldwide license under Intel's copyrights in the
262SN/A * base code distributed originally by Intel ("Original Intel Code") to copy,
272SN/A * make derivatives, distribute, use and display any portion of the Covered
282SN/A * Code in any form, with the right to sublicense such rights; and
292SN/A *
301173Sattila * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
312SN/A * license (with the right to sublicense), under only those claims of Intel
321173Sattila * patents that are infringed by the Original Intel Code, to make, use, sell,
33210SN/A * offer to sell, and import the Covered Code and derivative works thereof
342SN/A * solely to the minimum extent necessary to exercise the above copyright
352SN/A * license, and in no event shall the patent license extend to any additions
362SN/A * to or modifications of the Original Intel Code.  No other license or right
372SN/A * is granted directly or by implication, estoppel or otherwise;
382SN/A *
39210SN/A * The above copyright and patent license is granted only if the following
401173Sattila * conditions are met:
411068Sattila *
421068Sattila * 3. Conditions
432SN/A *
44210SN/A * 3.1. Redistribution of Source with Rights to Further Distribute Source.
452SN/A * Redistribution of source code of any substantial portion of the Covered
462SN/A * Code or modification with rights to further distribute source must include
47210SN/A * the above Copyright Notice, the above License, this list of Conditions,
482SN/A * and the following Disclaimer and Export Compliance provision.  In addition,
492SN/A * Licensee must cause all Covered Code to which Licensee contributes to
50210SN/A * contain a file documenting the changes Licensee made to create that Covered
512SN/A * Code and the date of any change.  Licensee must include in that file the
521173Sattila * documentation of any changes made by any predecessor Licensee.  Licensee
531173Sattila * must include a prominent statement that the modification is derived,
541173Sattila * directly or indirectly, from Original Intel Code.
551173Sattila *
561173Sattila * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
571173Sattila * Redistribution of source code of any substantial portion of the Covered
581173Sattila * Code or modification without rights to further distribute source must
591173Sattila * include the following Disclaimer and Export Compliance provision in the
601281Ssundar * documentation and/or other materials provided with distribution.  In
611173Sattila * addition, Licensee may not authorize further sublicense of source of any
621173Sattila * portion of the Covered Code, and must include terms to the effect that the
631173Sattila * license from Licensee to its licensee is limited to the intellectual
641173Sattila * property embodied in the software Licensee provides to its licensee, and
651173Sattila * not to intellectual property embodied in modifications its licensee may
661173Sattila * make.
672SN/A *
681399Sattila * 3.3. Redistribution of Executable. Redistribution in executable form of any
692SN/A * substantial portion of the Covered Code or modification must reproduce the
70850SN/A * above Copyright Notice, and the following Disclaimer and Export Compliance
71850SN/A * provision in the documentation and/or other materials provided with the
722SN/A * distribution.
732SN/A *
742SN/A * 3.4. Intel retains all right, title, and interest in and to the Original
75252SN/A * Intel Code.
76210SN/A *
77210SN/A * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78210SN/A * Intel shall be used in advertising or otherwise to promote the sale, use or
79210SN/A * other dealings in products derived from or relating to the Covered Code
80210SN/A * without prior written authorization from Intel.
812SN/A *
82252SN/A * 4. Disclaimer and Export Compliance
83252SN/A *
84252SN/A * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85210SN/A * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86210SN/A * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87850SN/A * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
881173Sattila * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
891399Sattila * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
902SN/A * PARTICULAR PURPOSE.
912SN/A *
921399Sattila * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
932SN/A * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94252SN/A * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95210SN/A * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96210SN/A * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97850SN/A * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
981173Sattila * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
991399Sattila * LIMITED REMEDY.
1002SN/A *
1012SN/A * 4.3. Licensee shall not export, either directly or indirectly, any of this
1022SN/A * software or system incorporating such software without first obtaining any
103210SN/A * required license or other approval from the U. S. Department of Commerce or
104210SN/A * any other agency or department of the United States Government.  In the
1051399Sattila * event Licensee exports any such software from the United States or
106210SN/A * re-exports any such software from a foreign destination, Licensee shall
107210SN/A * ensure that the distribution and export/re-export of the software is in
108210SN/A * compliance with all laws, regulations, orders, or other restrictions of the
109210SN/A * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110210SN/A * any of its subsidiaries will export/re-export any technical data, process,
111210SN/A * software, or service, directly or indirectly, to any country for which the
112210SN/A * United States government or any agency thereof requires an export license,
113210SN/A * other governmental approval, or letter of assurance, without first obtaining
114210SN/A * such license, approval or letter.
115210SN/A *
116210SN/A *****************************************************************************/
117210SN/A
118210SN/A
1192SN/A#define __NSXFOBJ_C__
1202SN/A
1212SN/A#include "acpi.h"
1222SN/A#include "acinterp.h"
1232SN/A#include "acnamesp.h"
1242SN/A#include "acdispat.h"
1252SN/A
1261304Ssundar
127210SN/A#define _COMPONENT          NAMESPACE
128210SN/A        MODULE_NAME         ("nsxfobj")
129210SN/A
130210SN/A
131210SN/A/*******************************************************************************
1321173Sattila *
1331173Sattila * FUNCTION:    AcpiEvaluateObject
1341173Sattila *
1351173Sattila * PARAMETERS:  Handle              - Object handle (optional)
1362SN/A *              *Pathname           - Object pathname (optional)
1372SN/A *              **Params            - List of parameters to pass to
1382SN/A *                                    method, terminated by NULL.
1392SN/A *                                    Params itself may be NULL
1402SN/A *                                    if no parameters are being
1412SN/A *                                    passed.
142858SN/A *              *ReturnObject       - Where to put method's return value (if
143210SN/A *                                    any).  If NULL, no value is returned.
1442SN/A *
1452SN/A * RETURN:      Status
1462SN/A *
1472SN/A * DESCRIPTION: Find and evaluate the given object, passing the given
1482SN/A *              parameters if necessary.  One of "Handle" or "Pathname" must
1492SN/A *              be valid (non-null)
1502SN/A *
1512SN/A ******************************************************************************/
1522SN/A
1532SN/AACPI_STATUS
1542SN/AAcpiEvaluateObject (
1552SN/A    ACPI_HANDLE             Handle,
1561173Sattila    ACPI_STRING             Pathname,
1572SN/A    ACPI_OBJECT_LIST        *ParamObjects,
158210SN/A    ACPI_BUFFER             *ReturnBuffer)
1592SN/A{
1601173Sattila    ACPI_STATUS             Status;
161210SN/A    ACPI_OPERAND_OBJECT     **ParamPtr = NULL;
162210SN/A    ACPI_OPERAND_OBJECT     *ReturnObj = NULL;
163210SN/A    ACPI_OPERAND_OBJECT     *ObjectPtr = NULL;
1641399Sattila    UINT32                  BufferSpaceNeeded;
1652SN/A    UINT32                  UserBufferLength;
1662SN/A    UINT32                  Count;
1672SN/A    UINT32                  i;
1682SN/A    UINT32                  ParamLength;
1692SN/A    UINT32                  ObjectLength;
1702SN/A
1712SN/A
1722SN/A    FUNCTION_TRACE ("AcpiEvaluateObject");
1732SN/A
174850SN/A
1752SN/A    /*
176210SN/A     * If there are parameters to be passed to the object
177143SN/A     * (which must be a control method), the external objects
178143SN/A     * must be converted to internal objects
179850SN/A     */
180850SN/A
181850SN/A    if (ParamObjects && ParamObjects->Count)
182850SN/A    {
183143SN/A        /*
1842SN/A         * Allocate a new parameter block for the internal objects
1852SN/A         * Add 1 to count to allow for null terminated internal list
1862SN/A         */
1872SN/A
1882SN/A        Count           = ParamObjects->Count;
1892SN/A        ParamLength     = (Count + 1) * sizeof (void *);
1902SN/A        ObjectLength    = Count * sizeof (ACPI_OPERAND_OBJECT);
1912SN/A
1922SN/A        ParamPtr = AcpiCmCallocate (ParamLength +   /* Parameter List part */
1931173Sattila                                    ObjectLength);  /* Actual objects */
1942SN/A        if (!ParamPtr)
195210SN/A        {
1962SN/A            return_ACPI_STATUS (AE_NO_MEMORY);
1971173Sattila        }
198210SN/A
199210SN/A        ObjectPtr = (ACPI_OPERAND_OBJECT  *) ((UINT8 *) ParamPtr +
200210SN/A                        ParamLength);
2011399Sattila
2022SN/A        /*
2032SN/A         * Init the param array of pointers and NULL terminate
2042SN/A         * the list
2052SN/A         */
2062SN/A
2072SN/A        for (i = 0; i < Count; i++)
2082SN/A        {
2092SN/A            ParamPtr[i] = &ObjectPtr[i];
2102SN/A            AcpiCmInitStaticObject (&ObjectPtr[i]);
2112SN/A        }
2122SN/A        ParamPtr[Count] = NULL;
2131399Sattila
2142SN/A        /*
215210SN/A         * Convert each external object in the list to an
2162SN/A         * internal object
2171399Sattila         */
2181399Sattila        for (i = 0; i < Count; i++)
2191399Sattila        {
2201399Sattila            Status =
2211399Sattila                AcpiCmBuildInternalObject (&ParamObjects->Pointer[i],
2222SN/A                                            ParamPtr[i]);
2232SN/A
2242SN/A            if (ACPI_FAILURE (Status))
2252SN/A            {
2262SN/A                AcpiCmDeleteInternalObjectList (ParamPtr);
2272SN/A                return_ACPI_STATUS (Status);
2282SN/A            }
2292SN/A        }
2302SN/A    }
2312SN/A
2322SN/A
2331173Sattila    /*
2341173Sattila     * Three major cases:
2351173Sattila     * 1) Fully qualified pathname
2361173Sattila     * 2) No handle, not fully qualified pathname (error)
2371173Sattila     * 3) Valid handle
2381173Sattila     */
2391173Sattila
2401173Sattila    if ((Pathname) &&
2411173Sattila        (AcpiNsValidRootPrefix (Pathname[0])))
2421173Sattila    {
2431173Sattila        /*
2441173Sattila         *  The path is fully qualified, just evaluate by name
2451173Sattila         */
2461173Sattila        Status = AcpiNsEvaluateByName (Pathname, ParamPtr, &ReturnObj);
2471173Sattila    }
2481173Sattila
2491173Sattila    else if (!Handle)
2501173Sattila    {
2511173Sattila        /*
2521173Sattila         * A handle is optional iff a fully qualified pathname
2531173Sattila         * is specified.  Since we've already handled fully
2541173Sattila         * qualified names above, this is an error
2551173Sattila         */
2561173Sattila
2571173Sattila        if (!Pathname)
2581173Sattila        {
2591173Sattila            DEBUG_PRINT (ACPI_ERROR,
2601173Sattila                ("AcpiEvaluateObject: Both Handle and Pathname are NULL\n"));
2611173Sattila        }
2621173Sattila
2631173Sattila        else
2641173Sattila        {
2651173Sattila            DEBUG_PRINT (ACPI_ERROR,
2661173Sattila                ("AcpiEvaluateObject: Handle is NULL and Pathname is relative\n"));
2671173Sattila        }
2681173Sattila
2691173Sattila        Status = AE_BAD_PARAMETER;
2701173Sattila    }
2711173Sattila
2721173Sattila    else
2731173Sattila    {
2741173Sattila        /*
2752SN/A         * We get here if we have a handle -- and if we have a
2761173Sattila         * pathname it is relative.  The handle will be validated
2772SN/A         * in the lower procedures
278210SN/A         */
2792SN/A
2801173Sattila        if (!Pathname)
281210SN/A        {
282210SN/A            /*
283210SN/A             * The null pathname case means the handle is for
2841399Sattila             * the actual object to be evaluated
2851173Sattila             */
2861173Sattila            Status = AcpiNsEvaluateByHandle (Handle, ParamPtr, &ReturnObj);
2871173Sattila        }
2881173Sattila
2891173Sattila        else
2901173Sattila        {
2911173Sattila           /*
2921173Sattila            * Both a Handle and a relative Pathname
2931173Sattila            */
2941173Sattila            Status = AcpiNsEvaluateRelative (Handle, Pathname, ParamPtr,
2951173Sattila                                                &ReturnObj);
2961173Sattila        }
2971173Sattila    }
2981173Sattila
2991173Sattila
3001399Sattila    /*
3011173Sattila     * If we are expecting a return value, and all went well above,
3021173Sattila     * copy the return value to an external object.
3031173Sattila     */
3041173Sattila
3051173Sattila    if (ReturnBuffer)
3061173Sattila    {
3071173Sattila        UserBufferLength = ReturnBuffer->Length;
3081173Sattila        ReturnBuffer->Length = 0;
3091173Sattila
3101173Sattila        if (ReturnObj)
3111173Sattila        {
3121173Sattila            if (VALID_DESCRIPTOR_TYPE (ReturnObj, ACPI_DESC_TYPE_NAMED))
3131173Sattila            {
314850SN/A                /*
315850SN/A                 * If we got an Node as a return object,
316850SN/A                 * this means the object we are evaluating
317850SN/A                 * has nothing interesting to return (such
318850SN/A                 * as a mutex, etc.)  We return an error
319850SN/A                 * because these types are essentially
320850SN/A                 * unsupported by this interface.  We
3211399Sattila                 * don't check up front because this makes
322850SN/A                 * it easier to add support for various
323850SN/A                 * types at a later date if necessary.
324850SN/A                 */
325850SN/A                Status = AE_TYPE;
326850SN/A                ReturnObj = NULL;   /* No need to delete an Node */
3272SN/A            }
3282SN/A
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}