Deleted Added
full compact
utdelete.c (123315) utdelete.c (126372)
1/*******************************************************************************
2 *
3 * Module Name: utdelete - object deletion and reference count utilities
1/*******************************************************************************
2 *
3 * Module Name: utdelete - object deletion and reference count utilities
4 * $Revision: 98 $
4 * $Revision: 99 $
5 *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
5 *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
12 * Some or all of this work - Copyright (c) 1999 - 2004, 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
124#define _COMPONENT ACPI_UTILITIES
125 ACPI_MODULE_NAME ("utdelete")
126
127
128/*******************************************************************************
129 *
130 * FUNCTION: AcpiUtDeleteInternalObj
131 *
132 * PARAMETERS: *Object - Pointer to the list to be deleted
133 *
134 * RETURN: None
135 *
136 * DESCRIPTION: Low level object deletion, after reference counts have been
137 * updated (All reference counts, including sub-objects!)
138 *
139 ******************************************************************************/
140
141void
142AcpiUtDeleteInternalObj (
143 ACPI_OPERAND_OBJECT *Object)
144{
145 void *ObjPointer = NULL;
146 ACPI_OPERAND_OBJECT *HandlerDesc;
147 ACPI_OPERAND_OBJECT *SecondDesc;
148 ACPI_OPERAND_OBJECT *NextDesc;
149
150
151 ACPI_FUNCTION_TRACE_PTR ("UtDeleteInternalObj", Object);
152
153
154 if (!Object)
155 {
156 return_VOID;
157 }
158
159 /*
160 * Must delete or free any pointers within the object that are not
161 * actual ACPI objects (for example, a raw buffer pointer).
162 */
163 switch (ACPI_GET_OBJECT_TYPE (Object))
164 {
165 case ACPI_TYPE_STRING:
166
167 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
168 Object, Object->String.Pointer));
169
170 /* Free the actual string buffer */
171
172 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
173 {
174 /* But only if it is NOT a pointer into an ACPI table */
175
176 ObjPointer = Object->String.Pointer;
177 }
178 break;
179
180
181 case ACPI_TYPE_BUFFER:
182
183 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
184 Object, Object->Buffer.Pointer));
185
186 /* Free the actual buffer */
187
188 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
189 {
190 /* But only if it is NOT a pointer into an ACPI table */
191
192 ObjPointer = Object->Buffer.Pointer;
193 }
194 break;
195
196
197 case ACPI_TYPE_PACKAGE:
198
199 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
200 Object->Package.Count));
201
202 /*
203 * Elements of the package are not handled here, they are deleted
204 * separately
205 */
206
207 /* Free the (variable length) element pointer array */
208
209 ObjPointer = Object->Package.Elements;
210 break;
211
212
213 case ACPI_TYPE_DEVICE:
214
215 if (Object->Device.GpeBlock)
216 {
217 (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock);
218 }
219
220 /* Walk the handler list for this device */
221
222 HandlerDesc = Object->Device.Handler;
223 while (HandlerDesc)
224 {
225 NextDesc = HandlerDesc->AddressSpace.Next;
226 AcpiUtRemoveReference (HandlerDesc);
227 HandlerDesc = NextDesc;
228 }
229 break;
230
231
232 case ACPI_TYPE_MUTEX:
233
234 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Mutex %p, Semaphore %p\n",
235 Object, Object->Mutex.Semaphore));
236
237 AcpiExUnlinkMutex (Object);
238 (void) AcpiOsDeleteSemaphore (Object->Mutex.Semaphore);
239 break;
240
241
242 case ACPI_TYPE_EVENT:
243
244 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Event %p, Semaphore %p\n",
245 Object, Object->Event.Semaphore));
246
247 (void) AcpiOsDeleteSemaphore (Object->Event.Semaphore);
248 Object->Event.Semaphore = NULL;
249 break;
250
251
252 case ACPI_TYPE_METHOD:
253
254 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Method %p\n", Object));
255
256 /* Delete the method semaphore if it exists */
257
258 if (Object->Method.Semaphore)
259 {
260 (void) AcpiOsDeleteSemaphore (Object->Method.Semaphore);
261 Object->Method.Semaphore = NULL;
262 }
263 break;
264
265
266 case ACPI_TYPE_REGION:
267
268 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Region %p\n", Object));
269
270 SecondDesc = AcpiNsGetSecondaryObject (Object);
271 if (SecondDesc)
272 {
273 /*
274 * Free the RegionContext if and only if the handler is one of the
275 * default handlers -- and therefore, we created the context object
276 * locally, it was not created by an external caller.
277 */
278 HandlerDesc = Object->Region.Handler;
279 if (HandlerDesc)
280 {
281 if (HandlerDesc->AddressSpace.Hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
282 {
283 ObjPointer = SecondDesc->Extra.RegionContext;
284 }
285
286 AcpiUtRemoveReference (HandlerDesc);
287 }
288
289 /* Now we can free the Extra object */
290
291 AcpiUtDeleteObjectDesc (SecondDesc);
292 }
293 break;
294
295
296 case ACPI_TYPE_BUFFER_FIELD:
297
298 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Buffer Field %p\n", Object));
299
300 SecondDesc = AcpiNsGetSecondaryObject (Object);
301 if (SecondDesc)
302 {
303 AcpiUtDeleteObjectDesc (SecondDesc);
304 }
305 break;
306
307
308 default:
309 break;
310 }
311
312 /* Free any allocated memory (pointer within the object) found above */
313
314 if (ObjPointer)
315 {
316 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
317 ObjPointer));
318 ACPI_MEM_FREE (ObjPointer);
319 }
320
321 /* Now the object can be safely deleted */
322
323 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
324 Object, AcpiUtGetObjectTypeName (Object)));
325
326 AcpiUtDeleteObjectDesc (Object);
327 return_VOID;
328}
329
330
331/*******************************************************************************
332 *
333 * FUNCTION: AcpiUtDeleteInternalObjectList
334 *
335 * PARAMETERS: *ObjList - Pointer to the list to be deleted
336 *
337 * RETURN: None
338 *
339 * DESCRIPTION: This function deletes an internal object list, including both
340 * simple objects and package objects
341 *
342 ******************************************************************************/
343
344void
345AcpiUtDeleteInternalObjectList (
346 ACPI_OPERAND_OBJECT **ObjList)
347{
348 ACPI_OPERAND_OBJECT **InternalObj;
349
350
351 ACPI_FUNCTION_TRACE ("UtDeleteInternalObjectList");
352
353
354 /* Walk the null-terminated internal list */
355
356 for (InternalObj = ObjList; *InternalObj; InternalObj++)
357 {
358 AcpiUtRemoveReference (*InternalObj);
359 }
360
361 /* Free the combined parameter pointer list and object array */
362
363 ACPI_MEM_FREE (ObjList);
364 return_VOID;
365}
366
367
368/*******************************************************************************
369 *
370 * FUNCTION: AcpiUtUpdateRefCount
371 *
372 * PARAMETERS: *Object - Object whose ref count is to be updated
373 * Action - What to do
374 *
375 * RETURN: New ref count
376 *
377 * DESCRIPTION: Modify the ref count and return it.
378 *
379 ******************************************************************************/
380
381static void
382AcpiUtUpdateRefCount (
383 ACPI_OPERAND_OBJECT *Object,
384 UINT32 Action)
385{
386 UINT16 Count;
387 UINT16 NewCount;
388
389
390 ACPI_FUNCTION_NAME ("UtUpdateRefCount");
391
392
393 if (!Object)
394 {
395 return;
396 }
397
398 Count = Object->Common.ReferenceCount;
399 NewCount = Count;
400
401 /*
402 * Perform the reference count action (increment, decrement, or force delete)
403 */
404 switch (Action)
405 {
406
407 case REF_INCREMENT:
408
409 NewCount++;
410 Object->Common.ReferenceCount = NewCount;
411
412 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Incremented]\n",
413 Object, NewCount));
414 break;
415
416
417 case REF_DECREMENT:
418
419 if (Count < 1)
420 {
421 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
422 Object, NewCount));
423
424 NewCount = 0;
425 }
426 else
427 {
428 NewCount--;
429
430 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Decremented]\n",
431 Object, NewCount));
432 }
433
434 if (ACPI_GET_OBJECT_TYPE (Object) == ACPI_TYPE_METHOD)
435 {
436 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n",
437 Object, NewCount));
438 }
439
440 Object->Common.ReferenceCount = NewCount;
441 if (NewCount == 0)
442 {
443 AcpiUtDeleteInternalObj (Object);
444 }
445
446 break;
447
448
449 case REF_FORCE_DELETE:
450
451 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, Force delete! (Set to 0)\n",
452 Object, Count));
453
454 NewCount = 0;
455 Object->Common.ReferenceCount = NewCount;
456 AcpiUtDeleteInternalObj (Object);
457 break;
458
459
460 default:
461
462 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown action (%X)\n", Action));
463 break;
464 }
465
466 /*
467 * Sanity check the reference count, for debug purposes only.
468 * (A deleted object will have a huge reference count)
469 */
470 if (Count > ACPI_MAX_REFERENCE_COUNT)
471 {
472
473 ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
474 "**** Warning **** Large Reference Count (%X) in object %p\n\n",
475 Count, Object));
476 }
477
478 return;
479}
480
481
482/*******************************************************************************
483 *
484 * FUNCTION: AcpiUtUpdateObjectReference
485 *
486 * PARAMETERS: *Object - Increment ref count for this object
487 * and all sub-objects
488 * Action - Either REF_INCREMENT or REF_DECREMENT or
489 * REF_FORCE_DELETE
490 *
491 * RETURN: Status
492 *
493 * DESCRIPTION: Increment the object reference count
494 *
495 * Object references are incremented when:
496 * 1) An object is attached to a Node (namespace object)
497 * 2) An object is copied (all subobjects must be incremented)
498 *
499 * Object references are decremented when:
500 * 1) An object is detached from an Node
501 *
502 ******************************************************************************/
503
504ACPI_STATUS
505AcpiUtUpdateObjectReference (
506 ACPI_OPERAND_OBJECT *Object,
507 UINT16 Action)
508{
509 ACPI_STATUS Status;
510 UINT32 i;
511 ACPI_GENERIC_STATE *StateList = NULL;
512 ACPI_GENERIC_STATE *State;
513
514
515 ACPI_FUNCTION_TRACE_PTR ("UtUpdateObjectReference", Object);
516
517
518 /* Ignore a null object ptr */
519
520 if (!Object)
521 {
522 return_ACPI_STATUS (AE_OK);
523 }
524
525 /* Make sure that this isn't a namespace handle */
526
527 if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
528 {
529 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", Object));
530 return_ACPI_STATUS (AE_OK);
531 }
532
533 State = AcpiUtCreateUpdateState (Object, Action);
534
535 while (State)
536 {
537 Object = State->Update.Object;
538 Action = State->Update.Value;
539 AcpiUtDeleteGenericState (State);
540
541 /*
542 * All sub-objects must have their reference count incremented also.
543 * Different object types have different subobjects.
544 */
545 switch (ACPI_GET_OBJECT_TYPE (Object))
546 {
547 case ACPI_TYPE_DEVICE:
548
549 AcpiUtUpdateRefCount (Object->Device.SystemNotify, Action);
550 AcpiUtUpdateRefCount (Object->Device.DeviceNotify, Action);
551 break;
552
553
554 case ACPI_TYPE_PACKAGE:
555
556 /*
557 * We must update all the sub-objects of the package
558 * (Each of whom may have their own sub-objects, etc.
559 */
560 for (i = 0; i < Object->Package.Count; i++)
561 {
562 /*
563 * Push each element onto the stack for later processing.
564 * Note: There can be null elements within the package,
565 * these are simply ignored
566 */
567 Status = AcpiUtCreateUpdateStateAndPush (
568 Object->Package.Elements[i], Action, &StateList);
569 if (ACPI_FAILURE (Status))
570 {
571 goto ErrorExit;
572 }
573 }
574 break;
575
576
577 case ACPI_TYPE_BUFFER_FIELD:
578
579 Status = AcpiUtCreateUpdateStateAndPush (
580 Object->BufferField.BufferObj, Action, &StateList);
581 if (ACPI_FAILURE (Status))
582 {
583 goto ErrorExit;
584 }
585 break;
586
587
588 case ACPI_TYPE_LOCAL_REGION_FIELD:
589
590 Status = AcpiUtCreateUpdateStateAndPush (
591 Object->Field.RegionObj, Action, &StateList);
592 if (ACPI_FAILURE (Status))
593 {
594 goto ErrorExit;
595 }
596 break;
597
598
599 case ACPI_TYPE_LOCAL_BANK_FIELD:
600
601 Status = AcpiUtCreateUpdateStateAndPush (
602 Object->BankField.BankObj, Action, &StateList);
603 if (ACPI_FAILURE (Status))
604 {
605 goto ErrorExit;
606 }
607
608 Status = AcpiUtCreateUpdateStateAndPush (
609 Object->BankField.RegionObj, Action, &StateList);
610 if (ACPI_FAILURE (Status))
611 {
612 goto ErrorExit;
613 }
614 break;
615
616
617 case ACPI_TYPE_LOCAL_INDEX_FIELD:
618
619 Status = AcpiUtCreateUpdateStateAndPush (
620 Object->IndexField.IndexObj, Action, &StateList);
621 if (ACPI_FAILURE (Status))
622 {
623 goto ErrorExit;
624 }
625
626 Status = AcpiUtCreateUpdateStateAndPush (
627 Object->IndexField.DataObj, Action, &StateList);
628 if (ACPI_FAILURE (Status))
629 {
630 goto ErrorExit;
631 }
632 break;
633
634
635 case ACPI_TYPE_REGION:
636 case ACPI_TYPE_LOCAL_REFERENCE:
637 default:
638
639 /* No subobjects */
640 break;
641 }
642
643 /*
644 * Now we can update the count in the main object. This can only
645 * happen after we update the sub-objects in case this causes the
646 * main object to be deleted.
647 */
648 AcpiUtUpdateRefCount (Object, Action);
649
650 /* Move on to the next object to be updated */
651
652 State = AcpiUtPopGenericState (&StateList);
653 }
654
655 return_ACPI_STATUS (AE_OK);
656
657
658ErrorExit:
659
660 ACPI_REPORT_ERROR (("Could not update object reference count, %s\n",
661 AcpiFormatException (Status)));
662
663 return_ACPI_STATUS (Status);
664}
665
666
667/*******************************************************************************
668 *
669 * FUNCTION: AcpiUtAddReference
670 *
671 * PARAMETERS: *Object - Object whose reference count is to be
672 * incremented
673 *
674 * RETURN: None
675 *
676 * DESCRIPTION: Add one reference to an ACPI object
677 *
678 ******************************************************************************/
679
680void
681AcpiUtAddReference (
682 ACPI_OPERAND_OBJECT *Object)
683{
684
685 ACPI_FUNCTION_TRACE_PTR ("UtAddReference", Object);
686
687
688 /* Ensure that we have a valid object */
689
690 if (!AcpiUtValidInternalObject (Object))
691 {
692 return_VOID;
693 }
694
695 /* Increment the reference count */
696
697 (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
698 return_VOID;
699}
700
701
702/*******************************************************************************
703 *
704 * FUNCTION: AcpiUtRemoveReference
705 *
706 * PARAMETERS: *Object - Object whose ref count will be decremented
707 *
708 * RETURN: None
709 *
710 * DESCRIPTION: Decrement the reference count of an ACPI internal object
711 *
712 ******************************************************************************/
713
714void
715AcpiUtRemoveReference (
716 ACPI_OPERAND_OBJECT *Object)
717{
718
719 ACPI_FUNCTION_TRACE_PTR ("UtRemoveReference", Object);
720
721
722 /*
723 * Allow a NULL pointer to be passed in, just ignore it. This saves
724 * each caller from having to check. Also, ignore NS nodes.
725 *
726 */
727 if (!Object ||
728 (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))
729
730 {
731 return_VOID;
732 }
733
734 /* Ensure that we have a valid object */
735
736 if (!AcpiUtValidInternalObject (Object))
737 {
738 return_VOID;
739 }
740
741 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X\n",
742 Object, Object->Common.ReferenceCount));
743
744 /*
745 * Decrement the reference count, and only actually delete the object
746 * if the reference count becomes 0. (Must also decrement the ref count
747 * of all subobjects!)
748 */
749 (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
750 return_VOID;
751}
752
753
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
124#define _COMPONENT ACPI_UTILITIES
125 ACPI_MODULE_NAME ("utdelete")
126
127
128/*******************************************************************************
129 *
130 * FUNCTION: AcpiUtDeleteInternalObj
131 *
132 * PARAMETERS: *Object - Pointer to the list to be deleted
133 *
134 * RETURN: None
135 *
136 * DESCRIPTION: Low level object deletion, after reference counts have been
137 * updated (All reference counts, including sub-objects!)
138 *
139 ******************************************************************************/
140
141void
142AcpiUtDeleteInternalObj (
143 ACPI_OPERAND_OBJECT *Object)
144{
145 void *ObjPointer = NULL;
146 ACPI_OPERAND_OBJECT *HandlerDesc;
147 ACPI_OPERAND_OBJECT *SecondDesc;
148 ACPI_OPERAND_OBJECT *NextDesc;
149
150
151 ACPI_FUNCTION_TRACE_PTR ("UtDeleteInternalObj", Object);
152
153
154 if (!Object)
155 {
156 return_VOID;
157 }
158
159 /*
160 * Must delete or free any pointers within the object that are not
161 * actual ACPI objects (for example, a raw buffer pointer).
162 */
163 switch (ACPI_GET_OBJECT_TYPE (Object))
164 {
165 case ACPI_TYPE_STRING:
166
167 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
168 Object, Object->String.Pointer));
169
170 /* Free the actual string buffer */
171
172 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
173 {
174 /* But only if it is NOT a pointer into an ACPI table */
175
176 ObjPointer = Object->String.Pointer;
177 }
178 break;
179
180
181 case ACPI_TYPE_BUFFER:
182
183 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
184 Object, Object->Buffer.Pointer));
185
186 /* Free the actual buffer */
187
188 if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
189 {
190 /* But only if it is NOT a pointer into an ACPI table */
191
192 ObjPointer = Object->Buffer.Pointer;
193 }
194 break;
195
196
197 case ACPI_TYPE_PACKAGE:
198
199 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
200 Object->Package.Count));
201
202 /*
203 * Elements of the package are not handled here, they are deleted
204 * separately
205 */
206
207 /* Free the (variable length) element pointer array */
208
209 ObjPointer = Object->Package.Elements;
210 break;
211
212
213 case ACPI_TYPE_DEVICE:
214
215 if (Object->Device.GpeBlock)
216 {
217 (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock);
218 }
219
220 /* Walk the handler list for this device */
221
222 HandlerDesc = Object->Device.Handler;
223 while (HandlerDesc)
224 {
225 NextDesc = HandlerDesc->AddressSpace.Next;
226 AcpiUtRemoveReference (HandlerDesc);
227 HandlerDesc = NextDesc;
228 }
229 break;
230
231
232 case ACPI_TYPE_MUTEX:
233
234 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Mutex %p, Semaphore %p\n",
235 Object, Object->Mutex.Semaphore));
236
237 AcpiExUnlinkMutex (Object);
238 (void) AcpiOsDeleteSemaphore (Object->Mutex.Semaphore);
239 break;
240
241
242 case ACPI_TYPE_EVENT:
243
244 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Event %p, Semaphore %p\n",
245 Object, Object->Event.Semaphore));
246
247 (void) AcpiOsDeleteSemaphore (Object->Event.Semaphore);
248 Object->Event.Semaphore = NULL;
249 break;
250
251
252 case ACPI_TYPE_METHOD:
253
254 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Method %p\n", Object));
255
256 /* Delete the method semaphore if it exists */
257
258 if (Object->Method.Semaphore)
259 {
260 (void) AcpiOsDeleteSemaphore (Object->Method.Semaphore);
261 Object->Method.Semaphore = NULL;
262 }
263 break;
264
265
266 case ACPI_TYPE_REGION:
267
268 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Region %p\n", Object));
269
270 SecondDesc = AcpiNsGetSecondaryObject (Object);
271 if (SecondDesc)
272 {
273 /*
274 * Free the RegionContext if and only if the handler is one of the
275 * default handlers -- and therefore, we created the context object
276 * locally, it was not created by an external caller.
277 */
278 HandlerDesc = Object->Region.Handler;
279 if (HandlerDesc)
280 {
281 if (HandlerDesc->AddressSpace.Hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
282 {
283 ObjPointer = SecondDesc->Extra.RegionContext;
284 }
285
286 AcpiUtRemoveReference (HandlerDesc);
287 }
288
289 /* Now we can free the Extra object */
290
291 AcpiUtDeleteObjectDesc (SecondDesc);
292 }
293 break;
294
295
296 case ACPI_TYPE_BUFFER_FIELD:
297
298 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Buffer Field %p\n", Object));
299
300 SecondDesc = AcpiNsGetSecondaryObject (Object);
301 if (SecondDesc)
302 {
303 AcpiUtDeleteObjectDesc (SecondDesc);
304 }
305 break;
306
307
308 default:
309 break;
310 }
311
312 /* Free any allocated memory (pointer within the object) found above */
313
314 if (ObjPointer)
315 {
316 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
317 ObjPointer));
318 ACPI_MEM_FREE (ObjPointer);
319 }
320
321 /* Now the object can be safely deleted */
322
323 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
324 Object, AcpiUtGetObjectTypeName (Object)));
325
326 AcpiUtDeleteObjectDesc (Object);
327 return_VOID;
328}
329
330
331/*******************************************************************************
332 *
333 * FUNCTION: AcpiUtDeleteInternalObjectList
334 *
335 * PARAMETERS: *ObjList - Pointer to the list to be deleted
336 *
337 * RETURN: None
338 *
339 * DESCRIPTION: This function deletes an internal object list, including both
340 * simple objects and package objects
341 *
342 ******************************************************************************/
343
344void
345AcpiUtDeleteInternalObjectList (
346 ACPI_OPERAND_OBJECT **ObjList)
347{
348 ACPI_OPERAND_OBJECT **InternalObj;
349
350
351 ACPI_FUNCTION_TRACE ("UtDeleteInternalObjectList");
352
353
354 /* Walk the null-terminated internal list */
355
356 for (InternalObj = ObjList; *InternalObj; InternalObj++)
357 {
358 AcpiUtRemoveReference (*InternalObj);
359 }
360
361 /* Free the combined parameter pointer list and object array */
362
363 ACPI_MEM_FREE (ObjList);
364 return_VOID;
365}
366
367
368/*******************************************************************************
369 *
370 * FUNCTION: AcpiUtUpdateRefCount
371 *
372 * PARAMETERS: *Object - Object whose ref count is to be updated
373 * Action - What to do
374 *
375 * RETURN: New ref count
376 *
377 * DESCRIPTION: Modify the ref count and return it.
378 *
379 ******************************************************************************/
380
381static void
382AcpiUtUpdateRefCount (
383 ACPI_OPERAND_OBJECT *Object,
384 UINT32 Action)
385{
386 UINT16 Count;
387 UINT16 NewCount;
388
389
390 ACPI_FUNCTION_NAME ("UtUpdateRefCount");
391
392
393 if (!Object)
394 {
395 return;
396 }
397
398 Count = Object->Common.ReferenceCount;
399 NewCount = Count;
400
401 /*
402 * Perform the reference count action (increment, decrement, or force delete)
403 */
404 switch (Action)
405 {
406
407 case REF_INCREMENT:
408
409 NewCount++;
410 Object->Common.ReferenceCount = NewCount;
411
412 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Incremented]\n",
413 Object, NewCount));
414 break;
415
416
417 case REF_DECREMENT:
418
419 if (Count < 1)
420 {
421 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
422 Object, NewCount));
423
424 NewCount = 0;
425 }
426 else
427 {
428 NewCount--;
429
430 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Decremented]\n",
431 Object, NewCount));
432 }
433
434 if (ACPI_GET_OBJECT_TYPE (Object) == ACPI_TYPE_METHOD)
435 {
436 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n",
437 Object, NewCount));
438 }
439
440 Object->Common.ReferenceCount = NewCount;
441 if (NewCount == 0)
442 {
443 AcpiUtDeleteInternalObj (Object);
444 }
445
446 break;
447
448
449 case REF_FORCE_DELETE:
450
451 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, Force delete! (Set to 0)\n",
452 Object, Count));
453
454 NewCount = 0;
455 Object->Common.ReferenceCount = NewCount;
456 AcpiUtDeleteInternalObj (Object);
457 break;
458
459
460 default:
461
462 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown action (%X)\n", Action));
463 break;
464 }
465
466 /*
467 * Sanity check the reference count, for debug purposes only.
468 * (A deleted object will have a huge reference count)
469 */
470 if (Count > ACPI_MAX_REFERENCE_COUNT)
471 {
472
473 ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
474 "**** Warning **** Large Reference Count (%X) in object %p\n\n",
475 Count, Object));
476 }
477
478 return;
479}
480
481
482/*******************************************************************************
483 *
484 * FUNCTION: AcpiUtUpdateObjectReference
485 *
486 * PARAMETERS: *Object - Increment ref count for this object
487 * and all sub-objects
488 * Action - Either REF_INCREMENT or REF_DECREMENT or
489 * REF_FORCE_DELETE
490 *
491 * RETURN: Status
492 *
493 * DESCRIPTION: Increment the object reference count
494 *
495 * Object references are incremented when:
496 * 1) An object is attached to a Node (namespace object)
497 * 2) An object is copied (all subobjects must be incremented)
498 *
499 * Object references are decremented when:
500 * 1) An object is detached from an Node
501 *
502 ******************************************************************************/
503
504ACPI_STATUS
505AcpiUtUpdateObjectReference (
506 ACPI_OPERAND_OBJECT *Object,
507 UINT16 Action)
508{
509 ACPI_STATUS Status;
510 UINT32 i;
511 ACPI_GENERIC_STATE *StateList = NULL;
512 ACPI_GENERIC_STATE *State;
513
514
515 ACPI_FUNCTION_TRACE_PTR ("UtUpdateObjectReference", Object);
516
517
518 /* Ignore a null object ptr */
519
520 if (!Object)
521 {
522 return_ACPI_STATUS (AE_OK);
523 }
524
525 /* Make sure that this isn't a namespace handle */
526
527 if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
528 {
529 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", Object));
530 return_ACPI_STATUS (AE_OK);
531 }
532
533 State = AcpiUtCreateUpdateState (Object, Action);
534
535 while (State)
536 {
537 Object = State->Update.Object;
538 Action = State->Update.Value;
539 AcpiUtDeleteGenericState (State);
540
541 /*
542 * All sub-objects must have their reference count incremented also.
543 * Different object types have different subobjects.
544 */
545 switch (ACPI_GET_OBJECT_TYPE (Object))
546 {
547 case ACPI_TYPE_DEVICE:
548
549 AcpiUtUpdateRefCount (Object->Device.SystemNotify, Action);
550 AcpiUtUpdateRefCount (Object->Device.DeviceNotify, Action);
551 break;
552
553
554 case ACPI_TYPE_PACKAGE:
555
556 /*
557 * We must update all the sub-objects of the package
558 * (Each of whom may have their own sub-objects, etc.
559 */
560 for (i = 0; i < Object->Package.Count; i++)
561 {
562 /*
563 * Push each element onto the stack for later processing.
564 * Note: There can be null elements within the package,
565 * these are simply ignored
566 */
567 Status = AcpiUtCreateUpdateStateAndPush (
568 Object->Package.Elements[i], Action, &StateList);
569 if (ACPI_FAILURE (Status))
570 {
571 goto ErrorExit;
572 }
573 }
574 break;
575
576
577 case ACPI_TYPE_BUFFER_FIELD:
578
579 Status = AcpiUtCreateUpdateStateAndPush (
580 Object->BufferField.BufferObj, Action, &StateList);
581 if (ACPI_FAILURE (Status))
582 {
583 goto ErrorExit;
584 }
585 break;
586
587
588 case ACPI_TYPE_LOCAL_REGION_FIELD:
589
590 Status = AcpiUtCreateUpdateStateAndPush (
591 Object->Field.RegionObj, Action, &StateList);
592 if (ACPI_FAILURE (Status))
593 {
594 goto ErrorExit;
595 }
596 break;
597
598
599 case ACPI_TYPE_LOCAL_BANK_FIELD:
600
601 Status = AcpiUtCreateUpdateStateAndPush (
602 Object->BankField.BankObj, Action, &StateList);
603 if (ACPI_FAILURE (Status))
604 {
605 goto ErrorExit;
606 }
607
608 Status = AcpiUtCreateUpdateStateAndPush (
609 Object->BankField.RegionObj, Action, &StateList);
610 if (ACPI_FAILURE (Status))
611 {
612 goto ErrorExit;
613 }
614 break;
615
616
617 case ACPI_TYPE_LOCAL_INDEX_FIELD:
618
619 Status = AcpiUtCreateUpdateStateAndPush (
620 Object->IndexField.IndexObj, Action, &StateList);
621 if (ACPI_FAILURE (Status))
622 {
623 goto ErrorExit;
624 }
625
626 Status = AcpiUtCreateUpdateStateAndPush (
627 Object->IndexField.DataObj, Action, &StateList);
628 if (ACPI_FAILURE (Status))
629 {
630 goto ErrorExit;
631 }
632 break;
633
634
635 case ACPI_TYPE_REGION:
636 case ACPI_TYPE_LOCAL_REFERENCE:
637 default:
638
639 /* No subobjects */
640 break;
641 }
642
643 /*
644 * Now we can update the count in the main object. This can only
645 * happen after we update the sub-objects in case this causes the
646 * main object to be deleted.
647 */
648 AcpiUtUpdateRefCount (Object, Action);
649
650 /* Move on to the next object to be updated */
651
652 State = AcpiUtPopGenericState (&StateList);
653 }
654
655 return_ACPI_STATUS (AE_OK);
656
657
658ErrorExit:
659
660 ACPI_REPORT_ERROR (("Could not update object reference count, %s\n",
661 AcpiFormatException (Status)));
662
663 return_ACPI_STATUS (Status);
664}
665
666
667/*******************************************************************************
668 *
669 * FUNCTION: AcpiUtAddReference
670 *
671 * PARAMETERS: *Object - Object whose reference count is to be
672 * incremented
673 *
674 * RETURN: None
675 *
676 * DESCRIPTION: Add one reference to an ACPI object
677 *
678 ******************************************************************************/
679
680void
681AcpiUtAddReference (
682 ACPI_OPERAND_OBJECT *Object)
683{
684
685 ACPI_FUNCTION_TRACE_PTR ("UtAddReference", Object);
686
687
688 /* Ensure that we have a valid object */
689
690 if (!AcpiUtValidInternalObject (Object))
691 {
692 return_VOID;
693 }
694
695 /* Increment the reference count */
696
697 (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
698 return_VOID;
699}
700
701
702/*******************************************************************************
703 *
704 * FUNCTION: AcpiUtRemoveReference
705 *
706 * PARAMETERS: *Object - Object whose ref count will be decremented
707 *
708 * RETURN: None
709 *
710 * DESCRIPTION: Decrement the reference count of an ACPI internal object
711 *
712 ******************************************************************************/
713
714void
715AcpiUtRemoveReference (
716 ACPI_OPERAND_OBJECT *Object)
717{
718
719 ACPI_FUNCTION_TRACE_PTR ("UtRemoveReference", Object);
720
721
722 /*
723 * Allow a NULL pointer to be passed in, just ignore it. This saves
724 * each caller from having to check. Also, ignore NS nodes.
725 *
726 */
727 if (!Object ||
728 (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))
729
730 {
731 return_VOID;
732 }
733
734 /* Ensure that we have a valid object */
735
736 if (!AcpiUtValidInternalObject (Object))
737 {
738 return_VOID;
739 }
740
741 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X\n",
742 Object, Object->Common.ReferenceCount));
743
744 /*
745 * Decrement the reference count, and only actually delete the object
746 * if the reference count becomes 0. (Must also decrement the ref count
747 * of all subobjects!)
748 */
749 (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
750 return_VOID;
751}
752
753