1 /******************************************************************************* 2 * 3 * Module Name: utdelete - object deletion and reference count utilities 4 * 5 ******************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include <contrib/dev/acpica/include/acpi.h> 153 #include <contrib/dev/acpica/include/accommon.h> 154 #include <contrib/dev/acpica/include/acinterp.h> 155 #include <contrib/dev/acpica/include/acnamesp.h> 156 #include <contrib/dev/acpica/include/acevents.h> 157 158 159 #define _COMPONENT ACPI_UTILITIES 160 ACPI_MODULE_NAME ("utdelete") 161 162 /* Local prototypes */ 163 164 static void 165 AcpiUtDeleteInternalObj ( 166 ACPI_OPERAND_OBJECT *Object); 167 168 static void 169 AcpiUtUpdateRefCount ( 170 ACPI_OPERAND_OBJECT *Object, 171 UINT32 Action); 172 173 174 /******************************************************************************* 175 * 176 * FUNCTION: AcpiUtDeleteInternalObj 177 * 178 * PARAMETERS: Object - Object to be deleted 179 * 180 * RETURN: None 181 * 182 * DESCRIPTION: Low level object deletion, after reference counts have been 183 * updated (All reference counts, including sub-objects!) 184 * 185 ******************************************************************************/ 186 187 static void 188 AcpiUtDeleteInternalObj ( 189 ACPI_OPERAND_OBJECT *Object) 190 { 191 void *ObjPointer = NULL; 192 ACPI_OPERAND_OBJECT *HandlerDesc; 193 ACPI_OPERAND_OBJECT *SecondDesc; 194 ACPI_OPERAND_OBJECT *NextDesc; 195 ACPI_OPERAND_OBJECT *StartDesc; 196 ACPI_OPERAND_OBJECT **LastObjPtr; 197 198 199 ACPI_FUNCTION_TRACE_PTR (UtDeleteInternalObj, Object); 200 201 202 if (!Object) 203 { 204 return_VOID; 205 } 206 207 /* 208 * Must delete or free any pointers within the object that are not 209 * actual ACPI objects (for example, a raw buffer pointer). 210 */ 211 switch (Object->Common.Type) 212 { 213 case ACPI_TYPE_STRING: 214 215 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n", 216 Object, Object->String.Pointer)); 217 218 /* Free the actual string buffer */ 219 220 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER)) 221 { 222 /* But only if it is NOT a pointer into an ACPI table */ 223 224 ObjPointer = Object->String.Pointer; 225 } 226 break; 227 228 case ACPI_TYPE_BUFFER: 229 230 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n", 231 Object, Object->Buffer.Pointer)); 232 233 /* Free the actual buffer */ 234 235 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER)) 236 { 237 /* But only if it is NOT a pointer into an ACPI table */ 238 239 ObjPointer = Object->Buffer.Pointer; 240 } 241 break; 242 243 case ACPI_TYPE_PACKAGE: 244 245 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n", 246 Object->Package.Count)); 247 248 /* 249 * Elements of the package are not handled here, they are deleted 250 * separately 251 */ 252 253 /* Free the (variable length) element pointer array */ 254 255 ObjPointer = Object->Package.Elements; 256 break; 257 258 /* 259 * These objects have a possible list of notify handlers. 260 * Device object also may have a GPE block. 261 */ 262 case ACPI_TYPE_DEVICE: 263 264 if (Object->Device.GpeBlock) 265 { 266 (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock); 267 } 268 269 ACPI_FALLTHROUGH; 270 271 case ACPI_TYPE_PROCESSOR: 272 case ACPI_TYPE_THERMAL: 273 274 /* Walk the address handler list for this object */ 275 276 HandlerDesc = Object->CommonNotify.Handler; 277 while (HandlerDesc) 278 { 279 NextDesc = HandlerDesc->AddressSpace.Next; 280 AcpiUtRemoveReference (HandlerDesc); 281 HandlerDesc = NextDesc; 282 } 283 break; 284 285 case ACPI_TYPE_MUTEX: 286 287 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 288 "***** Mutex %p, OS Mutex %p\n", 289 Object, Object->Mutex.OsMutex)); 290 291 if (Object == AcpiGbl_GlobalLockMutex) 292 { 293 /* Global Lock has extra semaphore */ 294 295 (void) AcpiOsDeleteSemaphore (AcpiGbl_GlobalLockSemaphore); 296 AcpiGbl_GlobalLockSemaphore = NULL; 297 298 AcpiOsDeleteMutex (Object->Mutex.OsMutex); 299 AcpiGbl_GlobalLockMutex = NULL; 300 } 301 else 302 { 303 AcpiExUnlinkMutex (Object); 304 AcpiOsDeleteMutex (Object->Mutex.OsMutex); 305 } 306 break; 307 308 case ACPI_TYPE_EVENT: 309 310 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 311 "***** Event %p, OS Semaphore %p\n", 312 Object, Object->Event.OsSemaphore)); 313 314 (void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore); 315 Object->Event.OsSemaphore = NULL; 316 break; 317 318 case ACPI_TYPE_METHOD: 319 320 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 321 "***** Method %p\n", Object)); 322 323 /* Delete the method mutex if it exists */ 324 325 if (Object->Method.Mutex) 326 { 327 AcpiOsDeleteMutex (Object->Method.Mutex->Mutex.OsMutex); 328 AcpiUtDeleteObjectDesc (Object->Method.Mutex); 329 Object->Method.Mutex = NULL; 330 } 331 332 if (Object->Method.Node) 333 { 334 Object->Method.Node = NULL; 335 } 336 break; 337 338 case ACPI_TYPE_REGION: 339 340 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 341 "***** Region %p\n", Object)); 342 343 /* 344 * Update AddressRange list. However, only permanent regions 345 * are installed in this list. (Not created within a method) 346 */ 347 if (!(Object->Region.Node->Flags & ANOBJ_TEMPORARY)) 348 { 349 AcpiUtRemoveAddressRange (Object->Region.SpaceId, 350 Object->Region.Node); 351 } 352 353 SecondDesc = AcpiNsGetSecondaryObject (Object); 354 if (SecondDesc) 355 { 356 /* 357 * Free the RegionContext if and only if the handler is one of the 358 * default handlers -- and therefore, we created the context object 359 * locally, it was not created by an external caller. 360 */ 361 HandlerDesc = Object->Region.Handler; 362 if (HandlerDesc) 363 { 364 NextDesc = HandlerDesc->AddressSpace.RegionList; 365 StartDesc = NextDesc; 366 LastObjPtr = &HandlerDesc->AddressSpace.RegionList; 367 368 /* Remove the region object from the handler list */ 369 370 while (NextDesc) 371 { 372 if (NextDesc == Object) 373 { 374 *LastObjPtr = NextDesc->Region.Next; 375 break; 376 } 377 378 /* Walk the linked list of handlers */ 379 380 LastObjPtr = &NextDesc->Region.Next; 381 NextDesc = NextDesc->Region.Next; 382 383 /* Prevent infinite loop if list is corrupted */ 384 385 if (NextDesc == StartDesc) 386 { 387 ACPI_ERROR ((AE_INFO, 388 "Circular region list in address handler object %p", 389 HandlerDesc)); 390 return_VOID; 391 } 392 } 393 394 if (HandlerDesc->AddressSpace.HandlerFlags & 395 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) 396 { 397 /* Deactivate region and free region context */ 398 399 if (HandlerDesc->AddressSpace.Setup) 400 { 401 (void) HandlerDesc->AddressSpace.Setup (Object, 402 ACPI_REGION_DEACTIVATE, 403 HandlerDesc->AddressSpace.Context, 404 &SecondDesc->Extra.RegionContext); 405 } 406 } 407 408 AcpiUtRemoveReference (HandlerDesc); 409 } 410 411 /* Now we can free the Extra object */ 412 413 AcpiUtDeleteObjectDesc (SecondDesc); 414 } 415 if (Object->Field.InternalPccBuffer) 416 { 417 ACPI_FREE(Object->Field.InternalPccBuffer); 418 } 419 420 break; 421 422 case ACPI_TYPE_BUFFER_FIELD: 423 424 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 425 "***** Buffer Field %p\n", Object)); 426 427 SecondDesc = AcpiNsGetSecondaryObject (Object); 428 if (SecondDesc) 429 { 430 AcpiUtDeleteObjectDesc (SecondDesc); 431 } 432 break; 433 434 case ACPI_TYPE_LOCAL_BANK_FIELD: 435 436 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 437 "***** Bank Field %p\n", Object)); 438 439 SecondDesc = AcpiNsGetSecondaryObject (Object); 440 if (SecondDesc) 441 { 442 AcpiUtDeleteObjectDesc (SecondDesc); 443 } 444 break; 445 446 case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: 447 448 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 449 "***** Address handler %p\n", Object)); 450 451 AcpiOsDeleteMutex (Object->AddressSpace.ContextMutex); 452 break; 453 454 default: 455 456 break; 457 } 458 459 /* Free any allocated memory (pointer within the object) found above */ 460 461 if (ObjPointer) 462 { 463 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n", 464 ObjPointer)); 465 ACPI_FREE (ObjPointer); 466 } 467 468 /* Now the object can be safely deleted */ 469 470 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS, "%s: Deleting Object %p [%s]\n", 471 ACPI_GET_FUNCTION_NAME, Object, AcpiUtGetObjectTypeName (Object))); 472 473 AcpiUtDeleteObjectDesc (Object); 474 return_VOID; 475 } 476 477 478 /******************************************************************************* 479 * 480 * FUNCTION: AcpiUtDeleteInternalObjectList 481 * 482 * PARAMETERS: ObjList - Pointer to the list to be deleted 483 * 484 * RETURN: None 485 * 486 * DESCRIPTION: This function deletes an internal object list, including both 487 * simple objects and package objects 488 * 489 ******************************************************************************/ 490 491 void 492 AcpiUtDeleteInternalObjectList ( 493 ACPI_OPERAND_OBJECT **ObjList) 494 { 495 ACPI_OPERAND_OBJECT **InternalObj; 496 497 498 ACPI_FUNCTION_ENTRY (); 499 500 501 /* Walk the null-terminated internal list */ 502 503 for (InternalObj = ObjList; *InternalObj; InternalObj++) 504 { 505 AcpiUtRemoveReference (*InternalObj); 506 } 507 508 /* Free the combined parameter pointer list and object array */ 509 510 ACPI_FREE (ObjList); 511 return; 512 } 513 514 515 /******************************************************************************* 516 * 517 * FUNCTION: AcpiUtUpdateRefCount 518 * 519 * PARAMETERS: Object - Object whose ref count is to be updated 520 * Action - What to do (REF_INCREMENT or REF_DECREMENT) 521 * 522 * RETURN: None. Sets new reference count within the object 523 * 524 * DESCRIPTION: Modify the reference count for an internal acpi object 525 * 526 ******************************************************************************/ 527 528 static void 529 AcpiUtUpdateRefCount ( 530 ACPI_OPERAND_OBJECT *Object, 531 UINT32 Action) 532 { 533 UINT16 OriginalCount; 534 UINT16 NewCount = 0; 535 ACPI_CPU_FLAGS LockFlags; 536 char *Message; 537 538 539 ACPI_FUNCTION_NAME (UtUpdateRefCount); 540 541 542 if (!Object) 543 { 544 return; 545 } 546 547 /* 548 * Always get the reference count lock. Note: Interpreter and/or 549 * Namespace is not always locked when this function is called. 550 */ 551 LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock); 552 OriginalCount = Object->Common.ReferenceCount; 553 554 /* Perform the reference count action (increment, decrement) */ 555 556 switch (Action) 557 { 558 case REF_INCREMENT: 559 560 NewCount = OriginalCount + 1; 561 Object->Common.ReferenceCount = NewCount; 562 AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); 563 564 /* The current reference count should never be zero here */ 565 566 if (!OriginalCount) 567 { 568 ACPI_WARNING ((AE_INFO, 569 "Obj %p, Reference Count was zero before increment\n", 570 Object)); 571 } 572 573 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 574 "Obj %p Type %.2X [%s] Refs %.2X [Incremented]\n", 575 Object, Object->Common.Type, 576 AcpiUtGetObjectTypeName (Object), NewCount)); 577 Message = "Incremement"; 578 break; 579 580 case REF_DECREMENT: 581 582 /* The current reference count must be non-zero */ 583 584 if (OriginalCount) 585 { 586 NewCount = OriginalCount - 1; 587 Object->Common.ReferenceCount = NewCount; 588 } 589 590 AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); 591 592 if (!OriginalCount) 593 { 594 ACPI_WARNING ((AE_INFO, 595 "Obj %p, Reference Count is already zero, cannot decrement\n", 596 Object)); 597 return; 598 } 599 600 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS, 601 "%s: Obj %p Type %.2X Refs %.2X [Decremented]\n", 602 ACPI_GET_FUNCTION_NAME, Object, Object->Common.Type, NewCount)); 603 604 /* Actually delete the object on a reference count of zero */ 605 606 if (NewCount == 0) 607 { 608 AcpiUtDeleteInternalObj (Object); 609 } 610 Message = "Decrement"; 611 break; 612 613 default: 614 615 AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); 616 ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)", 617 Action)); 618 return; 619 } 620 621 /* 622 * Sanity check the reference count, for debug purposes only. 623 * (A deleted object will have a huge reference count) 624 */ 625 if (NewCount > ACPI_MAX_REFERENCE_COUNT) 626 { 627 ACPI_WARNING ((AE_INFO, 628 "Large Reference Count (0x%X) in object %p, Type=0x%.2X Operation=%s", 629 NewCount, Object, Object->Common.Type, Message)); 630 } 631 } 632 633 634 /******************************************************************************* 635 * 636 * FUNCTION: AcpiUtUpdateObjectReference 637 * 638 * PARAMETERS: Object - Increment or decrement the ref count for 639 * this object and all sub-objects 640 * Action - Either REF_INCREMENT or REF_DECREMENT 641 * 642 * RETURN: Status 643 * 644 * DESCRIPTION: Increment or decrement the object reference count 645 * 646 * Object references are incremented when: 647 * 1) An object is attached to a Node (namespace object) 648 * 2) An object is copied (all subobjects must be incremented) 649 * 650 * Object references are decremented when: 651 * 1) An object is detached from an Node 652 * 653 ******************************************************************************/ 654 655 ACPI_STATUS 656 AcpiUtUpdateObjectReference ( 657 ACPI_OPERAND_OBJECT *Object, 658 UINT16 Action) 659 { 660 ACPI_STATUS Status = AE_OK; 661 ACPI_GENERIC_STATE *StateList = NULL; 662 ACPI_OPERAND_OBJECT *NextObject = NULL; 663 ACPI_OPERAND_OBJECT *PrevObject; 664 ACPI_GENERIC_STATE *State; 665 UINT32 i; 666 667 668 ACPI_FUNCTION_NAME (UtUpdateObjectReference); 669 670 671 while (Object) 672 { 673 /* Make sure that this isn't a namespace handle */ 674 675 if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED) 676 { 677 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 678 "Object %p is NS handle\n", Object)); 679 return (AE_OK); 680 } 681 682 /* 683 * All sub-objects must have their reference count updated 684 * also. Different object types have different subobjects. 685 */ 686 switch (Object->Common.Type) 687 { 688 case ACPI_TYPE_DEVICE: 689 case ACPI_TYPE_PROCESSOR: 690 case ACPI_TYPE_POWER: 691 case ACPI_TYPE_THERMAL: 692 /* 693 * Update the notify objects for these types (if present) 694 * Two lists, system and device notify handlers. 695 */ 696 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 697 { 698 PrevObject = Object->CommonNotify.NotifyList[i]; 699 while (PrevObject) 700 { 701 NextObject = PrevObject->Notify.Next[i]; 702 AcpiUtUpdateRefCount (PrevObject, Action); 703 PrevObject = NextObject; 704 } 705 } 706 break; 707 708 case ACPI_TYPE_PACKAGE: 709 /* 710 * We must update all the sub-objects of the package, 711 * each of whom may have their own sub-objects. 712 */ 713 for (i = 0; i < Object->Package.Count; i++) 714 { 715 /* 716 * Null package elements are legal and can be simply 717 * ignored. 718 */ 719 NextObject = Object->Package.Elements[i]; 720 if (!NextObject) 721 { 722 continue; 723 } 724 725 switch (NextObject->Common.Type) 726 { 727 case ACPI_TYPE_INTEGER: 728 case ACPI_TYPE_STRING: 729 case ACPI_TYPE_BUFFER: 730 /* 731 * For these very simple sub-objects, we can just 732 * update the reference count here and continue. 733 * Greatly increases performance of this operation. 734 */ 735 AcpiUtUpdateRefCount (NextObject, Action); 736 break; 737 738 default: 739 /* 740 * For complex sub-objects, push them onto the stack 741 * for later processing (this eliminates recursion.) 742 */ 743 Status = AcpiUtCreateUpdateStateAndPush ( 744 NextObject, Action, &StateList); 745 if (ACPI_FAILURE (Status)) 746 { 747 goto ErrorExit; 748 } 749 break; 750 } 751 } 752 753 NextObject = NULL; 754 break; 755 756 case ACPI_TYPE_BUFFER_FIELD: 757 758 NextObject = Object->BufferField.BufferObj; 759 break; 760 761 case ACPI_TYPE_LOCAL_BANK_FIELD: 762 763 NextObject = Object->BankField.BankObj; 764 Status = AcpiUtCreateUpdateStateAndPush ( 765 Object->BankField.RegionObj, Action, &StateList); 766 if (ACPI_FAILURE (Status)) 767 { 768 goto ErrorExit; 769 } 770 break; 771 772 case ACPI_TYPE_LOCAL_INDEX_FIELD: 773 774 NextObject = Object->IndexField.IndexObj; 775 Status = AcpiUtCreateUpdateStateAndPush ( 776 Object->IndexField.DataObj, Action, &StateList); 777 if (ACPI_FAILURE (Status)) 778 { 779 goto ErrorExit; 780 } 781 break; 782 783 case ACPI_TYPE_LOCAL_REFERENCE: 784 /* 785 * The target of an Index (a package, string, or buffer) or a named 786 * reference must track changes to the ref count of the index or 787 * target object. 788 */ 789 if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) || 790 (Object->Reference.Class== ACPI_REFCLASS_NAME)) 791 { 792 NextObject = Object->Reference.Object; 793 } 794 break; 795 796 case ACPI_TYPE_LOCAL_REGION_FIELD: 797 case ACPI_TYPE_REGION: 798 default: 799 800 break; /* No subobjects for all other types */ 801 } 802 803 /* 804 * Now we can update the count in the main object. This can only 805 * happen after we update the sub-objects in case this causes the 806 * main object to be deleted. 807 */ 808 AcpiUtUpdateRefCount (Object, Action); 809 Object = NULL; 810 811 /* Move on to the next object to be updated */ 812 813 if (NextObject) 814 { 815 Object = NextObject; 816 NextObject = NULL; 817 } 818 else if (StateList) 819 { 820 State = AcpiUtPopGenericState (&StateList); 821 Object = State->Update.Object; 822 AcpiUtDeleteGenericState (State); 823 } 824 } 825 826 return (AE_OK); 827 828 829 ErrorExit: 830 831 ACPI_EXCEPTION ((AE_INFO, Status, 832 "Could not update object reference count")); 833 834 /* Free any stacked Update State objects */ 835 836 while (StateList) 837 { 838 State = AcpiUtPopGenericState (&StateList); 839 AcpiUtDeleteGenericState (State); 840 } 841 842 return (Status); 843 } 844 845 846 /******************************************************************************* 847 * 848 * FUNCTION: AcpiUtAddReference 849 * 850 * PARAMETERS: Object - Object whose reference count is to be 851 * incremented 852 * 853 * RETURN: None 854 * 855 * DESCRIPTION: Add one reference to an ACPI object 856 * 857 ******************************************************************************/ 858 859 void 860 AcpiUtAddReference ( 861 ACPI_OPERAND_OBJECT *Object) 862 { 863 864 ACPI_FUNCTION_NAME (UtAddReference); 865 866 867 /* Ensure that we have a valid object */ 868 869 if (!AcpiUtValidInternalObject (Object)) 870 { 871 return; 872 } 873 874 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 875 "Obj %p Current Refs=%X [To Be Incremented]\n", 876 Object, Object->Common.ReferenceCount)); 877 878 /* Increment the reference count */ 879 880 (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT); 881 return; 882 } 883 884 885 /******************************************************************************* 886 * 887 * FUNCTION: AcpiUtRemoveReference 888 * 889 * PARAMETERS: Object - Object whose ref count will be decremented 890 * 891 * RETURN: None 892 * 893 * DESCRIPTION: Decrement the reference count of an ACPI internal object 894 * 895 ******************************************************************************/ 896 897 void 898 AcpiUtRemoveReference ( 899 ACPI_OPERAND_OBJECT *Object) 900 { 901 902 ACPI_FUNCTION_NAME (UtRemoveReference); 903 904 905 /* 906 * Allow a NULL pointer to be passed in, just ignore it. This saves 907 * each caller from having to check. Also, ignore NS nodes. 908 */ 909 if (!Object || 910 (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)) 911 912 { 913 return; 914 } 915 916 /* Ensure that we have a valid object */ 917 918 if (!AcpiUtValidInternalObject (Object)) 919 { 920 return; 921 } 922 923 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS, 924 "%s: Obj %p Current Refs=%X [To Be Decremented]\n", 925 ACPI_GET_FUNCTION_NAME, Object, Object->Common.ReferenceCount)); 926 927 /* 928 * Decrement the reference count, and only actually delete the object 929 * if the reference count becomes 0. (Must also decrement the ref count 930 * of all subobjects!) 931 */ 932 (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT); 933 return; 934 } 935