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