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