Bring in acpica 20110211, still not ok anyway
[dragonfly.git] / sys / contrib / dev / acpica-unix / namespace / nsxfeval.c
1 /*******************************************************************************
2  *
3  * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4  *                         ACPI Object evaluation interfaces
5  *
6  ******************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116
117
118 #define __NSXFEVAL_C__
119
120 #include "acpi.h"
121 #include "accommon.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 = AcpiNsValidateHandle (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 ((Info->ReturnObject)->Common.Type != 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  *              PreOrderVisit       - Called during tree pre-order visit
548  *                                    when an object of "Type" is found
549  *              PostOrderVisit      - Called during tree post-order visit
550  *                                    when an object of "Type" is found
551  *              Context             - Passed to user function(s) above
552  *              ReturnValue         - Location where return value of
553  *                                    UserFunction is put if terminated early
554  *
555  * RETURNS      Return value from the UserFunction if terminated early.
556  *              Otherwise, returns NULL.
557  *
558  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
559  *              starting (and ending) at the object specified by StartHandle.
560  *              The callback function is called whenever an object that matches
561  *              the type parameter is found. If the callback function returns
562  *              a non-zero value, the search is terminated immediately and this
563  *              value is returned to the caller.
564  *
565  *              The point of this procedure is to provide a generic namespace
566  *              walk routine that can be called from multiple places to
567  *              provide multiple services; the callback function(s) can be
568  *              tailored to each task, whether it is a print function,
569  *              a compare function, etc.
570  *
571  ******************************************************************************/
572
573 ACPI_STATUS
574 AcpiWalkNamespace (
575     ACPI_OBJECT_TYPE        Type,
576     ACPI_HANDLE             StartObject,
577     UINT32                  MaxDepth,
578     ACPI_WALK_CALLBACK      PreOrderVisit,
579     ACPI_WALK_CALLBACK      PostOrderVisit,
580     void                    *Context,
581     void                    **ReturnValue)
582 {
583     ACPI_STATUS             Status;
584
585
586     ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
587
588
589     /* Parameter validation */
590
591     if ((Type > ACPI_TYPE_LOCAL_MAX) ||
592         (!MaxDepth)                  ||
593         (!PreOrderVisit && !PostOrderVisit))
594     {
595         return_ACPI_STATUS (AE_BAD_PARAMETER);
596     }
597
598     /*
599      * Need to acquire the namespace reader lock to prevent interference
600      * with any concurrent table unloads (which causes the deletion of
601      * namespace objects). We cannot allow the deletion of a namespace node
602      * while the user function is using it. The exception to this are the
603      * nodes created and deleted during control method execution -- these
604      * nodes are marked as temporary nodes and are ignored by the namespace
605      * walk. Thus, control methods can be executed while holding the
606      * namespace deletion lock (and the user function can execute control
607      * methods.)
608      */
609     Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
610     if (ACPI_FAILURE (Status))
611     {
612         return (Status);
613     }
614
615     /*
616      * Lock the namespace around the walk. The namespace will be
617      * unlocked/locked around each call to the user function - since the user
618      * function must be allowed to make ACPICA calls itself (for example, it
619      * will typically execute control methods during device enumeration.)
620      */
621     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
622     if (ACPI_FAILURE (Status))
623     {
624         goto UnlockAndExit;
625     }
626
627     Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
628                 ACPI_NS_WALK_UNLOCK, PreOrderVisit,
629                 PostOrderVisit, Context, ReturnValue);
630
631     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
632
633 UnlockAndExit:
634     (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
635     return_ACPI_STATUS (Status);
636 }
637
638 ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
639
640
641 /*******************************************************************************
642  *
643  * FUNCTION:    AcpiNsGetDeviceCallback
644  *
645  * PARAMETERS:  Callback from AcpiGetDevice
646  *
647  * RETURN:      Status
648  *
649  * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
650  *              present devices, or if they specified a HID, it filters based
651  *              on that.
652  *
653  ******************************************************************************/
654
655 static ACPI_STATUS
656 AcpiNsGetDeviceCallback (
657     ACPI_HANDLE             ObjHandle,
658     UINT32                  NestingLevel,
659     void                    *Context,
660     void                    **ReturnValue)
661 {
662     ACPI_GET_DEVICES_INFO   *Info = Context;
663     ACPI_STATUS             Status;
664     ACPI_NAMESPACE_NODE     *Node;
665     UINT32                  Flags;
666     ACPI_DEVICE_ID          *Hid;
667     ACPI_DEVICE_ID_LIST     *Cid;
668     UINT32                  i;
669     BOOLEAN                 Found;
670     int                     NoMatch;
671
672
673     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
674     if (ACPI_FAILURE (Status))
675     {
676         return (Status);
677     }
678
679     Node = AcpiNsValidateHandle (ObjHandle);
680     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
681     if (ACPI_FAILURE (Status))
682     {
683         return (Status);
684     }
685
686     if (!Node)
687     {
688         return (AE_BAD_PARAMETER);
689     }
690
691     /*
692      * First, filter based on the device HID and CID.
693      *
694      * 01/2010: For this case where a specific HID is requested, we don't
695      * want to run _STA until we have an actual HID match. Thus, we will
696      * not unnecessarily execute _STA on devices for which the caller
697      * doesn't care about. Previously, _STA was executed unconditionally
698      * on all devices found here.
699      *
700      * A side-effect of this change is that now we will continue to search
701      * for a matching HID even under device trees where the parent device
702      * would have returned a _STA that indicates it is not present or
703      * not functioning (thus aborting the search on that branch).
704      */
705     if (Info->Hid != NULL)
706     {
707         Status = AcpiUtExecute_HID (Node, &Hid);
708         if (Status == AE_NOT_FOUND)
709         {
710             return (AE_OK);
711         }
712         else if (ACPI_FAILURE (Status))
713         {
714             return (AE_CTRL_DEPTH);
715         }
716
717         NoMatch = ACPI_STRCMP (Hid->String, Info->Hid);
718         ACPI_FREE (Hid);
719
720         if (NoMatch)
721         {
722             /*
723              * HID does not match, attempt match within the
724              * list of Compatible IDs (CIDs)
725              */
726             Status = AcpiUtExecute_CID (Node, &Cid);
727             if (Status == AE_NOT_FOUND)
728             {
729                 return (AE_OK);
730             }
731             else if (ACPI_FAILURE (Status))
732             {
733                 return (AE_CTRL_DEPTH);
734             }
735
736             /* Walk the CID list */
737
738             Found = FALSE;
739             for (i = 0; i < Cid->Count; i++)
740             {
741                 if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
742                 {
743                     /* Found a matching CID */
744
745                     Found = TRUE;
746                     break;
747                 }
748             }
749
750             ACPI_FREE (Cid);
751             if (!Found)
752             {
753                 return (AE_OK);
754             }
755         }
756     }
757
758     /* Run _STA to determine if device is present */
759
760     Status = AcpiUtExecute_STA (Node, &Flags);
761     if (ACPI_FAILURE (Status))
762     {
763         return (AE_CTRL_DEPTH);
764     }
765
766     if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
767         !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
768     {
769         /*
770          * Don't examine the children of the device only when the
771          * device is neither present nor functional. See ACPI spec,
772          * description of _STA for more information.
773          */
774         return (AE_CTRL_DEPTH);
775     }
776
777     /* We have a valid device, invoke the user function */
778
779     Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
780                 ReturnValue);
781     return (Status);
782 }
783
784
785 /*******************************************************************************
786  *
787  * FUNCTION:    AcpiGetDevices
788  *
789  * PARAMETERS:  HID                 - HID to search for. Can be NULL.
790  *              UserFunction        - Called when a matching object is found
791  *              Context             - Passed to user function
792  *              ReturnValue         - Location where return value of
793  *                                    UserFunction is put if terminated early
794  *
795  * RETURNS      Return value from the UserFunction if terminated early.
796  *              Otherwise, returns NULL.
797  *
798  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
799  *              starting (and ending) at the object specified by StartHandle.
800  *              The UserFunction is called whenever an object of type
801  *              Device is found.  If the user function returns
802  *              a non-zero value, the search is terminated immediately and this
803  *              value is returned to the caller.
804  *
805  *              This is a wrapper for WalkNamespace, but the callback performs
806  *              additional filtering. Please see AcpiNsGetDeviceCallback.
807  *
808  ******************************************************************************/
809
810 ACPI_STATUS
811 AcpiGetDevices (
812     char                    *HID,
813     ACPI_WALK_CALLBACK      UserFunction,
814     void                    *Context,
815     void                    **ReturnValue)
816 {
817     ACPI_STATUS             Status;
818     ACPI_GET_DEVICES_INFO   Info;
819
820
821     ACPI_FUNCTION_TRACE (AcpiGetDevices);
822
823
824     /* Parameter validation */
825
826     if (!UserFunction)
827     {
828         return_ACPI_STATUS (AE_BAD_PARAMETER);
829     }
830
831     /*
832      * We're going to call their callback from OUR callback, so we need
833      * to know what it is, and their context parameter.
834      */
835     Info.Hid          = HID;
836     Info.Context      = Context;
837     Info.UserFunction = UserFunction;
838
839     /*
840      * Lock the namespace around the walk.
841      * The namespace will be unlocked/locked around each call
842      * to the user function - since this function
843      * must be allowed to make Acpi calls itself.
844      */
845     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
846     if (ACPI_FAILURE (Status))
847     {
848         return_ACPI_STATUS (Status);
849     }
850
851     Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
852                 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
853                 AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
854
855     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
856     return_ACPI_STATUS (Status);
857 }
858
859 ACPI_EXPORT_SYMBOL (AcpiGetDevices)
860
861
862 /*******************************************************************************
863  *
864  * FUNCTION:    AcpiAttachData
865  *
866  * PARAMETERS:  ObjHandle           - Namespace node
867  *              Handler             - Handler for this attachment
868  *              Data                - Pointer to data to be attached
869  *
870  * RETURN:      Status
871  *
872  * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
873  *
874  ******************************************************************************/
875
876 ACPI_STATUS
877 AcpiAttachData (
878     ACPI_HANDLE             ObjHandle,
879     ACPI_OBJECT_HANDLER     Handler,
880     void                    *Data)
881 {
882     ACPI_NAMESPACE_NODE     *Node;
883     ACPI_STATUS             Status;
884
885
886     /* Parameter validation */
887
888     if (!ObjHandle  ||
889         !Handler    ||
890         !Data)
891     {
892         return (AE_BAD_PARAMETER);
893     }
894
895     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
896     if (ACPI_FAILURE (Status))
897     {
898         return (Status);
899     }
900
901     /* Convert and validate the handle */
902
903     Node = AcpiNsValidateHandle (ObjHandle);
904     if (!Node)
905     {
906         Status = AE_BAD_PARAMETER;
907         goto UnlockAndExit;
908     }
909
910     Status = AcpiNsAttachData (Node, Handler, Data);
911
912 UnlockAndExit:
913     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
914     return (Status);
915 }
916
917 ACPI_EXPORT_SYMBOL (AcpiAttachData)
918
919
920 /*******************************************************************************
921  *
922  * FUNCTION:    AcpiDetachData
923  *
924  * PARAMETERS:  ObjHandle           - Namespace node handle
925  *              Handler             - Handler used in call to AcpiAttachData
926  *
927  * RETURN:      Status
928  *
929  * DESCRIPTION: Remove data that was previously attached to a node.
930  *
931  ******************************************************************************/
932
933 ACPI_STATUS
934 AcpiDetachData (
935     ACPI_HANDLE             ObjHandle,
936     ACPI_OBJECT_HANDLER     Handler)
937 {
938     ACPI_NAMESPACE_NODE     *Node;
939     ACPI_STATUS             Status;
940
941
942     /* Parameter validation */
943
944     if (!ObjHandle  ||
945         !Handler)
946     {
947         return (AE_BAD_PARAMETER);
948     }
949
950     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
951     if (ACPI_FAILURE (Status))
952     {
953         return (Status);
954     }
955
956     /* Convert and validate the handle */
957
958     Node = AcpiNsValidateHandle (ObjHandle);
959     if (!Node)
960     {
961         Status = AE_BAD_PARAMETER;
962         goto UnlockAndExit;
963     }
964
965     Status = AcpiNsDetachData (Node, Handler);
966
967 UnlockAndExit:
968     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
969     return (Status);
970 }
971
972 ACPI_EXPORT_SYMBOL (AcpiDetachData)
973
974
975 /*******************************************************************************
976  *
977  * FUNCTION:    AcpiGetData
978  *
979  * PARAMETERS:  ObjHandle           - Namespace node
980  *              Handler             - Handler used in call to AttachData
981  *              Data                - Where the data is returned
982  *
983  * RETURN:      Status
984  *
985  * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
986  *
987  ******************************************************************************/
988
989 ACPI_STATUS
990 AcpiGetData (
991     ACPI_HANDLE             ObjHandle,
992     ACPI_OBJECT_HANDLER     Handler,
993     void                    **Data)
994 {
995     ACPI_NAMESPACE_NODE     *Node;
996     ACPI_STATUS             Status;
997
998
999     /* Parameter validation */
1000
1001     if (!ObjHandle  ||
1002         !Handler    ||
1003         !Data)
1004     {
1005         return (AE_BAD_PARAMETER);
1006     }
1007
1008     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1009     if (ACPI_FAILURE (Status))
1010     {
1011         return (Status);
1012     }
1013
1014     /* Convert and validate the handle */
1015
1016     Node = AcpiNsValidateHandle (ObjHandle);
1017     if (!Node)
1018     {
1019         Status = AE_BAD_PARAMETER;
1020         goto UnlockAndExit;
1021     }
1022
1023     Status = AcpiNsGetAttachedData (Node, Handler, Data);
1024
1025 UnlockAndExit:
1026     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1027     return (Status);
1028 }
1029
1030 ACPI_EXPORT_SYMBOL (AcpiGetData)
1031
1032