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