1*c2c66affSColin Finck /*******************************************************************************
2*c2c66affSColin Finck  *
3*c2c66affSColin Finck  * Module Name: utdelete - object deletion and reference count utilities
4*c2c66affSColin Finck  *
5*c2c66affSColin Finck  ******************************************************************************/
6*c2c66affSColin Finck 
7*c2c66affSColin Finck /*
8*c2c66affSColin Finck  * Copyright (C) 2000 - 2017, Intel Corp.
9*c2c66affSColin Finck  * All rights reserved.
10*c2c66affSColin Finck  *
11*c2c66affSColin Finck  * Redistribution and use in source and binary forms, with or without
12*c2c66affSColin Finck  * modification, are permitted provided that the following conditions
13*c2c66affSColin Finck  * are met:
14*c2c66affSColin Finck  * 1. Redistributions of source code must retain the above copyright
15*c2c66affSColin Finck  *    notice, this list of conditions, and the following disclaimer,
16*c2c66affSColin Finck  *    without modification.
17*c2c66affSColin Finck  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*c2c66affSColin Finck  *    substantially similar to the "NO WARRANTY" disclaimer below
19*c2c66affSColin Finck  *    ("Disclaimer") and any redistribution must be conditioned upon
20*c2c66affSColin Finck  *    including a substantially similar Disclaimer requirement for further
21*c2c66affSColin Finck  *    binary redistribution.
22*c2c66affSColin Finck  * 3. Neither the names of the above-listed copyright holders nor the names
23*c2c66affSColin Finck  *    of any contributors may be used to endorse or promote products derived
24*c2c66affSColin Finck  *    from this software without specific prior written permission.
25*c2c66affSColin Finck  *
26*c2c66affSColin Finck  * Alternatively, this software may be distributed under the terms of the
27*c2c66affSColin Finck  * GNU General Public License ("GPL") version 2 as published by the Free
28*c2c66affSColin Finck  * Software Foundation.
29*c2c66affSColin Finck  *
30*c2c66affSColin Finck  * NO WARRANTY
31*c2c66affSColin Finck  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*c2c66affSColin Finck  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*c2c66affSColin Finck  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*c2c66affSColin Finck  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*c2c66affSColin Finck  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*c2c66affSColin Finck  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*c2c66affSColin Finck  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*c2c66affSColin Finck  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*c2c66affSColin Finck  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*c2c66affSColin Finck  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*c2c66affSColin Finck  * POSSIBILITY OF SUCH DAMAGES.
42*c2c66affSColin Finck  */
43*c2c66affSColin Finck 
44*c2c66affSColin Finck #include "acpi.h"
45*c2c66affSColin Finck #include "accommon.h"
46*c2c66affSColin Finck #include "acinterp.h"
47*c2c66affSColin Finck #include "acnamesp.h"
48*c2c66affSColin Finck #include "acevents.h"
49*c2c66affSColin Finck 
50*c2c66affSColin Finck 
51*c2c66affSColin Finck #define _COMPONENT          ACPI_UTILITIES
52*c2c66affSColin Finck         ACPI_MODULE_NAME    ("utdelete")
53*c2c66affSColin Finck 
54*c2c66affSColin Finck /* Local prototypes */
55*c2c66affSColin Finck 
56*c2c66affSColin Finck static void
57*c2c66affSColin Finck AcpiUtDeleteInternalObj (
58*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *Object);
59*c2c66affSColin Finck 
60*c2c66affSColin Finck static void
61*c2c66affSColin Finck AcpiUtUpdateRefCount (
62*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *Object,
63*c2c66affSColin Finck     UINT32                  Action);
64*c2c66affSColin Finck 
65*c2c66affSColin Finck 
66*c2c66affSColin Finck /*******************************************************************************
67*c2c66affSColin Finck  *
68*c2c66affSColin Finck  * FUNCTION:    AcpiUtDeleteInternalObj
69*c2c66affSColin Finck  *
70*c2c66affSColin Finck  * PARAMETERS:  Object         - Object to be deleted
71*c2c66affSColin Finck  *
72*c2c66affSColin Finck  * RETURN:      None
73*c2c66affSColin Finck  *
74*c2c66affSColin Finck  * DESCRIPTION: Low level object deletion, after reference counts have been
75*c2c66affSColin Finck  *              updated (All reference counts, including sub-objects!)
76*c2c66affSColin Finck  *
77*c2c66affSColin Finck  ******************************************************************************/
78*c2c66affSColin Finck 
79*c2c66affSColin Finck static void
80*c2c66affSColin Finck AcpiUtDeleteInternalObj (
81*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *Object)
82*c2c66affSColin Finck {
83*c2c66affSColin Finck     void                    *ObjPointer = NULL;
84*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *HandlerDesc;
85*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *SecondDesc;
86*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *NextDesc;
87*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *StartDesc;
88*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     **LastObjPtr;
89*c2c66affSColin Finck 
90*c2c66affSColin Finck 
91*c2c66affSColin Finck     ACPI_FUNCTION_TRACE_PTR (UtDeleteInternalObj, Object);
92*c2c66affSColin Finck 
93*c2c66affSColin Finck 
94*c2c66affSColin Finck     if (!Object)
95*c2c66affSColin Finck     {
96*c2c66affSColin Finck         return_VOID;
97*c2c66affSColin Finck     }
98*c2c66affSColin Finck 
99*c2c66affSColin Finck     /*
100*c2c66affSColin Finck      * Must delete or free any pointers within the object that are not
101*c2c66affSColin Finck      * actual ACPI objects (for example, a raw buffer pointer).
102*c2c66affSColin Finck      */
103*c2c66affSColin Finck     switch (Object->Common.Type)
104*c2c66affSColin Finck     {
105*c2c66affSColin Finck     case ACPI_TYPE_STRING:
106*c2c66affSColin Finck 
107*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
108*c2c66affSColin Finck             Object, Object->String.Pointer));
109*c2c66affSColin Finck 
110*c2c66affSColin Finck         /* Free the actual string buffer */
111*c2c66affSColin Finck 
112*c2c66affSColin Finck         if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
113*c2c66affSColin Finck         {
114*c2c66affSColin Finck             /* But only if it is NOT a pointer into an ACPI table */
115*c2c66affSColin Finck 
116*c2c66affSColin Finck             ObjPointer = Object->String.Pointer;
117*c2c66affSColin Finck         }
118*c2c66affSColin Finck         break;
119*c2c66affSColin Finck 
120*c2c66affSColin Finck     case ACPI_TYPE_BUFFER:
121*c2c66affSColin Finck 
122*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
123*c2c66affSColin Finck             Object, Object->Buffer.Pointer));
124*c2c66affSColin Finck 
125*c2c66affSColin Finck         /* Free the actual buffer */
126*c2c66affSColin Finck 
127*c2c66affSColin Finck         if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
128*c2c66affSColin Finck         {
129*c2c66affSColin Finck             /* But only if it is NOT a pointer into an ACPI table */
130*c2c66affSColin Finck 
131*c2c66affSColin Finck             ObjPointer = Object->Buffer.Pointer;
132*c2c66affSColin Finck         }
133*c2c66affSColin Finck         break;
134*c2c66affSColin Finck 
135*c2c66affSColin Finck     case ACPI_TYPE_PACKAGE:
136*c2c66affSColin Finck 
137*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
138*c2c66affSColin Finck             Object->Package.Count));
139*c2c66affSColin Finck 
140*c2c66affSColin Finck         /*
141*c2c66affSColin Finck          * Elements of the package are not handled here, they are deleted
142*c2c66affSColin Finck          * separately
143*c2c66affSColin Finck          */
144*c2c66affSColin Finck 
145*c2c66affSColin Finck         /* Free the (variable length) element pointer array */
146*c2c66affSColin Finck 
147*c2c66affSColin Finck         ObjPointer = Object->Package.Elements;
148*c2c66affSColin Finck         break;
149*c2c66affSColin Finck 
150*c2c66affSColin Finck     /*
151*c2c66affSColin Finck      * These objects have a possible list of notify handlers.
152*c2c66affSColin Finck      * Device object also may have a GPE block.
153*c2c66affSColin Finck      */
154*c2c66affSColin Finck     case ACPI_TYPE_DEVICE:
155*c2c66affSColin Finck 
156*c2c66affSColin Finck         if (Object->Device.GpeBlock)
157*c2c66affSColin Finck         {
158*c2c66affSColin Finck             (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock);
159*c2c66affSColin Finck         }
160*c2c66affSColin Finck 
161*c2c66affSColin Finck         /*lint -fallthrough */
162*c2c66affSColin Finck 
163*c2c66affSColin Finck     case ACPI_TYPE_PROCESSOR:
164*c2c66affSColin Finck     case ACPI_TYPE_THERMAL:
165*c2c66affSColin Finck 
166*c2c66affSColin Finck         /* Walk the address handler list for this object */
167*c2c66affSColin Finck 
168*c2c66affSColin Finck         HandlerDesc = Object->CommonNotify.Handler;
169*c2c66affSColin Finck         while (HandlerDesc)
170*c2c66affSColin Finck         {
171*c2c66affSColin Finck             NextDesc = HandlerDesc->AddressSpace.Next;
172*c2c66affSColin Finck             AcpiUtRemoveReference (HandlerDesc);
173*c2c66affSColin Finck             HandlerDesc = NextDesc;
174*c2c66affSColin Finck         }
175*c2c66affSColin Finck         break;
176*c2c66affSColin Finck 
177*c2c66affSColin Finck     case ACPI_TYPE_MUTEX:
178*c2c66affSColin Finck 
179*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
180*c2c66affSColin Finck             "***** Mutex %p, OS Mutex %p\n",
181*c2c66affSColin Finck             Object, Object->Mutex.OsMutex));
182*c2c66affSColin Finck 
183*c2c66affSColin Finck         if (Object == AcpiGbl_GlobalLockMutex)
184*c2c66affSColin Finck         {
185*c2c66affSColin Finck             /* Global Lock has extra semaphore */
186*c2c66affSColin Finck 
187*c2c66affSColin Finck             (void) AcpiOsDeleteSemaphore (AcpiGbl_GlobalLockSemaphore);
188*c2c66affSColin Finck             AcpiGbl_GlobalLockSemaphore = NULL;
189*c2c66affSColin Finck 
190*c2c66affSColin Finck             AcpiOsDeleteMutex (Object->Mutex.OsMutex);
191*c2c66affSColin Finck             AcpiGbl_GlobalLockMutex = NULL;
192*c2c66affSColin Finck         }
193*c2c66affSColin Finck         else
194*c2c66affSColin Finck         {
195*c2c66affSColin Finck             AcpiExUnlinkMutex (Object);
196*c2c66affSColin Finck             AcpiOsDeleteMutex (Object->Mutex.OsMutex);
197*c2c66affSColin Finck         }
198*c2c66affSColin Finck         break;
199*c2c66affSColin Finck 
200*c2c66affSColin Finck     case ACPI_TYPE_EVENT:
201*c2c66affSColin Finck 
202*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
203*c2c66affSColin Finck             "***** Event %p, OS Semaphore %p\n",
204*c2c66affSColin Finck             Object, Object->Event.OsSemaphore));
205*c2c66affSColin Finck 
206*c2c66affSColin Finck         (void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore);
207*c2c66affSColin Finck         Object->Event.OsSemaphore = NULL;
208*c2c66affSColin Finck         break;
209*c2c66affSColin Finck 
210*c2c66affSColin Finck     case ACPI_TYPE_METHOD:
211*c2c66affSColin Finck 
212*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
213*c2c66affSColin Finck             "***** Method %p\n", Object));
214*c2c66affSColin Finck 
215*c2c66affSColin Finck         /* Delete the method mutex if it exists */
216*c2c66affSColin Finck 
217*c2c66affSColin Finck         if (Object->Method.Mutex)
218*c2c66affSColin Finck         {
219*c2c66affSColin Finck             AcpiOsDeleteMutex (Object->Method.Mutex->Mutex.OsMutex);
220*c2c66affSColin Finck             AcpiUtDeleteObjectDesc (Object->Method.Mutex);
221*c2c66affSColin Finck             Object->Method.Mutex = NULL;
222*c2c66affSColin Finck         }
223*c2c66affSColin Finck 
224*c2c66affSColin Finck         if (Object->Method.Node)
225*c2c66affSColin Finck         {
226*c2c66affSColin Finck             Object->Method.Node = NULL;
227*c2c66affSColin Finck         }
228*c2c66affSColin Finck         break;
229*c2c66affSColin Finck 
230*c2c66affSColin Finck     case ACPI_TYPE_REGION:
231*c2c66affSColin Finck 
232*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
233*c2c66affSColin Finck             "***** Region %p\n", Object));
234*c2c66affSColin Finck 
235*c2c66affSColin Finck         /*
236*c2c66affSColin Finck          * Update AddressRange list. However, only permanent regions
237*c2c66affSColin Finck          * are installed in this list. (Not created within a method)
238*c2c66affSColin Finck          */
239*c2c66affSColin Finck         if (!(Object->Region.Node->Flags & ANOBJ_TEMPORARY))
240*c2c66affSColin Finck         {
241*c2c66affSColin Finck             AcpiUtRemoveAddressRange (Object->Region.SpaceId,
242*c2c66affSColin Finck                 Object->Region.Node);
243*c2c66affSColin Finck         }
244*c2c66affSColin Finck 
245*c2c66affSColin Finck         SecondDesc = AcpiNsGetSecondaryObject (Object);
246*c2c66affSColin Finck         if (SecondDesc)
247*c2c66affSColin Finck         {
248*c2c66affSColin Finck             /*
249*c2c66affSColin Finck              * Free the RegionContext if and only if the handler is one of the
250*c2c66affSColin Finck              * default handlers -- and therefore, we created the context object
251*c2c66affSColin Finck              * locally, it was not created by an external caller.
252*c2c66affSColin Finck              */
253*c2c66affSColin Finck             HandlerDesc = Object->Region.Handler;
254*c2c66affSColin Finck             if (HandlerDesc)
255*c2c66affSColin Finck             {
256*c2c66affSColin Finck                 NextDesc = HandlerDesc->AddressSpace.RegionList;
257*c2c66affSColin Finck                 StartDesc = NextDesc;
258*c2c66affSColin Finck                 LastObjPtr = &HandlerDesc->AddressSpace.RegionList;
259*c2c66affSColin Finck 
260*c2c66affSColin Finck                 /* Remove the region object from the handler list */
261*c2c66affSColin Finck 
262*c2c66affSColin Finck                 while (NextDesc)
263*c2c66affSColin Finck                 {
264*c2c66affSColin Finck                     if (NextDesc == Object)
265*c2c66affSColin Finck                     {
266*c2c66affSColin Finck                         *LastObjPtr = NextDesc->Region.Next;
267*c2c66affSColin Finck                         break;
268*c2c66affSColin Finck                     }
269*c2c66affSColin Finck 
270*c2c66affSColin Finck                     /* Walk the linked list of handlers */
271*c2c66affSColin Finck 
272*c2c66affSColin Finck                     LastObjPtr = &NextDesc->Region.Next;
273*c2c66affSColin Finck                     NextDesc = NextDesc->Region.Next;
274*c2c66affSColin Finck 
275*c2c66affSColin Finck                     /* Prevent infinite loop if list is corrupted */
276*c2c66affSColin Finck 
277*c2c66affSColin Finck                     if (NextDesc == StartDesc)
278*c2c66affSColin Finck                     {
279*c2c66affSColin Finck                         ACPI_ERROR ((AE_INFO,
280*c2c66affSColin Finck                             "Circular region list in address handler object %p",
281*c2c66affSColin Finck                             HandlerDesc));
282*c2c66affSColin Finck                         return_VOID;
283*c2c66affSColin Finck                     }
284*c2c66affSColin Finck                 }
285*c2c66affSColin Finck 
286*c2c66affSColin Finck                 if (HandlerDesc->AddressSpace.HandlerFlags &
287*c2c66affSColin Finck                     ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
288*c2c66affSColin Finck                 {
289*c2c66affSColin Finck                     /* Deactivate region and free region context */
290*c2c66affSColin Finck 
291*c2c66affSColin Finck                     if (HandlerDesc->AddressSpace.Setup)
292*c2c66affSColin Finck                     {
293*c2c66affSColin Finck                         (void) HandlerDesc->AddressSpace.Setup (Object,
294*c2c66affSColin Finck                             ACPI_REGION_DEACTIVATE,
295*c2c66affSColin Finck                             HandlerDesc->AddressSpace.Context,
296*c2c66affSColin Finck                             &SecondDesc->Extra.RegionContext);
297*c2c66affSColin Finck                     }
298*c2c66affSColin Finck                 }
299*c2c66affSColin Finck 
300*c2c66affSColin Finck                 AcpiUtRemoveReference (HandlerDesc);
301*c2c66affSColin Finck             }
302*c2c66affSColin Finck 
303*c2c66affSColin Finck             /* Now we can free the Extra object */
304*c2c66affSColin Finck 
305*c2c66affSColin Finck             AcpiUtDeleteObjectDesc (SecondDesc);
306*c2c66affSColin Finck         }
307*c2c66affSColin Finck         break;
308*c2c66affSColin Finck 
309*c2c66affSColin Finck     case ACPI_TYPE_BUFFER_FIELD:
310*c2c66affSColin Finck 
311*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
312*c2c66affSColin Finck             "***** Buffer Field %p\n", Object));
313*c2c66affSColin Finck 
314*c2c66affSColin Finck         SecondDesc = AcpiNsGetSecondaryObject (Object);
315*c2c66affSColin Finck         if (SecondDesc)
316*c2c66affSColin Finck         {
317*c2c66affSColin Finck             AcpiUtDeleteObjectDesc (SecondDesc);
318*c2c66affSColin Finck         }
319*c2c66affSColin Finck         break;
320*c2c66affSColin Finck 
321*c2c66affSColin Finck     case ACPI_TYPE_LOCAL_BANK_FIELD:
322*c2c66affSColin Finck 
323*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
324*c2c66affSColin Finck             "***** Bank Field %p\n", Object));
325*c2c66affSColin Finck 
326*c2c66affSColin Finck         SecondDesc = AcpiNsGetSecondaryObject (Object);
327*c2c66affSColin Finck         if (SecondDesc)
328*c2c66affSColin Finck         {
329*c2c66affSColin Finck             AcpiUtDeleteObjectDesc (SecondDesc);
330*c2c66affSColin Finck         }
331*c2c66affSColin Finck         break;
332*c2c66affSColin Finck 
333*c2c66affSColin Finck     default:
334*c2c66affSColin Finck 
335*c2c66affSColin Finck         break;
336*c2c66affSColin Finck     }
337*c2c66affSColin Finck 
338*c2c66affSColin Finck     /* Free any allocated memory (pointer within the object) found above */
339*c2c66affSColin Finck 
340*c2c66affSColin Finck     if (ObjPointer)
341*c2c66affSColin Finck     {
342*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
343*c2c66affSColin Finck             ObjPointer));
344*c2c66affSColin Finck         ACPI_FREE (ObjPointer);
345*c2c66affSColin Finck     }
346*c2c66affSColin Finck 
347*c2c66affSColin Finck     /* Now the object can be safely deleted */
348*c2c66affSColin Finck 
349*c2c66affSColin Finck     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
350*c2c66affSColin Finck         Object, AcpiUtGetObjectTypeName (Object)));
351*c2c66affSColin Finck 
352*c2c66affSColin Finck     AcpiUtDeleteObjectDesc (Object);
353*c2c66affSColin Finck     return_VOID;
354*c2c66affSColin Finck }
355*c2c66affSColin Finck 
356*c2c66affSColin Finck 
357*c2c66affSColin Finck /*******************************************************************************
358*c2c66affSColin Finck  *
359*c2c66affSColin Finck  * FUNCTION:    AcpiUtDeleteInternalObjectList
360*c2c66affSColin Finck  *
361*c2c66affSColin Finck  * PARAMETERS:  ObjList         - Pointer to the list to be deleted
362*c2c66affSColin Finck  *
363*c2c66affSColin Finck  * RETURN:      None
364*c2c66affSColin Finck  *
365*c2c66affSColin Finck  * DESCRIPTION: This function deletes an internal object list, including both
366*c2c66affSColin Finck  *              simple objects and package objects
367*c2c66affSColin Finck  *
368*c2c66affSColin Finck  ******************************************************************************/
369*c2c66affSColin Finck 
370*c2c66affSColin Finck void
371*c2c66affSColin Finck AcpiUtDeleteInternalObjectList (
372*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     **ObjList)
373*c2c66affSColin Finck {
374*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     **InternalObj;
375*c2c66affSColin Finck 
376*c2c66affSColin Finck 
377*c2c66affSColin Finck     ACPI_FUNCTION_ENTRY ();
378*c2c66affSColin Finck 
379*c2c66affSColin Finck 
380*c2c66affSColin Finck     /* Walk the null-terminated internal list */
381*c2c66affSColin Finck 
382*c2c66affSColin Finck     for (InternalObj = ObjList; *InternalObj; InternalObj++)
383*c2c66affSColin Finck     {
384*c2c66affSColin Finck         AcpiUtRemoveReference (*InternalObj);
385*c2c66affSColin Finck     }
386*c2c66affSColin Finck 
387*c2c66affSColin Finck     /* Free the combined parameter pointer list and object array */
388*c2c66affSColin Finck 
389*c2c66affSColin Finck     ACPI_FREE (ObjList);
390*c2c66affSColin Finck     return;
391*c2c66affSColin Finck }
392*c2c66affSColin Finck 
393*c2c66affSColin Finck 
394*c2c66affSColin Finck /*******************************************************************************
395*c2c66affSColin Finck  *
396*c2c66affSColin Finck  * FUNCTION:    AcpiUtUpdateRefCount
397*c2c66affSColin Finck  *
398*c2c66affSColin Finck  * PARAMETERS:  Object          - Object whose ref count is to be updated
399*c2c66affSColin Finck  *              Action          - What to do (REF_INCREMENT or REF_DECREMENT)
400*c2c66affSColin Finck  *
401*c2c66affSColin Finck  * RETURN:      None. Sets new reference count within the object
402*c2c66affSColin Finck  *
403*c2c66affSColin Finck  * DESCRIPTION: Modify the reference count for an internal acpi object
404*c2c66affSColin Finck  *
405*c2c66affSColin Finck  ******************************************************************************/
406*c2c66affSColin Finck 
407*c2c66affSColin Finck static void
408*c2c66affSColin Finck AcpiUtUpdateRefCount (
409*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *Object,
410*c2c66affSColin Finck     UINT32                  Action)
411*c2c66affSColin Finck {
412*c2c66affSColin Finck     UINT16                  OriginalCount;
413*c2c66affSColin Finck     UINT16                  NewCount = 0;
414*c2c66affSColin Finck     ACPI_CPU_FLAGS          LockFlags;
415*c2c66affSColin Finck 
416*c2c66affSColin Finck 
417*c2c66affSColin Finck     ACPI_FUNCTION_NAME (UtUpdateRefCount);
418*c2c66affSColin Finck 
419*c2c66affSColin Finck 
420*c2c66affSColin Finck     if (!Object)
421*c2c66affSColin Finck     {
422*c2c66affSColin Finck         return;
423*c2c66affSColin Finck     }
424*c2c66affSColin Finck 
425*c2c66affSColin Finck     /*
426*c2c66affSColin Finck      * Always get the reference count lock. Note: Interpreter and/or
427*c2c66affSColin Finck      * Namespace is not always locked when this function is called.
428*c2c66affSColin Finck      */
429*c2c66affSColin Finck     LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock);
430*c2c66affSColin Finck     OriginalCount = Object->Common.ReferenceCount;
431*c2c66affSColin Finck 
432*c2c66affSColin Finck     /* Perform the reference count action (increment, decrement) */
433*c2c66affSColin Finck 
434*c2c66affSColin Finck     switch (Action)
435*c2c66affSColin Finck     {
436*c2c66affSColin Finck     case REF_INCREMENT:
437*c2c66affSColin Finck 
438*c2c66affSColin Finck         NewCount = OriginalCount + 1;
439*c2c66affSColin Finck         Object->Common.ReferenceCount = NewCount;
440*c2c66affSColin Finck         AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
441*c2c66affSColin Finck 
442*c2c66affSColin Finck         /* The current reference count should never be zero here */
443*c2c66affSColin Finck 
444*c2c66affSColin Finck         if (!OriginalCount)
445*c2c66affSColin Finck         {
446*c2c66affSColin Finck             ACPI_WARNING ((AE_INFO,
447*c2c66affSColin Finck                 "Obj %p, Reference Count was zero before increment\n",
448*c2c66affSColin Finck                 Object));
449*c2c66affSColin Finck         }
450*c2c66affSColin Finck 
451*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
452*c2c66affSColin Finck             "Obj %p Type %.2X [%s] Refs %.2X [Incremented]\n",
453*c2c66affSColin Finck             Object, Object->Common.Type,
454*c2c66affSColin Finck             AcpiUtGetObjectTypeName (Object), NewCount));
455*c2c66affSColin Finck         break;
456*c2c66affSColin Finck 
457*c2c66affSColin Finck     case REF_DECREMENT:
458*c2c66affSColin Finck 
459*c2c66affSColin Finck         /* The current reference count must be non-zero */
460*c2c66affSColin Finck 
461*c2c66affSColin Finck         if (OriginalCount)
462*c2c66affSColin Finck         {
463*c2c66affSColin Finck             NewCount = OriginalCount - 1;
464*c2c66affSColin Finck             Object->Common.ReferenceCount = NewCount;
465*c2c66affSColin Finck         }
466*c2c66affSColin Finck 
467*c2c66affSColin Finck         AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
468*c2c66affSColin Finck 
469*c2c66affSColin Finck         if (!OriginalCount)
470*c2c66affSColin Finck         {
471*c2c66affSColin Finck             ACPI_WARNING ((AE_INFO,
472*c2c66affSColin Finck                 "Obj %p, Reference Count is already zero, cannot decrement\n",
473*c2c66affSColin Finck                 Object));
474*c2c66affSColin Finck         }
475*c2c66affSColin Finck 
476*c2c66affSColin Finck         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
477*c2c66affSColin Finck             "Obj %p Type %.2X Refs %.2X [Decremented]\n",
478*c2c66affSColin Finck             Object, Object->Common.Type, NewCount));
479*c2c66affSColin Finck 
480*c2c66affSColin Finck         /* Actually delete the object on a reference count of zero */
481*c2c66affSColin Finck 
482*c2c66affSColin Finck         if (NewCount == 0)
483*c2c66affSColin Finck         {
484*c2c66affSColin Finck             AcpiUtDeleteInternalObj (Object);
485*c2c66affSColin Finck         }
486*c2c66affSColin Finck         break;
487*c2c66affSColin Finck 
488*c2c66affSColin Finck     default:
489*c2c66affSColin Finck 
490*c2c66affSColin Finck         AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
491*c2c66affSColin Finck         ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)",
492*c2c66affSColin Finck             Action));
493*c2c66affSColin Finck         return;
494*c2c66affSColin Finck     }
495*c2c66affSColin Finck 
496*c2c66affSColin Finck     /*
497*c2c66affSColin Finck      * Sanity check the reference count, for debug purposes only.
498*c2c66affSColin Finck      * (A deleted object will have a huge reference count)
499*c2c66affSColin Finck      */
500*c2c66affSColin Finck     if (NewCount > ACPI_MAX_REFERENCE_COUNT)
501*c2c66affSColin Finck     {
502*c2c66affSColin Finck         ACPI_WARNING ((AE_INFO,
503*c2c66affSColin Finck             "Large Reference Count (0x%X) in object %p, Type=0x%.2X",
504*c2c66affSColin Finck             NewCount, Object, Object->Common.Type));
505*c2c66affSColin Finck     }
506*c2c66affSColin Finck }
507*c2c66affSColin Finck 
508*c2c66affSColin Finck 
509*c2c66affSColin Finck /*******************************************************************************
510*c2c66affSColin Finck  *
511*c2c66affSColin Finck  * FUNCTION:    AcpiUtUpdateObjectReference
512*c2c66affSColin Finck  *
513*c2c66affSColin Finck  * PARAMETERS:  Object              - Increment ref count for this object
514*c2c66affSColin Finck  *                                    and all sub-objects
515*c2c66affSColin Finck  *              Action              - Either REF_INCREMENT or REF_DECREMENT
516*c2c66affSColin Finck  *
517*c2c66affSColin Finck  * RETURN:      Status
518*c2c66affSColin Finck  *
519*c2c66affSColin Finck  * DESCRIPTION: Increment the object reference count
520*c2c66affSColin Finck  *
521*c2c66affSColin Finck  * Object references are incremented when:
522*c2c66affSColin Finck  * 1) An object is attached to a Node (namespace object)
523*c2c66affSColin Finck  * 2) An object is copied (all subobjects must be incremented)
524*c2c66affSColin Finck  *
525*c2c66affSColin Finck  * Object references are decremented when:
526*c2c66affSColin Finck  * 1) An object is detached from an Node
527*c2c66affSColin Finck  *
528*c2c66affSColin Finck  ******************************************************************************/
529*c2c66affSColin Finck 
530*c2c66affSColin Finck ACPI_STATUS
531*c2c66affSColin Finck AcpiUtUpdateObjectReference (
532*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *Object,
533*c2c66affSColin Finck     UINT16                  Action)
534*c2c66affSColin Finck {
535*c2c66affSColin Finck     ACPI_STATUS             Status = AE_OK;
536*c2c66affSColin Finck     ACPI_GENERIC_STATE      *StateList = NULL;
537*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *NextObject = NULL;
538*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *PrevObject;
539*c2c66affSColin Finck     ACPI_GENERIC_STATE      *State;
540*c2c66affSColin Finck     UINT32                  i;
541*c2c66affSColin Finck 
542*c2c66affSColin Finck 
543*c2c66affSColin Finck     ACPI_FUNCTION_NAME (UtUpdateObjectReference);
544*c2c66affSColin Finck 
545*c2c66affSColin Finck 
546*c2c66affSColin Finck     while (Object)
547*c2c66affSColin Finck     {
548*c2c66affSColin Finck         /* Make sure that this isn't a namespace handle */
549*c2c66affSColin Finck 
550*c2c66affSColin Finck         if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
551*c2c66affSColin Finck         {
552*c2c66affSColin Finck             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
553*c2c66affSColin Finck                 "Object %p is NS handle\n", Object));
554*c2c66affSColin Finck             return (AE_OK);
555*c2c66affSColin Finck         }
556*c2c66affSColin Finck 
557*c2c66affSColin Finck         /*
558*c2c66affSColin Finck          * All sub-objects must have their reference count incremented
559*c2c66affSColin Finck          * also. Different object types have different subobjects.
560*c2c66affSColin Finck          */
561*c2c66affSColin Finck         switch (Object->Common.Type)
562*c2c66affSColin Finck         {
563*c2c66affSColin Finck         case ACPI_TYPE_DEVICE:
564*c2c66affSColin Finck         case ACPI_TYPE_PROCESSOR:
565*c2c66affSColin Finck         case ACPI_TYPE_POWER:
566*c2c66affSColin Finck         case ACPI_TYPE_THERMAL:
567*c2c66affSColin Finck             /*
568*c2c66affSColin Finck              * Update the notify objects for these types (if present)
569*c2c66affSColin Finck              * Two lists, system and device notify handlers.
570*c2c66affSColin Finck              */
571*c2c66affSColin Finck             for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
572*c2c66affSColin Finck             {
573*c2c66affSColin Finck                 PrevObject = Object->CommonNotify.NotifyList[i];
574*c2c66affSColin Finck                 while (PrevObject)
575*c2c66affSColin Finck                 {
576*c2c66affSColin Finck                     NextObject = PrevObject->Notify.Next[i];
577*c2c66affSColin Finck                     AcpiUtUpdateRefCount (PrevObject, Action);
578*c2c66affSColin Finck                     PrevObject = NextObject;
579*c2c66affSColin Finck                 }
580*c2c66affSColin Finck             }
581*c2c66affSColin Finck             break;
582*c2c66affSColin Finck 
583*c2c66affSColin Finck         case ACPI_TYPE_PACKAGE:
584*c2c66affSColin Finck             /*
585*c2c66affSColin Finck              * We must update all the sub-objects of the package,
586*c2c66affSColin Finck              * each of whom may have their own sub-objects.
587*c2c66affSColin Finck              */
588*c2c66affSColin Finck             for (i = 0; i < Object->Package.Count; i++)
589*c2c66affSColin Finck             {
590*c2c66affSColin Finck                 /*
591*c2c66affSColin Finck                  * Null package elements are legal and can be simply
592*c2c66affSColin Finck                  * ignored.
593*c2c66affSColin Finck                  */
594*c2c66affSColin Finck                 NextObject = Object->Package.Elements[i];
595*c2c66affSColin Finck                 if (!NextObject)
596*c2c66affSColin Finck                 {
597*c2c66affSColin Finck                     continue;
598*c2c66affSColin Finck                 }
599*c2c66affSColin Finck 
600*c2c66affSColin Finck                 switch (NextObject->Common.Type)
601*c2c66affSColin Finck                 {
602*c2c66affSColin Finck                 case ACPI_TYPE_INTEGER:
603*c2c66affSColin Finck                 case ACPI_TYPE_STRING:
604*c2c66affSColin Finck                 case ACPI_TYPE_BUFFER:
605*c2c66affSColin Finck                     /*
606*c2c66affSColin Finck                      * For these very simple sub-objects, we can just
607*c2c66affSColin Finck                      * update the reference count here and continue.
608*c2c66affSColin Finck                      * Greatly increases performance of this operation.
609*c2c66affSColin Finck                      */
610*c2c66affSColin Finck                     AcpiUtUpdateRefCount (NextObject, Action);
611*c2c66affSColin Finck                     break;
612*c2c66affSColin Finck 
613*c2c66affSColin Finck                 default:
614*c2c66affSColin Finck                     /*
615*c2c66affSColin Finck                      * For complex sub-objects, push them onto the stack
616*c2c66affSColin Finck                      * for later processing (this eliminates recursion.)
617*c2c66affSColin Finck                      */
618*c2c66affSColin Finck                     Status = AcpiUtCreateUpdateStateAndPush (
619*c2c66affSColin Finck                         NextObject, Action, &StateList);
620*c2c66affSColin Finck                     if (ACPI_FAILURE (Status))
621*c2c66affSColin Finck                     {
622*c2c66affSColin Finck                         goto ErrorExit;
623*c2c66affSColin Finck                     }
624*c2c66affSColin Finck                     break;
625*c2c66affSColin Finck                 }
626*c2c66affSColin Finck             }
627*c2c66affSColin Finck             NextObject = NULL;
628*c2c66affSColin Finck             break;
629*c2c66affSColin Finck 
630*c2c66affSColin Finck         case ACPI_TYPE_BUFFER_FIELD:
631*c2c66affSColin Finck 
632*c2c66affSColin Finck             NextObject = Object->BufferField.BufferObj;
633*c2c66affSColin Finck             break;
634*c2c66affSColin Finck 
635*c2c66affSColin Finck         case ACPI_TYPE_LOCAL_REGION_FIELD:
636*c2c66affSColin Finck 
637*c2c66affSColin Finck             NextObject = Object->Field.RegionObj;
638*c2c66affSColin Finck             break;
639*c2c66affSColin Finck 
640*c2c66affSColin Finck         case ACPI_TYPE_LOCAL_BANK_FIELD:
641*c2c66affSColin Finck 
642*c2c66affSColin Finck             NextObject = Object->BankField.BankObj;
643*c2c66affSColin Finck             Status = AcpiUtCreateUpdateStateAndPush (
644*c2c66affSColin Finck                 Object->BankField.RegionObj, Action, &StateList);
645*c2c66affSColin Finck             if (ACPI_FAILURE (Status))
646*c2c66affSColin Finck             {
647*c2c66affSColin Finck                 goto ErrorExit;
648*c2c66affSColin Finck             }
649*c2c66affSColin Finck             break;
650*c2c66affSColin Finck 
651*c2c66affSColin Finck         case ACPI_TYPE_LOCAL_INDEX_FIELD:
652*c2c66affSColin Finck 
653*c2c66affSColin Finck             NextObject = Object->IndexField.IndexObj;
654*c2c66affSColin Finck             Status = AcpiUtCreateUpdateStateAndPush (
655*c2c66affSColin Finck                 Object->IndexField.DataObj, Action, &StateList);
656*c2c66affSColin Finck             if (ACPI_FAILURE (Status))
657*c2c66affSColin Finck             {
658*c2c66affSColin Finck                 goto ErrorExit;
659*c2c66affSColin Finck             }
660*c2c66affSColin Finck             break;
661*c2c66affSColin Finck 
662*c2c66affSColin Finck         case ACPI_TYPE_LOCAL_REFERENCE:
663*c2c66affSColin Finck             /*
664*c2c66affSColin Finck              * The target of an Index (a package, string, or buffer) or a named
665*c2c66affSColin Finck              * reference must track changes to the ref count of the index or
666*c2c66affSColin Finck              * target object.
667*c2c66affSColin Finck              */
668*c2c66affSColin Finck             if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) ||
669*c2c66affSColin Finck                 (Object->Reference.Class== ACPI_REFCLASS_NAME))
670*c2c66affSColin Finck             {
671*c2c66affSColin Finck                 NextObject = Object->Reference.Object;
672*c2c66affSColin Finck             }
673*c2c66affSColin Finck             break;
674*c2c66affSColin Finck 
675*c2c66affSColin Finck         case ACPI_TYPE_REGION:
676*c2c66affSColin Finck         default:
677*c2c66affSColin Finck 
678*c2c66affSColin Finck             break; /* No subobjects for all other types */
679*c2c66affSColin Finck         }
680*c2c66affSColin Finck 
681*c2c66affSColin Finck         /*
682*c2c66affSColin Finck          * Now we can update the count in the main object. This can only
683*c2c66affSColin Finck          * happen after we update the sub-objects in case this causes the
684*c2c66affSColin Finck          * main object to be deleted.
685*c2c66affSColin Finck          */
686*c2c66affSColin Finck         AcpiUtUpdateRefCount (Object, Action);
687*c2c66affSColin Finck         Object = NULL;
688*c2c66affSColin Finck 
689*c2c66affSColin Finck         /* Move on to the next object to be updated */
690*c2c66affSColin Finck 
691*c2c66affSColin Finck         if (NextObject)
692*c2c66affSColin Finck         {
693*c2c66affSColin Finck             Object = NextObject;
694*c2c66affSColin Finck             NextObject = NULL;
695*c2c66affSColin Finck         }
696*c2c66affSColin Finck         else if (StateList)
697*c2c66affSColin Finck         {
698*c2c66affSColin Finck             State = AcpiUtPopGenericState (&StateList);
699*c2c66affSColin Finck             Object = State->Update.Object;
700*c2c66affSColin Finck             AcpiUtDeleteGenericState (State);
701*c2c66affSColin Finck         }
702*c2c66affSColin Finck     }
703*c2c66affSColin Finck 
704*c2c66affSColin Finck     return (AE_OK);
705*c2c66affSColin Finck 
706*c2c66affSColin Finck 
707*c2c66affSColin Finck ErrorExit:
708*c2c66affSColin Finck 
709*c2c66affSColin Finck     ACPI_EXCEPTION ((AE_INFO, Status,
710*c2c66affSColin Finck         "Could not update object reference count"));
711*c2c66affSColin Finck 
712*c2c66affSColin Finck     /* Free any stacked Update State objects */
713*c2c66affSColin Finck 
714*c2c66affSColin Finck     while (StateList)
715*c2c66affSColin Finck     {
716*c2c66affSColin Finck         State = AcpiUtPopGenericState (&StateList);
717*c2c66affSColin Finck         AcpiUtDeleteGenericState (State);
718*c2c66affSColin Finck     }
719*c2c66affSColin Finck 
720*c2c66affSColin Finck     return (Status);
721*c2c66affSColin Finck }
722*c2c66affSColin Finck 
723*c2c66affSColin Finck 
724*c2c66affSColin Finck /*******************************************************************************
725*c2c66affSColin Finck  *
726*c2c66affSColin Finck  * FUNCTION:    AcpiUtAddReference
727*c2c66affSColin Finck  *
728*c2c66affSColin Finck  * PARAMETERS:  Object          - Object whose reference count is to be
729*c2c66affSColin Finck  *                                incremented
730*c2c66affSColin Finck  *
731*c2c66affSColin Finck  * RETURN:      None
732*c2c66affSColin Finck  *
733*c2c66affSColin Finck  * DESCRIPTION: Add one reference to an ACPI object
734*c2c66affSColin Finck  *
735*c2c66affSColin Finck  ******************************************************************************/
736*c2c66affSColin Finck 
737*c2c66affSColin Finck void
738*c2c66affSColin Finck AcpiUtAddReference (
739*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *Object)
740*c2c66affSColin Finck {
741*c2c66affSColin Finck 
742*c2c66affSColin Finck     ACPI_FUNCTION_NAME (UtAddReference);
743*c2c66affSColin Finck 
744*c2c66affSColin Finck 
745*c2c66affSColin Finck     /* Ensure that we have a valid object */
746*c2c66affSColin Finck 
747*c2c66affSColin Finck     if (!AcpiUtValidInternalObject (Object))
748*c2c66affSColin Finck     {
749*c2c66affSColin Finck         return;
750*c2c66affSColin Finck     }
751*c2c66affSColin Finck 
752*c2c66affSColin Finck     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
753*c2c66affSColin Finck         "Obj %p Current Refs=%X [To Be Incremented]\n",
754*c2c66affSColin Finck         Object, Object->Common.ReferenceCount));
755*c2c66affSColin Finck 
756*c2c66affSColin Finck     /* Increment the reference count */
757*c2c66affSColin Finck 
758*c2c66affSColin Finck     (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
759*c2c66affSColin Finck     return;
760*c2c66affSColin Finck }
761*c2c66affSColin Finck 
762*c2c66affSColin Finck 
763*c2c66affSColin Finck /*******************************************************************************
764*c2c66affSColin Finck  *
765*c2c66affSColin Finck  * FUNCTION:    AcpiUtRemoveReference
766*c2c66affSColin Finck  *
767*c2c66affSColin Finck  * PARAMETERS:  Object         - Object whose ref count will be decremented
768*c2c66affSColin Finck  *
769*c2c66affSColin Finck  * RETURN:      None
770*c2c66affSColin Finck  *
771*c2c66affSColin Finck  * DESCRIPTION: Decrement the reference count of an ACPI internal object
772*c2c66affSColin Finck  *
773*c2c66affSColin Finck  ******************************************************************************/
774*c2c66affSColin Finck 
775*c2c66affSColin Finck void
776*c2c66affSColin Finck AcpiUtRemoveReference (
777*c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *Object)
778*c2c66affSColin Finck {
779*c2c66affSColin Finck 
780*c2c66affSColin Finck     ACPI_FUNCTION_NAME (UtRemoveReference);
781*c2c66affSColin Finck 
782*c2c66affSColin Finck 
783*c2c66affSColin Finck     /*
784*c2c66affSColin Finck      * Allow a NULL pointer to be passed in, just ignore it. This saves
785*c2c66affSColin Finck      * each caller from having to check. Also, ignore NS nodes.
786*c2c66affSColin Finck      */
787*c2c66affSColin Finck     if (!Object ||
788*c2c66affSColin Finck         (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))
789*c2c66affSColin Finck 
790*c2c66affSColin Finck     {
791*c2c66affSColin Finck         return;
792*c2c66affSColin Finck     }
793*c2c66affSColin Finck 
794*c2c66affSColin Finck     /* Ensure that we have a valid object */
795*c2c66affSColin Finck 
796*c2c66affSColin Finck     if (!AcpiUtValidInternalObject (Object))
797*c2c66affSColin Finck     {
798*c2c66affSColin Finck         return;
799*c2c66affSColin Finck     }
800*c2c66affSColin Finck 
801*c2c66affSColin Finck     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
802*c2c66affSColin Finck         "Obj %p Current Refs=%X [To Be Decremented]\n",
803*c2c66affSColin Finck         Object, Object->Common.ReferenceCount));
804*c2c66affSColin Finck 
805*c2c66affSColin Finck     /*
806*c2c66affSColin Finck      * Decrement the reference count, and only actually delete the object
807*c2c66affSColin Finck      * if the reference count becomes 0. (Must also decrement the ref count
808*c2c66affSColin Finck      * of all subobjects!)
809*c2c66affSColin Finck      */
810*c2c66affSColin Finck     (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
811*c2c66affSColin Finck     return;
812*c2c66affSColin Finck }
813