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