ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

utdelete.c
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Module Name: utdelete - object deletion and reference count utilities
00004  *
00005  ******************************************************************************/
00006 
00007 /******************************************************************************
00008  *
00009  * 1. Copyright Notice
00010  *
00011  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00012  * All rights reserved.
00013  *
00014  * 2. License
00015  *
00016  * 2.1. This is your license from Intel Corp. under its intellectual property
00017  * rights.  You may have additional license terms from the party that provided
00018  * you this software, covering your right to use that party's intellectual
00019  * property rights.
00020  *
00021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00022  * copy of the source code appearing in this file ("Covered Code") an
00023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00024  * base code distributed originally by Intel ("Original Intel Code") to copy,
00025  * make derivatives, distribute, use and display any portion of the Covered
00026  * Code in any form, with the right to sublicense such rights; and
00027  *
00028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00029  * license (with the right to sublicense), under only those claims of Intel
00030  * patents that are infringed by the Original Intel Code, to make, use, sell,
00031  * offer to sell, and import the Covered Code and derivative works thereof
00032  * solely to the minimum extent necessary to exercise the above copyright
00033  * license, and in no event shall the patent license extend to any additions
00034  * to or modifications of the Original Intel Code.  No other license or right
00035  * is granted directly or by implication, estoppel or otherwise;
00036  *
00037  * The above copyright and patent license is granted only if the following
00038  * conditions are met:
00039  *
00040  * 3. Conditions
00041  *
00042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00043  * Redistribution of source code of any substantial portion of the Covered
00044  * Code or modification with rights to further distribute source must include
00045  * the above Copyright Notice, the above License, this list of Conditions,
00046  * and the following Disclaimer and Export Compliance provision.  In addition,
00047  * Licensee must cause all Covered Code to which Licensee contributes to
00048  * contain a file documenting the changes Licensee made to create that Covered
00049  * Code and the date of any change.  Licensee must include in that file the
00050  * documentation of any changes made by any predecessor Licensee.  Licensee
00051  * must include a prominent statement that the modification is derived,
00052  * directly or indirectly, from Original Intel Code.
00053  *
00054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00055  * Redistribution of source code of any substantial portion of the Covered
00056  * Code or modification without rights to further distribute source must
00057  * include the following Disclaimer and Export Compliance provision in the
00058  * documentation and/or other materials provided with distribution.  In
00059  * addition, Licensee may not authorize further sublicense of source of any
00060  * portion of the Covered Code, and must include terms to the effect that the
00061  * license from Licensee to its licensee is limited to the intellectual
00062  * property embodied in the software Licensee provides to its licensee, and
00063  * not to intellectual property embodied in modifications its licensee may
00064  * make.
00065  *
00066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00067  * substantial portion of the Covered Code or modification must reproduce the
00068  * above Copyright Notice, and the following Disclaimer and Export Compliance
00069  * provision in the documentation and/or other materials provided with the
00070  * distribution.
00071  *
00072  * 3.4. Intel retains all right, title, and interest in and to the Original
00073  * Intel Code.
00074  *
00075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00076  * Intel shall be used in advertising or otherwise to promote the sale, use or
00077  * other dealings in products derived from or relating to the Covered Code
00078  * without prior written authorization from Intel.
00079  *
00080  * 4. Disclaimer and Export Compliance
00081  *
00082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00083  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00085  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00086  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00088  * PARTICULAR PURPOSE.
00089  *
00090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00097  * LIMITED REMEDY.
00098  *
00099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00100  * software or system incorporating such software without first obtaining any
00101  * required license or other approval from the U. S. Department of Commerce or
00102  * any other agency or department of the United States Government.  In the
00103  * event Licensee exports any such software from the United States or
00104  * re-exports any such software from a foreign destination, Licensee shall
00105  * ensure that the distribution and export/re-export of the software is in
00106  * compliance with all laws, regulations, orders, or other restrictions of the
00107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00108  * any of its subsidiaries will export/re-export any technical data, process,
00109  * software, or service, directly or indirectly, to any country for which the
00110  * United States government or any agency thereof requires an export license,
00111  * other governmental approval, or letter of assurance, without first obtaining
00112  * such license, approval or letter.
00113  *
00114  *****************************************************************************/
00115 
00116 #define __UTDELETE_C__
00117 
00118 #include "acpi.h"
00119 #include "accommon.h"
00120 #include "acinterp.h"
00121 #include "acnamesp.h"
00122 #include "acevents.h"
00123 
00124 
00125 #define _COMPONENT          ACPI_UTILITIES
00126         ACPI_MODULE_NAME    ("utdelete")
00127 
00128 /* Local prototypes */
00129 
00130 static void
00131 AcpiUtDeleteInternalObj (
00132     ACPI_OPERAND_OBJECT     *Object);
00133 
00134 static void
00135 AcpiUtUpdateRefCount (
00136     ACPI_OPERAND_OBJECT     *Object,
00137     UINT32                  Action);
00138 
00139 
00140 /*******************************************************************************
00141  *
00142  * FUNCTION:    AcpiUtDeleteInternalObj
00143  *
00144  * PARAMETERS:  Object         - Object to be deleted
00145  *
00146  * RETURN:      None
00147  *
00148  * DESCRIPTION: Low level object deletion, after reference counts have been
00149  *              updated (All reference counts, including sub-objects!)
00150  *
00151  ******************************************************************************/
00152 
00153 static void
00154 AcpiUtDeleteInternalObj (
00155     ACPI_OPERAND_OBJECT     *Object)
00156 {
00157     void                    *ObjPointer = NULL;
00158     ACPI_OPERAND_OBJECT     *HandlerDesc;
00159     ACPI_OPERAND_OBJECT     *SecondDesc;
00160     ACPI_OPERAND_OBJECT     *NextDesc;
00161     ACPI_OPERAND_OBJECT     **LastObjPtr;
00162 
00163 
00164     ACPI_FUNCTION_TRACE_PTR (UtDeleteInternalObj, Object);
00165 
00166 
00167     if (!Object)
00168     {
00169         return_VOID;
00170     }
00171 
00172     /*
00173      * Must delete or free any pointers within the object that are not
00174      * actual ACPI objects (for example, a raw buffer pointer).
00175      */
00176     switch (Object->Common.Type)
00177     {
00178     case ACPI_TYPE_STRING:
00179 
00180         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
00181             Object, Object->String.Pointer));
00182 
00183         /* Free the actual string buffer */
00184 
00185         if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
00186         {
00187             /* But only if it is NOT a pointer into an ACPI table */
00188 
00189             ObjPointer = Object->String.Pointer;
00190         }
00191         break;
00192 
00193 
00194     case ACPI_TYPE_BUFFER:
00195 
00196         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
00197             Object, Object->Buffer.Pointer));
00198 
00199         /* Free the actual buffer */
00200 
00201         if (!(Object->Common.Flags & AOPOBJ_STATIC_POINTER))
00202         {
00203             /* But only if it is NOT a pointer into an ACPI table */
00204 
00205             ObjPointer = Object->Buffer.Pointer;
00206         }
00207         break;
00208 
00209 
00210     case ACPI_TYPE_PACKAGE:
00211 
00212         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
00213             Object->Package.Count));
00214 
00215         /*
00216          * Elements of the package are not handled here, they are deleted
00217          * separately
00218          */
00219 
00220         /* Free the (variable length) element pointer array */
00221 
00222         ObjPointer = Object->Package.Elements;
00223         break;
00224 
00225 
00226     /*
00227      * These objects have a possible list of notify handlers.
00228      * Device object also may have a GPE block.
00229      */
00230     case ACPI_TYPE_DEVICE:
00231 
00232         if (Object->Device.GpeBlock)
00233         {
00234             (void) AcpiEvDeleteGpeBlock (Object->Device.GpeBlock);
00235         }
00236 
00237         /*lint -fallthrough */
00238 
00239     case ACPI_TYPE_PROCESSOR:
00240     case ACPI_TYPE_THERMAL:
00241 
00242         /* Walk the notify handler list for this object */
00243 
00244         HandlerDesc = Object->CommonNotify.Handler;
00245         while (HandlerDesc)
00246         {
00247             NextDesc = HandlerDesc->AddressSpace.Next;
00248             AcpiUtRemoveReference (HandlerDesc);
00249             HandlerDesc = NextDesc;
00250         }
00251         break;
00252 
00253 
00254     case ACPI_TYPE_MUTEX:
00255 
00256         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00257             "***** Mutex %p, OS Mutex %p\n",
00258             Object, Object->Mutex.OsMutex));
00259 
00260         if (Object == AcpiGbl_GlobalLockMutex)
00261         {
00262             /* Global Lock has extra semaphore */
00263 
00264             (void) AcpiOsDeleteSemaphore (AcpiGbl_GlobalLockSemaphore);
00265             AcpiGbl_GlobalLockSemaphore = NULL;
00266 
00267             AcpiOsDeleteMutex (Object->Mutex.OsMutex);
00268             AcpiGbl_GlobalLockMutex = NULL;
00269         }
00270         else
00271         {
00272             AcpiExUnlinkMutex (Object);
00273             AcpiOsDeleteMutex (Object->Mutex.OsMutex);
00274         }
00275         break;
00276 
00277 
00278     case ACPI_TYPE_EVENT:
00279 
00280         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00281             "***** Event %p, OS Semaphore %p\n",
00282             Object, Object->Event.OsSemaphore));
00283 
00284         (void) AcpiOsDeleteSemaphore (Object->Event.OsSemaphore);
00285         Object->Event.OsSemaphore = NULL;
00286         break;
00287 
00288 
00289     case ACPI_TYPE_METHOD:
00290 
00291         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00292             "***** Method %p\n", Object));
00293 
00294         /* Delete the method mutex if it exists */
00295 
00296         if (Object->Method.Mutex)
00297         {
00298             AcpiOsDeleteMutex (Object->Method.Mutex->Mutex.OsMutex);
00299             AcpiUtDeleteObjectDesc (Object->Method.Mutex);
00300             Object->Method.Mutex = NULL;
00301         }
00302         break;
00303 
00304 
00305     case ACPI_TYPE_REGION:
00306 
00307         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00308             "***** Region %p\n", Object));
00309 
00310         SecondDesc = AcpiNsGetSecondaryObject (Object);
00311         if (SecondDesc)
00312         {
00313             /*
00314              * Free the RegionContext if and only if the handler is one of the
00315              * default handlers -- and therefore, we created the context object
00316              * locally, it was not created by an external caller.
00317              */
00318             HandlerDesc = Object->Region.Handler;
00319             if (HandlerDesc)
00320             {
00321                 NextDesc = HandlerDesc->AddressSpace.RegionList;
00322                 LastObjPtr = &HandlerDesc->AddressSpace.RegionList;
00323 
00324                 /* Remove the region object from the handler's list */
00325 
00326                 while (NextDesc)
00327                 {
00328                     if (NextDesc == Object)
00329                     {
00330                         *LastObjPtr = NextDesc->Region.Next;
00331                         break;
00332                     }
00333 
00334                     /* Walk the linked list of handler */
00335 
00336                     LastObjPtr = &NextDesc->Region.Next;
00337                     NextDesc = NextDesc->Region.Next;
00338                 }
00339 
00340                 if (HandlerDesc->AddressSpace.HandlerFlags &
00341                     ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
00342                 {
00343                     /* Deactivate region and free region context */
00344 
00345                     if (HandlerDesc->AddressSpace.Setup)
00346                     {
00347                         (void) HandlerDesc->AddressSpace.Setup (Object,
00348                             ACPI_REGION_DEACTIVATE,
00349                             HandlerDesc->AddressSpace.Context,
00350                             &SecondDesc->Extra.RegionContext);
00351                     }
00352                 }
00353 
00354                 AcpiUtRemoveReference (HandlerDesc);
00355             }
00356 
00357             /* Now we can free the Extra object */
00358 
00359             AcpiUtDeleteObjectDesc (SecondDesc);
00360         }
00361         break;
00362 
00363 
00364     case ACPI_TYPE_BUFFER_FIELD:
00365 
00366         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00367             "***** Buffer Field %p\n", Object));
00368 
00369         SecondDesc = AcpiNsGetSecondaryObject (Object);
00370         if (SecondDesc)
00371         {
00372             AcpiUtDeleteObjectDesc (SecondDesc);
00373         }
00374         break;
00375 
00376 
00377     case ACPI_TYPE_LOCAL_BANK_FIELD:
00378 
00379         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00380             "***** Bank Field %p\n", Object));
00381 
00382         SecondDesc = AcpiNsGetSecondaryObject (Object);
00383         if (SecondDesc)
00384         {
00385             AcpiUtDeleteObjectDesc (SecondDesc);
00386         }
00387         break;
00388 
00389 
00390     default:
00391         break;
00392     }
00393 
00394     /* Free any allocated memory (pointer within the object) found above */
00395 
00396     if (ObjPointer)
00397     {
00398         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
00399             ObjPointer));
00400         ACPI_FREE (ObjPointer);
00401     }
00402 
00403     /* Now the object can be safely deleted */
00404 
00405     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
00406         Object, AcpiUtGetObjectTypeName (Object)));
00407 
00408     AcpiUtDeleteObjectDesc (Object);
00409     return_VOID;
00410 }
00411 
00412 
00413 /*******************************************************************************
00414  *
00415  * FUNCTION:    AcpiUtDeleteInternalObjectList
00416  *
00417  * PARAMETERS:  ObjList         - Pointer to the list to be deleted
00418  *
00419  * RETURN:      None
00420  *
00421  * DESCRIPTION: This function deletes an internal object list, including both
00422  *              simple objects and package objects
00423  *
00424  ******************************************************************************/
00425 
00426 void
00427 AcpiUtDeleteInternalObjectList (
00428     ACPI_OPERAND_OBJECT     **ObjList)
00429 {
00430     ACPI_OPERAND_OBJECT     **InternalObj;
00431 
00432 
00433     ACPI_FUNCTION_TRACE (UtDeleteInternalObjectList);
00434 
00435 
00436     /* Walk the null-terminated internal list */
00437 
00438     for (InternalObj = ObjList; *InternalObj; InternalObj++)
00439     {
00440         AcpiUtRemoveReference (*InternalObj);
00441     }
00442 
00443     /* Free the combined parameter pointer list and object array */
00444 
00445     ACPI_FREE (ObjList);
00446     return_VOID;
00447 }
00448 
00449 
00450 /*******************************************************************************
00451  *
00452  * FUNCTION:    AcpiUtUpdateRefCount
00453  *
00454  * PARAMETERS:  Object          - Object whose ref count is to be updated
00455  *              Action          - What to do
00456  *
00457  * RETURN:      New ref count
00458  *
00459  * DESCRIPTION: Modify the ref count and return it.
00460  *
00461  ******************************************************************************/
00462 
00463 static void
00464 AcpiUtUpdateRefCount (
00465     ACPI_OPERAND_OBJECT     *Object,
00466     UINT32                  Action)
00467 {
00468     UINT16                  Count;
00469     UINT16                  NewCount;
00470 
00471 
00472     ACPI_FUNCTION_NAME (UtUpdateRefCount);
00473 
00474 
00475     if (!Object)
00476     {
00477         return;
00478     }
00479 
00480     Count = Object->Common.ReferenceCount;
00481     NewCount = Count;
00482 
00483     /*
00484      * Perform the reference count action (increment, decrement, force delete)
00485      */
00486     switch (Action)
00487     {
00488     case REF_INCREMENT:
00489 
00490         NewCount++;
00491         Object->Common.ReferenceCount = NewCount;
00492 
00493         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00494             "Obj %p Refs=%X, [Incremented]\n",
00495             Object, NewCount));
00496         break;
00497 
00498     case REF_DECREMENT:
00499 
00500         if (Count < 1)
00501         {
00502             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00503                 "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
00504                 Object, NewCount));
00505 
00506             NewCount = 0;
00507         }
00508         else
00509         {
00510             NewCount--;
00511 
00512             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00513                 "Obj %p Refs=%X, [Decremented]\n",
00514                 Object, NewCount));
00515         }
00516 
00517         if (Object->Common.Type == ACPI_TYPE_METHOD)
00518         {
00519             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00520                 "Method Obj %p Refs=%X, [Decremented]\n", Object, NewCount));
00521         }
00522 
00523         Object->Common.ReferenceCount = NewCount;
00524         if (NewCount == 0)
00525         {
00526             AcpiUtDeleteInternalObj (Object);
00527         }
00528         break;
00529 
00530     case REF_FORCE_DELETE:
00531 
00532         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00533             "Obj %p Refs=%X, Force delete! (Set to 0)\n", Object, Count));
00534 
00535         NewCount = 0;
00536         Object->Common.ReferenceCount = NewCount;
00537         AcpiUtDeleteInternalObj (Object);
00538         break;
00539 
00540     default:
00541 
00542         ACPI_ERROR ((AE_INFO, "Unknown action (0x%X)", Action));
00543         break;
00544     }
00545 
00546     /*
00547      * Sanity check the reference count, for debug purposes only.
00548      * (A deleted object will have a huge reference count)
00549      */
00550     if (Count > ACPI_MAX_REFERENCE_COUNT)
00551     {
00552         ACPI_WARNING ((AE_INFO,
00553             "Large Reference Count (0x%X) in object %p", Count, Object));
00554     }
00555 }
00556 
00557 
00558 /*******************************************************************************
00559  *
00560  * FUNCTION:    AcpiUtUpdateObjectReference
00561  *
00562  * PARAMETERS:  Object              - Increment ref count for this object
00563  *                                    and all sub-objects
00564  *              Action              - Either REF_INCREMENT or REF_DECREMENT or
00565  *                                    REF_FORCE_DELETE
00566  *
00567  * RETURN:      Status
00568  *
00569  * DESCRIPTION: Increment the object reference count
00570  *
00571  * Object references are incremented when:
00572  * 1) An object is attached to a Node (namespace object)
00573  * 2) An object is copied (all subobjects must be incremented)
00574  *
00575  * Object references are decremented when:
00576  * 1) An object is detached from an Node
00577  *
00578  ******************************************************************************/
00579 
00580 ACPI_STATUS
00581 AcpiUtUpdateObjectReference (
00582     ACPI_OPERAND_OBJECT     *Object,
00583     UINT16                  Action)
00584 {
00585     ACPI_STATUS             Status = AE_OK;
00586     ACPI_GENERIC_STATE      *StateList = NULL;
00587     ACPI_OPERAND_OBJECT     *NextObject = NULL;
00588     ACPI_GENERIC_STATE      *State;
00589     UINT32                  i;
00590 
00591 
00592     ACPI_FUNCTION_TRACE_PTR (UtUpdateObjectReference, Object);
00593 
00594 
00595     while (Object)
00596     {
00597         /* Make sure that this isn't a namespace handle */
00598 
00599         if (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)
00600         {
00601             ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00602                 "Object %p is NS handle\n", Object));
00603             return_ACPI_STATUS (AE_OK);
00604         }
00605 
00606         /*
00607          * All sub-objects must have their reference count incremented also.
00608          * Different object types have different subobjects.
00609          */
00610         switch (Object->Common.Type)
00611         {
00612         case ACPI_TYPE_DEVICE:
00613         case ACPI_TYPE_PROCESSOR:
00614         case ACPI_TYPE_POWER:
00615         case ACPI_TYPE_THERMAL:
00616 
00617             /* Update the notify objects for these types (if present) */
00618 
00619             AcpiUtUpdateRefCount (Object->CommonNotify.SystemNotify, Action);
00620             AcpiUtUpdateRefCount (Object->CommonNotify.DeviceNotify, Action);
00621             break;
00622 
00623         case ACPI_TYPE_PACKAGE:
00624             /*
00625              * We must update all the sub-objects of the package,
00626              * each of whom may have their own sub-objects.
00627              */
00628             for (i = 0; i < Object->Package.Count; i++)
00629             {
00630                 /*
00631                  * Push each element onto the stack for later processing.
00632                  * Note: There can be null elements within the package,
00633                  * these are simply ignored
00634                  */
00635                 Status = AcpiUtCreateUpdateStateAndPush (
00636                             Object->Package.Elements[i], Action, &StateList);
00637                 if (ACPI_FAILURE (Status))
00638                 {
00639                     goto ErrorExit;
00640                 }
00641             }
00642             break;
00643 
00644         case ACPI_TYPE_BUFFER_FIELD:
00645 
00646             NextObject = Object->BufferField.BufferObj;
00647             break;
00648 
00649         case ACPI_TYPE_LOCAL_REGION_FIELD:
00650 
00651             NextObject = Object->Field.RegionObj;
00652             break;
00653 
00654         case ACPI_TYPE_LOCAL_BANK_FIELD:
00655 
00656             NextObject = Object->BankField.BankObj;
00657             Status = AcpiUtCreateUpdateStateAndPush (
00658                         Object->BankField.RegionObj, Action, &StateList);
00659             if (ACPI_FAILURE (Status))
00660             {
00661                 goto ErrorExit;
00662             }
00663             break;
00664 
00665         case ACPI_TYPE_LOCAL_INDEX_FIELD:
00666 
00667             NextObject = Object->IndexField.IndexObj;
00668             Status = AcpiUtCreateUpdateStateAndPush (
00669                         Object->IndexField.DataObj, Action, &StateList);
00670             if (ACPI_FAILURE (Status))
00671             {
00672                 goto ErrorExit;
00673             }
00674             break;
00675 
00676         case ACPI_TYPE_LOCAL_REFERENCE:
00677             /*
00678              * The target of an Index (a package, string, or buffer) or a named
00679              * reference must track changes to the ref count of the index or
00680              * target object.
00681              */
00682             if ((Object->Reference.Class == ACPI_REFCLASS_INDEX) ||
00683                 (Object->Reference.Class== ACPI_REFCLASS_NAME))
00684             {
00685                 NextObject = Object->Reference.Object;
00686             }
00687             break;
00688 
00689         case ACPI_TYPE_REGION:
00690         default:
00691             break; /* No subobjects for all other types */
00692         }
00693 
00694         /*
00695          * Now we can update the count in the main object. This can only
00696          * happen after we update the sub-objects in case this causes the
00697          * main object to be deleted.
00698          */
00699         AcpiUtUpdateRefCount (Object, Action);
00700         Object = NULL;
00701 
00702         /* Move on to the next object to be updated */
00703 
00704         if (NextObject)
00705         {
00706             Object = NextObject;
00707             NextObject = NULL;
00708         }
00709         else if (StateList)
00710         {
00711             State = AcpiUtPopGenericState (&StateList);
00712             Object = State->Update.Object;
00713             AcpiUtDeleteGenericState (State);
00714         }
00715     }
00716 
00717     return_ACPI_STATUS (AE_OK);
00718 
00719 
00720 ErrorExit:
00721 
00722     ACPI_EXCEPTION ((AE_INFO, Status,
00723         "Could not update object reference count"));
00724 
00725     /* Free any stacked Update State objects */
00726 
00727     while (StateList)
00728     {
00729         State = AcpiUtPopGenericState (&StateList);
00730         AcpiUtDeleteGenericState (State);
00731     }
00732 
00733     return_ACPI_STATUS (Status);
00734 }
00735 
00736 
00737 /*******************************************************************************
00738  *
00739  * FUNCTION:    AcpiUtAddReference
00740  *
00741  * PARAMETERS:  Object          - Object whose reference count is to be
00742  *                                incremented
00743  *
00744  * RETURN:      None
00745  *
00746  * DESCRIPTION: Add one reference to an ACPI object
00747  *
00748  ******************************************************************************/
00749 
00750 void
00751 AcpiUtAddReference (
00752     ACPI_OPERAND_OBJECT     *Object)
00753 {
00754 
00755     ACPI_FUNCTION_TRACE_PTR (UtAddReference, Object);
00756 
00757 
00758     /* Ensure that we have a valid object */
00759 
00760     if (!AcpiUtValidInternalObject (Object))
00761     {
00762         return_VOID;
00763     }
00764 
00765     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00766         "Obj %p Current Refs=%X [To Be Incremented]\n",
00767         Object, Object->Common.ReferenceCount));
00768 
00769     /* Increment the reference count */
00770 
00771     (void) AcpiUtUpdateObjectReference (Object, REF_INCREMENT);
00772     return_VOID;
00773 }
00774 
00775 
00776 /*******************************************************************************
00777  *
00778  * FUNCTION:    AcpiUtRemoveReference
00779  *
00780  * PARAMETERS:  Object         - Object whose ref count will be decremented
00781  *
00782  * RETURN:      None
00783  *
00784  * DESCRIPTION: Decrement the reference count of an ACPI internal object
00785  *
00786  ******************************************************************************/
00787 
00788 void
00789 AcpiUtRemoveReference (
00790     ACPI_OPERAND_OBJECT     *Object)
00791 {
00792 
00793     ACPI_FUNCTION_TRACE_PTR (UtRemoveReference, Object);
00794 
00795 
00796     /*
00797      * Allow a NULL pointer to be passed in, just ignore it. This saves
00798      * each caller from having to check. Also, ignore NS nodes.
00799      *
00800      */
00801     if (!Object ||
00802         (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED))
00803 
00804     {
00805         return_VOID;
00806     }
00807 
00808     /* Ensure that we have a valid object */
00809 
00810     if (!AcpiUtValidInternalObject (Object))
00811     {
00812         return_VOID;
00813     }
00814 
00815     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
00816         "Obj %p Current Refs=%X [To Be Decremented]\n",
00817         Object, Object->Common.ReferenceCount));
00818 
00819     /*
00820      * Decrement the reference count, and only actually delete the object
00821      * if the reference count becomes 0. (Must also decrement the ref count
00822      * of all subobjects!)
00823      */
00824     (void) AcpiUtUpdateObjectReference (Object, REF_DECREMENT);
00825     return_VOID;
00826 }
00827 
00828 

Generated on Sat May 26 2012 04:25:57 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.