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