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