Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

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