Home | History | Annotate | Line # | Download | only in utilities
utdelete.c revision 1.1.1.2.4.2
      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.
     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 "acpi.h"
     47 #include "accommon.h"
     48 #include "acinterp.h"
     49 #include "acnamesp.h"
     50 #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 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                     {
    258                         *LastObjPtr = NextDesc->Region.Next;
    259                         break;
    260                     }
    261 
    262                     /* Walk the linked list of handler */
    263 
    264                     LastObjPtr = &NextDesc->Region.Next;
    265                     NextDesc = NextDesc->Region.Next;
    266                 }
    267 
    268                 if (HandlerDesc->AddressSpace.HandlerFlags &
    269                     ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
    270                 {
    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 }
    339 
    340 
    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;
    590             }
    591             break;
    592 
    593         case ACPI_TYPE_LOCAL_INDEX_FIELD:
    594 
    595             NextObject = Object->IndexField.IndexObj;
    596             Status = AcpiUtCreateUpdateStateAndPush (
    597                         Object->IndexField.DataObj, Action, &StateList);
    598             if (ACPI_FAILURE (Status))
    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 
    757