nsxfobj.c revision 99679
1/******************************************************************************* 2 * 3 * Module Name: nsxfobj - Public interfaces to the ACPI subsystem 4 * ACPI Object oriented interfaces 5 * $Revision: 112 $ 6 * 7 ******************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118 119#define __NSXFOBJ_C__ 120 121#include "acpi.h" 122#include "acnamesp.h" 123 124 125#define _COMPONENT ACPI_NAMESPACE 126 ACPI_MODULE_NAME ("nsxfobj") 127 128 129/******************************************************************************* 130 * 131 * FUNCTION: AcpiEvaluateObjectTyped 132 * 133 * PARAMETERS: Handle - Object handle (optional) 134 * *Pathname - Object pathname (optional) 135 * **ExternalParams - List of parameters to pass to method, 136 * terminated by NULL. May be NULL 137 * if no parameters are being passed. 138 * *ReturnBuffer - Where to put method's return value (if 139 * any). If NULL, no value is returned. 140 * ReturnType - Expected type of return object 141 * 142 * RETURN: Status 143 * 144 * DESCRIPTION: Find and evaluate the given object, passing the given 145 * parameters if necessary. One of "Handle" or "Pathname" must 146 * be valid (non-null) 147 * 148 ******************************************************************************/ 149 150ACPI_STATUS 151AcpiEvaluateObjectTyped ( 152 ACPI_HANDLE Handle, 153 ACPI_STRING Pathname, 154 ACPI_OBJECT_LIST *ExternalParams, 155 ACPI_BUFFER *ReturnBuffer, 156 ACPI_OBJECT_TYPE ReturnType) 157{ 158 ACPI_STATUS Status; 159 BOOLEAN MustFree = FALSE; 160 161 162 ACPI_FUNCTION_TRACE ("AcpiEvaluateObjectTyped"); 163 164 165 /* Return buffer must be valid */ 166 167 if (!ReturnBuffer) 168 { 169 return_ACPI_STATUS (AE_BAD_PARAMETER); 170 } 171 172 if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) 173 { 174 MustFree = TRUE; 175 } 176 177 /* Evaluate the object */ 178 179 Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer); 180 if (ACPI_FAILURE (Status)) 181 { 182 return_ACPI_STATUS (Status); 183 } 184 185 /* Type ANY means "don't care" */ 186 187 if (ReturnType == ACPI_TYPE_ANY) 188 { 189 return_ACPI_STATUS (AE_OK); 190 } 191 192 if (ReturnBuffer->Length == 0) 193 { 194 /* Error because caller specifically asked for a return value */ 195 196 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 197 "No return value\n")); 198 199 return_ACPI_STATUS (AE_NULL_OBJECT); 200 } 201 202 /* Examine the object type returned from EvaluateObject */ 203 204 if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) 205 { 206 return_ACPI_STATUS (AE_OK); 207 } 208 209 /* Return object type does not match requested type */ 210 211 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 212 "Incorrect return type [%s] requested [%s]\n", 213 AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), 214 AcpiUtGetTypeName (ReturnType))); 215 216 if (MustFree) 217 { 218 /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ 219 220 AcpiOsFree (ReturnBuffer->Pointer); 221 ReturnBuffer->Pointer = NULL; 222 } 223 224 ReturnBuffer->Length = 0; 225 return_ACPI_STATUS (AE_TYPE); 226} 227 228 229/******************************************************************************* 230 * 231 * FUNCTION: AcpiEvaluateObject 232 * 233 * PARAMETERS: Handle - Object handle (optional) 234 * *Pathname - Object pathname (optional) 235 * **ExternalParams - List of parameters to pass to method, 236 * terminated by NULL. May be NULL 237 * if no parameters are being passed. 238 * *ReturnBuffer - Where to put method's return value (if 239 * any). If NULL, no value is returned. 240 * 241 * RETURN: Status 242 * 243 * DESCRIPTION: Find and evaluate the given object, passing the given 244 * parameters if necessary. One of "Handle" or "Pathname" must 245 * be valid (non-null) 246 * 247 ******************************************************************************/ 248 249ACPI_STATUS 250AcpiEvaluateObject ( 251 ACPI_HANDLE Handle, 252 ACPI_STRING Pathname, 253 ACPI_OBJECT_LIST *ExternalParams, 254 ACPI_BUFFER *ReturnBuffer) 255{ 256 ACPI_STATUS Status; 257 ACPI_OPERAND_OBJECT **InternalParams = NULL; 258 ACPI_OPERAND_OBJECT *InternalReturnObj = NULL; 259 ACPI_SIZE BufferSpaceNeeded; 260 UINT32 i; 261 262 263 ACPI_FUNCTION_TRACE ("AcpiEvaluateObject"); 264 265 266 /* 267 * If there are parameters to be passed to the object 268 * (which must be a control method), the external objects 269 * must be converted to internal objects 270 */ 271 if (ExternalParams && ExternalParams->Count) 272 { 273 /* 274 * Allocate a new parameter block for the internal objects 275 * Add 1 to count to allow for null terminated internal list 276 */ 277 InternalParams = ACPI_MEM_CALLOCATE (((ACPI_SIZE) ExternalParams->Count + 1) * 278 sizeof (void *)); 279 if (!InternalParams) 280 { 281 return_ACPI_STATUS (AE_NO_MEMORY); 282 } 283 284 /* 285 * Convert each external object in the list to an 286 * internal object 287 */ 288 for (i = 0; i < ExternalParams->Count; i++) 289 { 290 Status = AcpiUtCopyEobjectToIobject (&ExternalParams->Pointer[i], 291 &InternalParams[i]); 292 if (ACPI_FAILURE (Status)) 293 { 294 AcpiUtDeleteInternalObjectList (InternalParams); 295 return_ACPI_STATUS (Status); 296 } 297 } 298 InternalParams[ExternalParams->Count] = NULL; 299 } 300 301 /* 302 * Three major cases: 303 * 1) Fully qualified pathname 304 * 2) No handle, not fully qualified pathname (error) 305 * 3) Valid handle 306 */ 307 if ((Pathname) && 308 (AcpiNsValidRootPrefix (Pathname[0]))) 309 { 310 /* 311 * The path is fully qualified, just evaluate by name 312 */ 313 Status = AcpiNsEvaluateByName (Pathname, InternalParams, 314 &InternalReturnObj); 315 } 316 else if (!Handle) 317 { 318 /* 319 * A handle is optional iff a fully qualified pathname 320 * is specified. Since we've already handled fully 321 * qualified names above, this is an error 322 */ 323 if (!Pathname) 324 { 325 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 326 "Both Handle and Pathname are NULL\n")); 327 } 328 else 329 { 330 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 331 "Handle is NULL and Pathname is relative\n")); 332 } 333 334 Status = AE_BAD_PARAMETER; 335 } 336 else 337 { 338 /* 339 * We get here if we have a handle -- and if we have a 340 * pathname it is relative. The handle will be validated 341 * in the lower procedures 342 */ 343 if (!Pathname) 344 { 345 /* 346 * The null pathname case means the handle is for 347 * the actual object to be evaluated 348 */ 349 Status = AcpiNsEvaluateByHandle (Handle, InternalParams, 350 &InternalReturnObj); 351 } 352 else 353 { 354 /* 355 * Both a Handle and a relative Pathname 356 */ 357 Status = AcpiNsEvaluateRelative (Handle, Pathname, InternalParams, 358 &InternalReturnObj); 359 } 360 } 361 362 363 /* 364 * If we are expecting a return value, and all went well above, 365 * copy the return value to an external object. 366 */ 367 if (ReturnBuffer) 368 { 369 if (!InternalReturnObj) 370 { 371 ReturnBuffer->Length = 0; 372 } 373 else 374 { 375 if (ACPI_GET_DESCRIPTOR_TYPE (InternalReturnObj) == ACPI_DESC_TYPE_NAMED) 376 { 377 /* 378 * If we received a NS Node as a return object, this means that 379 * the object we are evaluating has nothing interesting to 380 * return (such as a mutex, etc.) We return an error because 381 * these types are essentially unsupported by this interface. 382 * We don't check up front because this makes it easier to add 383 * support for various types at a later date if necessary. 384 */ 385 Status = AE_TYPE; 386 InternalReturnObj = NULL; /* No need to delete a NS Node */ 387 ReturnBuffer->Length = 0; 388 } 389 390 if (ACPI_SUCCESS (Status)) 391 { 392 /* 393 * Find out how large a buffer is needed 394 * to contain the returned object 395 */ 396 Status = AcpiUtGetObjectSize (InternalReturnObj, 397 &BufferSpaceNeeded); 398 if (ACPI_SUCCESS (Status)) 399 { 400 /* Validate/Allocate/Clear caller buffer */ 401 402 Status = AcpiUtInitializeBuffer (ReturnBuffer, BufferSpaceNeeded); 403 if (ACPI_FAILURE (Status)) 404 { 405 /* 406 * Caller's buffer is too small or a new one can't be allocated 407 */ 408 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 409 "Needed buffer size %X, %s\n", 410 (UINT32) BufferSpaceNeeded, AcpiFormatException (Status))); 411 } 412 else 413 { 414 /* 415 * We have enough space for the object, build it 416 */ 417 Status = AcpiUtCopyIobjectToEobject (InternalReturnObj, 418 ReturnBuffer); 419 } 420 } 421 } 422 } 423 } 424 425 /* Delete the return and parameter objects */ 426 427 if (InternalReturnObj) 428 { 429 /* 430 * Delete the internal return object. (Or at least 431 * decrement the reference count by one) 432 */ 433 AcpiUtRemoveReference (InternalReturnObj); 434 } 435 436 /* 437 * Free the input parameter list (if we created one), 438 */ 439 if (InternalParams) 440 { 441 /* Free the allocated parameter block */ 442 443 AcpiUtDeleteInternalObjectList (InternalParams); 444 } 445 446 return_ACPI_STATUS (Status); 447} 448 449 450/******************************************************************************* 451 * 452 * FUNCTION: AcpiGetNextObject 453 * 454 * PARAMETERS: Type - Type of object to be searched for 455 * Parent - Parent object whose children we are getting 456 * LastChild - Previous child that was found. 457 * The NEXT child will be returned 458 * RetHandle - Where handle to the next object is placed 459 * 460 * RETURN: Status 461 * 462 * DESCRIPTION: Return the next peer object within the namespace. If Handle is 463 * valid, Scope is ignored. Otherwise, the first object within 464 * Scope is returned. 465 * 466 ******************************************************************************/ 467 468ACPI_STATUS 469AcpiGetNextObject ( 470 ACPI_OBJECT_TYPE Type, 471 ACPI_HANDLE Parent, 472 ACPI_HANDLE Child, 473 ACPI_HANDLE *RetHandle) 474{ 475 ACPI_STATUS Status; 476 ACPI_NAMESPACE_NODE *Node; 477 ACPI_NAMESPACE_NODE *ParentNode = NULL; 478 ACPI_NAMESPACE_NODE *ChildNode = NULL; 479 480 481 /* Parameter validation */ 482 483 if (Type > ACPI_TYPE_MAX) 484 { 485 return (AE_BAD_PARAMETER); 486 } 487 488 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 489 if (ACPI_FAILURE (Status)) 490 { 491 return (Status); 492 } 493 494 /* If null handle, use the parent */ 495 496 if (!Child) 497 { 498 /* Start search at the beginning of the specified scope */ 499 500 ParentNode = AcpiNsMapHandleToNode (Parent); 501 if (!ParentNode) 502 { 503 Status = AE_BAD_PARAMETER; 504 goto UnlockAndExit; 505 } 506 } 507 else 508 { 509 /* Non-null handle, ignore the parent */ 510 /* Convert and validate the handle */ 511 512 ChildNode = AcpiNsMapHandleToNode (Child); 513 if (!ChildNode) 514 { 515 Status = AE_BAD_PARAMETER; 516 goto UnlockAndExit; 517 } 518 } 519 520 /* Internal function does the real work */ 521 522 Node = AcpiNsGetNextNode (Type, ParentNode, ChildNode); 523 if (!Node) 524 { 525 Status = AE_NOT_FOUND; 526 goto UnlockAndExit; 527 } 528 529 if (RetHandle) 530 { 531 *RetHandle = AcpiNsConvertEntryToHandle (Node); 532 } 533 534 535UnlockAndExit: 536 537 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 538 return (Status); 539} 540 541 542/******************************************************************************* 543 * 544 * FUNCTION: AcpiGetType 545 * 546 * PARAMETERS: Handle - Handle of object whose type is desired 547 * *RetType - Where the type will be placed 548 * 549 * RETURN: Status 550 * 551 * DESCRIPTION: This routine returns the type associatd with a particular handle 552 * 553 ******************************************************************************/ 554 555ACPI_STATUS 556AcpiGetType ( 557 ACPI_HANDLE Handle, 558 ACPI_OBJECT_TYPE *RetType) 559{ 560 ACPI_NAMESPACE_NODE *Node; 561 ACPI_STATUS Status; 562 563 564 /* Parameter Validation */ 565 566 if (!RetType) 567 { 568 return (AE_BAD_PARAMETER); 569 } 570 571 /* 572 * Special case for the predefined Root Node 573 * (return type ANY) 574 */ 575 if (Handle == ACPI_ROOT_OBJECT) 576 { 577 *RetType = ACPI_TYPE_ANY; 578 return (AE_OK); 579 } 580 581 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 582 if (ACPI_FAILURE (Status)) 583 { 584 return (Status); 585 } 586 587 /* Convert and validate the handle */ 588 589 Node = AcpiNsMapHandleToNode (Handle); 590 if (!Node) 591 { 592 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 593 return (AE_BAD_PARAMETER); 594 } 595 596 *RetType = Node->Type; 597 598 599 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 600 return (Status); 601} 602 603 604/******************************************************************************* 605 * 606 * FUNCTION: AcpiGetParent 607 * 608 * PARAMETERS: Handle - Handle of object whose parent is desired 609 * RetHandle - Where the parent handle will be placed 610 * 611 * RETURN: Status 612 * 613 * DESCRIPTION: Returns a handle to the parent of the object represented by 614 * Handle. 615 * 616 ******************************************************************************/ 617 618ACPI_STATUS 619AcpiGetParent ( 620 ACPI_HANDLE Handle, 621 ACPI_HANDLE *RetHandle) 622{ 623 ACPI_NAMESPACE_NODE *Node; 624 ACPI_STATUS Status; 625 626 627 if (!RetHandle) 628 { 629 return (AE_BAD_PARAMETER); 630 } 631 632 /* Special case for the predefined Root Node (no parent) */ 633 634 if (Handle == ACPI_ROOT_OBJECT) 635 { 636 return (AE_NULL_ENTRY); 637 } 638 639 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 640 if (ACPI_FAILURE (Status)) 641 { 642 return (Status); 643 } 644 645 /* Convert and validate the handle */ 646 647 Node = AcpiNsMapHandleToNode (Handle); 648 if (!Node) 649 { 650 Status = AE_BAD_PARAMETER; 651 goto UnlockAndExit; 652 } 653 654 /* Get the parent entry */ 655 656 *RetHandle = 657 AcpiNsConvertEntryToHandle (AcpiNsGetParentNode (Node)); 658 659 /* Return exeption if parent is null */ 660 661 if (!AcpiNsGetParentNode (Node)) 662 { 663 Status = AE_NULL_ENTRY; 664 } 665 666 667UnlockAndExit: 668 669 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 670 return (Status); 671} 672 673 674/******************************************************************************* 675 * 676 * FUNCTION: AcpiWalkNamespace 677 * 678 * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 679 * StartObject - Handle in namespace where search begins 680 * MaxDepth - Depth to which search is to reach 681 * UserFunction - Called when an object of "Type" is found 682 * Context - Passed to user function 683 * ReturnValue - Location where return value of 684 * UserFunction is put if terminated early 685 * 686 * RETURNS Return value from the UserFunction if terminated early. 687 * Otherwise, returns NULL. 688 * 689 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 690 * starting (and ending) at the object specified by StartHandle. 691 * The UserFunction is called whenever an object that matches 692 * the type parameter is found. If the user function returns 693 * a non-zero value, the search is terminated immediately and this 694 * value is returned to the caller. 695 * 696 * The point of this procedure is to provide a generic namespace 697 * walk routine that can be called from multiple places to 698 * provide multiple services; the User Function can be tailored 699 * to each task, whether it is a print function, a compare 700 * function, etc. 701 * 702 ******************************************************************************/ 703 704ACPI_STATUS 705AcpiWalkNamespace ( 706 ACPI_OBJECT_TYPE Type, 707 ACPI_HANDLE StartObject, 708 UINT32 MaxDepth, 709 ACPI_WALK_CALLBACK UserFunction, 710 void *Context, 711 void **ReturnValue) 712{ 713 ACPI_STATUS Status; 714 715 716 ACPI_FUNCTION_TRACE ("AcpiWalkNamespace"); 717 718 719 /* Parameter validation */ 720 721 if ((Type > ACPI_TYPE_MAX) || 722 (!MaxDepth) || 723 (!UserFunction)) 724 { 725 return_ACPI_STATUS (AE_BAD_PARAMETER); 726 } 727 728 /* 729 * Lock the namespace around the walk. 730 * The namespace will be unlocked/locked around each call 731 * to the user function - since this function 732 * must be allowed to make Acpi calls itself. 733 */ 734 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 735 if (ACPI_FAILURE (Status)) 736 { 737 return_ACPI_STATUS (Status); 738 } 739 740 Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, ACPI_NS_WALK_UNLOCK, 741 UserFunction, Context, ReturnValue); 742 743 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 744 return_ACPI_STATUS (Status); 745} 746 747 748/******************************************************************************* 749 * 750 * FUNCTION: AcpiNsGetDeviceCallback 751 * 752 * PARAMETERS: Callback from AcpiGetDevice 753 * 754 * RETURN: Status 755 * 756 * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non- 757 * present devices, or if they specified a HID, it filters based 758 * on that. 759 * 760 ******************************************************************************/ 761 762static ACPI_STATUS 763AcpiNsGetDeviceCallback ( 764 ACPI_HANDLE ObjHandle, 765 UINT32 NestingLevel, 766 void *Context, 767 void **ReturnValue) 768{ 769 ACPI_STATUS Status; 770 ACPI_NAMESPACE_NODE *Node; 771 UINT32 Flags; 772 ACPI_DEVICE_ID Hid; 773 ACPI_DEVICE_ID Cid; 774 ACPI_GET_DEVICES_INFO *Info; 775 776 777 Info = Context; 778 779 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 780 if (ACPI_FAILURE (Status)) 781 { 782 return (Status); 783 } 784 785 Node = AcpiNsMapHandleToNode (ObjHandle); 786 Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 787 if (ACPI_FAILURE (Status)) 788 { 789 return (Status); 790 } 791 792 if (!Node) 793 { 794 return (AE_BAD_PARAMETER); 795 } 796 797 /* 798 * Run _STA to determine if device is present 799 */ 800 Status = AcpiUtExecute_STA (Node, &Flags); 801 if (ACPI_FAILURE (Status)) 802 { 803 return (AE_CTRL_DEPTH); 804 } 805 806 if (!(Flags & 0x01)) 807 { 808 /* Don't return at the device or children of the device if not there */ 809 return (AE_CTRL_DEPTH); 810 } 811 812 /* 813 * Filter based on device HID & CID 814 */ 815 if (Info->Hid != NULL) 816 { 817 Status = AcpiUtExecute_HID (Node, &Hid); 818 if (Status == AE_NOT_FOUND) 819 { 820 return (AE_OK); 821 } 822 else if (ACPI_FAILURE (Status)) 823 { 824 return (AE_CTRL_DEPTH); 825 } 826 827 if (ACPI_STRNCMP (Hid.Buffer, Info->Hid, sizeof (Hid.Buffer)) != 0) 828 { 829 Status = AcpiUtExecute_CID (Node, &Cid); 830 if (Status == AE_NOT_FOUND) 831 { 832 return (AE_OK); 833 } 834 else if (ACPI_FAILURE (Status)) 835 { 836 return (AE_CTRL_DEPTH); 837 } 838 839 /* TBD: Handle CID packages */ 840 841 if (ACPI_STRNCMP (Cid.Buffer, Info->Hid, sizeof (Cid.Buffer)) != 0) 842 { 843 return (AE_OK); 844 } 845 } 846 } 847 848 Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue); 849 return (Status); 850} 851 852 853/******************************************************************************* 854 * 855 * FUNCTION: AcpiGetDevices 856 * 857 * PARAMETERS: HID - HID to search for. Can be NULL. 858 * UserFunction - Called when a matching object is found 859 * Context - Passed to user function 860 * ReturnValue - Location where return value of 861 * UserFunction is put if terminated early 862 * 863 * RETURNS Return value from the UserFunction if terminated early. 864 * Otherwise, returns NULL. 865 * 866 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 867 * starting (and ending) at the object specified by StartHandle. 868 * The UserFunction is called whenever an object that matches 869 * the type parameter is found. If the user function returns 870 * a non-zero value, the search is terminated immediately and this 871 * value is returned to the caller. 872 * 873 * This is a wrapper for WalkNamespace, but the callback performs 874 * additional filtering. Please see AcpiGetDeviceCallback. 875 * 876 ******************************************************************************/ 877 878ACPI_STATUS 879AcpiGetDevices ( 880 NATIVE_CHAR *HID, 881 ACPI_WALK_CALLBACK UserFunction, 882 void *Context, 883 void **ReturnValue) 884{ 885 ACPI_STATUS Status; 886 ACPI_GET_DEVICES_INFO Info; 887 888 889 ACPI_FUNCTION_TRACE ("AcpiGetDevices"); 890 891 892 /* Parameter validation */ 893 894 if (!UserFunction) 895 { 896 return_ACPI_STATUS (AE_BAD_PARAMETER); 897 } 898 899 /* 900 * We're going to call their callback from OUR callback, so we need 901 * to know what it is, and their context parameter. 902 */ 903 Info.Context = Context; 904 Info.UserFunction = UserFunction; 905 Info.Hid = HID; 906 907 /* 908 * Lock the namespace around the walk. 909 * The namespace will be unlocked/locked around each call 910 * to the user function - since this function 911 * must be allowed to make Acpi calls itself. 912 */ 913 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 914 if (ACPI_FAILURE (Status)) 915 { 916 return_ACPI_STATUS (Status); 917 } 918 919 Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, 920 ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 921 ACPI_NS_WALK_UNLOCK, 922 AcpiNsGetDeviceCallback, &Info, 923 ReturnValue); 924 925 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 926 return_ACPI_STATUS (Status); 927} 928 929 930/******************************************************************************* 931 * 932 * FUNCTION: AcpiAttachData 933 * 934 * PARAMETERS: 935 * 936 * RETURN: Status 937 * 938 * DESCRIPTION: 939 * 940 ******************************************************************************/ 941 942ACPI_STATUS 943AcpiAttachData ( 944 ACPI_HANDLE ObjHandle, 945 ACPI_OBJECT_HANDLER Handler, 946 void *Data) 947{ 948 ACPI_NAMESPACE_NODE *Node; 949 ACPI_STATUS Status; 950 951 952 /* Parameter validation */ 953 954 if (!ObjHandle || 955 !Handler || 956 !Data) 957 { 958 return (AE_BAD_PARAMETER); 959 } 960 961 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 962 if (ACPI_FAILURE (Status)) 963 { 964 return (Status); 965 } 966 967 /* Convert and validate the handle */ 968 969 Node = AcpiNsMapHandleToNode (ObjHandle); 970 if (!Node) 971 { 972 Status = AE_BAD_PARAMETER; 973 goto UnlockAndExit; 974 } 975 976 Status = AcpiNsAttachData (Node, Handler, Data); 977 978UnlockAndExit: 979 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 980 return (Status); 981} 982 983 984/******************************************************************************* 985 * 986 * FUNCTION: AcpiDetachData 987 * 988 * PARAMETERS: 989 * 990 * RETURN: Status 991 * 992 * DESCRIPTION: 993 * 994 ******************************************************************************/ 995 996ACPI_STATUS 997AcpiDetachData ( 998 ACPI_HANDLE ObjHandle, 999 ACPI_OBJECT_HANDLER Handler) 1000{ 1001 ACPI_NAMESPACE_NODE *Node; 1002 ACPI_STATUS Status; 1003 1004 1005 /* Parameter validation */ 1006 1007 if (!ObjHandle || 1008 !Handler) 1009 { 1010 return (AE_BAD_PARAMETER); 1011 } 1012 1013 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1014 if (ACPI_FAILURE (Status)) 1015 { 1016 return (Status); 1017 } 1018 1019 /* Convert and validate the handle */ 1020 1021 Node = AcpiNsMapHandleToNode (ObjHandle); 1022 if (!Node) 1023 { 1024 Status = AE_BAD_PARAMETER; 1025 goto UnlockAndExit; 1026 } 1027 1028 Status = AcpiNsDetachData (Node, Handler); 1029 1030UnlockAndExit: 1031 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1032 return (Status); 1033} 1034 1035 1036/******************************************************************************* 1037 * 1038 * FUNCTION: AcpiGetData 1039 * 1040 * PARAMETERS: 1041 * 1042 * RETURN: Status 1043 * 1044 * DESCRIPTION: 1045 * 1046 ******************************************************************************/ 1047 1048ACPI_STATUS 1049AcpiGetData ( 1050 ACPI_HANDLE ObjHandle, 1051 ACPI_OBJECT_HANDLER Handler, 1052 void **Data) 1053{ 1054 ACPI_NAMESPACE_NODE *Node; 1055 ACPI_STATUS Status; 1056 1057 1058 /* Parameter validation */ 1059 1060 if (!ObjHandle || 1061 !Handler || 1062 !Data) 1063 { 1064 return (AE_BAD_PARAMETER); 1065 } 1066 1067 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1068 if (ACPI_FAILURE (Status)) 1069 { 1070 return (Status); 1071 } 1072 1073 /* Convert and validate the handle */ 1074 1075 Node = AcpiNsMapHandleToNode (ObjHandle); 1076 if (!Node) 1077 { 1078 Status = AE_BAD_PARAMETER; 1079 goto UnlockAndExit; 1080 } 1081 1082 Status = AcpiNsGetAttachedData (Node, Handler, Data); 1083 1084UnlockAndExit: 1085 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1086 return (Status); 1087} 1088 1089 1090