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