Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:03

0001 /*******************************************************************************
0002  *
0003  * Module Name: utdelete - object deletion and reference count utilities
0004  *
0005  ******************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government. In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************
0115  *
0116  * Alternatively, you may choose to be licensed under the terms of the
0117  * following license:
0118  *
0119  * Redistribution and use in source and binary forms, with or without
0120  * modification, are permitted provided that the following conditions
0121  * are met:
0122  * 1. Redistributions of source code must retain the above copyright
0123  *    notice, this list of conditions, and the following disclaimer,
0124  *    without modification.
0125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0126  *    substantially similar to the "NO WARRANTY" disclaimer below
0127  *    ("Disclaimer") and any redistribution must be conditioned upon
0128  *    including a substantially similar Disclaimer requirement for further
0129  *    binary redistribution.
0130  * 3. Neither the names of the above-listed copyright holders nor the names
0131  *    of any contributors may be used to endorse or promote products derived
0132  *    from this software without specific prior written permission.
0133  *
0134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0145  *
0146  * Alternatively, you may choose to be licensed under the terms of the
0147  * GNU General Public License ("GPL") version 2 as published by the Free
0148  * Software Foundation.
0149  *
0150  *****************************************************************************/
0151 
0152 #include "acpi.h"
0153 #include "accommon.h"
0154 #include "acinterp.h"
0155 #include "acnamesp.h"
0156 #include "acevents.h"
0157 
0158 
0159 #define _COMPONENT          ACPI_UTILITIES
0160         ACPI_MODULE_NAME    ("utdelete")
0161 
0162 /* Local prototypes */
0163 
0164 static void
0165 AcpiUtDeleteInternalObj (
0166     ACPI_OPERAND_OBJECT     *Object);
0167 
0168 static void
0169 AcpiUtUpdateRefCount (
0170     ACPI_OPERAND_OBJECT     *Object,
0171     UINT32                  Action);
0172 
0173 
0174 /*******************************************************************************
0175  *
0176  * FUNCTION:    AcpiUtDeleteInternalObj
0177  *
0178  * PARAMETERS:  Object         - Object to be deleted
0179  *
0180  * RETURN:      None
0181  *
0182  * DESCRIPTION: Low level object deletion, after reference counts have been
0183  *              updated (All reference counts, including sub-objects!)
0184  *
0185  ******************************************************************************/
0186 
0187 static void
0188 AcpiUtDeleteInternalObj (
0189     ACPI_OPERAND_OBJECT     *Object)
0190 {
0191     void                    *ObjPointer = NULL;
0192     ACPI_OPERAND_OBJECT     *HandlerDesc;
0193     ACPI_OPERAND_OBJECT     *SecondDesc;
0194     ACPI_OPERAND_OBJECT     *NextDesc;
0195     ACPI_OPERAND_OBJECT     *StartDesc;
0196     ACPI_OPERAND_OBJECT     **LastObjPtr;
0197 
0198 
0199     ACPI_FUNCTION_TRACE_PTR (UtDeleteInternalObj, Object);
0200 
0201 
0202     if (!Object)
0203     {
0204         return_VOID;
0205     }
0206 
0207     /*
0208      * Must delete or free any pointers within the object that are not
0209      * actual ACPI objects (for example, a raw buffer pointer).
0210      */
0211     switch (Object->Common.Type)
0212     {
0213     case ACPI_TYPE_STRING:
0214 
0215         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
0216             Object, Object->String.Pointer));
0217 
0218         /* Free the actual string buffer */
0219 
0220         if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
0221         {
0222             /* But only if it is NOT a pointer into an ACPI table */
0223 
0224             ObjPointer = Object->String.Pointer;
0225         }
0226         break;
0227 
0228     case ACPI_TYPE_BUFFER:
0229 
0230         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
0231             Object, Object->Buffer.Pointer));
0232 
0233         /* Free the actual buffer */
0234 
0235         if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
0236         {
0237             /* But only if it is NOT a pointer into an ACPI table */
0238 
0239             ObjPointer = Object->Buffer.Pointer;
0240         }
0241         break;
0242 
0243     case ACPI_TYPE_PACKAGE:
0244 
0245         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
0246             Object->Package.Count));
0247 
0248         /*
0249          * Elements of the package are not handled here, they are deleted
0250          * separately
0251          */
0252 
0253         /* Free the (variable length) element pointer array */
0254 
0255         ObjPointer = Object->Package.Elements;
0256         break;
0257 
0258     /*
0259      * These objects have a possible list of notify handlers.
0260      * Device object also may have a GPE block.
0261      */
0262     case ACPI_TYPE_DEVICE:
0263 
0264         if (Object->Device.GpeBlock)
0265         {
0266             (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock);
0267         }
0268 
0269         ACPI_FALLTHROUGH;
0270 
0271     case ACPI_TYPE_PROCESSOR:
0272     case ACPI_TYPE_THERMAL:
0273 
0274         /* Walk the address handler list for this object */
0275 
0276         HandlerDesc = Object->CommonNotify.Handler;
0277         while (HandlerDesc)
0278         {
0279             NextDesc = HandlerDesc->AddressSpace.Next;
0280             AcpiUtRemoveReference (HandlerDesc);
0281             HandlerDesc = NextDesc;
0282         }
0283         break;
0284 
0285     case ACPI_TYPE_MUTEX:
0286 
0287         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0288             "***** Mutex %p, OS Mutex %p\n",
0289             Object, Object->Mutex.OsMutex));
0290 
0291         if (Object == AcpiGbl_GlobalLockMutex)
0292         {
0293             /* Global Lock has extra semaphore */
0294 
0295             (void) AcpiOsDeleteSemaphore (AcpiGbl_GlobalLockSemaphore);
0296             AcpiGbl_GlobalLockSemaphore = ACPI_SEMAPHORE_NULL;
0297 
0298             AcpiOsDeleteMutex (Object->Mutex.OsMutex);
0299             AcpiGbl_GlobalLockMutex = NULL;
0300         }
0301         else
0302         {
0303             AcpiExUnlinkMutex (Object);
0304             AcpiOsDeleteMutex (Object->Mutex.OsMutex);
0305         }
0306         break;
0307 
0308     case ACPI_TYPE_EVENT:
0309 
0310         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0311             "***** Event %p, OS Semaphore %p\n",
0312             Object, Object->Event.OsSemaphore));
0313 
0314         (void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore);
0315         Object->Event.OsSemaphore = ACPI_SEMAPHORE_NULL;
0316         break;
0317 
0318     case ACPI_TYPE_METHOD:
0319 
0320         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0321             "***** Method %p\n", Object));
0322 
0323         /* Delete the method mutex if it exists */
0324 
0325         if (Object->Method.Mutex)
0326         {
0327             AcpiOsDeleteMutex (Object->Method.Mutex->Mutex.OsMutex);
0328             AcpiUtDeleteObjectDesc (Object->Method.Mutex);
0329             Object->Method.Mutex = NULL;
0330         }
0331 
0332         if (Object->Method.Node)
0333         {
0334             Object->Method.Node = NULL;
0335         }
0336         break;
0337 
0338     case ACPI_TYPE_REGION:
0339 
0340         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0341             "***** Region %p\n", Object));
0342 
0343         /*
0344          * Update AddressRange list. However, only permanent regions
0345          * are installed in this list. (Not created within a method)
0346          */
0347         if (!(Object->Region.Node->Flags & ANOBJ_TEMPORARY))
0348         {
0349             AcpiUtRemoveAddressRange (Object->Region.SpaceId,
0350                 Object->Region.Node);
0351         }
0352 
0353         SecondDesc = AcpiNsGetSecondaryObject (Object);
0354         if (SecondDesc)
0355         {
0356             /*
0357              * Free the RegionContext if and only if the handler is one of the
0358              * default handlers -- and therefore, we created the context object
0359              * locally, it was not created by an external caller.
0360              */
0361             HandlerDesc = Object->Region.Handler;
0362             if (HandlerDesc)
0363             {
0364                 NextDesc = HandlerDesc->AddressSpace.RegionList;
0365                 StartDesc = NextDesc;
0366                 LastObjPtr = &HandlerDesc->AddressSpace.RegionList;
0367 
0368                 /* Remove the region object from the handler list */
0369 
0370                 while (NextDesc)
0371                 {
0372                     if (NextDesc == Object)
0373                     {
0374                         *LastObjPtr = NextDesc->Region.Next;
0375                         break;
0376                     }
0377 
0378                     /* Walk the linked list of handlers */
0379 
0380                     LastObjPtr = &NextDesc->Region.Next;
0381                     NextDesc = NextDesc->Region.Next;
0382 
0383                     /* Prevent infinite loop if list is corrupted */
0384 
0385                     if (NextDesc == StartDesc)
0386                     {
0387                         ACPI_ERROR ((AE_INFO,
0388                             "Circular region list in address handler object %p",
0389                             HandlerDesc));
0390                         return_VOID;
0391                     }
0392                 }
0393 
0394                 if (HandlerDesc->AddressSpace.HandlerFlags &
0395                     ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
0396                 {
0397                     /* Deactivate region and free region context */
0398 
0399                     if (HandlerDesc->AddressSpace.Setup)
0400                     {
0401                         (void) HandlerDesc->AddressSpace.Setup (Object,
0402                             ACPI_REGION_DEACTIVATE,
0403                             HandlerDesc->AddressSpace.Context,
0404                             &SecondDesc->Extra.RegionContext);
0405                     }
0406                 }
0407 
0408                 AcpiUtRemoveReference (HandlerDesc);
0409             }
0410 
0411             /* Now we can free the Extra object */
0412 
0413             AcpiUtDeleteObjectDesc (SecondDesc);
0414         }
0415         if (Object->Field.InternalPccBuffer)
0416         {
0417             ACPI_FREE(Object->Field.InternalPccBuffer);
0418         }
0419 
0420         break;
0421 
0422     case ACPI_TYPE_BUFFER_FIELD:
0423 
0424         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0425             "***** Buffer Field %p\n", Object));
0426 
0427         SecondDesc = AcpiNsGetSecondaryObject (Object);
0428         if (SecondDesc)
0429         {
0430             AcpiUtDeleteObjectDesc (SecondDesc);
0431         }
0432         break;
0433 
0434     case ACPI_TYPE_LOCAL_BANK_FIELD:
0435 
0436         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0437             "***** Bank Field %p\n", Object));
0438 
0439         SecondDesc = AcpiNsGetSecondaryObject (Object);
0440         if (SecondDesc)
0441         {
0442             AcpiUtDeleteObjectDesc (SecondDesc);
0443         }
0444         break;
0445 
0446     case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
0447 
0448         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0449             "***** Address handler %p\n", Object));
0450 
0451         AcpiOsDeleteMutex (Object->AddressSpace.ContextMutex);
0452         break;
0453 
0454     default:
0455 
0456         break;
0457     }
0458 
0459     /* Free any allocated memory (pointer within the object) found above */
0460 
0461     if (ObjPointer)
0462     {
0463         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
0464             ObjPointer));
0465         ACPI_FREE (ObjPointer);
0466     }
0467 
0468     /* Now the object can be safely deleted */
0469 
0470     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS, "%s: Deleting Object %p [%s]\n",
0471         ACPI_GET_FUNCTION_NAME, Object, AcpiUtGetObjectTypeName (Object)));
0472 
0473     AcpiUtDeleteObjectDesc (Object);
0474     return_VOID;
0475 }
0476 
0477 
0478 /*******************************************************************************
0479  *
0480  * FUNCTION:    AcpiUtDeleteInternalObjectList
0481  *
0482  * PARAMETERS:  ObjList         - Pointer to the list to be deleted
0483  *
0484  * RETURN:      None
0485  *
0486  * DESCRIPTION: This function deletes an internal object list, including both
0487  *              simple objects and package objects
0488  *
0489  ******************************************************************************/
0490 
0491 void
0492 AcpiUtDeleteInternalObjectList (
0493     ACPI_OPERAND_OBJECT     **ObjList)
0494 {
0495     ACPI_OPERAND_OBJECT     **InternalObj;
0496 
0497 
0498     ACPI_FUNCTION_ENTRY ();
0499 
0500 
0501     /* Walk the null-terminated internal list */
0502 
0503     for (InternalObj = ObjList; *InternalObj; InternalObj++)
0504     {
0505         AcpiUtRemoveReference (*InternalObj);
0506     }
0507 
0508     /* Free the combined parameter pointer list and object array */
0509 
0510     ACPI_FREE (ObjList);
0511     return;
0512 }
0513 
0514 
0515 /*******************************************************************************
0516  *
0517  * FUNCTION:    AcpiUtUpdateRefCount
0518  *
0519  * PARAMETERS:  Object          - Object whose ref count is to be updated
0520  *              Action          - What to do (REF_INCREMENT or REF_DECREMENT)
0521  *
0522  * RETURN:      None. Sets new reference count within the object
0523  *
0524  * DESCRIPTION: Modify the reference count for an internal acpi object
0525  *
0526  ******************************************************************************/
0527 
0528 static void
0529 AcpiUtUpdateRefCount (
0530     ACPI_OPERAND_OBJECT     *Object,
0531     UINT32                  Action)
0532 {
0533     UINT16                  OriginalCount;
0534     UINT16                  NewCount = 0;
0535     ACPI_CPU_FLAGS          LockFlags;
0536     char                    *Message;
0537 
0538 
0539     ACPI_FUNCTION_NAME (UtUpdateRefCount);
0540 
0541 
0542     if (!Object)
0543     {
0544         return;
0545     }
0546 
0547     /*
0548      * Always get the reference count lock. Note: Interpreter and/or
0549      * Namespace is not always locked when this function is called.
0550      */
0551     LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock);
0552     OriginalCount = Object->Common.ReferenceCount;
0553 
0554     /* Perform the reference count action (increment, decrement) */
0555 
0556     switch (Action)
0557     {
0558     case REF_INCREMENT:
0559 
0560         NewCount = OriginalCount + 1;
0561         Object->Common.ReferenceCount = NewCount;
0562         AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
0563 
0564         /* The current reference count should never be zero here */
0565 
0566         if (!OriginalCount)
0567         {
0568             ACPI_WARNING ((AE_INFO,
0569                 "Obj %p, Reference Count was zero before increment\n",
0570                 Object));
0571         }
0572 
0573         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0574             "Obj %p Type %.2X [%s] Refs %.2X [Incremented]\n",
0575             Object, Object->Common.Type,
0576             AcpiUtGetObjectTypeName (Object), NewCount));
0577         Message = "Incremement";
0578         break;
0579 
0580     case REF_DECREMENT:
0581 
0582         /* The current reference count must be non-zero */
0583 
0584         if (OriginalCount)
0585         {
0586             NewCount = OriginalCount - 1;
0587             Object->Common.ReferenceCount = NewCount;
0588         }
0589 
0590         AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
0591 
0592         if (!OriginalCount)
0593         {
0594             ACPI_WARNING ((AE_INFO,
0595                 "Obj %p, Reference Count is already zero, cannot decrement\n",
0596                 Object));
0597             return;
0598         }
0599 
0600         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS,
0601             "%s: Obj %p Type %.2X Refs %.2X [Decremented]\n",
0602             ACPI_GET_FUNCTION_NAME, Object, Object->Common.Type, NewCount));
0603 
0604         /* Actually delete the object on a reference count of zero */
0605 
0606         if (NewCount == 0)
0607         {
0608             AcpiUtDeleteInternalObj (Object);
0609         }
0610         Message = "Decrement";
0611         break;
0612 
0613     default:
0614 
0615         AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
0616         ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)",
0617             Action));
0618         return;
0619     }
0620 
0621     /*
0622      * Sanity check the reference count, for debug purposes only.
0623      * (A deleted object will have a huge reference count)
0624      */
0625     if (NewCount > ACPI_MAX_REFERENCE_COUNT)
0626     {
0627         ACPI_WARNING ((AE_INFO,
0628             "Large Reference Count (0x%X) in object %p, Type=0x%.2X Operation=%s",
0629             NewCount, Object, Object->Common.Type, Message));
0630     }
0631 }
0632 
0633 
0634 /*******************************************************************************
0635  *
0636  * FUNCTION:    AcpiUtUpdateObjectReference
0637  *
0638  * PARAMETERS:  Object              - Increment or decrement the ref count for
0639  *                                    this object and all sub-objects
0640  *              Action              - Either REF_INCREMENT or REF_DECREMENT
0641  *
0642  * RETURN:      Status
0643  *
0644  * DESCRIPTION: Increment or decrement the object reference count
0645  *
0646  * Object references are incremented when:
0647  * 1) An object is attached to a Node (namespace object)
0648  * 2) An object is copied (all subobjects must be incremented)
0649  *
0650  * Object references are decremented when:
0651  * 1) An object is detached from an Node
0652  *
0653  ******************************************************************************/
0654 
0655 ACPI_STATUS
0656 AcpiUtUpdateObjectReference (
0657     ACPI_OPERAND_OBJECT     *Object,
0658     UINT16                  Action)
0659 {
0660     ACPI_STATUS             Status = AE_OK;
0661     ACPI_GENERIC_STATE      *StateList = NULL;
0662     ACPI_OPERAND_OBJECT     *NextObject = NULL;
0663     ACPI_OPERAND_OBJECT     *PrevObject;
0664     ACPI_GENERIC_STATE      *State;
0665     UINT32                  i;
0666 
0667 
0668     ACPI_FUNCTION_NAME (UtUpdateObjectReference);
0669 
0670 
0671     while (Object)
0672     {
0673         /* Make sure that this isn't a namespace handle */
0674 
0675         if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
0676         {
0677             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0678                 "Object %p is NS handle\n", Object));
0679             return (AE_OK);
0680         }
0681 
0682         /*
0683          * All sub-objects must have their reference count updated
0684          * also. Different object types have different subobjects.
0685          */
0686         switch (Object->Common.Type)
0687         {
0688         case ACPI_TYPE_DEVICE:
0689         case ACPI_TYPE_PROCESSOR:
0690         case ACPI_TYPE_POWER:
0691         case ACPI_TYPE_THERMAL:
0692             /*
0693              * Update the notify objects for these types (if present)
0694              * Two lists, system and device notify handlers.
0695              */
0696             for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
0697             {
0698                 PrevObject = Object->CommonNotify.NotifyList[i];
0699                 while (PrevObject)
0700                 {
0701                     NextObject = PrevObject->Notify.Next[i];
0702                     AcpiUtUpdateRefCount (PrevObject, Action);
0703                     PrevObject = NextObject;
0704                 }
0705             }
0706             break;
0707 
0708         case ACPI_TYPE_PACKAGE:
0709             /*
0710              * We must update all the sub-objects of the package,
0711              * each of whom may have their own sub-objects.
0712              */
0713             for (i = 0; i < Object->Package.Count; i++)
0714             {
0715                 /*
0716                  * Null package elements are legal and can be simply
0717                  * ignored.
0718                  */
0719                 NextObject = Object->Package.Elements[i];
0720                 if (!NextObject)
0721                 {
0722                     continue;
0723                 }
0724 
0725                 switch (NextObject->Common.Type)
0726                 {
0727                 case ACPI_TYPE_INTEGER:
0728                 case ACPI_TYPE_STRING:
0729                 case ACPI_TYPE_BUFFER:
0730                     /*
0731                      * For these very simple sub-objects, we can just
0732                      * update the reference count here and continue.
0733                      * Greatly increases performance of this operation.
0734                      */
0735                     AcpiUtUpdateRefCount (NextObject, Action);
0736                     break;
0737 
0738                 default:
0739                     /*
0740                      * For complex sub-objects, push them onto the stack
0741                      * for later processing (this eliminates recursion.)
0742                      */
0743                     Status = AcpiUtCreateUpdateStateAndPush (
0744                         NextObject, Action, &StateList);
0745                     if (ACPI_FAILURE (Status))
0746                     {
0747                         goto ErrorExit;
0748                     }
0749                     break;
0750                 }
0751             }
0752 
0753             NextObject = NULL;
0754             break;
0755 
0756         case ACPI_TYPE_BUFFER_FIELD:
0757 
0758             NextObject = Object->BufferField.BufferObj;
0759             break;
0760 
0761         case ACPI_TYPE_LOCAL_BANK_FIELD:
0762 
0763             NextObject = Object->BankField.BankObj;
0764             Status = AcpiUtCreateUpdateStateAndPush (
0765                 Object->BankField.RegionObj, Action, &StateList);
0766             if (ACPI_FAILURE (Status))
0767             {
0768                 goto ErrorExit;
0769             }
0770             break;
0771 
0772         case ACPI_TYPE_LOCAL_INDEX_FIELD:
0773 
0774             NextObject = Object->IndexField.IndexObj;
0775             Status = AcpiUtCreateUpdateStateAndPush (
0776                 Object->IndexField.DataObj, Action, &StateList);
0777             if (ACPI_FAILURE (Status))
0778             {
0779                 goto ErrorExit;
0780             }
0781             break;
0782 
0783         case ACPI_TYPE_LOCAL_REFERENCE:
0784             /*
0785              * The target of an Index (a package, string, or buffer) or a named
0786              * reference must track changes to the ref count of the index or
0787              * target object.
0788              */
0789             if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) ||
0790                 (Object->Reference.Class== ACPI_REFCLASS_NAME))
0791             {
0792                 NextObject = Object->Reference.Object;
0793             }
0794             break;
0795 
0796         case ACPI_TYPE_LOCAL_REGION_FIELD:
0797         case ACPI_TYPE_REGION:
0798         default:
0799 
0800             break; /* No subobjects for all other types */
0801         }
0802 
0803         /*
0804          * Now we can update the count in the main object. This can only
0805          * happen after we update the sub-objects in case this causes the
0806          * main object to be deleted.
0807          */
0808         AcpiUtUpdateRefCount (Object, Action);
0809         Object = NULL;
0810 
0811         /* Move on to the next object to be updated */
0812 
0813         if (NextObject)
0814         {
0815             Object = NextObject;
0816             NextObject = NULL;
0817         }
0818         else if (StateList)
0819         {
0820             State = AcpiUtPopGenericState (&StateList);
0821             Object = State->Update.Object;
0822             AcpiUtDeleteGenericState (State);
0823         }
0824     }
0825 
0826     return (AE_OK);
0827 
0828 
0829 ErrorExit:
0830 
0831     ACPI_EXCEPTION ((AE_INFO, Status,
0832         "Could not update object reference count"));
0833 
0834     /* Free any stacked Update State objects */
0835 
0836     while (StateList)
0837     {
0838         State = AcpiUtPopGenericState (&StateList);
0839         AcpiUtDeleteGenericState (State);
0840     }
0841 
0842     return (Status);
0843 }
0844 
0845 
0846 /*******************************************************************************
0847  *
0848  * FUNCTION:    AcpiUtAddReference
0849  *
0850  * PARAMETERS:  Object          - Object whose reference count is to be
0851  *                                incremented
0852  *
0853  * RETURN:      None
0854  *
0855  * DESCRIPTION: Add one reference to an ACPI object
0856  *
0857  ******************************************************************************/
0858 
0859 void
0860 AcpiUtAddReference (
0861     ACPI_OPERAND_OBJECT     *Object)
0862 {
0863 
0864     ACPI_FUNCTION_NAME (UtAddReference);
0865 
0866 
0867     /* Ensure that we have a valid object */
0868 
0869     if (!AcpiUtValidInternalObject (Object))
0870     {
0871         return;
0872     }
0873 
0874     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
0875         "Obj %p Current Refs=%X [To Be Incremented]\n",
0876         Object, Object->Common.ReferenceCount));
0877 
0878     /* Increment the reference count */
0879 
0880     (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
0881     return;
0882 }
0883 
0884 
0885 /*******************************************************************************
0886  *
0887  * FUNCTION:    AcpiUtRemoveReference
0888  *
0889  * PARAMETERS:  Object         - Object whose ref count will be decremented
0890  *
0891  * RETURN:      None
0892  *
0893  * DESCRIPTION: Decrement the reference count of an ACPI internal object
0894  *
0895  ******************************************************************************/
0896 
0897 void
0898 AcpiUtRemoveReference (
0899     ACPI_OPERAND_OBJECT     *Object)
0900 {
0901 
0902     ACPI_FUNCTION_NAME (UtRemoveReference);
0903 
0904 
0905     /*
0906      * Allow a NULL pointer to be passed in, just ignore it. This saves
0907      * each caller from having to check. Also, ignore NS nodes.
0908      */
0909     if (!Object ||
0910         (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))
0911 
0912     {
0913         return;
0914     }
0915 
0916     /* Ensure that we have a valid object */
0917 
0918     if (!AcpiUtValidInternalObject (Object))
0919     {
0920         return;
0921     }
0922 
0923     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ALLOCATIONS,
0924         "%s: Obj %p Current Refs=%X [To Be Decremented]\n",
0925         ACPI_GET_FUNCTION_NAME, Object, Object->Common.ReferenceCount));
0926 
0927     /*
0928      * Decrement the reference count, and only actually delete the object
0929      * if the reference count becomes 0. (Must also decrement the ref count
0930      * of all subobjects!)
0931      */
0932     (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
0933     return;
0934 }