1 /******************************************************************************* 2 * 3 * Module Name: utdelete - object deletion and reference count utilities 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #define __UTDELETE_C__ 45 46 #include <contrib/dev/acpica/include/acpi.h> 47 #include <contrib/dev/acpica/include/accommon.h> 48 #include <contrib/dev/acpica/include/acinterp.h> 49 #include <contrib/dev/acpica/include/acnamesp.h> 50 #include <contrib/dev/acpica/include/acevents.h> 51 52 53 #define _COMPONENT ACPI_UTILITIES 54 ACPI_MODULE_NAME ("utdelete") 55 56 /* Local prototypes */ 57 58 static void 59 AcpiUtDeleteInternalObj ( 60 ACPI_OPERAND_OBJECT *Object); 61 62 static void 63 AcpiUtUpdateRefCount ( 64 ACPI_OPERAND_OBJECT *Object, 65 UINT32 Action); 66 67 68 /******************************************************************************* 69 * 70 * FUNCTION: AcpiUtDeleteInternalObj 71 * 72 * PARAMETERS: Object - Object to be deleted 73 * 74 * RETURN: None 75 * 76 * DESCRIPTION: Low level object deletion, after reference counts have been 77 * updated (All reference counts, including sub-objects!) 78 * 79 ******************************************************************************/ 80 81 static void 82 AcpiUtDeleteInternalObj ( 83 ACPI_OPERAND_OBJECT *Object) 84 { 85 void *ObjPointer = NULL; 86 ACPI_OPERAND_OBJECT *HandlerDesc; 87 ACPI_OPERAND_OBJECT *SecondDesc; 88 ACPI_OPERAND_OBJECT *NextDesc; 89 ACPI_OPERAND_OBJECT **LastObjPtr; 90 91 92 ACPI_FUNCTION_TRACE_PTR (UtDeleteInternalObj, Object); 93 94 95 if (!Object) 96 { 97 return_VOID; 98 } 99 100 /* 101 * Must delete or free any pointers within the object that are not 102 * actual ACPI objects (for example, a raw buffer pointer). 103 */ 104 switch (Object->Common.Type) 105 { 106 case ACPI_TYPE_STRING: 107 108 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n", 109 Object, Object->String.Pointer)); 110 111 /* Free the actual string buffer */ 112 113 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER)) 114 { 115 /* But only if it is NOT a pointer into an ACPI table */ 116 117 ObjPointer = Object->String.Pointer; 118 } 119 break; 120 121 122 case ACPI_TYPE_BUFFER: 123 124 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n", 125 Object, Object->Buffer.Pointer)); 126 127 /* Free the actual buffer */ 128 129 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER)) 130 { 131 /* But only if it is NOT a pointer into an ACPI table */ 132 133 ObjPointer = Object->Buffer.Pointer; 134 } 135 break; 136 137 138 case ACPI_TYPE_PACKAGE: 139 140 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n", 141 Object->Package.Count)); 142 143 /* 144 * Elements of the package are not handled here, they are deleted 145 * separately 146 */ 147 148 /* Free the (variable length) element pointer array */ 149 150 ObjPointer = Object->Package.Elements; 151 break; 152 153 154 /* 155 * These objects have a possible list of notify handlers. 156 * Device object also may have a GPE block. 157 */ 158 case ACPI_TYPE_DEVICE: 159 160 if (Object->Device.GpeBlock) 161 { 162 (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock); 163 } 164 165 /*lint -fallthrough */ 166 167 case ACPI_TYPE_PROCESSOR: 168 case ACPI_TYPE_THERMAL: 169 170 /* Walk the address handler list for this object */ 171 172 HandlerDesc = Object->CommonNotify.Handler; 173 while (HandlerDesc) 174 { 175 NextDesc = HandlerDesc->AddressSpace.Next; 176 AcpiUtRemoveReference (HandlerDesc); 177 HandlerDesc = NextDesc; 178 } 179 break; 180 181 182 case ACPI_TYPE_MUTEX: 183 184 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 185 "***** Mutex %p, OS Mutex %p\n", 186 Object, Object->Mutex.OsMutex)); 187 188 if (Object == AcpiGbl_GlobalLockMutex) 189 { 190 /* Global Lock has extra semaphore */ 191 192 (void) AcpiOsDeleteSemaphore (AcpiGbl_GlobalLockSemaphore); 193 AcpiGbl_GlobalLockSemaphore = NULL; 194 195 AcpiOsDeleteMutex (Object->Mutex.OsMutex); 196 AcpiGbl_GlobalLockMutex = NULL; 197 } 198 else 199 { 200 AcpiExUnlinkMutex (Object); 201 AcpiOsDeleteMutex (Object->Mutex.OsMutex); 202 } 203 break; 204 205 206 case ACPI_TYPE_EVENT: 207 208 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 209 "***** Event %p, OS Semaphore %p\n", 210 Object, Object->Event.OsSemaphore)); 211 212 (void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore); 213 Object->Event.OsSemaphore = NULL; 214 break; 215 216 217 case ACPI_TYPE_METHOD: 218 219 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 220 "***** Method %p\n", Object)); 221 222 /* Delete the method mutex if it exists */ 223 224 if (Object->Method.Mutex) 225 { 226 AcpiOsDeleteMutex (Object->Method.Mutex->Mutex.OsMutex); 227 AcpiUtDeleteObjectDesc (Object->Method.Mutex); 228 Object->Method.Mutex = NULL; 229 } 230 break; 231 232 233 case ACPI_TYPE_REGION: 234 235 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 236 "***** Region %p\n", Object)); 237 238 /* 239 * Update AddressRange list. However, only permanent regions 240 * are installed in this list. (Not created within a method) 241 */ 242 if (!(Object->Region.Node->Flags & ANOBJ_TEMPORARY)) 243 { 244 AcpiUtRemoveAddressRange (Object->Region.SpaceId, 245 Object->Region.Node); 246 } 247 248 SecondDesc = AcpiNsGetSecondaryObject (Object); 249 if (SecondDesc) 250 { 251 /* 252 * Free the RegionContext if and only if the handler is one of the 253 * default handlers -- and therefore, we created the context object 254 * locally, it was not created by an external caller. 255 */ 256 HandlerDesc = Object->Region.Handler; 257 if (HandlerDesc) 258 { 259 NextDesc = HandlerDesc->AddressSpace.RegionList; 260 LastObjPtr = &HandlerDesc->AddressSpace.RegionList; 261 262 /* Remove the region object from the handler's list */ 263 264 while (NextDesc) 265 { 266 if (NextDesc == Object) 267 { 268 *LastObjPtr = NextDesc->Region.Next; 269 break; 270 } 271 272 /* Walk the linked list of handler */ 273 274 LastObjPtr = &NextDesc->Region.Next; 275 NextDesc = NextDesc->Region.Next; 276 } 277 278 if (HandlerDesc->AddressSpace.HandlerFlags & 279 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) 280 { 281 /* Deactivate region and free region context */ 282 283 if (HandlerDesc->AddressSpace.Setup) 284 { 285 (void) HandlerDesc->AddressSpace.Setup (Object, 286 ACPI_REGION_DEACTIVATE, 287 HandlerDesc->AddressSpace.Context, 288 &SecondDesc->Extra.RegionContext); 289 } 290 } 291 292 AcpiUtRemoveReference (HandlerDesc); 293 } 294 295 /* Now we can free the Extra object */ 296 297 AcpiUtDeleteObjectDesc (SecondDesc); 298 } 299 break; 300 301 302 case ACPI_TYPE_BUFFER_FIELD: 303 304 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 305 "***** Buffer Field %p\n", Object)); 306 307 SecondDesc = AcpiNsGetSecondaryObject (Object); 308 if (SecondDesc) 309 { 310 AcpiUtDeleteObjectDesc (SecondDesc); 311 } 312 break; 313 314 315 case ACPI_TYPE_LOCAL_BANK_FIELD: 316 317 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 318 "***** Bank Field %p\n", Object)); 319 320 SecondDesc = AcpiNsGetSecondaryObject (Object); 321 if (SecondDesc) 322 { 323 AcpiUtDeleteObjectDesc (SecondDesc); 324 } 325 break; 326 327 328 default: 329 break; 330 } 331 332 /* Free any allocated memory (pointer within the object) found above */ 333 334 if (ObjPointer) 335 { 336 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n", 337 ObjPointer)); 338 ACPI_FREE (ObjPointer); 339 } 340 341 /* Now the object can be safely deleted */ 342 343 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n", 344 Object, AcpiUtGetObjectTypeName (Object))); 345 346 AcpiUtDeleteObjectDesc (Object); 347 return_VOID; 348 } 349 350 351 /******************************************************************************* 352 * 353 * FUNCTION: AcpiUtDeleteInternalObjectList 354 * 355 * PARAMETERS: ObjList - Pointer to the list to be deleted 356 * 357 * RETURN: None 358 * 359 * DESCRIPTION: This function deletes an internal object list, including both 360 * simple objects and package objects 361 * 362 ******************************************************************************/ 363 364 void 365 AcpiUtDeleteInternalObjectList ( 366 ACPI_OPERAND_OBJECT **ObjList) 367 { 368 ACPI_OPERAND_OBJECT **InternalObj; 369 370 371 ACPI_FUNCTION_ENTRY (); 372 373 374 /* Walk the null-terminated internal list */ 375 376 for (InternalObj = ObjList; *InternalObj; InternalObj++) 377 { 378 AcpiUtRemoveReference (*InternalObj); 379 } 380 381 /* Free the combined parameter pointer list and object array */ 382 383 ACPI_FREE (ObjList); 384 return; 385 } 386 387 388 /******************************************************************************* 389 * 390 * FUNCTION: AcpiUtUpdateRefCount 391 * 392 * PARAMETERS: Object - Object whose ref count is to be updated 393 * Action - What to do (REF_INCREMENT or REF_DECREMENT) 394 * 395 * RETURN: None. Sets new reference count within the object 396 * 397 * DESCRIPTION: Modify the reference count for an internal acpi object 398 * 399 ******************************************************************************/ 400 401 static void 402 AcpiUtUpdateRefCount ( 403 ACPI_OPERAND_OBJECT *Object, 404 UINT32 Action) 405 { 406 UINT16 OriginalCount; 407 UINT16 NewCount = 0; 408 ACPI_CPU_FLAGS LockFlags; 409 410 411 ACPI_FUNCTION_NAME (UtUpdateRefCount); 412 413 414 if (!Object) 415 { 416 return; 417 } 418 419 /* 420 * Always get the reference count lock. Note: Interpreter and/or 421 * Namespace is not always locked when this function is called. 422 */ 423 LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock); 424 OriginalCount = Object->Common.ReferenceCount; 425 426 /* Perform the reference count action (increment, decrement) */ 427 428 switch (Action) 429 { 430 case REF_INCREMENT: 431 432 NewCount = OriginalCount + 1; 433 Object->Common.ReferenceCount = NewCount; 434 AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); 435 436 /* The current reference count should never be zero here */ 437 438 if (!OriginalCount) 439 { 440 ACPI_WARNING ((AE_INFO, 441 "Obj %p, Reference Count was zero before increment\n", 442 Object)); 443 } 444 445 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 446 "Obj %p Type %.2X Refs %.2X [Incremented]\n", 447 Object, Object->Common.Type, NewCount)); 448 break; 449 450 case REF_DECREMENT: 451 452 /* The current reference count must be non-zero */ 453 454 if (OriginalCount) 455 { 456 NewCount = OriginalCount - 1; 457 Object->Common.ReferenceCount = NewCount; 458 } 459 460 AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); 461 462 if (!OriginalCount) 463 { 464 ACPI_WARNING ((AE_INFO, 465 "Obj %p, Reference Count is already zero, cannot decrement\n", 466 Object)); 467 } 468 469 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 470 "Obj %p Type %.2X Refs %.2X [Decremented]\n", 471 Object, Object->Common.Type, NewCount)); 472 473 /* Actually delete the object on a reference count of zero */ 474 475 if (NewCount == 0) 476 { 477 AcpiUtDeleteInternalObj (Object); 478 } 479 break; 480 481 default: 482 483 AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); 484 ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)", 485 Action)); 486 return; 487 } 488 489 /* 490 * Sanity check the reference count, for debug purposes only. 491 * (A deleted object will have a huge reference count) 492 */ 493 if (NewCount > ACPI_MAX_REFERENCE_COUNT) 494 { 495 ACPI_WARNING ((AE_INFO, 496 "Large Reference Count (0x%X) in object %p, Type=0x%.2X", 497 NewCount, Object, Object->Common.Type)); 498 } 499 } 500 501 502 /******************************************************************************* 503 * 504 * FUNCTION: AcpiUtUpdateObjectReference 505 * 506 * PARAMETERS: Object - Increment ref count for this object 507 * and all sub-objects 508 * Action - Either REF_INCREMENT or REF_DECREMENT 509 * 510 * RETURN: Status 511 * 512 * DESCRIPTION: Increment the object reference count 513 * 514 * Object references are incremented when: 515 * 1) An object is attached to a Node (namespace object) 516 * 2) An object is copied (all subobjects must be incremented) 517 * 518 * Object references are decremented when: 519 * 1) An object is detached from an Node 520 * 521 ******************************************************************************/ 522 523 ACPI_STATUS 524 AcpiUtUpdateObjectReference ( 525 ACPI_OPERAND_OBJECT *Object, 526 UINT16 Action) 527 { 528 ACPI_STATUS Status = AE_OK; 529 ACPI_GENERIC_STATE *StateList = NULL; 530 ACPI_OPERAND_OBJECT *NextObject = NULL; 531 ACPI_OPERAND_OBJECT *PrevObject; 532 ACPI_GENERIC_STATE *State; 533 UINT32 i; 534 535 536 ACPI_FUNCTION_NAME (UtUpdateObjectReference); 537 538 539 while (Object) 540 { 541 /* Make sure that this isn't a namespace handle */ 542 543 if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED) 544 { 545 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 546 "Object %p is NS handle\n", Object)); 547 return (AE_OK); 548 } 549 550 /* 551 * All sub-objects must have their reference count incremented also. 552 * Different object types have different subobjects. 553 */ 554 switch (Object->Common.Type) 555 { 556 case ACPI_TYPE_DEVICE: 557 case ACPI_TYPE_PROCESSOR: 558 case ACPI_TYPE_POWER: 559 case ACPI_TYPE_THERMAL: 560 561 /* 562 * Update the notify objects for these types (if present) 563 * Two lists, system and device notify handlers. 564 */ 565 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 566 { 567 PrevObject = Object->CommonNotify.NotifyList[i]; 568 while (PrevObject) 569 { 570 NextObject = PrevObject->Notify.Next[i]; 571 AcpiUtUpdateRefCount (PrevObject, Action); 572 PrevObject = NextObject; 573 } 574 } 575 break; 576 577 case ACPI_TYPE_PACKAGE: 578 /* 579 * We must update all the sub-objects of the package, 580 * each of whom may have their own sub-objects. 581 */ 582 for (i = 0; i < Object->Package.Count; i++) 583 { 584 /* 585 * Null package elements are legal and can be simply 586 * ignored. 587 */ 588 NextObject = Object->Package.Elements[i]; 589 if (!NextObject) 590 { 591 continue; 592 } 593 594 switch (NextObject->Common.Type) 595 { 596 case ACPI_TYPE_INTEGER: 597 case ACPI_TYPE_STRING: 598 case ACPI_TYPE_BUFFER: 599 /* 600 * For these very simple sub-objects, we can just 601 * update the reference count here and continue. 602 * Greatly increases performance of this operation. 603 */ 604 AcpiUtUpdateRefCount (NextObject, Action); 605 break; 606 607 default: 608 /* 609 * For complex sub-objects, push them onto the stack 610 * for later processing (this eliminates recursion.) 611 */ 612 Status = AcpiUtCreateUpdateStateAndPush ( 613 NextObject, Action, &StateList); 614 if (ACPI_FAILURE (Status)) 615 { 616 goto ErrorExit; 617 } 618 break; 619 } 620 } 621 NextObject = NULL; 622 break; 623 624 case ACPI_TYPE_BUFFER_FIELD: 625 626 NextObject = Object->BufferField.BufferObj; 627 break; 628 629 case ACPI_TYPE_LOCAL_REGION_FIELD: 630 631 NextObject = Object->Field.RegionObj; 632 break; 633 634 case ACPI_TYPE_LOCAL_BANK_FIELD: 635 636 NextObject = Object->BankField.BankObj; 637 Status = AcpiUtCreateUpdateStateAndPush ( 638 Object->BankField.RegionObj, Action, &StateList); 639 if (ACPI_FAILURE (Status)) 640 { 641 goto ErrorExit; 642 } 643 break; 644 645 case ACPI_TYPE_LOCAL_INDEX_FIELD: 646 647 NextObject = Object->IndexField.IndexObj; 648 Status = AcpiUtCreateUpdateStateAndPush ( 649 Object->IndexField.DataObj, Action, &StateList); 650 if (ACPI_FAILURE (Status)) 651 { 652 goto ErrorExit; 653 } 654 break; 655 656 case ACPI_TYPE_LOCAL_REFERENCE: 657 /* 658 * The target of an Index (a package, string, or buffer) or a named 659 * reference must track changes to the ref count of the index or 660 * target object. 661 */ 662 if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) || 663 (Object->Reference.Class== ACPI_REFCLASS_NAME)) 664 { 665 NextObject = Object->Reference.Object; 666 } 667 break; 668 669 case ACPI_TYPE_REGION: 670 default: 671 break; /* No subobjects for all other types */ 672 } 673 674 /* 675 * Now we can update the count in the main object. This can only 676 * happen after we update the sub-objects in case this causes the 677 * main object to be deleted. 678 */ 679 AcpiUtUpdateRefCount (Object, Action); 680 Object = NULL; 681 682 /* Move on to the next object to be updated */ 683 684 if (NextObject) 685 { 686 Object = NextObject; 687 NextObject = NULL; 688 } 689 else if (StateList) 690 { 691 State = AcpiUtPopGenericState (&StateList); 692 Object = State->Update.Object; 693 AcpiUtDeleteGenericState (State); 694 } 695 } 696 697 return (AE_OK); 698 699 700 ErrorExit: 701 702 ACPI_EXCEPTION ((AE_INFO, Status, 703 "Could not update object reference count")); 704 705 /* Free any stacked Update State objects */ 706 707 while (StateList) 708 { 709 State = AcpiUtPopGenericState (&StateList); 710 AcpiUtDeleteGenericState (State); 711 } 712 713 return (Status); 714 } 715 716 717 /******************************************************************************* 718 * 719 * FUNCTION: AcpiUtAddReference 720 * 721 * PARAMETERS: Object - Object whose reference count is to be 722 * incremented 723 * 724 * RETURN: None 725 * 726 * DESCRIPTION: Add one reference to an ACPI object 727 * 728 ******************************************************************************/ 729 730 void 731 AcpiUtAddReference ( 732 ACPI_OPERAND_OBJECT *Object) 733 { 734 735 ACPI_FUNCTION_NAME (UtAddReference); 736 737 738 /* Ensure that we have a valid object */ 739 740 if (!AcpiUtValidInternalObject (Object)) 741 { 742 return; 743 } 744 745 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 746 "Obj %p Current Refs=%X [To Be Incremented]\n", 747 Object, Object->Common.ReferenceCount)); 748 749 /* Increment the reference count */ 750 751 (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT); 752 return; 753 } 754 755 756 /******************************************************************************* 757 * 758 * FUNCTION: AcpiUtRemoveReference 759 * 760 * PARAMETERS: Object - Object whose ref count will be decremented 761 * 762 * RETURN: None 763 * 764 * DESCRIPTION: Decrement the reference count of an ACPI internal object 765 * 766 ******************************************************************************/ 767 768 void 769 AcpiUtRemoveReference ( 770 ACPI_OPERAND_OBJECT *Object) 771 { 772 773 ACPI_FUNCTION_NAME (UtRemoveReference); 774 775 776 /* 777 * Allow a NULL pointer to be passed in, just ignore it. This saves 778 * each caller from having to check. Also, ignore NS nodes. 779 */ 780 if (!Object || 781 (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)) 782 783 { 784 return; 785 } 786 787 /* Ensure that we have a valid object */ 788 789 if (!AcpiUtValidInternalObject (Object)) 790 { 791 return; 792 } 793 794 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 795 "Obj %p Current Refs=%X [To Be Decremented]\n", 796 Object, Object->Common.ReferenceCount)); 797 798 /* 799 * Decrement the reference count, and only actually delete the object 800 * if the reference count becomes 0. (Must also decrement the ref count 801 * of all subobjects!) 802 */ 803 (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT); 804 return; 805 } 806