Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 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
 *
2216 Serge 12
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 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