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