Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/components/namespace/nsxfeval.c
48524 views
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 - 2025, 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
* Alternatively, you may choose to be licensed under the terms of the
118
* following license:
119
*
120
* Redistribution and use in source and binary forms, with or without
121
* modification, are permitted provided that the following conditions
122
* are met:
123
* 1. Redistributions of source code must retain the above copyright
124
* notice, this list of conditions, and the following disclaimer,
125
* without modification.
126
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
127
* substantially similar to the "NO WARRANTY" disclaimer below
128
* ("Disclaimer") and any redistribution must be conditioned upon
129
* including a substantially similar Disclaimer requirement for further
130
* binary redistribution.
131
* 3. Neither the names of the above-listed copyright holders nor the names
132
* of any contributors may be used to endorse or promote products derived
133
* from this software without specific prior written permission.
134
*
135
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
136
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
137
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
138
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
139
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
140
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
141
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
142
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
143
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146
*
147
* Alternatively, you may choose to be licensed under the terms of the
148
* GNU General Public License ("GPL") version 2 as published by the Free
149
* Software Foundation.
150
*
151
*****************************************************************************/
152
153
#define EXPORT_ACPI_INTERFACES
154
155
#include <contrib/dev/acpica/include/acpi.h>
156
#include <contrib/dev/acpica/include/accommon.h>
157
#include <contrib/dev/acpica/include/acnamesp.h>
158
#include <contrib/dev/acpica/include/acinterp.h>
159
160
161
#define _COMPONENT ACPI_NAMESPACE
162
ACPI_MODULE_NAME ("nsxfeval")
163
164
/* Local prototypes */
165
166
static void
167
AcpiNsResolveReferences (
168
ACPI_EVALUATE_INFO *Info);
169
170
171
/*******************************************************************************
172
*
173
* FUNCTION: AcpiEvaluateObjectTyped
174
*
175
* PARAMETERS: Handle - Object handle (optional)
176
* Pathname - Object pathname (optional)
177
* ExternalParams - List of parameters to pass to a method,
178
* terminated by NULL. May be NULL
179
* if no parameters are being passed.
180
* ReturnBuffer - Where to put the object return value (if
181
* any). Required.
182
* ReturnType - Expected type of return object
183
*
184
* RETURN: Status
185
*
186
* DESCRIPTION: Find and evaluate the given object, passing the given
187
* parameters if necessary. One of "Handle" or "Pathname" must
188
* be valid (non-null)
189
*
190
******************************************************************************/
191
192
ACPI_STATUS
193
AcpiEvaluateObjectTyped (
194
ACPI_HANDLE Handle,
195
ACPI_STRING Pathname,
196
ACPI_OBJECT_LIST *ExternalParams,
197
ACPI_BUFFER *ReturnBuffer,
198
ACPI_OBJECT_TYPE ReturnType)
199
{
200
ACPI_STATUS Status;
201
BOOLEAN FreeBufferOnError = FALSE;
202
ACPI_HANDLE TargetHandle;
203
char *FullPathname;
204
205
206
ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
207
208
209
/* Return buffer must be valid */
210
211
if (!ReturnBuffer)
212
{
213
return_ACPI_STATUS (AE_BAD_PARAMETER);
214
}
215
216
if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
217
{
218
FreeBufferOnError = TRUE;
219
}
220
221
/* Get a handle here, in order to build an error message if needed */
222
223
TargetHandle = Handle;
224
if (Pathname)
225
{
226
Status = AcpiGetHandle (Handle, Pathname, &TargetHandle);
227
if (ACPI_FAILURE (Status))
228
{
229
return_ACPI_STATUS (Status);
230
}
231
}
232
233
FullPathname = AcpiNsGetExternalPathname (TargetHandle);
234
if (!FullPathname)
235
{
236
return_ACPI_STATUS (AE_NO_MEMORY);
237
}
238
239
/* Evaluate the object */
240
241
Status = AcpiEvaluateObject (TargetHandle, NULL, ExternalParams,
242
ReturnBuffer);
243
if (ACPI_FAILURE (Status))
244
{
245
goto Exit;
246
}
247
248
/* Type ANY means "don't care about return value type" */
249
250
if (ReturnType == ACPI_TYPE_ANY)
251
{
252
goto Exit;
253
}
254
255
if (ReturnBuffer->Length == 0)
256
{
257
/* Error because caller specifically asked for a return value */
258
259
ACPI_ERROR ((AE_INFO, "%s did not return any object",
260
FullPathname));
261
Status = AE_NULL_OBJECT;
262
goto Exit;
263
}
264
265
/* Examine the object type returned from EvaluateObject */
266
267
if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
268
{
269
goto Exit;
270
}
271
272
/* Return object type does not match requested type */
273
274
ACPI_ERROR ((AE_INFO,
275
"Incorrect return type from %s - received [%s], requested [%s]",
276
FullPathname,
277
AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
278
AcpiUtGetTypeName (ReturnType)));
279
280
if (FreeBufferOnError)
281
{
282
/*
283
* Free a buffer created via ACPI_ALLOCATE_BUFFER.
284
* Note: We use AcpiOsFree here because AcpiOsAllocate was used
285
* to allocate the buffer. This purposefully bypasses the
286
* (optionally enabled) allocation tracking mechanism since we
287
* only want to track internal allocations.
288
*/
289
AcpiOsFree (ReturnBuffer->Pointer);
290
ReturnBuffer->Pointer = NULL;
291
}
292
293
ReturnBuffer->Length = 0;
294
Status = AE_TYPE;
295
296
Exit:
297
ACPI_FREE (FullPathname);
298
return_ACPI_STATUS (Status);
299
}
300
301
ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
302
303
304
/*******************************************************************************
305
*
306
* FUNCTION: AcpiEvaluateObject
307
*
308
* PARAMETERS: Handle - Object handle (optional)
309
* Pathname - Object pathname (optional)
310
* ExternalParams - List of parameters to pass to method,
311
* terminated by NULL. May be NULL
312
* if no parameters are being passed.
313
* ReturnBuffer - Where to put method's return value (if
314
* any). If NULL, no value is returned.
315
*
316
* RETURN: Status
317
*
318
* DESCRIPTION: Find and evaluate the given object, passing the given
319
* parameters if necessary. One of "Handle" or "Pathname" must
320
* be valid (non-null)
321
*
322
******************************************************************************/
323
324
ACPI_STATUS
325
AcpiEvaluateObject (
326
ACPI_HANDLE Handle,
327
ACPI_STRING Pathname,
328
ACPI_OBJECT_LIST *ExternalParams,
329
ACPI_BUFFER *ReturnBuffer)
330
{
331
ACPI_STATUS Status;
332
ACPI_EVALUATE_INFO *Info;
333
ACPI_SIZE BufferSpaceNeeded;
334
UINT32 i;
335
336
337
ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
338
339
340
/* Allocate and initialize the evaluation information block */
341
342
Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
343
if (!Info)
344
{
345
return_ACPI_STATUS (AE_NO_MEMORY);
346
}
347
348
/* Convert and validate the device handle */
349
350
Info->PrefixNode = AcpiNsValidateHandle (Handle);
351
if (!Info->PrefixNode)
352
{
353
Status = AE_BAD_PARAMETER;
354
goto Cleanup;
355
}
356
357
/*
358
* Get the actual namespace node for the target object.
359
* Handles these cases:
360
*
361
* 1) Null node, valid pathname from root (absolute path)
362
* 2) Node and valid pathname (path relative to Node)
363
* 3) Node, Null pathname
364
*/
365
if ((Pathname) &&
366
(ACPI_IS_ROOT_PREFIX (Pathname[0])))
367
{
368
/* The path is fully qualified, just evaluate by name */
369
370
Info->PrefixNode = NULL;
371
}
372
else if (!Handle)
373
{
374
/*
375
* A handle is optional iff a fully qualified pathname is specified.
376
* Since we've already handled fully qualified names above, this is
377
* an error.
378
*/
379
if (!Pathname)
380
{
381
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
382
"Both Handle and Pathname are NULL"));
383
}
384
else
385
{
386
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
387
"Null Handle with relative pathname [%s]", Pathname));
388
}
389
390
Status = AE_BAD_PARAMETER;
391
goto Cleanup;
392
}
393
394
Info->RelativePathname = Pathname;
395
396
/*
397
* Convert all external objects passed as arguments to the
398
* internal version(s).
399
*/
400
if (ExternalParams && ExternalParams->Count)
401
{
402
Info->ParamCount = (UINT16) ExternalParams->Count;
403
404
/* Warn on impossible argument count */
405
406
if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
407
{
408
ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
409
"Excess arguments (%u) - using only %u",
410
Info->ParamCount, ACPI_METHOD_NUM_ARGS));
411
412
Info->ParamCount = ACPI_METHOD_NUM_ARGS;
413
}
414
415
/*
416
* Allocate a new parameter block for the internal objects
417
* Add 1 to count to allow for null terminated internal list
418
*/
419
Info->Parameters = ACPI_ALLOCATE_ZEROED (
420
((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
421
if (!Info->Parameters)
422
{
423
Status = AE_NO_MEMORY;
424
goto Cleanup;
425
}
426
427
/* Convert each external object in the list to an internal object */
428
429
for (i = 0; i < Info->ParamCount; i++)
430
{
431
Status = AcpiUtCopyEobjectToIobject (
432
&ExternalParams->Pointer[i], &Info->Parameters[i]);
433
if (ACPI_FAILURE (Status))
434
{
435
goto Cleanup;
436
}
437
}
438
439
Info->Parameters[Info->ParamCount] = NULL;
440
}
441
442
443
#ifdef _FUTURE_FEATURE
444
445
/*
446
* Begin incoming argument count analysis. Check for too few args
447
* and too many args.
448
*/
449
switch (AcpiNsGetType (Info->Node))
450
{
451
case ACPI_TYPE_METHOD:
452
453
/* Check incoming argument count against the method definition */
454
455
if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)
456
{
457
ACPI_ERROR ((AE_INFO,
458
"Insufficient arguments (%u) - %u are required",
459
Info->ParamCount,
460
Info->ObjDesc->Method.ParamCount));
461
462
Status = AE_MISSING_ARGUMENTS;
463
goto Cleanup;
464
}
465
466
else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)
467
{
468
ACPI_WARNING ((AE_INFO,
469
"Excess arguments (%u) - only %u are required",
470
Info->ParamCount,
471
Info->ObjDesc->Method.ParamCount));
472
473
/* Just pass the required number of arguments */
474
475
Info->ParamCount = Info->ObjDesc->Method.ParamCount;
476
}
477
478
/*
479
* Any incoming external objects to be passed as arguments to the
480
* method must be converted to internal objects
481
*/
482
if (Info->ParamCount)
483
{
484
/*
485
* Allocate a new parameter block for the internal objects
486
* Add 1 to count to allow for null terminated internal list
487
*/
488
Info->Parameters = ACPI_ALLOCATE_ZEROED (
489
((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
490
if (!Info->Parameters)
491
{
492
Status = AE_NO_MEMORY;
493
goto Cleanup;
494
}
495
496
/* Convert each external object in the list to an internal object */
497
498
for (i = 0; i < Info->ParamCount; i++)
499
{
500
Status = AcpiUtCopyEobjectToIobject (
501
&ExternalParams->Pointer[i], &Info->Parameters[i]);
502
if (ACPI_FAILURE (Status))
503
{
504
goto Cleanup;
505
}
506
}
507
508
Info->Parameters[Info->ParamCount] = NULL;
509
}
510
break;
511
512
default:
513
514
/* Warn if arguments passed to an object that is not a method */
515
516
if (Info->ParamCount)
517
{
518
ACPI_WARNING ((AE_INFO,
519
"%u arguments were passed to a non-method ACPI object",
520
Info->ParamCount));
521
}
522
break;
523
}
524
525
#endif
526
527
528
/* Now we can evaluate the object */
529
530
Status = AcpiNsEvaluate (Info);
531
532
/*
533
* If we are expecting a return value, and all went well above,
534
* copy the return value to an external object.
535
*/
536
if (!ReturnBuffer)
537
{
538
goto CleanupReturnObject;
539
}
540
541
if (!Info->ReturnObject)
542
{
543
ReturnBuffer->Length = 0;
544
goto Cleanup;
545
}
546
547
if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
548
ACPI_DESC_TYPE_NAMED)
549
{
550
/*
551
* If we received a NS Node as a return object, this means that
552
* the object we are evaluating has nothing interesting to
553
* return (such as a mutex, etc.) We return an error because
554
* these types are essentially unsupported by this interface.
555
* We don't check up front because this makes it easier to add
556
* support for various types at a later date if necessary.
557
*/
558
Status = AE_TYPE;
559
Info->ReturnObject = NULL; /* No need to delete a NS Node */
560
ReturnBuffer->Length = 0;
561
}
562
563
if (ACPI_FAILURE (Status))
564
{
565
goto CleanupReturnObject;
566
}
567
568
/* Dereference Index and RefOf references */
569
570
AcpiNsResolveReferences (Info);
571
572
/* Get the size of the returned object */
573
574
Status = AcpiUtGetObjectSize (Info->ReturnObject,
575
&BufferSpaceNeeded);
576
if (ACPI_SUCCESS (Status))
577
{
578
/* Validate/Allocate/Clear caller buffer */
579
580
Status = AcpiUtInitializeBuffer (ReturnBuffer,
581
BufferSpaceNeeded);
582
if (ACPI_FAILURE (Status))
583
{
584
/*
585
* Caller's buffer is too small or a new one can't
586
* be allocated
587
*/
588
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
589
"Needed buffer size %X, %s\n",
590
(UINT32) BufferSpaceNeeded,
591
AcpiFormatException (Status)));
592
}
593
else
594
{
595
/* We have enough space for the object, build it */
596
597
Status = AcpiUtCopyIobjectToEobject (
598
Info->ReturnObject, ReturnBuffer);
599
}
600
}
601
602
CleanupReturnObject:
603
604
if (Info->ReturnObject)
605
{
606
/*
607
* Delete the internal return object. NOTE: Interpreter must be
608
* locked to avoid race condition.
609
*/
610
AcpiExEnterInterpreter ();
611
612
/* Remove one reference on the return object (should delete it) */
613
614
AcpiUtRemoveReference (Info->ReturnObject);
615
AcpiExExitInterpreter ();
616
}
617
618
619
Cleanup:
620
621
/* Free the input parameter list (if we created one) */
622
623
if (Info->Parameters)
624
{
625
/* Free the allocated parameter block */
626
627
AcpiUtDeleteInternalObjectList (Info->Parameters);
628
}
629
630
ACPI_FREE (Info);
631
return_ACPI_STATUS (Status);
632
}
633
634
ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
635
636
637
/*******************************************************************************
638
*
639
* FUNCTION: AcpiNsResolveReferences
640
*
641
* PARAMETERS: Info - Evaluation info block
642
*
643
* RETURN: Info->ReturnObject is replaced with the dereferenced object
644
*
645
* DESCRIPTION: Dereference certain reference objects. Called before an
646
* internal return object is converted to an external ACPI_OBJECT.
647
*
648
* Performs an automatic dereference of Index and RefOf reference objects.
649
* These reference objects are not supported by the ACPI_OBJECT, so this is a
650
* last resort effort to return something useful. Also, provides compatibility
651
* with other ACPI implementations.
652
*
653
* NOTE: does not handle references within returned package objects or nested
654
* references, but this support could be added later if found to be necessary.
655
*
656
******************************************************************************/
657
658
static void
659
AcpiNsResolveReferences (
660
ACPI_EVALUATE_INFO *Info)
661
{
662
ACPI_OPERAND_OBJECT *ObjDesc = NULL;
663
ACPI_NAMESPACE_NODE *Node;
664
665
666
/* We are interested in reference objects only */
667
668
if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
669
{
670
return;
671
}
672
673
/*
674
* Two types of references are supported - those created by Index and
675
* RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
676
* to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
677
* (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
678
* an ACPI_OBJECT.
679
*/
680
switch (Info->ReturnObject->Reference.Class)
681
{
682
case ACPI_REFCLASS_INDEX:
683
684
ObjDesc = *(Info->ReturnObject->Reference.Where);
685
break;
686
687
case ACPI_REFCLASS_REFOF:
688
689
Node = Info->ReturnObject->Reference.Object;
690
if (Node)
691
{
692
ObjDesc = Node->Object;
693
}
694
break;
695
696
default:
697
698
return;
699
}
700
701
/* Replace the existing reference object */
702
703
if (ObjDesc)
704
{
705
AcpiUtAddReference (ObjDesc);
706
AcpiUtRemoveReference (Info->ReturnObject);
707
Info->ReturnObject = ObjDesc;
708
}
709
710
return;
711
}
712
713
714
/*******************************************************************************
715
*
716
* FUNCTION: AcpiWalkNamespace
717
*
718
* PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
719
* StartObject - Handle in namespace where search begins
720
* MaxDepth - Depth to which search is to reach
721
* DescendingCallback - Called during tree descent
722
* when an object of "Type" is found
723
* AscendingCallback - Called during tree ascent
724
* when an object of "Type" is found
725
* Context - Passed to user function(s) above
726
* ReturnValue - Location where return value of
727
* UserFunction is put if terminated early
728
*
729
* RETURNS Return value from the UserFunction if terminated early.
730
* Otherwise, returns NULL.
731
*
732
* DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
733
* starting (and ending) at the object specified by StartHandle.
734
* The callback function is called whenever an object that matches
735
* the type parameter is found. If the callback function returns
736
* a non-zero value, the search is terminated immediately and this
737
* value is returned to the caller.
738
*
739
* The point of this procedure is to provide a generic namespace
740
* walk routine that can be called from multiple places to
741
* provide multiple services; the callback function(s) can be
742
* tailored to each task, whether it is a print function,
743
* a compare function, etc.
744
*
745
******************************************************************************/
746
747
ACPI_STATUS
748
AcpiWalkNamespace (
749
ACPI_OBJECT_TYPE Type,
750
ACPI_HANDLE StartObject,
751
UINT32 MaxDepth,
752
ACPI_WALK_CALLBACK DescendingCallback,
753
ACPI_WALK_CALLBACK AscendingCallback,
754
void *Context,
755
void **ReturnValue)
756
{
757
ACPI_STATUS Status;
758
759
760
ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
761
762
763
/* Parameter validation */
764
765
if ((Type > ACPI_TYPE_LOCAL_MAX) ||
766
(!MaxDepth) ||
767
(!DescendingCallback && !AscendingCallback))
768
{
769
return_ACPI_STATUS (AE_BAD_PARAMETER);
770
}
771
772
/*
773
* Need to acquire the namespace reader lock to prevent interference
774
* with any concurrent table unloads (which causes the deletion of
775
* namespace objects). We cannot allow the deletion of a namespace node
776
* while the user function is using it. The exception to this are the
777
* nodes created and deleted during control method execution -- these
778
* nodes are marked as temporary nodes and are ignored by the namespace
779
* walk. Thus, control methods can be executed while holding the
780
* namespace deletion lock (and the user function can execute control
781
* methods.)
782
*/
783
Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
784
if (ACPI_FAILURE (Status))
785
{
786
return_ACPI_STATUS (Status);
787
}
788
789
/*
790
* Lock the namespace around the walk. The namespace will be
791
* unlocked/locked around each call to the user function - since the user
792
* function must be allowed to make ACPICA calls itself (for example, it
793
* will typically execute control methods during device enumeration.)
794
*/
795
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
796
if (ACPI_FAILURE (Status))
797
{
798
goto UnlockAndExit;
799
}
800
801
/* Now we can validate the starting node */
802
803
if (!AcpiNsValidateHandle (StartObject))
804
{
805
Status = AE_BAD_PARAMETER;
806
goto UnlockAndExit2;
807
}
808
809
Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
810
ACPI_NS_WALK_UNLOCK, DescendingCallback,
811
AscendingCallback, Context, ReturnValue);
812
813
UnlockAndExit2:
814
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
815
816
UnlockAndExit:
817
(void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
818
return_ACPI_STATUS (Status);
819
}
820
821
ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
822
823
824
/*******************************************************************************
825
*
826
* FUNCTION: AcpiNsGetDeviceCallback
827
*
828
* PARAMETERS: Callback from AcpiGetDevice
829
*
830
* RETURN: Status
831
*
832
* DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
833
* present devices, or if they specified a HID, it filters based
834
* on that.
835
*
836
******************************************************************************/
837
838
static ACPI_STATUS
839
AcpiNsGetDeviceCallback (
840
ACPI_HANDLE ObjHandle,
841
UINT32 NestingLevel,
842
void *Context,
843
void **ReturnValue)
844
{
845
ACPI_GET_DEVICES_INFO *Info = Context;
846
ACPI_STATUS Status;
847
ACPI_NAMESPACE_NODE *Node;
848
UINT32 Flags;
849
ACPI_PNP_DEVICE_ID *Hid;
850
ACPI_PNP_DEVICE_ID_LIST *Cid;
851
UINT32 i;
852
BOOLEAN Found;
853
int NoMatch;
854
855
856
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
857
if (ACPI_FAILURE (Status))
858
{
859
return (Status);
860
}
861
862
Node = AcpiNsValidateHandle (ObjHandle);
863
Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
864
if (ACPI_FAILURE (Status))
865
{
866
return (Status);
867
}
868
869
if (!Node)
870
{
871
return (AE_BAD_PARAMETER);
872
}
873
874
/*
875
* First, filter based on the device HID and CID.
876
*
877
* 01/2010: For this case where a specific HID is requested, we don't
878
* want to run _STA until we have an actual HID match. Thus, we will
879
* not unnecessarily execute _STA on devices for which the caller
880
* doesn't care about. Previously, _STA was executed unconditionally
881
* on all devices found here.
882
*
883
* A side-effect of this change is that now we will continue to search
884
* for a matching HID even under device trees where the parent device
885
* would have returned a _STA that indicates it is not present or
886
* not functioning (thus aborting the search on that branch).
887
*/
888
if (Info->Hid != NULL)
889
{
890
Status = AcpiUtExecute_HID (Node, &Hid);
891
if (Status == AE_NOT_FOUND)
892
{
893
return (AE_OK);
894
}
895
else if (ACPI_FAILURE (Status))
896
{
897
return (AE_CTRL_DEPTH);
898
}
899
900
NoMatch = strcmp (Hid->String, Info->Hid);
901
ACPI_FREE (Hid);
902
903
if (NoMatch)
904
{
905
/*
906
* HID does not match, attempt match within the
907
* list of Compatible IDs (CIDs)
908
*/
909
Status = AcpiUtExecute_CID (Node, &Cid);
910
if (Status == AE_NOT_FOUND)
911
{
912
return (AE_OK);
913
}
914
else if (ACPI_FAILURE (Status))
915
{
916
return (AE_CTRL_DEPTH);
917
}
918
919
/* Walk the CID list */
920
921
Found = FALSE;
922
for (i = 0; i < Cid->Count; i++)
923
{
924
if (strcmp (Cid->Ids[i].String, Info->Hid) == 0)
925
{
926
/* Found a matching CID */
927
928
Found = TRUE;
929
break;
930
}
931
}
932
933
ACPI_FREE (Cid);
934
if (!Found)
935
{
936
return (AE_OK);
937
}
938
}
939
}
940
941
/* Run _STA to determine if device is present */
942
943
Status = AcpiUtExecute_STA (Node, &Flags);
944
if (ACPI_FAILURE (Status))
945
{
946
return (AE_CTRL_DEPTH);
947
}
948
949
if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
950
!(Flags & ACPI_STA_DEVICE_FUNCTIONING))
951
{
952
/*
953
* Don't examine the children of the device only when the
954
* device is neither present nor functional. See ACPI spec,
955
* description of _STA for more information.
956
*/
957
return (AE_CTRL_DEPTH);
958
}
959
960
/* We have a valid device, invoke the user function */
961
962
Status = Info->UserFunction (ObjHandle, NestingLevel,
963
Info->Context, ReturnValue);
964
return (Status);
965
}
966
967
968
/*******************************************************************************
969
*
970
* FUNCTION: AcpiGetDevices
971
*
972
* PARAMETERS: HID - HID to search for. Can be NULL.
973
* UserFunction - Called when a matching object is found
974
* Context - Passed to user function
975
* ReturnValue - Location where return value of
976
* UserFunction is put if terminated early
977
*
978
* RETURNS Return value from the UserFunction if terminated early.
979
* Otherwise, returns NULL.
980
*
981
* DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
982
* starting (and ending) at the object specified by StartHandle.
983
* The UserFunction is called whenever an object of type
984
* Device is found. If the user function returns
985
* a non-zero value, the search is terminated immediately and this
986
* value is returned to the caller.
987
*
988
* This is a wrapper for WalkNamespace, but the callback performs
989
* additional filtering. Please see AcpiNsGetDeviceCallback.
990
*
991
******************************************************************************/
992
993
ACPI_STATUS
994
AcpiGetDevices (
995
char *HID,
996
ACPI_WALK_CALLBACK UserFunction,
997
void *Context,
998
void **ReturnValue)
999
{
1000
ACPI_STATUS Status;
1001
ACPI_GET_DEVICES_INFO Info;
1002
1003
1004
ACPI_FUNCTION_TRACE (AcpiGetDevices);
1005
1006
1007
/* Parameter validation */
1008
1009
if (!UserFunction)
1010
{
1011
return_ACPI_STATUS (AE_BAD_PARAMETER);
1012
}
1013
1014
/*
1015
* We're going to call their callback from OUR callback, so we need
1016
* to know what it is, and their context parameter.
1017
*/
1018
Info.Hid = HID;
1019
Info.Context = Context;
1020
Info.UserFunction = UserFunction;
1021
1022
/*
1023
* Lock the namespace around the walk.
1024
* The namespace will be unlocked/locked around each call
1025
* to the user function - since this function
1026
* must be allowed to make Acpi calls itself.
1027
*/
1028
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1029
if (ACPI_FAILURE (Status))
1030
{
1031
return_ACPI_STATUS (Status);
1032
}
1033
1034
Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1035
ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
1036
AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
1037
1038
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1039
return_ACPI_STATUS (Status);
1040
}
1041
1042
ACPI_EXPORT_SYMBOL (AcpiGetDevices)
1043
1044
1045
/*******************************************************************************
1046
*
1047
* FUNCTION: AcpiAttachData
1048
*
1049
* PARAMETERS: ObjHandle - Namespace node
1050
* Handler - Handler for this attachment
1051
* Data - Pointer to data to be attached
1052
*
1053
* RETURN: Status
1054
*
1055
* DESCRIPTION: Attach arbitrary data and handler to a namespace node.
1056
*
1057
******************************************************************************/
1058
1059
ACPI_STATUS
1060
AcpiAttachData (
1061
ACPI_HANDLE ObjHandle,
1062
ACPI_OBJECT_HANDLER Handler,
1063
void *Data)
1064
{
1065
ACPI_NAMESPACE_NODE *Node;
1066
ACPI_STATUS Status;
1067
1068
1069
/* Parameter validation */
1070
1071
if (!ObjHandle ||
1072
!Handler ||
1073
!Data)
1074
{
1075
return (AE_BAD_PARAMETER);
1076
}
1077
1078
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1079
if (ACPI_FAILURE (Status))
1080
{
1081
return (Status);
1082
}
1083
1084
/* Convert and validate the handle */
1085
1086
Node = AcpiNsValidateHandle (ObjHandle);
1087
if (!Node)
1088
{
1089
Status = AE_BAD_PARAMETER;
1090
goto UnlockAndExit;
1091
}
1092
1093
Status = AcpiNsAttachData (Node, Handler, Data);
1094
1095
UnlockAndExit:
1096
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1097
return (Status);
1098
}
1099
1100
ACPI_EXPORT_SYMBOL (AcpiAttachData)
1101
1102
1103
/*******************************************************************************
1104
*
1105
* FUNCTION: AcpiDetachData
1106
*
1107
* PARAMETERS: ObjHandle - Namespace node handle
1108
* Handler - Handler used in call to AcpiAttachData
1109
*
1110
* RETURN: Status
1111
*
1112
* DESCRIPTION: Remove data that was previously attached to a node.
1113
*
1114
******************************************************************************/
1115
1116
ACPI_STATUS
1117
AcpiDetachData (
1118
ACPI_HANDLE ObjHandle,
1119
ACPI_OBJECT_HANDLER Handler)
1120
{
1121
ACPI_NAMESPACE_NODE *Node;
1122
ACPI_STATUS Status;
1123
1124
1125
/* Parameter validation */
1126
1127
if (!ObjHandle ||
1128
!Handler)
1129
{
1130
return (AE_BAD_PARAMETER);
1131
}
1132
1133
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1134
if (ACPI_FAILURE (Status))
1135
{
1136
return (Status);
1137
}
1138
1139
/* Convert and validate the handle */
1140
1141
Node = AcpiNsValidateHandle (ObjHandle);
1142
if (!Node)
1143
{
1144
Status = AE_BAD_PARAMETER;
1145
goto UnlockAndExit;
1146
}
1147
1148
Status = AcpiNsDetachData (Node, Handler);
1149
1150
UnlockAndExit:
1151
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1152
return (Status);
1153
}
1154
1155
ACPI_EXPORT_SYMBOL (AcpiDetachData)
1156
1157
1158
/*******************************************************************************
1159
*
1160
* FUNCTION: AcpiGetData
1161
*
1162
* PARAMETERS: ObjHandle - Namespace node
1163
* Handler - Handler used in call to AttachData
1164
* Data - Where the data is returned
1165
*
1166
* RETURN: Status
1167
*
1168
* DESCRIPTION: Retrieve data that was previously attached to a namespace node.
1169
*
1170
******************************************************************************/
1171
1172
ACPI_STATUS
1173
AcpiGetData (
1174
ACPI_HANDLE ObjHandle,
1175
ACPI_OBJECT_HANDLER Handler,
1176
void **Data)
1177
{
1178
ACPI_NAMESPACE_NODE *Node;
1179
ACPI_STATUS Status;
1180
1181
1182
/* Parameter validation */
1183
1184
if (!ObjHandle ||
1185
!Handler ||
1186
!Data)
1187
{
1188
return (AE_BAD_PARAMETER);
1189
}
1190
1191
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1192
if (ACPI_FAILURE (Status))
1193
{
1194
return (Status);
1195
}
1196
1197
/* Convert and validate the handle */
1198
1199
Node = AcpiNsValidateHandle (ObjHandle);
1200
if (!Node)
1201
{
1202
Status = AE_BAD_PARAMETER;
1203
goto UnlockAndExit;
1204
}
1205
1206
Status = AcpiNsGetAttachedData (Node, Handler, Data);
1207
1208
UnlockAndExit:
1209
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1210
return (Status);
1211
}
1212
1213
ACPI_EXPORT_SYMBOL (AcpiGetData)
1214
1215