xref: /titanic_50/usr/src/uts/intel/io/acpica/namespace/nsxfeval.c (revision 30cfc677d581f4c0f5cb44a91fac88545bffccc0)
1 /*******************************************************************************
2  *
3  * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4  *                         ACPI Object evaluation interfaces
5  *              $Revision: 1.33 $
6  *
7  ******************************************************************************/
8 
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2008, 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 __NSXFEVAL_C__
120 
121 #include "acpi.h"
122 #include "acnamesp.h"
123 #include "acinterp.h"
124 
125 
126 #define _COMPONENT          ACPI_NAMESPACE
127         ACPI_MODULE_NAME    ("nsxfeval")
128 
129 /* Local prototypes */
130 
131 static void
132 AcpiNsResolveReferences (
133     ACPI_EVALUATE_INFO      *Info);
134 
135 
136 /*******************************************************************************
137  *
138  * FUNCTION:    AcpiEvaluateObjectTyped
139  *
140  * PARAMETERS:  Handle              - Object handle (optional)
141  *              Pathname            - Object pathname (optional)
142  *              ExternalParams      - List of parameters to pass to method,
143  *                                    terminated by NULL.  May be NULL
144  *                                    if no parameters are being passed.
145  *              ReturnBuffer        - Where to put method's return value (if
146  *                                    any).  If NULL, no value is returned.
147  *              ReturnType          - Expected type of return object
148  *
149  * RETURN:      Status
150  *
151  * DESCRIPTION: Find and evaluate the given object, passing the given
152  *              parameters if necessary.  One of "Handle" or "Pathname" must
153  *              be valid (non-null)
154  *
155  ******************************************************************************/
156 
157 ACPI_STATUS
158 AcpiEvaluateObjectTyped (
159     ACPI_HANDLE             Handle,
160     ACPI_STRING             Pathname,
161     ACPI_OBJECT_LIST        *ExternalParams,
162     ACPI_BUFFER             *ReturnBuffer,
163     ACPI_OBJECT_TYPE        ReturnType)
164 {
165     ACPI_STATUS             Status;
166     BOOLEAN                 MustFree = FALSE;
167 
168 
169     ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
170 
171 
172     /* Return buffer must be valid */
173 
174     if (!ReturnBuffer)
175     {
176         return_ACPI_STATUS (AE_BAD_PARAMETER);
177     }
178 
179     if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
180     {
181         MustFree = TRUE;
182     }
183 
184     /* Evaluate the object */
185 
186     Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
187     if (ACPI_FAILURE (Status))
188     {
189         return_ACPI_STATUS (Status);
190     }
191 
192     /* Type ANY means "don't care" */
193 
194     if (ReturnType == ACPI_TYPE_ANY)
195     {
196         return_ACPI_STATUS (AE_OK);
197     }
198 
199     if (ReturnBuffer->Length == 0)
200     {
201         /* Error because caller specifically asked for a return value */
202 
203         ACPI_ERROR ((AE_INFO, "No return value"));
204         return_ACPI_STATUS (AE_NULL_OBJECT);
205     }
206 
207     /* Examine the object type returned from EvaluateObject */
208 
209     if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
210     {
211         return_ACPI_STATUS (AE_OK);
212     }
213 
214     /* Return object type does not match requested type */
215 
216     ACPI_ERROR ((AE_INFO,
217         "Incorrect return type [%s] requested [%s]",
218         AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
219         AcpiUtGetTypeName (ReturnType)));
220 
221     if (MustFree)
222     {
223         /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
224 
225         AcpiOsFree (ReturnBuffer->Pointer);
226         ReturnBuffer->Pointer = NULL;
227     }
228 
229     ReturnBuffer->Length = 0;
230     return_ACPI_STATUS (AE_TYPE);
231 }
232 
233 ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
234 
235 
236 /*******************************************************************************
237  *
238  * FUNCTION:    AcpiEvaluateObject
239  *
240  * PARAMETERS:  Handle              - Object handle (optional)
241  *              Pathname            - Object pathname (optional)
242  *              ExternalParams      - List of parameters to pass to method,
243  *                                    terminated by NULL.  May be NULL
244  *                                    if no parameters are being passed.
245  *              ReturnBuffer        - Where to put method's return value (if
246  *                                    any).  If NULL, no value is returned.
247  *
248  * RETURN:      Status
249  *
250  * DESCRIPTION: Find and evaluate the given object, passing the given
251  *              parameters if necessary.  One of "Handle" or "Pathname" must
252  *              be valid (non-null)
253  *
254  ******************************************************************************/
255 
256 ACPI_STATUS
257 AcpiEvaluateObject (
258     ACPI_HANDLE             Handle,
259     ACPI_STRING             Pathname,
260     ACPI_OBJECT_LIST        *ExternalParams,
261     ACPI_BUFFER             *ReturnBuffer)
262 {
263     ACPI_STATUS             Status;
264     ACPI_EVALUATE_INFO      *Info;
265     ACPI_SIZE               BufferSpaceNeeded;
266     UINT32                  i;
267 
268 
269     ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
270 
271 
272     /* Allocate and initialize the evaluation information block */
273 
274     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
275     if (!Info)
276     {
277         return_ACPI_STATUS (AE_NO_MEMORY);
278     }
279 
280     Info->Pathname = Pathname;
281 
282     /* Convert and validate the device handle */
283 
284     Info->PrefixNode = AcpiNsMapHandleToNode (Handle);
285     if (!Info->PrefixNode)
286     {
287         Status = AE_BAD_PARAMETER;
288         goto Cleanup;
289     }
290 
291     /*
292      * If there are parameters to be passed to a control method, the external
293      * objects must all be converted to internal objects
294      */
295     if (ExternalParams && ExternalParams->Count)
296     {
297         /*
298          * Allocate a new parameter block for the internal objects
299          * Add 1 to count to allow for null terminated internal list
300          */
301         Info->Parameters = ACPI_ALLOCATE_ZEROED (
302             ((ACPI_SIZE) ExternalParams->Count + 1) * sizeof (void *));
303         if (!Info->Parameters)
304         {
305             Status = AE_NO_MEMORY;
306             goto Cleanup;
307         }
308 
309         /* Convert each external object in the list to an internal object */
310 
311         for (i = 0; i < ExternalParams->Count; i++)
312         {
313             Status = AcpiUtCopyEobjectToIobject (
314                         &ExternalParams->Pointer[i], &Info->Parameters[i]);
315             if (ACPI_FAILURE (Status))
316             {
317                 goto Cleanup;
318             }
319         }
320         Info->Parameters[ExternalParams->Count] = NULL;
321     }
322 
323     /*
324      * Three major cases:
325      * 1) Fully qualified pathname
326      * 2) No handle, not fully qualified pathname (error)
327      * 3) Valid handle
328      */
329     if ((Pathname) &&
330         (AcpiNsValidRootPrefix (Pathname[0])))
331     {
332         /* The path is fully qualified, just evaluate by name */
333 
334         Info->PrefixNode = NULL;
335         Status = AcpiNsEvaluate (Info);
336     }
337     else if (!Handle)
338     {
339         /*
340          * A handle is optional iff a fully qualified pathname is specified.
341          * Since we've already handled fully qualified names above, this is
342          * an error
343          */
344         if (!Pathname)
345         {
346             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
347                 "Both Handle and Pathname are NULL"));
348         }
349         else
350         {
351             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
352                 "Null Handle with relative pathname [%s]", Pathname));
353         }
354 
355         Status = AE_BAD_PARAMETER;
356     }
357     else
358     {
359         /* We have a namespace a node and a possible relative path */
360 
361         Status = AcpiNsEvaluate (Info);
362     }
363 
364     /*
365      * If we are expecting a return value, and all went well above,
366      * copy the return value to an external object.
367      */
368     if (ReturnBuffer)
369     {
370         if (!Info->ReturnObject)
371         {
372             ReturnBuffer->Length = 0;
373         }
374         else
375         {
376             if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
377                 ACPI_DESC_TYPE_NAMED)
378             {
379                 /*
380                  * If we received a NS Node as a return object, this means that
381                  * the object we are evaluating has nothing interesting to
382                  * return (such as a mutex, etc.)  We return an error because
383                  * these types are essentially unsupported by this interface.
384                  * We don't check up front because this makes it easier to add
385                  * support for various types at a later date if necessary.
386                  */
387                 Status = AE_TYPE;
388                 Info->ReturnObject = NULL;   /* No need to delete a NS Node */
389                 ReturnBuffer->Length = 0;
390             }
391 
392             if (ACPI_SUCCESS (Status))
393             {
394                 /* Dereference Index and RefOf references */
395 
396                 AcpiNsResolveReferences (Info);
397 
398                 /* Get the size of the returned object */
399 
400                 Status = AcpiUtGetObjectSize (Info->ReturnObject,
401                             &BufferSpaceNeeded);
402                 if (ACPI_SUCCESS (Status))
403                 {
404                     /* Validate/Allocate/Clear caller buffer */
405 
406                     Status = AcpiUtInitializeBuffer (ReturnBuffer,
407                                 BufferSpaceNeeded);
408                     if (ACPI_FAILURE (Status))
409                     {
410                         /*
411                          * Caller's buffer is too small or a new one can't
412                          * be allocated
413                          */
414                         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
415                             "Needed buffer size %X, %s\n",
416                             (UINT32) BufferSpaceNeeded,
417                             AcpiFormatException (Status)));
418                     }
419                     else
420                     {
421                         /* We have enough space for the object, build it */
422 
423                         Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject,
424                                     ReturnBuffer);
425                     }
426                 }
427             }
428         }
429     }
430 
431     if (Info->ReturnObject)
432     {
433         /*
434          * Delete the internal return object. NOTE: Interpreter must be
435          * locked to avoid race condition.
436          */
437         AcpiExEnterInterpreter ();
438 
439         /* Remove one reference on the return object (should delete it) */
440 
441         AcpiUtRemoveReference (Info->ReturnObject);
442         AcpiExExitInterpreter ();
443     }
444 
445 
446 Cleanup:
447 
448     /* Free the input parameter list (if we created one) */
449 
450     if (Info->Parameters)
451     {
452         /* Free the allocated parameter block */
453 
454         AcpiUtDeleteInternalObjectList (Info->Parameters);
455     }
456 
457     ACPI_FREE (Info);
458     return_ACPI_STATUS (Status);
459 }
460 
461 ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
462 
463 
464 /*******************************************************************************
465  *
466  * FUNCTION:    AcpiNsResolveReferences
467  *
468  * PARAMETERS:  Info                    - Evaluation info block
469  *
470  * RETURN:      Info->ReturnObject is replaced with the dereferenced object
471  *
472  * DESCRIPTION: Dereference certain reference objects. Called before an
473  *              internal return object is converted to an external ACPI_OBJECT.
474  *
475  * Performs an automatic dereference of Index and RefOf reference objects.
476  * These reference objects are not supported by the ACPI_OBJECT, so this is a
477  * last resort effort to return something useful. Also, provides compatibility
478  * with other ACPI implementations.
479  *
480  * NOTE: does not handle references within returned package objects or nested
481  * references, but this support could be added later if found to be necessary.
482  *
483  ******************************************************************************/
484 
485 static void
486 AcpiNsResolveReferences (
487     ACPI_EVALUATE_INFO      *Info)
488 {
489     ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
490     ACPI_NAMESPACE_NODE     *Node;
491 
492 
493     /* We are interested in reference objects only */
494 
495     if (ACPI_GET_OBJECT_TYPE (Info->ReturnObject) != ACPI_TYPE_LOCAL_REFERENCE)
496     {
497         return;
498     }
499 
500     /*
501      * Two types of references are supported - those created by Index and
502      * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
503      * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
504      * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
505      * an ACPI_OBJECT.
506      */
507     switch (Info->ReturnObject->Reference.Class)
508     {
509     case ACPI_REFCLASS_INDEX:
510 
511         ObjDesc = *(Info->ReturnObject->Reference.Where);
512         break;
513 
514     case ACPI_REFCLASS_REFOF:
515 
516         Node = Info->ReturnObject->Reference.Object;
517         if (Node)
518         {
519             ObjDesc = Node->Object;
520         }
521         break;
522 
523     default:
524         return;
525     }
526 
527     /* Replace the existing reference object */
528 
529     if (ObjDesc)
530     {
531         AcpiUtAddReference (ObjDesc);
532         AcpiUtRemoveReference (Info->ReturnObject);
533         Info->ReturnObject = ObjDesc;
534     }
535 
536     return;
537 }
538 
539 
540 /*******************************************************************************
541  *
542  * FUNCTION:    AcpiWalkNamespace
543  *
544  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
545  *              StartObject         - Handle in namespace where search begins
546  *              MaxDepth            - Depth to which search is to reach
547  *              UserFunction        - Called when an object of "Type" is found
548  *              Context             - Passed to user function
549  *              ReturnValue         - Location where return value of
550  *                                    UserFunction is put if terminated early
551  *
552  * RETURNS      Return value from the UserFunction if terminated early.
553  *              Otherwise, returns NULL.
554  *
555  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
556  *              starting (and ending) at the object specified by StartHandle.
557  *              The UserFunction is called whenever an object that matches
558  *              the type parameter is found.  If the user function returns
559  *              a non-zero value, the search is terminated immediately and this
560  *              value is returned to the caller.
561  *
562  *              The point of this procedure is to provide a generic namespace
563  *              walk routine that can be called from multiple places to
564  *              provide multiple services;  the User Function can be tailored
565  *              to each task, whether it is a print function, a compare
566  *              function, etc.
567  *
568  ******************************************************************************/
569 
570 ACPI_STATUS
571 AcpiWalkNamespace (
572     ACPI_OBJECT_TYPE        Type,
573     ACPI_HANDLE             StartObject,
574     UINT32                  MaxDepth,
575     ACPI_WALK_CALLBACK      UserFunction,
576     void                    *Context,
577     void                    **ReturnValue)
578 {
579     ACPI_STATUS             Status;
580 
581 
582     ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
583 
584 
585     /* Parameter validation */
586 
587     if ((Type > ACPI_TYPE_LOCAL_MAX) ||
588         (!MaxDepth)                  ||
589         (!UserFunction))
590     {
591         return_ACPI_STATUS (AE_BAD_PARAMETER);
592     }
593 
594     /*
595      * Lock the namespace around the walk.
596      * The namespace will be unlocked/locked around each call
597      * to the user function - since this function
598      * must be allowed to make Acpi calls itself.
599      */
600     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
601     if (ACPI_FAILURE (Status))
602     {
603         return_ACPI_STATUS (Status);
604     }
605 
606     Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
607                     ACPI_NS_WALK_UNLOCK,
608                     UserFunction, Context, ReturnValue);
609 
610     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
611     return_ACPI_STATUS (Status);
612 }
613 
614 ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
615 
616 
617 /*******************************************************************************
618  *
619  * FUNCTION:    AcpiNsGetDeviceCallback
620  *
621  * PARAMETERS:  Callback from AcpiGetDevice
622  *
623  * RETURN:      Status
624  *
625  * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
626  *              present devices, or if they specified a HID, it filters based
627  *              on that.
628  *
629  ******************************************************************************/
630 
631 static ACPI_STATUS
632 AcpiNsGetDeviceCallback (
633     ACPI_HANDLE             ObjHandle,
634     UINT32                  NestingLevel,
635     void                    *Context,
636     void                    **ReturnValue)
637 {
638     ACPI_GET_DEVICES_INFO   *Info = Context;
639     ACPI_STATUS             Status;
640     ACPI_NAMESPACE_NODE     *Node;
641     UINT32                  Flags;
642     ACPI_DEVICE_ID          Hid;
643     ACPI_COMPATIBLE_ID_LIST *Cid;
644     UINT32                  i;
645     BOOLEAN                 Found;
646 
647 
648     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
649     if (ACPI_FAILURE (Status))
650     {
651         return (Status);
652     }
653 
654     Node = AcpiNsMapHandleToNode (ObjHandle);
655     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
656     if (ACPI_FAILURE (Status))
657     {
658         return (Status);
659     }
660 
661     if (!Node)
662     {
663         return (AE_BAD_PARAMETER);
664     }
665 
666     /* Run _STA to determine if device is present */
667 
668     Status = AcpiUtExecute_STA (Node, &Flags);
669     if (ACPI_FAILURE (Status))
670     {
671         return (AE_CTRL_DEPTH);
672     }
673 
674     if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
675         !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
676     {
677         /*
678          * Don't examine the children of the device only when the
679          * device is neither present nor functional. See ACPI spec,
680          * description of _STA for more information.
681          */
682         return (AE_CTRL_DEPTH);
683     }
684 
685     /* Filter based on device HID & CID */
686 
687     if (Info->Hid != NULL)
688     {
689         Status = AcpiUtExecute_HID (Node, &Hid);
690         if (Status == AE_NOT_FOUND)
691         {
692             return (AE_OK);
693         }
694         else if (ACPI_FAILURE (Status))
695         {
696             return (AE_CTRL_DEPTH);
697         }
698 
699         if (ACPI_STRNCMP (Hid.Value, Info->Hid, sizeof (Hid.Value)) != 0)
700         {
701             /*
702              * HID does not match, attempt match within the
703              * list of Compatible IDs (CIDs)
704              */
705             Status = AcpiUtExecute_CID (Node, &Cid);
706             if (Status == AE_NOT_FOUND)
707             {
708                 return (AE_OK);
709             }
710             else if (ACPI_FAILURE (Status))
711             {
712                 return (AE_CTRL_DEPTH);
713             }
714 
715             /* Walk the CID list */
716 
717             Found = FALSE;
718             for (i = 0; i < Cid->Count; i++)
719             {
720                 if (ACPI_STRNCMP (Cid->Id[i].Value, Info->Hid,
721                         sizeof (ACPI_COMPATIBLE_ID)) == 0)
722                 {
723                     /* Found a matching CID */
724 
725                     Found = TRUE;
726                     break;
727                 }
728             }
729 
730             ACPI_FREE (Cid);
731             if (!Found)
732             {
733                 return (AE_OK);
734             }
735         }
736     }
737 
738     /* We have a valid device, invoke the user function */
739 
740     Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
741                 ReturnValue);
742     return (Status);
743 }
744 
745 
746 /*******************************************************************************
747  *
748  * FUNCTION:    AcpiGetDevices
749  *
750  * PARAMETERS:  HID                 - HID to search for. Can be NULL.
751  *              UserFunction        - Called when a matching object is found
752  *              Context             - Passed to user function
753  *              ReturnValue         - Location where return value of
754  *                                    UserFunction is put if terminated early
755  *
756  * RETURNS      Return value from the UserFunction if terminated early.
757  *              Otherwise, returns NULL.
758  *
759  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
760  *              starting (and ending) at the object specified by StartHandle.
761  *              The UserFunction is called whenever an object of type
762  *              Device is found.  If the user function returns
763  *              a non-zero value, the search is terminated immediately and this
764  *              value is returned to the caller.
765  *
766  *              This is a wrapper for WalkNamespace, but the callback performs
767  *              additional filtering. Please see AcpiNsGetDeviceCallback.
768  *
769  ******************************************************************************/
770 
771 ACPI_STATUS
772 AcpiGetDevices (
773     char                    *HID,
774     ACPI_WALK_CALLBACK      UserFunction,
775     void                    *Context,
776     void                    **ReturnValue)
777 {
778     ACPI_STATUS             Status;
779     ACPI_GET_DEVICES_INFO   Info;
780 
781 
782     ACPI_FUNCTION_TRACE (AcpiGetDevices);
783 
784 
785     /* Parameter validation */
786 
787     if (!UserFunction)
788     {
789         return_ACPI_STATUS (AE_BAD_PARAMETER);
790     }
791 
792     /*
793      * We're going to call their callback from OUR callback, so we need
794      * to know what it is, and their context parameter.
795      */
796     Info.Hid          = HID;
797     Info.Context      = Context;
798     Info.UserFunction = UserFunction;
799 
800     /*
801      * Lock the namespace around the walk.
802      * The namespace will be unlocked/locked around each call
803      * to the user function - since this function
804      * must be allowed to make Acpi calls itself.
805      */
806     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
807     if (ACPI_FAILURE (Status))
808     {
809         return_ACPI_STATUS (Status);
810     }
811 
812     Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
813                 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
814                 AcpiNsGetDeviceCallback, &Info, ReturnValue);
815 
816     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
817     return_ACPI_STATUS (Status);
818 }
819 
820 ACPI_EXPORT_SYMBOL (AcpiGetDevices)
821 
822 
823 /*******************************************************************************
824  *
825  * FUNCTION:    AcpiAttachData
826  *
827  * PARAMETERS:  ObjHandle           - Namespace node
828  *              Handler             - Handler for this attachment
829  *              Data                - Pointer to data to be attached
830  *
831  * RETURN:      Status
832  *
833  * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
834  *
835  ******************************************************************************/
836 
837 ACPI_STATUS
838 AcpiAttachData (
839     ACPI_HANDLE             ObjHandle,
840     ACPI_OBJECT_HANDLER     Handler,
841     void                    *Data)
842 {
843     ACPI_NAMESPACE_NODE     *Node;
844     ACPI_STATUS             Status;
845 
846 
847     /* Parameter validation */
848 
849     if (!ObjHandle  ||
850         !Handler    ||
851         !Data)
852     {
853         return (AE_BAD_PARAMETER);
854     }
855 
856     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
857     if (ACPI_FAILURE (Status))
858     {
859         return (Status);
860     }
861 
862     /* Convert and validate the handle */
863 
864     Node = AcpiNsMapHandleToNode (ObjHandle);
865     if (!Node)
866     {
867         Status = AE_BAD_PARAMETER;
868         goto UnlockAndExit;
869     }
870 
871     Status = AcpiNsAttachData (Node, Handler, Data);
872 
873 UnlockAndExit:
874     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
875     return (Status);
876 }
877 
878 ACPI_EXPORT_SYMBOL (AcpiAttachData)
879 
880 
881 /*******************************************************************************
882  *
883  * FUNCTION:    AcpiDetachData
884  *
885  * PARAMETERS:  ObjHandle           - Namespace node handle
886  *              Handler             - Handler used in call to AcpiAttachData
887  *
888  * RETURN:      Status
889  *
890  * DESCRIPTION: Remove data that was previously attached to a node.
891  *
892  ******************************************************************************/
893 
894 ACPI_STATUS
895 AcpiDetachData (
896     ACPI_HANDLE             ObjHandle,
897     ACPI_OBJECT_HANDLER     Handler)
898 {
899     ACPI_NAMESPACE_NODE     *Node;
900     ACPI_STATUS             Status;
901 
902 
903     /* Parameter validation */
904 
905     if (!ObjHandle  ||
906         !Handler)
907     {
908         return (AE_BAD_PARAMETER);
909     }
910 
911     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
912     if (ACPI_FAILURE (Status))
913     {
914         return (Status);
915     }
916 
917     /* Convert and validate the handle */
918 
919     Node = AcpiNsMapHandleToNode (ObjHandle);
920     if (!Node)
921     {
922         Status = AE_BAD_PARAMETER;
923         goto UnlockAndExit;
924     }
925 
926     Status = AcpiNsDetachData (Node, Handler);
927 
928 UnlockAndExit:
929     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
930     return (Status);
931 }
932 
933 ACPI_EXPORT_SYMBOL (AcpiDetachData)
934 
935 
936 /*******************************************************************************
937  *
938  * FUNCTION:    AcpiGetData
939  *
940  * PARAMETERS:  ObjHandle           - Namespace node
941  *              Handler             - Handler used in call to AttachData
942  *              Data                - Where the data is returned
943  *
944  * RETURN:      Status
945  *
946  * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
947  *
948  ******************************************************************************/
949 
950 ACPI_STATUS
951 AcpiGetData (
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 
986 UnlockAndExit:
987     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
988     return (Status);
989 }
990 
991 ACPI_EXPORT_SYMBOL (AcpiGetData)
992 
993 
994