167754Smsmith/******************************************************************************* 267754Smsmith * 377424Smsmith * Module Name: utdelete - object deletion and reference count utilities 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 1270243Smsmith * All rights reserved. 1367754Smsmith * 14316303Sjkim * 2. License 15316303Sjkim * 16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17316303Sjkim * rights. You may have additional license terms from the party that provided 18316303Sjkim * you this software, covering your right to use that party's intellectual 19316303Sjkim * property rights. 20316303Sjkim * 21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 26316303Sjkim * Code in any form, with the right to sublicense such rights; and 27316303Sjkim * 28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29316303Sjkim * license (with the right to sublicense), under only those claims of Intel 30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 33316303Sjkim * license, and in no event shall the patent license extend to any additions 34316303Sjkim * to or modifications of the Original Intel Code. No other license or right 35316303Sjkim * is granted directly or by implication, estoppel or otherwise; 36316303Sjkim * 37316303Sjkim * The above copyright and patent license is granted only if the following 38316303Sjkim * conditions are met: 39316303Sjkim * 40316303Sjkim * 3. Conditions 41316303Sjkim * 42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43316303Sjkim * Redistribution of source code of any substantial portion of the Covered 44316303Sjkim * Code or modification with rights to further distribute source must include 45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 49316303Sjkim * Code and the date of any change. Licensee must include in that file the 50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51316303Sjkim * must include a prominent statement that the modification is derived, 52316303Sjkim * directly or indirectly, from Original Intel Code. 53316303Sjkim * 54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55316303Sjkim * Redistribution of source code of any substantial portion of the Covered 56316303Sjkim * Code or modification without rights to further distribute source must 57316303Sjkim * include the following Disclaimer and Export Compliance provision in the 58316303Sjkim * documentation and/or other materials provided with distribution. In 59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 61316303Sjkim * license from Licensee to its licensee is limited to the intellectual 62316303Sjkim * property embodied in the software Licensee provides to its licensee, and 63316303Sjkim * not to intellectual property embodied in modifications its licensee may 64316303Sjkim * make. 65316303Sjkim * 66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69316303Sjkim * provision in the documentation and/or other materials provided with the 70316303Sjkim * distribution. 71316303Sjkim * 72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73316303Sjkim * Intel Code. 74316303Sjkim * 75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77316303Sjkim * other dealings in products derived from or relating to the Covered Code 78316303Sjkim * without prior written authorization from Intel. 79316303Sjkim * 80316303Sjkim * 4. Disclaimer and Export Compliance 81316303Sjkim * 82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88316303Sjkim * PARTICULAR PURPOSE. 89316303Sjkim * 90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97316303Sjkim * LIMITED REMEDY. 98316303Sjkim * 99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100316303Sjkim * software or system incorporating such software without first obtaining any 101316303Sjkim * required license or other approval from the U. S. Department of Commerce or 102316303Sjkim * any other agency or department of the United States Government. In the 103316303Sjkim * event Licensee exports any such software from the United States or 104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 105316303Sjkim * ensure that the distribution and export/re-export of the software is in 106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109316303Sjkim * software, or service, directly or indirectly, to any country for which the 110316303Sjkim * United States government or any agency thereof requires an export license, 111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 112316303Sjkim * such license, approval or letter. 113316303Sjkim * 114316303Sjkim ***************************************************************************** 115316303Sjkim * 116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 117316303Sjkim * following license: 118316303Sjkim * 119217365Sjkim * Redistribution and use in source and binary forms, with or without 120217365Sjkim * modification, are permitted provided that the following conditions 121217365Sjkim * are met: 122217365Sjkim * 1. Redistributions of source code must retain the above copyright 123217365Sjkim * notice, this list of conditions, and the following disclaimer, 124217365Sjkim * without modification. 125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128217365Sjkim * including a substantially similar Disclaimer requirement for further 129217365Sjkim * binary redistribution. 130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131217365Sjkim * of any contributors may be used to endorse or promote products derived 132217365Sjkim * from this software without specific prior written permission. 13367754Smsmith * 134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145316303Sjkim * 146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148217365Sjkim * Software Foundation. 14967754Smsmith * 150316303Sjkim *****************************************************************************/ 15167754Smsmith 152193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 153193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 154193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 155193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 156193341Sjkim#include <contrib/dev/acpica/include/acevents.h> 15767754Smsmith 158193267Sjkim 15977424Smsmith#define _COMPONENT ACPI_UTILITIES 16091116Smsmith ACPI_MODULE_NAME ("utdelete") 16167754Smsmith 162151937Sjkim/* Local prototypes */ 16367754Smsmith 164151937Sjkimstatic void 165151937SjkimAcpiUtDeleteInternalObj ( 166151937Sjkim ACPI_OPERAND_OBJECT *Object); 167151937Sjkim 168151937Sjkimstatic void 169151937SjkimAcpiUtUpdateRefCount ( 170151937Sjkim ACPI_OPERAND_OBJECT *Object, 171151937Sjkim UINT32 Action); 172151937Sjkim 173151937Sjkim 17467754Smsmith/******************************************************************************* 17567754Smsmith * 17677424Smsmith * FUNCTION: AcpiUtDeleteInternalObj 17767754Smsmith * 178151937Sjkim * PARAMETERS: Object - Object to be deleted 17967754Smsmith * 18067754Smsmith * RETURN: None 18167754Smsmith * 18267754Smsmith * DESCRIPTION: Low level object deletion, after reference counts have been 18367754Smsmith * updated (All reference counts, including sub-objects!) 18467754Smsmith * 18567754Smsmith ******************************************************************************/ 18667754Smsmith 187151937Sjkimstatic void 18877424SmsmithAcpiUtDeleteInternalObj ( 18967754Smsmith ACPI_OPERAND_OBJECT *Object) 19067754Smsmith{ 19167754Smsmith void *ObjPointer = NULL; 19267754Smsmith ACPI_OPERAND_OBJECT *HandlerDesc; 19387031Smsmith ACPI_OPERAND_OBJECT *SecondDesc; 194117521Snjl ACPI_OPERAND_OBJECT *NextDesc; 195272444Sjkim ACPI_OPERAND_OBJECT *StartDesc; 196193267Sjkim ACPI_OPERAND_OBJECT **LastObjPtr; 19767754Smsmith 19867754Smsmith 199167802Sjkim ACPI_FUNCTION_TRACE_PTR (UtDeleteInternalObj, Object); 20067754Smsmith 20167754Smsmith 20267754Smsmith if (!Object) 20367754Smsmith { 20467754Smsmith return_VOID; 20567754Smsmith } 20667754Smsmith 20767754Smsmith /* 20867754Smsmith * Must delete or free any pointers within the object that are not 20967754Smsmith * actual ACPI objects (for example, a raw buffer pointer). 21067754Smsmith */ 211193267Sjkim switch (Object->Common.Type) 21267754Smsmith { 21367754Smsmith case ACPI_TYPE_STRING: 21467754Smsmith 21599146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n", 21667754Smsmith Object, Object->String.Pointer)); 21767754Smsmith 21867754Smsmith /* Free the actual string buffer */ 21967754Smsmith 22082367Smsmith if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER)) 22182367Smsmith { 222114237Snjl /* But only if it is NOT a pointer into an ACPI table */ 223114237Snjl 22482367Smsmith ObjPointer = Object->String.Pointer; 22582367Smsmith } 22667754Smsmith break; 22767754Smsmith 22867754Smsmith case ACPI_TYPE_BUFFER: 22967754Smsmith 23099146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n", 23167754Smsmith Object, Object->Buffer.Pointer)); 23267754Smsmith 23367754Smsmith /* Free the actual buffer */ 23467754Smsmith 235114237Snjl if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER)) 236114237Snjl { 237114237Snjl /* But only if it is NOT a pointer into an ACPI table */ 238114237Snjl 239114237Snjl ObjPointer = Object->Buffer.Pointer; 240114237Snjl } 24167754Smsmith break; 24267754Smsmith 24367754Smsmith case ACPI_TYPE_PACKAGE: 24467754Smsmith 24599146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n", 24667754Smsmith Object->Package.Count)); 24767754Smsmith 24867754Smsmith /* 24967754Smsmith * Elements of the package are not handled here, they are deleted 25067754Smsmith * separately 25167754Smsmith */ 25267754Smsmith 25367754Smsmith /* Free the (variable length) element pointer array */ 25467754Smsmith 25567754Smsmith ObjPointer = Object->Package.Elements; 25667754Smsmith break; 25767754Smsmith 258193267Sjkim /* 259193267Sjkim * These objects have a possible list of notify handlers. 260193267Sjkim * Device object also may have a GPE block. 261193267Sjkim */ 262117521Snjl case ACPI_TYPE_DEVICE: 263117521Snjl 264117521Snjl if (Object->Device.GpeBlock) 265117521Snjl { 266117521Snjl (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock); 267117521Snjl } 268117521Snjl 269193267Sjkim /*lint -fallthrough */ 270117521Snjl 271193267Sjkim case ACPI_TYPE_PROCESSOR: 272193267Sjkim case ACPI_TYPE_THERMAL: 273193267Sjkim 274234623Sjkim /* Walk the address handler list for this object */ 275193267Sjkim 276193267Sjkim HandlerDesc = Object->CommonNotify.Handler; 277117521Snjl while (HandlerDesc) 278117521Snjl { 279117521Snjl NextDesc = HandlerDesc->AddressSpace.Next; 280117521Snjl AcpiUtRemoveReference (HandlerDesc); 281117521Snjl HandlerDesc = NextDesc; 282117521Snjl } 283117521Snjl break; 284117521Snjl 28567754Smsmith case ACPI_TYPE_MUTEX: 28667754Smsmith 287151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 288167802Sjkim "***** Mutex %p, OS Mutex %p\n", 289167802Sjkim Object, Object->Mutex.OsMutex)); 29067754Smsmith 291167802Sjkim if (Object == AcpiGbl_GlobalLockMutex) 292167802Sjkim { 293167802Sjkim /* Global Lock has extra semaphore */ 294167802Sjkim 295167802Sjkim (void) AcpiOsDeleteSemaphore (AcpiGbl_GlobalLockSemaphore); 296167802Sjkim AcpiGbl_GlobalLockSemaphore = NULL; 297167802Sjkim 298167802Sjkim AcpiOsDeleteMutex (Object->Mutex.OsMutex); 299167802Sjkim AcpiGbl_GlobalLockMutex = NULL; 300167802Sjkim } 301167802Sjkim else 302167802Sjkim { 303167802Sjkim AcpiExUnlinkMutex (Object); 304167802Sjkim AcpiOsDeleteMutex (Object->Mutex.OsMutex); 305167802Sjkim } 30667754Smsmith break; 30767754Smsmith 30867754Smsmith case ACPI_TYPE_EVENT: 30967754Smsmith 310151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 311167802Sjkim "***** Event %p, OS Semaphore %p\n", 312167802Sjkim Object, Object->Event.OsSemaphore)); 31367754Smsmith 314167802Sjkim (void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore); 315167802Sjkim Object->Event.OsSemaphore = NULL; 31667754Smsmith break; 31767754Smsmith 31867754Smsmith case ACPI_TYPE_METHOD: 31967754Smsmith 320151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 321151937Sjkim "***** Method %p\n", Object)); 32267754Smsmith 323167802Sjkim /* Delete the method mutex if it exists */ 32467754Smsmith 325167802Sjkim if (Object->Method.Mutex) 32667754Smsmith { 327167802Sjkim AcpiOsDeleteMutex (Object->Method.Mutex->Mutex.OsMutex); 328167802Sjkim AcpiUtDeleteObjectDesc (Object->Method.Mutex); 329167802Sjkim Object->Method.Mutex = NULL; 33067754Smsmith } 331298714Sjkim 332285797Sjkim if (Object->Method.Node) 333285797Sjkim { 334285797Sjkim Object->Method.Node = NULL; 335285797Sjkim } 33667754Smsmith break; 33767754Smsmith 33867754Smsmith case ACPI_TYPE_REGION: 33967754Smsmith 340151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 341151937Sjkim "***** Region %p\n", Object)); 34267754Smsmith 343229989Sjkim /* 344229989Sjkim * Update AddressRange list. However, only permanent regions 345229989Sjkim * are installed in this list. (Not created within a method) 346229989Sjkim */ 347229989Sjkim if (!(Object->Region.Node->Flags & ANOBJ_TEMPORARY)) 348229989Sjkim { 349229989Sjkim AcpiUtRemoveAddressRange (Object->Region.SpaceId, 350229989Sjkim Object->Region.Node); 351229989Sjkim } 352229989Sjkim 35387031Smsmith SecondDesc = AcpiNsGetSecondaryObject (Object); 35487031Smsmith if (SecondDesc) 35567754Smsmith { 35669450Smsmith /* 35767754Smsmith * Free the RegionContext if and only if the handler is one of the 35867754Smsmith * default handlers -- and therefore, we created the context object 35967754Smsmith * locally, it was not created by an external caller. 36067754Smsmith */ 361123315Snjl HandlerDesc = Object->Region.Handler; 362117521Snjl if (HandlerDesc) 36367754Smsmith { 364193267Sjkim NextDesc = HandlerDesc->AddressSpace.RegionList; 365272444Sjkim StartDesc = NextDesc; 366193267Sjkim LastObjPtr = &HandlerDesc->AddressSpace.RegionList; 367193267Sjkim 368272444Sjkim /* Remove the region object from the handler list */ 369193267Sjkim 370193267Sjkim while (NextDesc) 371193267Sjkim { 372193267Sjkim if (NextDesc == Object) 373193267Sjkim { 374193267Sjkim *LastObjPtr = NextDesc->Region.Next; 375193267Sjkim break; 376193267Sjkim } 377193267Sjkim 378272444Sjkim /* Walk the linked list of handlers */ 379193267Sjkim 380193267Sjkim LastObjPtr = &NextDesc->Region.Next; 381193267Sjkim NextDesc = NextDesc->Region.Next; 382272444Sjkim 383272444Sjkim /* Prevent infinite loop if list is corrupted */ 384272444Sjkim 385272444Sjkim if (NextDesc == StartDesc) 386272444Sjkim { 387272444Sjkim ACPI_ERROR ((AE_INFO, 388272444Sjkim "Circular region list in address handler object %p", 389272444Sjkim HandlerDesc)); 390272444Sjkim return_VOID; 391272444Sjkim } 392193267Sjkim } 393193267Sjkim 394167802Sjkim if (HandlerDesc->AddressSpace.HandlerFlags & 395167802Sjkim ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) 396117521Snjl { 397167802Sjkim /* Deactivate region and free region context */ 398167802Sjkim 399167802Sjkim if (HandlerDesc->AddressSpace.Setup) 400167802Sjkim { 401167802Sjkim (void) HandlerDesc->AddressSpace.Setup (Object, 402167802Sjkim ACPI_REGION_DEACTIVATE, 403167802Sjkim HandlerDesc->AddressSpace.Context, 404167802Sjkim &SecondDesc->Extra.RegionContext); 405167802Sjkim } 406117521Snjl } 407117521Snjl 408117521Snjl AcpiUtRemoveReference (HandlerDesc); 40967754Smsmith } 41067754Smsmith 41167754Smsmith /* Now we can free the Extra object */ 41267754Smsmith 41387031Smsmith AcpiUtDeleteObjectDesc (SecondDesc); 41467754Smsmith } 41567754Smsmith break; 41667754Smsmith 41777424Smsmith case ACPI_TYPE_BUFFER_FIELD: 41867754Smsmith 419151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 420151937Sjkim "***** Buffer Field %p\n", Object)); 42167754Smsmith 42287031Smsmith SecondDesc = AcpiNsGetSecondaryObject (Object); 42387031Smsmith if (SecondDesc) 42467754Smsmith { 42587031Smsmith AcpiUtDeleteObjectDesc (SecondDesc); 42667754Smsmith } 42767754Smsmith break; 42867754Smsmith 429193267Sjkim case ACPI_TYPE_LOCAL_BANK_FIELD: 430193267Sjkim 431193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 432193267Sjkim "***** Bank Field %p\n", Object)); 433193267Sjkim 434193267Sjkim SecondDesc = AcpiNsGetSecondaryObject (Object); 435193267Sjkim if (SecondDesc) 436193267Sjkim { 437193267Sjkim AcpiUtDeleteObjectDesc (SecondDesc); 438193267Sjkim } 439193267Sjkim break; 440193267Sjkim 441250838Sjkim default: 442193267Sjkim 44367754Smsmith break; 44467754Smsmith } 44567754Smsmith 44691116Smsmith /* Free any allocated memory (pointer within the object) found above */ 44791116Smsmith 44867754Smsmith if (ObjPointer) 44967754Smsmith { 45099146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n", 451167802Sjkim ObjPointer)); 452167802Sjkim ACPI_FREE (ObjPointer); 45367754Smsmith } 45467754Smsmith 45591116Smsmith /* Now the object can be safely deleted */ 45667754Smsmith 45799146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n", 458167802Sjkim Object, AcpiUtGetObjectTypeName (Object))); 45967754Smsmith 46091116Smsmith AcpiUtDeleteObjectDesc (Object); 46167754Smsmith return_VOID; 46267754Smsmith} 46367754Smsmith 46467754Smsmith 46567754Smsmith/******************************************************************************* 46667754Smsmith * 46777424Smsmith * FUNCTION: AcpiUtDeleteInternalObjectList 46867754Smsmith * 469151937Sjkim * PARAMETERS: ObjList - Pointer to the list to be deleted 47067754Smsmith * 47199679Siwasaki * RETURN: None 47267754Smsmith * 47367754Smsmith * DESCRIPTION: This function deletes an internal object list, including both 47467754Smsmith * simple objects and package objects 47567754Smsmith * 47667754Smsmith ******************************************************************************/ 47767754Smsmith 47899679Siwasakivoid 47977424SmsmithAcpiUtDeleteInternalObjectList ( 48067754Smsmith ACPI_OPERAND_OBJECT **ObjList) 48167754Smsmith{ 48267754Smsmith ACPI_OPERAND_OBJECT **InternalObj; 48367754Smsmith 48467754Smsmith 485245582Sjkim ACPI_FUNCTION_ENTRY (); 48667754Smsmith 48767754Smsmith 48867754Smsmith /* Walk the null-terminated internal list */ 48967754Smsmith 49067754Smsmith for (InternalObj = ObjList; *InternalObj; InternalObj++) 49167754Smsmith { 49284491Smsmith AcpiUtRemoveReference (*InternalObj); 49367754Smsmith } 49467754Smsmith 49567754Smsmith /* Free the combined parameter pointer list and object array */ 49667754Smsmith 497167802Sjkim ACPI_FREE (ObjList); 498243347Sjkim return; 49967754Smsmith} 50067754Smsmith 50167754Smsmith 50267754Smsmith/******************************************************************************* 50367754Smsmith * 50477424Smsmith * FUNCTION: AcpiUtUpdateRefCount 50567754Smsmith * 506151937Sjkim * PARAMETERS: Object - Object whose ref count is to be updated 507249112Sjkim * Action - What to do (REF_INCREMENT or REF_DECREMENT) 50867754Smsmith * 509249112Sjkim * RETURN: None. Sets new reference count within the object 51067754Smsmith * 511249112Sjkim * DESCRIPTION: Modify the reference count for an internal acpi object 51267754Smsmith * 51367754Smsmith ******************************************************************************/ 51467754Smsmith 51569450Smsmithstatic void 51677424SmsmithAcpiUtUpdateRefCount ( 51767754Smsmith ACPI_OPERAND_OBJECT *Object, 51867754Smsmith UINT32 Action) 51967754Smsmith{ 520249112Sjkim UINT16 OriginalCount; 521249112Sjkim UINT16 NewCount = 0; 522249112Sjkim ACPI_CPU_FLAGS LockFlags; 52367754Smsmith 52467754Smsmith 525167802Sjkim ACPI_FUNCTION_NAME (UtUpdateRefCount); 52677424Smsmith 52799146Siwasaki 52867754Smsmith if (!Object) 52967754Smsmith { 53067754Smsmith return; 53167754Smsmith } 53267754Smsmith 53367754Smsmith /* 534249112Sjkim * Always get the reference count lock. Note: Interpreter and/or 535249112Sjkim * Namespace is not always locked when this function is called. 53667754Smsmith */ 537249112Sjkim LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock); 538249112Sjkim OriginalCount = Object->Common.ReferenceCount; 539249112Sjkim 540249112Sjkim /* Perform the reference count action (increment, decrement) */ 541249112Sjkim 54267754Smsmith switch (Action) 54367754Smsmith { 54467754Smsmith case REF_INCREMENT: 54567754Smsmith 546249112Sjkim NewCount = OriginalCount + 1; 54767754Smsmith Object->Common.ReferenceCount = NewCount; 548249112Sjkim AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); 54967754Smsmith 550249112Sjkim /* The current reference count should never be zero here */ 551249112Sjkim 552249112Sjkim if (!OriginalCount) 553249112Sjkim { 554249112Sjkim ACPI_WARNING ((AE_INFO, 555249112Sjkim "Obj %p, Reference Count was zero before increment\n", 556249112Sjkim Object)); 557249112Sjkim } 558249112Sjkim 559151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 560316303Sjkim "Obj %p Type %.2X [%s] Refs %.2X [Incremented]\n", 561316303Sjkim Object, Object->Common.Type, 562316303Sjkim AcpiUtGetObjectTypeName (Object), NewCount)); 56367754Smsmith break; 56467754Smsmith 56567754Smsmith case REF_DECREMENT: 56667754Smsmith 567249112Sjkim /* The current reference count must be non-zero */ 56867754Smsmith 569249112Sjkim if (OriginalCount) 57067754Smsmith { 571249112Sjkim NewCount = OriginalCount - 1; 572249112Sjkim Object->Common.ReferenceCount = NewCount; 57367754Smsmith } 57467754Smsmith 575249112Sjkim AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); 576249112Sjkim 577249112Sjkim if (!OriginalCount) 57867754Smsmith { 579249112Sjkim ACPI_WARNING ((AE_INFO, 580249112Sjkim "Obj %p, Reference Count is already zero, cannot decrement\n", 581249112Sjkim Object)); 58267754Smsmith } 58367754Smsmith 584249112Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 585249112Sjkim "Obj %p Type %.2X Refs %.2X [Decremented]\n", 586249112Sjkim Object, Object->Common.Type, NewCount)); 587249112Sjkim 588249112Sjkim /* Actually delete the object on a reference count of zero */ 589249112Sjkim 59067754Smsmith if (NewCount == 0) 59167754Smsmith { 59277424Smsmith AcpiUtDeleteInternalObj (Object); 59367754Smsmith } 59467754Smsmith break; 59567754Smsmith 59667754Smsmith default: 59767754Smsmith 598249112Sjkim AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); 599249112Sjkim ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)", 600249112Sjkim Action)); 601249112Sjkim return; 60267754Smsmith } 60367754Smsmith 60467754Smsmith /* 60567754Smsmith * Sanity check the reference count, for debug purposes only. 60667754Smsmith * (A deleted object will have a huge reference count) 60767754Smsmith */ 608249112Sjkim if (NewCount > ACPI_MAX_REFERENCE_COUNT) 60967754Smsmith { 610167802Sjkim ACPI_WARNING ((AE_INFO, 611249112Sjkim "Large Reference Count (0x%X) in object %p, Type=0x%.2X", 612249112Sjkim NewCount, Object, Object->Common.Type)); 61367754Smsmith } 61467754Smsmith} 61567754Smsmith 61667754Smsmith 61767754Smsmith/******************************************************************************* 61867754Smsmith * 61977424Smsmith * FUNCTION: AcpiUtUpdateObjectReference 62067754Smsmith * 621151937Sjkim * PARAMETERS: Object - Increment ref count for this object 62267754Smsmith * and all sub-objects 623249112Sjkim * Action - Either REF_INCREMENT or REF_DECREMENT 62467754Smsmith * 62567754Smsmith * RETURN: Status 62667754Smsmith * 62767754Smsmith * DESCRIPTION: Increment the object reference count 62867754Smsmith * 62967754Smsmith * Object references are incremented when: 63067754Smsmith * 1) An object is attached to a Node (namespace object) 63167754Smsmith * 2) An object is copied (all subobjects must be incremented) 63267754Smsmith * 63367754Smsmith * Object references are decremented when: 63467754Smsmith * 1) An object is detached from an Node 63567754Smsmith * 63667754Smsmith ******************************************************************************/ 63767754Smsmith 63867754SmsmithACPI_STATUS 63977424SmsmithAcpiUtUpdateObjectReference ( 64067754Smsmith ACPI_OPERAND_OBJECT *Object, 64167754Smsmith UINT16 Action) 64267754Smsmith{ 643151937Sjkim ACPI_STATUS Status = AE_OK; 644151937Sjkim ACPI_GENERIC_STATE *StateList = NULL; 645151937Sjkim ACPI_OPERAND_OBJECT *NextObject = NULL; 646234623Sjkim ACPI_OPERAND_OBJECT *PrevObject; 647151937Sjkim ACPI_GENERIC_STATE *State; 648193267Sjkim UINT32 i; 64967754Smsmith 65067754Smsmith 651243347Sjkim ACPI_FUNCTION_NAME (UtUpdateObjectReference); 65267754Smsmith 65367754Smsmith 654151937Sjkim while (Object) 65567754Smsmith { 656151937Sjkim /* Make sure that this isn't a namespace handle */ 65767754Smsmith 658151937Sjkim if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED) 659151937Sjkim { 660151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 661151937Sjkim "Object %p is NS handle\n", Object)); 662243347Sjkim return (AE_OK); 663151937Sjkim } 664117521Snjl 66567754Smsmith /* 666298714Sjkim * All sub-objects must have their reference count incremented 667298714Sjkim * also. Different object types have different subobjects. 66867754Smsmith */ 669193267Sjkim switch (Object->Common.Type) 67067754Smsmith { 67167754Smsmith case ACPI_TYPE_DEVICE: 672167802Sjkim case ACPI_TYPE_PROCESSOR: 673167802Sjkim case ACPI_TYPE_POWER: 674167802Sjkim case ACPI_TYPE_THERMAL: 675234623Sjkim /* 676234623Sjkim * Update the notify objects for these types (if present) 677234623Sjkim * Two lists, system and device notify handlers. 678234623Sjkim */ 679234623Sjkim for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 680234623Sjkim { 681234623Sjkim PrevObject = Object->CommonNotify.NotifyList[i]; 682234623Sjkim while (PrevObject) 683234623Sjkim { 684234623Sjkim NextObject = PrevObject->Notify.Next[i]; 685234623Sjkim AcpiUtUpdateRefCount (PrevObject, Action); 686234623Sjkim PrevObject = NextObject; 687234623Sjkim } 688234623Sjkim } 68967754Smsmith break; 69067754Smsmith 69167754Smsmith case ACPI_TYPE_PACKAGE: 69267754Smsmith /* 693151937Sjkim * We must update all the sub-objects of the package, 694151937Sjkim * each of whom may have their own sub-objects. 69567754Smsmith */ 69667754Smsmith for (i = 0; i < Object->Package.Count; i++) 69767754Smsmith { 69867754Smsmith /* 699243347Sjkim * Null package elements are legal and can be simply 700243347Sjkim * ignored. 70167754Smsmith */ 702243347Sjkim NextObject = Object->Package.Elements[i]; 703243347Sjkim if (!NextObject) 70467754Smsmith { 705243347Sjkim continue; 70667754Smsmith } 707243347Sjkim 708243347Sjkim switch (NextObject->Common.Type) 709243347Sjkim { 710243347Sjkim case ACPI_TYPE_INTEGER: 711243347Sjkim case ACPI_TYPE_STRING: 712243347Sjkim case ACPI_TYPE_BUFFER: 713243347Sjkim /* 714243347Sjkim * For these very simple sub-objects, we can just 715243347Sjkim * update the reference count here and continue. 716243347Sjkim * Greatly increases performance of this operation. 717243347Sjkim */ 718243347Sjkim AcpiUtUpdateRefCount (NextObject, Action); 719243347Sjkim break; 720243347Sjkim 721243347Sjkim default: 722243347Sjkim /* 723243347Sjkim * For complex sub-objects, push them onto the stack 724243347Sjkim * for later processing (this eliminates recursion.) 725243347Sjkim */ 726243347Sjkim Status = AcpiUtCreateUpdateStateAndPush ( 727298714Sjkim NextObject, Action, &StateList); 728243347Sjkim if (ACPI_FAILURE (Status)) 729243347Sjkim { 730243347Sjkim goto ErrorExit; 731243347Sjkim } 732243347Sjkim break; 733243347Sjkim } 73467754Smsmith } 735243347Sjkim NextObject = NULL; 73667754Smsmith break; 73767754Smsmith 73877424Smsmith case ACPI_TYPE_BUFFER_FIELD: 73967754Smsmith 740151937Sjkim NextObject = Object->BufferField.BufferObj; 74167754Smsmith break; 74267754Smsmith 743107325Siwasaki case ACPI_TYPE_LOCAL_REGION_FIELD: 74467754Smsmith 745151937Sjkim NextObject = Object->Field.RegionObj; 746151937Sjkim break; 74767754Smsmith 748107325Siwasaki case ACPI_TYPE_LOCAL_BANK_FIELD: 74967754Smsmith 750151937Sjkim NextObject = Object->BankField.BankObj; 75177424Smsmith Status = AcpiUtCreateUpdateStateAndPush ( 752298714Sjkim Object->BankField.RegionObj, Action, &StateList); 75367754Smsmith if (ACPI_FAILURE (Status)) 75467754Smsmith { 75599679Siwasaki goto ErrorExit; 75667754Smsmith } 75767754Smsmith break; 75867754Smsmith 759107325Siwasaki case ACPI_TYPE_LOCAL_INDEX_FIELD: 76077424Smsmith 761151937Sjkim NextObject = Object->IndexField.IndexObj; 76277424Smsmith Status = AcpiUtCreateUpdateStateAndPush ( 763298714Sjkim Object->IndexField.DataObj, Action, &StateList); 76477424Smsmith if (ACPI_FAILURE (Status)) 76577424Smsmith { 76699679Siwasaki goto ErrorExit; 76777424Smsmith } 768151937Sjkim break; 76977424Smsmith 770151937Sjkim case ACPI_TYPE_LOCAL_REFERENCE: 771151937Sjkim /* 772193267Sjkim * The target of an Index (a package, string, or buffer) or a named 773193267Sjkim * reference must track changes to the ref count of the index or 774193267Sjkim * target object. 775151937Sjkim */ 776193267Sjkim if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) || 777193267Sjkim (Object->Reference.Class== ACPI_REFCLASS_NAME)) 77877424Smsmith { 779151937Sjkim NextObject = Object->Reference.Object; 78077424Smsmith } 78177424Smsmith break; 78277424Smsmith 78367754Smsmith case ACPI_TYPE_REGION: 78499679Siwasaki default: 785250838Sjkim 786167802Sjkim break; /* No subobjects for all other types */ 78767754Smsmith } 78867754Smsmith 78967754Smsmith /* 790167802Sjkim * Now we can update the count in the main object. This can only 79167754Smsmith * happen after we update the sub-objects in case this causes the 79267754Smsmith * main object to be deleted. 79367754Smsmith */ 79477424Smsmith AcpiUtUpdateRefCount (Object, Action); 795151937Sjkim Object = NULL; 79667754Smsmith 79767754Smsmith /* Move on to the next object to be updated */ 79867754Smsmith 799151937Sjkim if (NextObject) 800151937Sjkim { 801151937Sjkim Object = NextObject; 802151937Sjkim NextObject = NULL; 803151937Sjkim } 804151937Sjkim else if (StateList) 805151937Sjkim { 806151937Sjkim State = AcpiUtPopGenericState (&StateList); 807151937Sjkim Object = State->Update.Object; 808151937Sjkim AcpiUtDeleteGenericState (State); 809151937Sjkim } 81067754Smsmith } 81167754Smsmith 812243347Sjkim return (AE_OK); 81399679Siwasaki 814193267Sjkim 81599679SiwasakiErrorExit: 81699679Siwasaki 817167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 818167802Sjkim "Could not update object reference count")); 81999679Siwasaki 820193267Sjkim /* Free any stacked Update State objects */ 821193267Sjkim 822193267Sjkim while (StateList) 823193267Sjkim { 824193267Sjkim State = AcpiUtPopGenericState (&StateList); 825193267Sjkim AcpiUtDeleteGenericState (State); 826193267Sjkim } 827193267Sjkim 828243347Sjkim return (Status); 82967754Smsmith} 83067754Smsmith 83167754Smsmith 83267754Smsmith/******************************************************************************* 83367754Smsmith * 83477424Smsmith * FUNCTION: AcpiUtAddReference 83567754Smsmith * 836151937Sjkim * PARAMETERS: Object - Object whose reference count is to be 837151937Sjkim * incremented 83867754Smsmith * 83967754Smsmith * RETURN: None 84067754Smsmith * 84167754Smsmith * DESCRIPTION: Add one reference to an ACPI object 84267754Smsmith * 84367754Smsmith ******************************************************************************/ 84467754Smsmith 84567754Smsmithvoid 84677424SmsmithAcpiUtAddReference ( 84767754Smsmith ACPI_OPERAND_OBJECT *Object) 84867754Smsmith{ 84967754Smsmith 850243347Sjkim ACPI_FUNCTION_NAME (UtAddReference); 85167754Smsmith 85267754Smsmith 853117521Snjl /* Ensure that we have a valid object */ 854117521Snjl 85577424Smsmith if (!AcpiUtValidInternalObject (Object)) 85667754Smsmith { 857243347Sjkim return; 85867754Smsmith } 85967754Smsmith 860138287Smarks ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 861138287Smarks "Obj %p Current Refs=%X [To Be Incremented]\n", 862138287Smarks Object, Object->Common.ReferenceCount)); 863138287Smarks 864117521Snjl /* Increment the reference count */ 865117521Snjl 866167802Sjkim (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT); 867243347Sjkim return; 86867754Smsmith} 86967754Smsmith 87067754Smsmith 87167754Smsmith/******************************************************************************* 87267754Smsmith * 87377424Smsmith * FUNCTION: AcpiUtRemoveReference 87467754Smsmith * 875151937Sjkim * PARAMETERS: Object - Object whose ref count will be decremented 87667754Smsmith * 87767754Smsmith * RETURN: None 87867754Smsmith * 87967754Smsmith * DESCRIPTION: Decrement the reference count of an ACPI internal object 88067754Smsmith * 88167754Smsmith ******************************************************************************/ 88267754Smsmith 88367754Smsmithvoid 88477424SmsmithAcpiUtRemoveReference ( 88567754Smsmith ACPI_OPERAND_OBJECT *Object) 88667754Smsmith{ 88767754Smsmith 888243347Sjkim ACPI_FUNCTION_NAME (UtRemoveReference); 88967754Smsmith 890117521Snjl 89185756Smsmith /* 892167802Sjkim * Allow a NULL pointer to be passed in, just ignore it. This saves 893167802Sjkim * each caller from having to check. Also, ignore NS nodes. 89485756Smsmith */ 89585756Smsmith if (!Object || 89691116Smsmith (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)) 89767754Smsmith 89885756Smsmith { 899243347Sjkim return; 90085756Smsmith } 90185756Smsmith 902117521Snjl /* Ensure that we have a valid object */ 903117521Snjl 90477424Smsmith if (!AcpiUtValidInternalObject (Object)) 90567754Smsmith { 906243347Sjkim return; 90767754Smsmith } 90867754Smsmith 909138287Smarks ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, 910138287Smarks "Obj %p Current Refs=%X [To Be Decremented]\n", 911138287Smarks Object, Object->Common.ReferenceCount)); 91267754Smsmith 91367754Smsmith /* 91467754Smsmith * Decrement the reference count, and only actually delete the object 915167802Sjkim * if the reference count becomes 0. (Must also decrement the ref count 91667754Smsmith * of all subobjects!) 91767754Smsmith */ 918167802Sjkim (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT); 919243347Sjkim return; 92067754Smsmith} 921