1 /*******************************************************************************
2 *
3 * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4 * ACPI Object evaluation interfaces
5 *
6 ******************************************************************************/
7
8 /*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46 #define __NSXFEVAL_C__
47
48 #include "acpi.h"
49 #include "accommon.h"
50 #include "acnamesp.h"
51 #include "acinterp.h"
52
53
54 #define _COMPONENT ACPI_NAMESPACE
55 ACPI_MODULE_NAME ("nsxfeval")
56
57 /* Local prototypes */
58
59 static void
60 AcpiNsResolveReferences (
61 ACPI_EVALUATE_INFO *Info);
62
63
64 /*******************************************************************************
65 *
66 * FUNCTION: AcpiEvaluateObjectTyped
74 * any). If NULL, no value is returned.
75 * ReturnType - Expected type of return object
76 *
77 * RETURN: Status
78 *
79 * DESCRIPTION: Find and evaluate the given object, passing the given
80 * parameters if necessary. One of "Handle" or "Pathname" must
81 * be valid (non-null)
82 *
83 ******************************************************************************/
84
85 ACPI_STATUS
86 AcpiEvaluateObjectTyped (
87 ACPI_HANDLE Handle,
88 ACPI_STRING Pathname,
89 ACPI_OBJECT_LIST *ExternalParams,
90 ACPI_BUFFER *ReturnBuffer,
91 ACPI_OBJECT_TYPE ReturnType)
92 {
93 ACPI_STATUS Status;
94 BOOLEAN MustFree = FALSE;
95
96
97 ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
98
99
100 /* Return buffer must be valid */
101
102 if (!ReturnBuffer)
103 {
104 return_ACPI_STATUS (AE_BAD_PARAMETER);
105 }
106
107 if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
108 {
109 MustFree = TRUE;
110 }
111
112 /* Evaluate the object */
113
114 Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
115 if (ACPI_FAILURE (Status))
116 {
117 return_ACPI_STATUS (Status);
118 }
119
120 /* Type ANY means "don't care" */
121
122 if (ReturnType == ACPI_TYPE_ANY)
123 {
124 return_ACPI_STATUS (AE_OK);
125 }
126
127 if (ReturnBuffer->Length == 0)
128 {
129 /* Error because caller specifically asked for a return value */
130
131 ACPI_ERROR ((AE_INFO, "No return value"));
132 return_ACPI_STATUS (AE_NULL_OBJECT);
133 }
134
135 /* Examine the object type returned from EvaluateObject */
136
137 if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
138 {
139 return_ACPI_STATUS (AE_OK);
140 }
141
142 /* Return object type does not match requested type */
143
144 ACPI_ERROR ((AE_INFO,
145 "Incorrect return type [%s] requested [%s]",
146 AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
147 AcpiUtGetTypeName (ReturnType)));
148
149 if (MustFree)
150 {
151 /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
152
153 AcpiOsFree (ReturnBuffer->Pointer);
154 ReturnBuffer->Pointer = NULL;
155 }
156
157 ReturnBuffer->Length = 0;
158 return_ACPI_STATUS (AE_TYPE);
159 }
160
161 ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
162
163
164 /*******************************************************************************
165 *
166 * FUNCTION: AcpiEvaluateObject
167 *
168 * PARAMETERS: Handle - Object handle (optional)
169 * Pathname - Object pathname (optional)
170 * ExternalParams - List of parameters to pass to method,
171 * terminated by NULL. May be NULL
172 * if no parameters are being passed.
188 ACPI_OBJECT_LIST *ExternalParams,
189 ACPI_BUFFER *ReturnBuffer)
190 {
191 ACPI_STATUS Status;
192 ACPI_EVALUATE_INFO *Info;
193 ACPI_SIZE BufferSpaceNeeded;
194 UINT32 i;
195
196
197 ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
198
199
200 /* Allocate and initialize the evaluation information block */
201
202 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
203 if (!Info)
204 {
205 return_ACPI_STATUS (AE_NO_MEMORY);
206 }
207
208 Info->Pathname = Pathname;
209
210 /* Convert and validate the device handle */
211
212 Info->PrefixNode = AcpiNsValidateHandle (Handle);
213 if (!Info->PrefixNode)
214 {
215 Status = AE_BAD_PARAMETER;
216 goto Cleanup;
217 }
218
219 /*
220 * If there are parameters to be passed to a control method, the external
221 * objects must all be converted to internal objects
222 */
223 if (ExternalParams && ExternalParams->Count)
224 {
225 /*
226 * Allocate a new parameter block for the internal objects
227 * Add 1 to count to allow for null terminated internal list
228 */
229 Info->Parameters = ACPI_ALLOCATE_ZEROED (
230 ((ACPI_SIZE) ExternalParams->Count + 1) * sizeof (void *));
231 if (!Info->Parameters)
232 {
233 Status = AE_NO_MEMORY;
234 goto Cleanup;
235 }
236
237 /* Convert each external object in the list to an internal object */
238
239 for (i = 0; i < ExternalParams->Count; i++)
240 {
241 Status = AcpiUtCopyEobjectToIobject (
242 &ExternalParams->Pointer[i], &Info->Parameters[i]);
243 if (ACPI_FAILURE (Status))
244 {
245 goto Cleanup;
246 }
247 }
248 Info->Parameters[ExternalParams->Count] = NULL;
249 }
250
251 /*
252 * Three major cases:
253 * 1) Fully qualified pathname
254 * 2) No handle, not fully qualified pathname (error)
255 * 3) Valid handle
256 */
257 if ((Pathname) &&
258 (AcpiNsValidRootPrefix (Pathname[0])))
259 {
260 /* The path is fully qualified, just evaluate by name */
261
262 Info->PrefixNode = NULL;
263 Status = AcpiNsEvaluate (Info);
264 }
265 else if (!Handle)
266 {
267 /*
268 * A handle is optional iff a fully qualified pathname is specified.
269 * Since we've already handled fully qualified names above, this is
270 * an error
271 */
272 if (!Pathname)
273 {
274 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
275 "Both Handle and Pathname are NULL"));
276 }
277 else
278 {
279 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
280 "Null Handle with relative pathname [%s]", Pathname));
281 }
282
283 Status = AE_BAD_PARAMETER;
284 }
285 else
286 {
287 /* We have a namespace a node and a possible relative path */
288
289 Status = AcpiNsEvaluate (Info);
290 }
291
292 /*
293 * If we are expecting a return value, and all went well above,
294 * copy the return value to an external object.
295 */
296 if (ReturnBuffer)
297 {
298 if (!Info->ReturnObject)
299 {
300 ReturnBuffer->Length = 0;
301 }
302 else
303 {
304 if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
305 ACPI_DESC_TYPE_NAMED)
306 {
307 /*
308 * If we received a NS Node as a return object, this means that
309 * the object we are evaluating has nothing interesting to
310 * return (such as a mutex, etc.) We return an error because
432 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
433 * an ACPI_OBJECT.
434 */
435 switch (Info->ReturnObject->Reference.Class)
436 {
437 case ACPI_REFCLASS_INDEX:
438
439 ObjDesc = *(Info->ReturnObject->Reference.Where);
440 break;
441
442 case ACPI_REFCLASS_REFOF:
443
444 Node = Info->ReturnObject->Reference.Object;
445 if (Node)
446 {
447 ObjDesc = Node->Object;
448 }
449 break;
450
451 default:
452 return;
453 }
454
455 /* Replace the existing reference object */
456
457 if (ObjDesc)
458 {
459 AcpiUtAddReference (ObjDesc);
460 AcpiUtRemoveReference (Info->ReturnObject);
461 Info->ReturnObject = ObjDesc;
462 }
463
464 return;
465 }
466
467
468 /*******************************************************************************
469 *
470 * FUNCTION: AcpiWalkNamespace
471 *
472 * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
473 * StartObject - Handle in namespace where search begins
474 * MaxDepth - Depth to which search is to reach
475 * PreOrderVisit - Called during tree pre-order visit
476 * when an object of "Type" is found
477 * PostOrderVisit - Called during tree post-order visit
478 * when an object of "Type" is found
479 * Context - Passed to user function(s) above
480 * ReturnValue - Location where return value of
481 * UserFunction is put if terminated early
482 *
483 * RETURNS Return value from the UserFunction if terminated early.
484 * Otherwise, returns NULL.
485 *
486 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
487 * starting (and ending) at the object specified by StartHandle.
488 * The callback function is called whenever an object that matches
489 * the type parameter is found. If the callback function returns
490 * a non-zero value, the search is terminated immediately and this
491 * value is returned to the caller.
492 *
493 * The point of this procedure is to provide a generic namespace
494 * walk routine that can be called from multiple places to
495 * provide multiple services; the callback function(s) can be
496 * tailored to each task, whether it is a print function,
497 * a compare function, etc.
498 *
499 ******************************************************************************/
500
501 ACPI_STATUS
502 AcpiWalkNamespace (
503 ACPI_OBJECT_TYPE Type,
504 ACPI_HANDLE StartObject,
505 UINT32 MaxDepth,
506 ACPI_WALK_CALLBACK PreOrderVisit,
507 ACPI_WALK_CALLBACK PostOrderVisit,
508 void *Context,
509 void **ReturnValue)
510 {
511 ACPI_STATUS Status;
512
513
514 ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
515
516
517 /* Parameter validation */
518
519 if ((Type > ACPI_TYPE_LOCAL_MAX) ||
520 (!MaxDepth) ||
521 (!PreOrderVisit && !PostOrderVisit))
522 {
523 return_ACPI_STATUS (AE_BAD_PARAMETER);
524 }
525
526 /*
527 * Need to acquire the namespace reader lock to prevent interference
528 * with any concurrent table unloads (which causes the deletion of
529 * namespace objects). We cannot allow the deletion of a namespace node
530 * while the user function is using it. The exception to this are the
531 * nodes created and deleted during control method execution -- these
532 * nodes are marked as temporary nodes and are ignored by the namespace
533 * walk. Thus, control methods can be executed while holding the
534 * namespace deletion lock (and the user function can execute control
535 * methods.)
536 */
537 Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
538 if (ACPI_FAILURE (Status))
539 {
540 return (Status);
541 }
542
543 /*
544 * Lock the namespace around the walk. The namespace will be
545 * unlocked/locked around each call to the user function - since the user
546 * function must be allowed to make ACPICA calls itself (for example, it
547 * will typically execute control methods during device enumeration.)
548 */
549 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
550 if (ACPI_FAILURE (Status))
551 {
552 goto UnlockAndExit;
553 }
554
555 Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
556 ACPI_NS_WALK_UNLOCK, PreOrderVisit,
557 PostOrderVisit, Context, ReturnValue);
558
559 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
560
561 UnlockAndExit:
562 (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
563 return_ACPI_STATUS (Status);
564 }
565
566 ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
567
568
569 /*******************************************************************************
570 *
571 * FUNCTION: AcpiNsGetDeviceCallback
572 *
573 * PARAMETERS: Callback from AcpiGetDevice
574 *
575 * RETURN: Status
576 *
577 * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
578 * present devices, or if they specified a HID, it filters based
579 * on that.
580 *
581 ******************************************************************************/
582
583 static ACPI_STATUS
584 AcpiNsGetDeviceCallback (
585 ACPI_HANDLE ObjHandle,
586 UINT32 NestingLevel,
587 void *Context,
588 void **ReturnValue)
589 {
590 ACPI_GET_DEVICES_INFO *Info = Context;
591 ACPI_STATUS Status;
592 ACPI_NAMESPACE_NODE *Node;
593 UINT32 Flags;
594 ACPI_DEVICE_ID *Hid;
595 ACPI_DEVICE_ID_LIST *Cid;
596 UINT32 i;
597 BOOLEAN Found;
598 int NoMatch;
599
600
601 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
602 if (ACPI_FAILURE (Status))
603 {
604 return (Status);
605 }
606
607 Node = AcpiNsValidateHandle (ObjHandle);
608 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
609 if (ACPI_FAILURE (Status))
610 {
611 return (Status);
612 }
613
614 if (!Node)
615 {
939 return (Status);
940 }
941
942 /* Convert and validate the handle */
943
944 Node = AcpiNsValidateHandle (ObjHandle);
945 if (!Node)
946 {
947 Status = AE_BAD_PARAMETER;
948 goto UnlockAndExit;
949 }
950
951 Status = AcpiNsGetAttachedData (Node, Handler, Data);
952
953 UnlockAndExit:
954 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
955 return (Status);
956 }
957
958 ACPI_EXPORT_SYMBOL (AcpiGetData)
959
960
|
1 /*******************************************************************************
2 *
3 * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4 * ACPI Object evaluation interfaces
5 *
6 ******************************************************************************/
7
8 /*
9 * Copyright (C) 2000 - 2013, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46 #define __NSXFEVAL_C__
47 #define EXPORT_ACPI_INTERFACES
48
49 #include "acpi.h"
50 #include "accommon.h"
51 #include "acnamesp.h"
52 #include "acinterp.h"
53
54
55 #define _COMPONENT ACPI_NAMESPACE
56 ACPI_MODULE_NAME ("nsxfeval")
57
58 /* Local prototypes */
59
60 static void
61 AcpiNsResolveReferences (
62 ACPI_EVALUATE_INFO *Info);
63
64
65 /*******************************************************************************
66 *
67 * FUNCTION: AcpiEvaluateObjectTyped
75 * any). If NULL, no value is returned.
76 * ReturnType - Expected type of return object
77 *
78 * RETURN: Status
79 *
80 * DESCRIPTION: Find and evaluate the given object, passing the given
81 * parameters if necessary. One of "Handle" or "Pathname" must
82 * be valid (non-null)
83 *
84 ******************************************************************************/
85
86 ACPI_STATUS
87 AcpiEvaluateObjectTyped (
88 ACPI_HANDLE Handle,
89 ACPI_STRING Pathname,
90 ACPI_OBJECT_LIST *ExternalParams,
91 ACPI_BUFFER *ReturnBuffer,
92 ACPI_OBJECT_TYPE ReturnType)
93 {
94 ACPI_STATUS Status;
95 BOOLEAN FreeBufferOnError = FALSE;
96
97
98 ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
99
100
101 /* Return buffer must be valid */
102
103 if (!ReturnBuffer)
104 {
105 return_ACPI_STATUS (AE_BAD_PARAMETER);
106 }
107
108 if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
109 {
110 FreeBufferOnError = TRUE;
111 }
112
113 /* Evaluate the object */
114
115 Status = AcpiEvaluateObject (Handle, Pathname,
116 ExternalParams, ReturnBuffer);
117 if (ACPI_FAILURE (Status))
118 {
119 return_ACPI_STATUS (Status);
120 }
121
122 /* Type ANY means "don't care" */
123
124 if (ReturnType == ACPI_TYPE_ANY)
125 {
126 return_ACPI_STATUS (AE_OK);
127 }
128
129 if (ReturnBuffer->Length == 0)
130 {
131 /* Error because caller specifically asked for a return value */
132
133 ACPI_ERROR ((AE_INFO, "No return value"));
134 return_ACPI_STATUS (AE_NULL_OBJECT);
135 }
136
137 /* Examine the object type returned from EvaluateObject */
138
139 if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
140 {
141 return_ACPI_STATUS (AE_OK);
142 }
143
144 /* Return object type does not match requested type */
145
146 ACPI_ERROR ((AE_INFO,
147 "Incorrect return type [%s] requested [%s]",
148 AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
149 AcpiUtGetTypeName (ReturnType)));
150
151 if (FreeBufferOnError)
152 {
153 /*
154 * Free a buffer created via ACPI_ALLOCATE_BUFFER.
155 * Note: We use AcpiOsFree here because AcpiOsAllocate was used
156 * to allocate the buffer. This purposefully bypasses the
157 * (optionally enabled) allocation tracking mechanism since we
158 * only want to track internal allocations.
159 */
160 AcpiOsFree (ReturnBuffer->Pointer);
161 ReturnBuffer->Pointer = NULL;
162 }
163
164 ReturnBuffer->Length = 0;
165 return_ACPI_STATUS (AE_TYPE);
166 }
167
168 ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
169
170
171 /*******************************************************************************
172 *
173 * FUNCTION: AcpiEvaluateObject
174 *
175 * PARAMETERS: Handle - Object handle (optional)
176 * Pathname - Object pathname (optional)
177 * ExternalParams - List of parameters to pass to method,
178 * terminated by NULL. May be NULL
179 * if no parameters are being passed.
195 ACPI_OBJECT_LIST *ExternalParams,
196 ACPI_BUFFER *ReturnBuffer)
197 {
198 ACPI_STATUS Status;
199 ACPI_EVALUATE_INFO *Info;
200 ACPI_SIZE BufferSpaceNeeded;
201 UINT32 i;
202
203
204 ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
205
206
207 /* Allocate and initialize the evaluation information block */
208
209 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
210 if (!Info)
211 {
212 return_ACPI_STATUS (AE_NO_MEMORY);
213 }
214
215 /* Convert and validate the device handle */
216
217 Info->PrefixNode = AcpiNsValidateHandle (Handle);
218 if (!Info->PrefixNode)
219 {
220 Status = AE_BAD_PARAMETER;
221 goto Cleanup;
222 }
223
224 /*
225 * Get the actual namespace node for the target object.
226 * Handles these cases:
227 *
228 * 1) Null node, valid pathname from root (absolute path)
229 * 2) Node and valid pathname (path relative to Node)
230 * 3) Node, Null pathname
231 */
232 if ((Pathname) &&
233 (ACPI_IS_ROOT_PREFIX (Pathname[0])))
234 {
235 /* The path is fully qualified, just evaluate by name */
236
237 Info->PrefixNode = NULL;
238 }
239 else if (!Handle)
240 {
241 /*
242 * A handle is optional iff a fully qualified pathname is specified.
243 * Since we've already handled fully qualified names above, this is
244 * an error.
245 */
246 if (!Pathname)
247 {
248 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
249 "Both Handle and Pathname are NULL"));
250 }
251 else
252 {
253 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
254 "Null Handle with relative pathname [%s]", Pathname));
255 }
256
257 Status = AE_BAD_PARAMETER;
258 goto Cleanup;
259 }
260
261 Info->RelativePathname = Pathname;
262
263 /*
264 * Convert all external objects passed as arguments to the
265 * internal version(s).
266 */
267 if (ExternalParams && ExternalParams->Count)
268 {
269 Info->ParamCount = (UINT16) ExternalParams->Count;
270
271 /* Warn on impossible argument count */
272
273 if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
274 {
275 ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
276 "Excess arguments (%u) - using only %u",
277 Info->ParamCount, ACPI_METHOD_NUM_ARGS));
278
279 Info->ParamCount = ACPI_METHOD_NUM_ARGS;
280 }
281
282 /*
283 * Allocate a new parameter block for the internal objects
284 * Add 1 to count to allow for null terminated internal list
285 */
286 Info->Parameters = ACPI_ALLOCATE_ZEROED (
287 ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
288 if (!Info->Parameters)
289 {
290 Status = AE_NO_MEMORY;
291 goto Cleanup;
292 }
293
294 /* Convert each external object in the list to an internal object */
295
296 for (i = 0; i < Info->ParamCount; i++)
297 {
298 Status = AcpiUtCopyEobjectToIobject (
299 &ExternalParams->Pointer[i], &Info->Parameters[i]);
300 if (ACPI_FAILURE (Status))
301 {
302 goto Cleanup;
303 }
304 }
305
306 Info->Parameters[Info->ParamCount] = NULL;
307 }
308
309
310 #if 0
311
312 /*
313 * Begin incoming argument count analysis. Check for too few args
314 * and too many args.
315 */
316
317 switch (AcpiNsGetType (Info->Node))
318 {
319 case ACPI_TYPE_METHOD:
320
321 /* Check incoming argument count against the method definition */
322
323 if (Info->ObjDesc->Method.ParamCount > Info->ParamCount)
324 {
325 ACPI_ERROR ((AE_INFO,
326 "Insufficient arguments (%u) - %u are required",
327 Info->ParamCount,
328 Info->ObjDesc->Method.ParamCount));
329
330 Status = AE_MISSING_ARGUMENTS;
331 goto Cleanup;
332 }
333
334 else if (Info->ObjDesc->Method.ParamCount < Info->ParamCount)
335 {
336 ACPI_WARNING ((AE_INFO,
337 "Excess arguments (%u) - only %u are required",
338 Info->ParamCount,
339 Info->ObjDesc->Method.ParamCount));
340
341 /* Just pass the required number of arguments */
342
343 Info->ParamCount = Info->ObjDesc->Method.ParamCount;
344 }
345
346 /*
347 * Any incoming external objects to be passed as arguments to the
348 * method must be converted to internal objects
349 */
350 if (Info->ParamCount)
351 {
352 /*
353 * Allocate a new parameter block for the internal objects
354 * Add 1 to count to allow for null terminated internal list
355 */
356 Info->Parameters = ACPI_ALLOCATE_ZEROED (
357 ((ACPI_SIZE) Info->ParamCount + 1) * sizeof (void *));
358 if (!Info->Parameters)
359 {
360 Status = AE_NO_MEMORY;
361 goto Cleanup;
362 }
363
364 /* Convert each external object in the list to an internal object */
365
366 for (i = 0; i < Info->ParamCount; i++)
367 {
368 Status = AcpiUtCopyEobjectToIobject (
369 &ExternalParams->Pointer[i], &Info->Parameters[i]);
370 if (ACPI_FAILURE (Status))
371 {
372 goto Cleanup;
373 }
374 }
375
376 Info->Parameters[Info->ParamCount] = NULL;
377 }
378 break;
379
380 default:
381
382 /* Warn if arguments passed to an object that is not a method */
383
384 if (Info->ParamCount)
385 {
386 ACPI_WARNING ((AE_INFO,
387 "%u arguments were passed to a non-method ACPI object",
388 Info->ParamCount));
389 }
390 break;
391 }
392
393 #endif
394
395
396 /* Now we can evaluate the object */
397
398 Status = AcpiNsEvaluate (Info);
399
400 /*
401 * If we are expecting a return value, and all went well above,
402 * copy the return value to an external object.
403 */
404 if (ReturnBuffer)
405 {
406 if (!Info->ReturnObject)
407 {
408 ReturnBuffer->Length = 0;
409 }
410 else
411 {
412 if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
413 ACPI_DESC_TYPE_NAMED)
414 {
415 /*
416 * If we received a NS Node as a return object, this means that
417 * the object we are evaluating has nothing interesting to
418 * return (such as a mutex, etc.) We return an error because
540 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
541 * an ACPI_OBJECT.
542 */
543 switch (Info->ReturnObject->Reference.Class)
544 {
545 case ACPI_REFCLASS_INDEX:
546
547 ObjDesc = *(Info->ReturnObject->Reference.Where);
548 break;
549
550 case ACPI_REFCLASS_REFOF:
551
552 Node = Info->ReturnObject->Reference.Object;
553 if (Node)
554 {
555 ObjDesc = Node->Object;
556 }
557 break;
558
559 default:
560
561 return;
562 }
563
564 /* Replace the existing reference object */
565
566 if (ObjDesc)
567 {
568 AcpiUtAddReference (ObjDesc);
569 AcpiUtRemoveReference (Info->ReturnObject);
570 Info->ReturnObject = ObjDesc;
571 }
572
573 return;
574 }
575
576
577 /*******************************************************************************
578 *
579 * FUNCTION: AcpiWalkNamespace
580 *
581 * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
582 * StartObject - Handle in namespace where search begins
583 * MaxDepth - Depth to which search is to reach
584 * DescendingCallback - Called during tree descent
585 * when an object of "Type" is found
586 * AscendingCallback - Called during tree ascent
587 * when an object of "Type" is found
588 * Context - Passed to user function(s) above
589 * ReturnValue - Location where return value of
590 * UserFunction is put if terminated early
591 *
592 * RETURNS Return value from the UserFunction if terminated early.
593 * Otherwise, returns NULL.
594 *
595 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
596 * starting (and ending) at the object specified by StartHandle.
597 * The callback function is called whenever an object that matches
598 * the type parameter is found. If the callback function returns
599 * a non-zero value, the search is terminated immediately and this
600 * value is returned to the caller.
601 *
602 * The point of this procedure is to provide a generic namespace
603 * walk routine that can be called from multiple places to
604 * provide multiple services; the callback function(s) can be
605 * tailored to each task, whether it is a print function,
606 * a compare function, etc.
607 *
608 ******************************************************************************/
609
610 ACPI_STATUS
611 AcpiWalkNamespace (
612 ACPI_OBJECT_TYPE Type,
613 ACPI_HANDLE StartObject,
614 UINT32 MaxDepth,
615 ACPI_WALK_CALLBACK DescendingCallback,
616 ACPI_WALK_CALLBACK AscendingCallback,
617 void *Context,
618 void **ReturnValue)
619 {
620 ACPI_STATUS Status;
621
622
623 ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
624
625
626 /* Parameter validation */
627
628 if ((Type > ACPI_TYPE_LOCAL_MAX) ||
629 (!MaxDepth) ||
630 (!DescendingCallback && !AscendingCallback))
631 {
632 return_ACPI_STATUS (AE_BAD_PARAMETER);
633 }
634
635 /*
636 * Need to acquire the namespace reader lock to prevent interference
637 * with any concurrent table unloads (which causes the deletion of
638 * namespace objects). We cannot allow the deletion of a namespace node
639 * while the user function is using it. The exception to this are the
640 * nodes created and deleted during control method execution -- these
641 * nodes are marked as temporary nodes and are ignored by the namespace
642 * walk. Thus, control methods can be executed while holding the
643 * namespace deletion lock (and the user function can execute control
644 * methods.)
645 */
646 Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
647 if (ACPI_FAILURE (Status))
648 {
649 return_ACPI_STATUS (Status);
650 }
651
652 /*
653 * Lock the namespace around the walk. The namespace will be
654 * unlocked/locked around each call to the user function - since the user
655 * function must be allowed to make ACPICA calls itself (for example, it
656 * will typically execute control methods during device enumeration.)
657 */
658 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
659 if (ACPI_FAILURE (Status))
660 {
661 goto UnlockAndExit;
662 }
663
664 /* Now we can validate the starting node */
665
666 if (!AcpiNsValidateHandle (StartObject))
667 {
668 Status = AE_BAD_PARAMETER;
669 goto UnlockAndExit2;
670 }
671
672 Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
673 ACPI_NS_WALK_UNLOCK, DescendingCallback,
674 AscendingCallback, Context, ReturnValue);
675
676 UnlockAndExit2:
677 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
678
679 UnlockAndExit:
680 (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
681 return_ACPI_STATUS (Status);
682 }
683
684 ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
685
686
687 /*******************************************************************************
688 *
689 * FUNCTION: AcpiNsGetDeviceCallback
690 *
691 * PARAMETERS: Callback from AcpiGetDevice
692 *
693 * RETURN: Status
694 *
695 * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
696 * present devices, or if they specified a HID, it filters based
697 * on that.
698 *
699 ******************************************************************************/
700
701 static ACPI_STATUS
702 AcpiNsGetDeviceCallback (
703 ACPI_HANDLE ObjHandle,
704 UINT32 NestingLevel,
705 void *Context,
706 void **ReturnValue)
707 {
708 ACPI_GET_DEVICES_INFO *Info = Context;
709 ACPI_STATUS Status;
710 ACPI_NAMESPACE_NODE *Node;
711 UINT32 Flags;
712 ACPI_PNP_DEVICE_ID *Hid;
713 ACPI_PNP_DEVICE_ID_LIST *Cid;
714 UINT32 i;
715 BOOLEAN Found;
716 int NoMatch;
717
718
719 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
720 if (ACPI_FAILURE (Status))
721 {
722 return (Status);
723 }
724
725 Node = AcpiNsValidateHandle (ObjHandle);
726 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
727 if (ACPI_FAILURE (Status))
728 {
729 return (Status);
730 }
731
732 if (!Node)
733 {
1057 return (Status);
1058 }
1059
1060 /* Convert and validate the handle */
1061
1062 Node = AcpiNsValidateHandle (ObjHandle);
1063 if (!Node)
1064 {
1065 Status = AE_BAD_PARAMETER;
1066 goto UnlockAndExit;
1067 }
1068
1069 Status = AcpiNsGetAttachedData (Node, Handler, Data);
1070
1071 UnlockAndExit:
1072 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1073 return (Status);
1074 }
1075
1076 ACPI_EXPORT_SYMBOL (AcpiGetData)
|