Print this page
acpica-unix2-20130823
PANKOVs restructure
   1 /*******************************************************************************
   2  *
   3  * Module Name: utdelete - object deletion and reference count utilities
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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.


 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 notify 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         SecondDesc = AcpiNsGetSecondaryObject (Object);
 239         if (SecondDesc)
 240         {
 241             /*
 242              * Free the RegionContext if and only if the handler is one of the
 243              * default handlers -- and therefore, we created the context object
 244              * locally, it was not created by an external caller.
 245              */
 246             HandlerDesc = Object->Region.Handler;
 247             if (HandlerDesc)
 248             {
 249                 NextDesc = HandlerDesc->AddressSpace.RegionList;
 250                 LastObjPtr = &HandlerDesc->AddressSpace.RegionList;
 251 
 252                 /* Remove the region object from the handler's list */
 253 
 254                 while (NextDesc)
 255                 {
 256                     if (NextDesc == Object)
 257                     {


 271                     /* Deactivate region and free region context */
 272 
 273                     if (HandlerDesc->AddressSpace.Setup)
 274                     {
 275                         (void) HandlerDesc->AddressSpace.Setup (Object,
 276                             ACPI_REGION_DEACTIVATE,
 277                             HandlerDesc->AddressSpace.Context,
 278                             &SecondDesc->Extra.RegionContext);
 279                     }
 280                 }
 281 
 282                 AcpiUtRemoveReference (HandlerDesc);
 283             }
 284 
 285             /* Now we can free the Extra object */
 286 
 287             AcpiUtDeleteObjectDesc (SecondDesc);
 288         }
 289         break;
 290 
 291 
 292     case ACPI_TYPE_BUFFER_FIELD:
 293 
 294         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 295             "***** Buffer Field %p\n", Object));
 296 
 297         SecondDesc = AcpiNsGetSecondaryObject (Object);
 298         if (SecondDesc)
 299         {
 300             AcpiUtDeleteObjectDesc (SecondDesc);
 301         }
 302         break;
 303 
 304 
 305     case ACPI_TYPE_LOCAL_BANK_FIELD:
 306 
 307         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 308             "***** Bank Field %p\n", Object));
 309 
 310         SecondDesc = AcpiNsGetSecondaryObject (Object);
 311         if (SecondDesc)
 312         {
 313             AcpiUtDeleteObjectDesc (SecondDesc);
 314         }
 315         break;
 316 
 317 
 318     default:

 319         break;
 320     }
 321 
 322     /* Free any allocated memory (pointer within the object) found above */
 323 
 324     if (ObjPointer)
 325     {
 326         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
 327             ObjPointer));
 328         ACPI_FREE (ObjPointer);
 329     }
 330 
 331     /* Now the object can be safely deleted */
 332 
 333     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
 334         Object, AcpiUtGetObjectTypeName (Object)));
 335 
 336     AcpiUtDeleteObjectDesc (Object);
 337     return_VOID;
 338 }


 341 /*******************************************************************************
 342  *
 343  * FUNCTION:    AcpiUtDeleteInternalObjectList
 344  *
 345  * PARAMETERS:  ObjList         - Pointer to the list to be deleted
 346  *
 347  * RETURN:      None
 348  *
 349  * DESCRIPTION: This function deletes an internal object list, including both
 350  *              simple objects and package objects
 351  *
 352  ******************************************************************************/
 353 
 354 void
 355 AcpiUtDeleteInternalObjectList (
 356     ACPI_OPERAND_OBJECT     **ObjList)
 357 {
 358     ACPI_OPERAND_OBJECT     **InternalObj;
 359 
 360 
 361     ACPI_FUNCTION_TRACE (UtDeleteInternalObjectList);
 362 
 363 
 364     /* Walk the null-terminated internal list */
 365 
 366     for (InternalObj = ObjList; *InternalObj; InternalObj++)
 367     {
 368         AcpiUtRemoveReference (*InternalObj);
 369     }
 370 
 371     /* Free the combined parameter pointer list and object array */
 372 
 373     ACPI_FREE (ObjList);
 374     return_VOID;
 375 }
 376 
 377 
 378 /*******************************************************************************
 379  *
 380  * FUNCTION:    AcpiUtUpdateRefCount
 381  *
 382  * PARAMETERS:  Object          - Object whose ref count is to be updated
 383  *              Action          - What to do
 384  *
 385  * RETURN:      New ref count
 386  *
 387  * DESCRIPTION: Modify the ref count and return it.
 388  *
 389  ******************************************************************************/
 390 
 391 static void
 392 AcpiUtUpdateRefCount (
 393     ACPI_OPERAND_OBJECT     *Object,
 394     UINT32                  Action)
 395 {
 396     UINT16                  Count;
 397     UINT16                  NewCount;

 398 
 399 
 400     ACPI_FUNCTION_NAME (UtUpdateRefCount);
 401 
 402 
 403     if (!Object)
 404     {
 405         return;
 406     }
 407 
 408     Count = Object->Common.ReferenceCount;
 409     NewCount = Count;
 410 
 411     /*
 412      * Perform the reference count action (increment, decrement, force delete)

 413      */





 414     switch (Action)
 415     {
 416     case REF_INCREMENT:
 417 
 418         NewCount++;
 419         Object->Common.ReferenceCount = NewCount;

 420 









 421         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 422             "Obj %p Refs=%X, [Incremented]\n",
 423             Object, NewCount));
 424         break;
 425 
 426     case REF_DECREMENT:
 427 
 428         if (Count < 1)
 429         {
 430             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 431                 "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
 432                 Object, NewCount));
 433 
 434             NewCount = 0;
 435         }
 436         else
 437         {
 438             NewCount--;
 439 
 440             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 441                 "Obj %p Refs=%X, [Decremented]\n",
 442                 Object, NewCount));
 443         }
 444 
 445         if (Object->Common.Type == ACPI_TYPE_METHOD)


 446         {
 447             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 448                 "Method Obj %p Refs=%X, [Decremented]\n", Object, NewCount));

 449         }
 450 
 451         Object->Common.ReferenceCount = NewCount;





 452         if (NewCount == 0)
 453         {
 454             AcpiUtDeleteInternalObj (Object);
 455         }
 456         break;
 457 
 458     case REF_FORCE_DELETE:
 459 
 460         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 461             "Obj %p Refs=%X, Force delete! (Set to 0)\n", Object, Count));
 462 
 463         NewCount = 0;
 464         Object->Common.ReferenceCount = NewCount;
 465         AcpiUtDeleteInternalObj (Object);
 466         break;
 467 
 468     default:
 469 
 470         ACPI_ERROR ((AE_INFO, "Unknown action (0x%X)", Action));
 471         break;


 472     }
 473 
 474     /*
 475      * Sanity check the reference count, for debug purposes only.
 476      * (A deleted object will have a huge reference count)
 477      */
 478     if (Count > ACPI_MAX_REFERENCE_COUNT)
 479     {
 480         ACPI_WARNING ((AE_INFO,
 481             "Large Reference Count (0x%X) in object %p", Count, Object));

 482     }
 483 }
 484 
 485 
 486 /*******************************************************************************
 487  *
 488  * FUNCTION:    AcpiUtUpdateObjectReference
 489  *
 490  * PARAMETERS:  Object              - Increment ref count for this object
 491  *                                    and all sub-objects
 492  *              Action              - Either REF_INCREMENT or REF_DECREMENT or
 493  *                                    REF_FORCE_DELETE
 494  *
 495  * RETURN:      Status
 496  *
 497  * DESCRIPTION: Increment the object reference count
 498  *
 499  * Object references are incremented when:
 500  * 1) An object is attached to a Node (namespace object)
 501  * 2) An object is copied (all subobjects must be incremented)
 502  *
 503  * Object references are decremented when:
 504  * 1) An object is detached from an Node
 505  *
 506  ******************************************************************************/
 507 
 508 ACPI_STATUS
 509 AcpiUtUpdateObjectReference (
 510     ACPI_OPERAND_OBJECT     *Object,
 511     UINT16                  Action)
 512 {
 513     ACPI_STATUS             Status = AE_OK;
 514     ACPI_GENERIC_STATE      *StateList = NULL;
 515     ACPI_OPERAND_OBJECT     *NextObject = NULL;

 516     ACPI_GENERIC_STATE      *State;
 517     UINT32                  i;
 518 
 519 
 520     ACPI_FUNCTION_TRACE_PTR (UtUpdateObjectReference, Object);
 521 
 522 
 523     while (Object)
 524     {
 525         /* Make sure that this isn't a namespace handle */
 526 
 527         if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
 528         {
 529             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 530                 "Object %p is NS handle\n", Object));
 531             return_ACPI_STATUS (AE_OK);
 532         }
 533 
 534         /*
 535          * All sub-objects must have their reference count incremented also.
 536          * Different object types have different subobjects.
 537          */
 538         switch (Object->Common.Type)
 539         {
 540         case ACPI_TYPE_DEVICE:
 541         case ACPI_TYPE_PROCESSOR:
 542         case ACPI_TYPE_POWER:
 543         case ACPI_TYPE_THERMAL:
 544 
 545             /* Update the notify objects for these types (if present) */
 546 
 547             AcpiUtUpdateRefCount (Object->CommonNotify.SystemNotify, Action);
 548             AcpiUtUpdateRefCount (Object->CommonNotify.DeviceNotify, Action);









 549             break;
 550 
 551         case ACPI_TYPE_PACKAGE:
 552             /*
 553              * We must update all the sub-objects of the package,
 554              * each of whom may have their own sub-objects.
 555              */
 556             for (i = 0; i < Object->Package.Count; i++)
 557             {
 558                 /*
 559                  * Push each element onto the stack for later processing.
 560                  * Note: There can be null elements within the package,
 561                  * these are simply ignored
 562                  */
























 563                 Status = AcpiUtCreateUpdateStateAndPush (
 564                             Object->Package.Elements[i], Action, &StateList);
 565                 if (ACPI_FAILURE (Status))
 566                 {
 567                     goto ErrorExit;
 568                 }

 569             }


 570             break;
 571 
 572         case ACPI_TYPE_BUFFER_FIELD:
 573 
 574             NextObject = Object->BufferField.BufferObj;
 575             break;
 576 
 577         case ACPI_TYPE_LOCAL_REGION_FIELD:
 578 
 579             NextObject = Object->Field.RegionObj;
 580             break;
 581 
 582         case ACPI_TYPE_LOCAL_BANK_FIELD:
 583 
 584             NextObject = Object->BankField.BankObj;
 585             Status = AcpiUtCreateUpdateStateAndPush (
 586                         Object->BankField.RegionObj, Action, &StateList);
 587             if (ACPI_FAILURE (Status))
 588             {
 589                 goto ErrorExit;


 599             {
 600                 goto ErrorExit;
 601             }
 602             break;
 603 
 604         case ACPI_TYPE_LOCAL_REFERENCE:
 605             /*
 606              * The target of an Index (a package, string, or buffer) or a named
 607              * reference must track changes to the ref count of the index or
 608              * target object.
 609              */
 610             if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) ||
 611                 (Object->Reference.Class== ACPI_REFCLASS_NAME))
 612             {
 613                 NextObject = Object->Reference.Object;
 614             }
 615             break;
 616 
 617         case ACPI_TYPE_REGION:
 618         default:

 619             break; /* No subobjects for all other types */
 620         }
 621 
 622         /*
 623          * Now we can update the count in the main object. This can only
 624          * happen after we update the sub-objects in case this causes the
 625          * main object to be deleted.
 626          */
 627         AcpiUtUpdateRefCount (Object, Action);
 628         Object = NULL;
 629 
 630         /* Move on to the next object to be updated */
 631 
 632         if (NextObject)
 633         {
 634             Object = NextObject;
 635             NextObject = NULL;
 636         }
 637         else if (StateList)
 638         {
 639             State = AcpiUtPopGenericState (&StateList);
 640             Object = State->Update.Object;
 641             AcpiUtDeleteGenericState (State);
 642         }
 643     }
 644 
 645     return_ACPI_STATUS (AE_OK);
 646 
 647 
 648 ErrorExit:
 649 
 650     ACPI_EXCEPTION ((AE_INFO, Status,
 651         "Could not update object reference count"));
 652 
 653     /* Free any stacked Update State objects */
 654 
 655     while (StateList)
 656     {
 657         State = AcpiUtPopGenericState (&StateList);
 658         AcpiUtDeleteGenericState (State);
 659     }
 660 
 661     return_ACPI_STATUS (Status);
 662 }
 663 
 664 
 665 /*******************************************************************************
 666  *
 667  * FUNCTION:    AcpiUtAddReference
 668  *
 669  * PARAMETERS:  Object          - Object whose reference count is to be
 670  *                                incremented
 671  *
 672  * RETURN:      None
 673  *
 674  * DESCRIPTION: Add one reference to an ACPI object
 675  *
 676  ******************************************************************************/
 677 
 678 void
 679 AcpiUtAddReference (
 680     ACPI_OPERAND_OBJECT     *Object)
 681 {
 682 
 683     ACPI_FUNCTION_TRACE_PTR (UtAddReference, Object);
 684 
 685 
 686     /* Ensure that we have a valid object */
 687 
 688     if (!AcpiUtValidInternalObject (Object))
 689     {
 690         return_VOID;
 691     }
 692 
 693     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 694         "Obj %p Current Refs=%X [To Be Incremented]\n",
 695         Object, Object->Common.ReferenceCount));
 696 
 697     /* Increment the reference count */
 698 
 699     (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
 700     return_VOID;
 701 }
 702 
 703 
 704 /*******************************************************************************
 705  *
 706  * FUNCTION:    AcpiUtRemoveReference
 707  *
 708  * PARAMETERS:  Object         - Object whose ref count will be decremented
 709  *
 710  * RETURN:      None
 711  *
 712  * DESCRIPTION: Decrement the reference count of an ACPI internal object
 713  *
 714  ******************************************************************************/
 715 
 716 void
 717 AcpiUtRemoveReference (
 718     ACPI_OPERAND_OBJECT     *Object)
 719 {
 720 
 721     ACPI_FUNCTION_TRACE_PTR (UtRemoveReference, Object);
 722 
 723 
 724     /*
 725      * Allow a NULL pointer to be passed in, just ignore it. This saves
 726      * each caller from having to check. Also, ignore NS nodes.
 727      *
 728      */
 729     if (!Object ||
 730         (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))
 731 
 732     {
 733         return_VOID;
 734     }
 735 
 736     /* Ensure that we have a valid object */
 737 
 738     if (!AcpiUtValidInternalObject (Object))
 739     {
 740         return_VOID;
 741     }
 742 
 743     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 744         "Obj %p Current Refs=%X [To Be Decremented]\n",
 745         Object, Object->Common.ReferenceCount));
 746 
 747     /*
 748      * Decrement the reference count, and only actually delete the object
 749      * if the reference count becomes 0. (Must also decrement the ref count
 750      * of all subobjects!)
 751      */
 752     (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
 753     return_VOID;
 754 }
 755 
 756 
   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.


 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     case ACPI_TYPE_BUFFER:
 122 
 123         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
 124             Object, Object->Buffer.Pointer));
 125 
 126         /* Free the actual buffer */
 127 
 128         if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
 129         {
 130             /* But only if it is NOT a pointer into an ACPI table */
 131 
 132             ObjPointer = Object->Buffer.Pointer;
 133         }
 134         break;
 135 

 136     case ACPI_TYPE_PACKAGE:
 137 
 138         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
 139             Object->Package.Count));
 140 
 141         /*
 142          * Elements of the package are not handled here, they are deleted
 143          * separately
 144          */
 145 
 146         /* Free the (variable length) element pointer array */
 147 
 148         ObjPointer = Object->Package.Elements;
 149         break;
 150 

 151     /*
 152      * These objects have a possible list of notify handlers.
 153      * Device object also may have a GPE block.
 154      */
 155     case ACPI_TYPE_DEVICE:
 156 
 157         if (Object->Device.GpeBlock)
 158         {
 159             (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock);
 160         }
 161 
 162         /*lint -fallthrough */
 163 
 164     case ACPI_TYPE_PROCESSOR:
 165     case ACPI_TYPE_THERMAL:
 166 
 167         /* Walk the address handler list for this object */
 168 
 169         HandlerDesc = Object->CommonNotify.Handler;
 170         while (HandlerDesc)
 171         {
 172             NextDesc = HandlerDesc->AddressSpace.Next;
 173             AcpiUtRemoveReference (HandlerDesc);
 174             HandlerDesc = NextDesc;
 175         }
 176         break;
 177 

 178     case ACPI_TYPE_MUTEX:
 179 
 180         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 181             "***** Mutex %p, OS Mutex %p\n",
 182             Object, Object->Mutex.OsMutex));
 183 
 184         if (Object == AcpiGbl_GlobalLockMutex)
 185         {
 186             /* Global Lock has extra semaphore */
 187 
 188             (void) AcpiOsDeleteSemaphore (AcpiGbl_GlobalLockSemaphore);
 189             AcpiGbl_GlobalLockSemaphore = NULL;
 190 
 191             AcpiOsDeleteMutex (Object->Mutex.OsMutex);
 192             AcpiGbl_GlobalLockMutex = NULL;
 193         }
 194         else
 195         {
 196             AcpiExUnlinkMutex (Object);
 197             AcpiOsDeleteMutex (Object->Mutex.OsMutex);
 198         }
 199         break;
 200 

 201     case ACPI_TYPE_EVENT:
 202 
 203         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 204             "***** Event %p, OS Semaphore %p\n",
 205             Object, Object->Event.OsSemaphore));
 206 
 207         (void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore);
 208         Object->Event.OsSemaphore = NULL;
 209         break;
 210 

 211     case ACPI_TYPE_METHOD:
 212 
 213         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 214             "***** Method %p\n", Object));
 215 
 216         /* Delete the method mutex if it exists */
 217 
 218         if (Object->Method.Mutex)
 219         {
 220             AcpiOsDeleteMutex (Object->Method.Mutex->Mutex.OsMutex);
 221             AcpiUtDeleteObjectDesc (Object->Method.Mutex);
 222             Object->Method.Mutex = NULL;
 223         }
 224         break;
 225 

 226     case ACPI_TYPE_REGION:
 227 
 228         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 229             "***** Region %p\n", Object));
 230 
 231         /*
 232          * Update AddressRange list. However, only permanent regions
 233          * are installed in this list. (Not created within a method)
 234          */
 235         if (!(Object->Region.Node->Flags & ANOBJ_TEMPORARY))
 236         {
 237             AcpiUtRemoveAddressRange (Object->Region.SpaceId,
 238                 Object->Region.Node);
 239         }
 240 
 241         SecondDesc = AcpiNsGetSecondaryObject (Object);
 242         if (SecondDesc)
 243         {
 244             /*
 245              * Free the RegionContext if and only if the handler is one of the
 246              * default handlers -- and therefore, we created the context object
 247              * locally, it was not created by an external caller.
 248              */
 249             HandlerDesc = Object->Region.Handler;
 250             if (HandlerDesc)
 251             {
 252                 NextDesc = HandlerDesc->AddressSpace.RegionList;
 253                 LastObjPtr = &HandlerDesc->AddressSpace.RegionList;
 254 
 255                 /* Remove the region object from the handler's list */
 256 
 257                 while (NextDesc)
 258                 {
 259                     if (NextDesc == Object)
 260                     {


 274                     /* Deactivate region and free region context */
 275 
 276                     if (HandlerDesc->AddressSpace.Setup)
 277                     {
 278                         (void) HandlerDesc->AddressSpace.Setup (Object,
 279                             ACPI_REGION_DEACTIVATE,
 280                             HandlerDesc->AddressSpace.Context,
 281                             &SecondDesc->Extra.RegionContext);
 282                     }
 283                 }
 284 
 285                 AcpiUtRemoveReference (HandlerDesc);
 286             }
 287 
 288             /* Now we can free the Extra object */
 289 
 290             AcpiUtDeleteObjectDesc (SecondDesc);
 291         }
 292         break;
 293 

 294     case ACPI_TYPE_BUFFER_FIELD:
 295 
 296         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 297             "***** Buffer Field %p\n", Object));
 298 
 299         SecondDesc = AcpiNsGetSecondaryObject (Object);
 300         if (SecondDesc)
 301         {
 302             AcpiUtDeleteObjectDesc (SecondDesc);
 303         }
 304         break;
 305 

 306     case ACPI_TYPE_LOCAL_BANK_FIELD:
 307 
 308         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 309             "***** Bank Field %p\n", Object));
 310 
 311         SecondDesc = AcpiNsGetSecondaryObject (Object);
 312         if (SecondDesc)
 313         {
 314             AcpiUtDeleteObjectDesc (SecondDesc);
 315         }
 316         break;
 317 

 318     default:
 319 
 320         break;
 321     }
 322 
 323     /* Free any allocated memory (pointer within the object) found above */
 324 
 325     if (ObjPointer)
 326     {
 327         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
 328             ObjPointer));
 329         ACPI_FREE (ObjPointer);
 330     }
 331 
 332     /* Now the object can be safely deleted */
 333 
 334     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
 335         Object, AcpiUtGetObjectTypeName (Object)));
 336 
 337     AcpiUtDeleteObjectDesc (Object);
 338     return_VOID;
 339 }


 342 /*******************************************************************************
 343  *
 344  * FUNCTION:    AcpiUtDeleteInternalObjectList
 345  *
 346  * PARAMETERS:  ObjList         - Pointer to the list to be deleted
 347  *
 348  * RETURN:      None
 349  *
 350  * DESCRIPTION: This function deletes an internal object list, including both
 351  *              simple objects and package objects
 352  *
 353  ******************************************************************************/
 354 
 355 void
 356 AcpiUtDeleteInternalObjectList (
 357     ACPI_OPERAND_OBJECT     **ObjList)
 358 {
 359     ACPI_OPERAND_OBJECT     **InternalObj;
 360 
 361 
 362     ACPI_FUNCTION_ENTRY ();
 363 
 364 
 365     /* Walk the null-terminated internal list */
 366 
 367     for (InternalObj = ObjList; *InternalObj; InternalObj++)
 368     {
 369         AcpiUtRemoveReference (*InternalObj);
 370     }
 371 
 372     /* Free the combined parameter pointer list and object array */
 373 
 374     ACPI_FREE (ObjList);
 375     return;
 376 }
 377 
 378 
 379 /*******************************************************************************
 380  *
 381  * FUNCTION:    AcpiUtUpdateRefCount
 382  *
 383  * PARAMETERS:  Object          - Object whose ref count is to be updated
 384  *              Action          - What to do (REF_INCREMENT or REF_DECREMENT)
 385  *
 386  * RETURN:      None. Sets new reference count within the object
 387  *
 388  * DESCRIPTION: Modify the reference count for an internal acpi object
 389  *
 390  ******************************************************************************/
 391 
 392 static void
 393 AcpiUtUpdateRefCount (
 394     ACPI_OPERAND_OBJECT     *Object,
 395     UINT32                  Action)
 396 {
 397     UINT16                  OriginalCount;
 398     UINT16                  NewCount = 0;
 399     ACPI_CPU_FLAGS          LockFlags;
 400 
 401 
 402     ACPI_FUNCTION_NAME (UtUpdateRefCount);
 403 
 404 
 405     if (!Object)
 406     {
 407         return;
 408     }
 409 



 410     /*
 411      * Always get the reference count lock. Note: Interpreter and/or
 412      * Namespace is not always locked when this function is called.
 413      */
 414     LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock);
 415     OriginalCount = Object->Common.ReferenceCount;
 416 
 417     /* Perform the reference count action (increment, decrement) */
 418 
 419     switch (Action)
 420     {
 421     case REF_INCREMENT:
 422 
 423         NewCount = OriginalCount + 1;
 424         Object->Common.ReferenceCount = NewCount;
 425         AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
 426 
 427         /* The current reference count should never be zero here */
 428 
 429         if (!OriginalCount)
 430         {
 431             ACPI_WARNING ((AE_INFO,
 432                 "Obj %p, Reference Count was zero before increment\n",
 433                 Object));
 434         }
 435 
 436         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 437             "Obj %p Type %.2X Refs %.2X [Incremented]\n",
 438             Object, Object->Common.Type, NewCount));
 439         break;
 440 
 441     case REF_DECREMENT:
 442 
 443         /* The current reference count must be non-zero */




 444 
 445         if (OriginalCount)


 446         {
 447             NewCount = OriginalCount - 1;
 448             Object->Common.ReferenceCount = NewCount;



 449         }
 450 
 451         AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
 452 
 453         if (!OriginalCount)
 454         {
 455             ACPI_WARNING ((AE_INFO,
 456                 "Obj %p, Reference Count is already zero, cannot decrement\n",
 457                 Object));
 458         }
 459 
 460         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 461             "Obj %p Type %.2X Refs %.2X [Decremented]\n",
 462             Object, Object->Common.Type, NewCount));
 463 
 464         /* Actually delete the object on a reference count of zero */
 465 
 466         if (NewCount == 0)
 467         {
 468             AcpiUtDeleteInternalObj (Object);
 469         }
 470         break;
 471 










 472     default:
 473 
 474         AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
 475         ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)",
 476             Action));
 477         return;
 478     }
 479 
 480     /*
 481      * Sanity check the reference count, for debug purposes only.
 482      * (A deleted object will have a huge reference count)
 483      */
 484     if (NewCount > ACPI_MAX_REFERENCE_COUNT)
 485     {
 486         ACPI_WARNING ((AE_INFO,
 487             "Large Reference Count (0x%X) in object %p, Type=0x%.2X",
 488             NewCount, Object, Object->Common.Type));
 489     }
 490 }
 491 
 492 
 493 /*******************************************************************************
 494  *
 495  * FUNCTION:    AcpiUtUpdateObjectReference
 496  *
 497  * PARAMETERS:  Object              - Increment ref count for this object
 498  *                                    and all sub-objects
 499  *              Action              - Either REF_INCREMENT or REF_DECREMENT

 500  *
 501  * RETURN:      Status
 502  *
 503  * DESCRIPTION: Increment the object reference count
 504  *
 505  * Object references are incremented when:
 506  * 1) An object is attached to a Node (namespace object)
 507  * 2) An object is copied (all subobjects must be incremented)
 508  *
 509  * Object references are decremented when:
 510  * 1) An object is detached from an Node
 511  *
 512  ******************************************************************************/
 513 
 514 ACPI_STATUS
 515 AcpiUtUpdateObjectReference (
 516     ACPI_OPERAND_OBJECT     *Object,
 517     UINT16                  Action)
 518 {
 519     ACPI_STATUS             Status = AE_OK;
 520     ACPI_GENERIC_STATE      *StateList = NULL;
 521     ACPI_OPERAND_OBJECT     *NextObject = NULL;
 522     ACPI_OPERAND_OBJECT     *PrevObject;
 523     ACPI_GENERIC_STATE      *State;
 524     UINT32                  i;
 525 
 526 
 527     ACPI_FUNCTION_NAME (UtUpdateObjectReference);
 528 
 529 
 530     while (Object)
 531     {
 532         /* Make sure that this isn't a namespace handle */
 533 
 534         if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
 535         {
 536             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 537                 "Object %p is NS handle\n", Object));
 538             return (AE_OK);
 539         }
 540 
 541         /*
 542          * All sub-objects must have their reference count incremented also.
 543          * Different object types have different subobjects.
 544          */
 545         switch (Object->Common.Type)
 546         {
 547         case ACPI_TYPE_DEVICE:
 548         case ACPI_TYPE_PROCESSOR:
 549         case ACPI_TYPE_POWER:
 550         case ACPI_TYPE_THERMAL:
 551             /*
 552              * Update the notify objects for these types (if present)
 553              * Two lists, system and device notify handlers.
 554              */
 555             for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
 556             {
 557                 PrevObject = Object->CommonNotify.NotifyList[i];
 558                 while (PrevObject)
 559                 {
 560                     NextObject = PrevObject->Notify.Next[i];
 561                     AcpiUtUpdateRefCount (PrevObject, Action);
 562                     PrevObject = NextObject;
 563                 }
 564             }
 565             break;
 566 
 567         case ACPI_TYPE_PACKAGE:
 568             /*
 569              * We must update all the sub-objects of the package,
 570              * each of whom may have their own sub-objects.
 571              */
 572             for (i = 0; i < Object->Package.Count; i++)
 573             {
 574                 /*
 575                  * Null package elements are legal and can be simply
 576                  * ignored.

 577                  */
 578                 NextObject = Object->Package.Elements[i];
 579                 if (!NextObject)
 580                 {
 581                     continue;
 582                 }
 583 
 584                 switch (NextObject->Common.Type)
 585                 {
 586                 case ACPI_TYPE_INTEGER:
 587                 case ACPI_TYPE_STRING:
 588                 case ACPI_TYPE_BUFFER:
 589                     /*
 590                      * For these very simple sub-objects, we can just
 591                      * update the reference count here and continue.
 592                      * Greatly increases performance of this operation.
 593                      */
 594                     AcpiUtUpdateRefCount (NextObject, Action);
 595                     break;
 596 
 597                 default:
 598                     /*
 599                      * For complex sub-objects, push them onto the stack
 600                      * for later processing (this eliminates recursion.)
 601                      */
 602                     Status = AcpiUtCreateUpdateStateAndPush (
 603                                  NextObject, Action, &StateList);
 604                     if (ACPI_FAILURE (Status))
 605                     {
 606                         goto ErrorExit;
 607                     }
 608                     break;
 609                 }
 610             }
 611             NextObject = NULL;
 612             break;
 613 
 614         case ACPI_TYPE_BUFFER_FIELD:
 615 
 616             NextObject = Object->BufferField.BufferObj;
 617             break;
 618 
 619         case ACPI_TYPE_LOCAL_REGION_FIELD:
 620 
 621             NextObject = Object->Field.RegionObj;
 622             break;
 623 
 624         case ACPI_TYPE_LOCAL_BANK_FIELD:
 625 
 626             NextObject = Object->BankField.BankObj;
 627             Status = AcpiUtCreateUpdateStateAndPush (
 628                         Object->BankField.RegionObj, Action, &StateList);
 629             if (ACPI_FAILURE (Status))
 630             {
 631                 goto ErrorExit;


 641             {
 642                 goto ErrorExit;
 643             }
 644             break;
 645 
 646         case ACPI_TYPE_LOCAL_REFERENCE:
 647             /*
 648              * The target of an Index (a package, string, or buffer) or a named
 649              * reference must track changes to the ref count of the index or
 650              * target object.
 651              */
 652             if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) ||
 653                 (Object->Reference.Class== ACPI_REFCLASS_NAME))
 654             {
 655                 NextObject = Object->Reference.Object;
 656             }
 657             break;
 658 
 659         case ACPI_TYPE_REGION:
 660         default:
 661 
 662             break; /* No subobjects for all other types */
 663         }
 664 
 665         /*
 666          * Now we can update the count in the main object. This can only
 667          * happen after we update the sub-objects in case this causes the
 668          * main object to be deleted.
 669          */
 670         AcpiUtUpdateRefCount (Object, Action);
 671         Object = NULL;
 672 
 673         /* Move on to the next object to be updated */
 674 
 675         if (NextObject)
 676         {
 677             Object = NextObject;
 678             NextObject = NULL;
 679         }
 680         else if (StateList)
 681         {
 682             State = AcpiUtPopGenericState (&StateList);
 683             Object = State->Update.Object;
 684             AcpiUtDeleteGenericState (State);
 685         }
 686     }
 687 
 688     return (AE_OK);
 689 
 690 
 691 ErrorExit:
 692 
 693     ACPI_EXCEPTION ((AE_INFO, Status,
 694         "Could not update object reference count"));
 695 
 696     /* Free any stacked Update State objects */
 697 
 698     while (StateList)
 699     {
 700         State = AcpiUtPopGenericState (&StateList);
 701         AcpiUtDeleteGenericState (State);
 702     }
 703 
 704     return (Status);
 705 }
 706 
 707 
 708 /*******************************************************************************
 709  *
 710  * FUNCTION:    AcpiUtAddReference
 711  *
 712  * PARAMETERS:  Object          - Object whose reference count is to be
 713  *                                incremented
 714  *
 715  * RETURN:      None
 716  *
 717  * DESCRIPTION: Add one reference to an ACPI object
 718  *
 719  ******************************************************************************/
 720 
 721 void
 722 AcpiUtAddReference (
 723     ACPI_OPERAND_OBJECT     *Object)
 724 {
 725 
 726     ACPI_FUNCTION_NAME (UtAddReference);
 727 
 728 
 729     /* Ensure that we have a valid object */
 730 
 731     if (!AcpiUtValidInternalObject (Object))
 732     {
 733         return;
 734     }
 735 
 736     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 737         "Obj %p Current Refs=%X [To Be Incremented]\n",
 738         Object, Object->Common.ReferenceCount));
 739 
 740     /* Increment the reference count */
 741 
 742     (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
 743     return;
 744 }
 745 
 746 
 747 /*******************************************************************************
 748  *
 749  * FUNCTION:    AcpiUtRemoveReference
 750  *
 751  * PARAMETERS:  Object         - Object whose ref count will be decremented
 752  *
 753  * RETURN:      None
 754  *
 755  * DESCRIPTION: Decrement the reference count of an ACPI internal object
 756  *
 757  ******************************************************************************/
 758 
 759 void
 760 AcpiUtRemoveReference (
 761     ACPI_OPERAND_OBJECT     *Object)
 762 {
 763 
 764     ACPI_FUNCTION_NAME (UtRemoveReference);
 765 
 766 
 767     /*
 768      * Allow a NULL pointer to be passed in, just ignore it. This saves
 769      * each caller from having to check. Also, ignore NS nodes.

 770      */
 771     if (!Object ||
 772         (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))
 773 
 774     {
 775         return;
 776     }
 777 
 778     /* Ensure that we have a valid object */
 779 
 780     if (!AcpiUtValidInternalObject (Object))
 781     {
 782         return;
 783     }
 784 
 785     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
 786         "Obj %p Current Refs=%X [To Be Decremented]\n",
 787         Object, Object->Common.ReferenceCount));
 788 
 789     /*
 790      * Decrement the reference count, and only actually delete the object
 791      * if the reference count becomes 0. (Must also decrement the ref count
 792      * of all subobjects!)
 793      */
 794     (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
 795     return;
 796 }