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