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

exconfig.c
Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
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 
00087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00089  * PARTICULAR PURPOSE.
00090  *
00091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00098  * LIMITED REMEDY.
00099  *
00100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00101  * software or system incorporating such software without first obtaining any
00102  * required license or other approval from the U. S. Department of Commerce or
00103  * any other agency or department of the United States Government.  In the
00104  * event Licensee exports any such software from the United States or
00105  * re-exports any such software from a foreign destination, Licensee shall
00106  * ensure that the distribution and export/re-export of the software is in
00107  * compliance with all laws, regulations, orders, or other restrictions of the
00108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00109  * any of its subsidiaries will export/re-export any technical data, process,
00110  * software, or service, directly or indirectly, to any country for which the
00111  * United States government or any agency thereof requires an export license,
00112  * other governmental approval, or letter of assurance, without first obtaining
00113  * such license, approval or letter.
00114  *
00115  *****************************************************************************/
00116 
00117 #define __EXCONFIG_C__
00118 
00119 #include "acpi.h"
00120 #include "accommon.h"
00121 #include "acinterp.h"
00122 #include "acnamesp.h"
00123 #include "actables.h"
00124 #include "acdispat.h"
00125 #include "acevents.h"
00126 
00127 
00128 #define _COMPONENT          ACPI_EXECUTER
00129         ACPI_MODULE_NAME    ("exconfig")
00130 
00131 /* Local prototypes */
00132 
00133 static ACPI_STATUS
00134 AcpiExAddTable (
00135     UINT32                  TableIndex,
00136     ACPI_NAMESPACE_NODE     *ParentNode,
00137     ACPI_OPERAND_OBJECT     **DdbHandle);
00138 
00139 static ACPI_STATUS
00140 AcpiExRegionRead (
00141     ACPI_OPERAND_OBJECT     *ObjDesc,
00142     UINT32                  Length,
00143     UINT8                   *Buffer);
00144 
00145 
00146 /*******************************************************************************
00147  *
00148  * FUNCTION:    AcpiExAddTable
00149  *
00150  * PARAMETERS:  Table               - Pointer to raw table
00151  *              ParentNode          - Where to load the table (scope)
00152  *              DdbHandle           - Where to return the table handle.
00153  *
00154  * RETURN:      Status
00155  *
00156  * DESCRIPTION: Common function to Install and Load an ACPI table with a
00157  *              returned table handle.
00158  *
00159  ******************************************************************************/
00160 
00161 static ACPI_STATUS
00162 AcpiExAddTable (
00163     UINT32                  TableIndex,
00164     ACPI_NAMESPACE_NODE     *ParentNode,
00165     ACPI_OPERAND_OBJECT     **DdbHandle)
00166 {
00167     ACPI_OPERAND_OBJECT     *ObjDesc;
00168     ACPI_STATUS             Status;
00169     ACPI_OWNER_ID           OwnerId;
00170 
00171 
00172     ACPI_FUNCTION_TRACE (ExAddTable);
00173 
00174 
00175     /* Create an object to be the table handle */
00176 
00177     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
00178     if (!ObjDesc)
00179     {
00180         return_ACPI_STATUS (AE_NO_MEMORY);
00181     }
00182 
00183     /* Init the table handle */
00184 
00185     ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
00186     ObjDesc->Reference.Class = ACPI_REFCLASS_TABLE;
00187     *DdbHandle = ObjDesc;
00188 
00189     /* Install the new table into the local data structures */
00190 
00191     ObjDesc->Reference.Value = TableIndex;
00192 
00193     /* Add the table to the namespace */
00194 
00195     Status = AcpiNsLoadTable (TableIndex, ParentNode);
00196     if (ACPI_FAILURE (Status))
00197     {
00198         AcpiUtRemoveReference (ObjDesc);
00199         *DdbHandle = NULL;
00200         return_ACPI_STATUS (Status);
00201     }
00202 
00203     /* Execute any module-level code that was found in the table */
00204 
00205     AcpiExExitInterpreter ();
00206     AcpiNsExecModuleCodeList ();
00207     AcpiExEnterInterpreter ();
00208 
00209     /*
00210      * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
00211      * responsible for discovering any new wake GPEs by running _PRW methods
00212      * that may have been loaded by this table.
00213      */
00214     Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
00215     if (ACPI_SUCCESS (Status))
00216     {
00217         AcpiEvUpdateGpes (OwnerId);
00218     }
00219 
00220     return_ACPI_STATUS (AE_OK);
00221 }
00222 
00223 
00224 /*******************************************************************************
00225  *
00226  * FUNCTION:    AcpiExLoadTableOp
00227  *
00228  * PARAMETERS:  WalkState           - Current state with operands
00229  *              ReturnDesc          - Where to store the return object
00230  *
00231  * RETURN:      Status
00232  *
00233  * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
00234  *
00235  ******************************************************************************/
00236 
00237 ACPI_STATUS
00238 AcpiExLoadTableOp (
00239     ACPI_WALK_STATE         *WalkState,
00240     ACPI_OPERAND_OBJECT     **ReturnDesc)
00241 {
00242     ACPI_STATUS             Status;
00243     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
00244     ACPI_NAMESPACE_NODE     *ParentNode;
00245     ACPI_NAMESPACE_NODE     *StartNode;
00246     ACPI_NAMESPACE_NODE     *ParameterNode = NULL;
00247     ACPI_OPERAND_OBJECT     *DdbHandle;
00248     ACPI_TABLE_HEADER       *Table;
00249     UINT32                  TableIndex;
00250 
00251 
00252     ACPI_FUNCTION_TRACE (ExLoadTableOp);
00253 
00254 
00255     /* Validate lengths for the SignatureString, OEMIDString, OEMTableID */
00256 
00257     if ((Operand[0]->String.Length > ACPI_NAME_SIZE) ||
00258         (Operand[1]->String.Length > ACPI_OEM_ID_SIZE) ||
00259         (Operand[2]->String.Length > ACPI_OEM_TABLE_ID_SIZE))
00260     {
00261         return_ACPI_STATUS (AE_BAD_PARAMETER);
00262     }
00263 
00264     /* Find the ACPI table in the RSDT/XSDT */
00265 
00266     Status = AcpiTbFindTable (Operand[0]->String.Pointer,
00267                               Operand[1]->String.Pointer,
00268                               Operand[2]->String.Pointer, &TableIndex);
00269     if (ACPI_FAILURE (Status))
00270     {
00271         if (Status != AE_NOT_FOUND)
00272         {
00273             return_ACPI_STATUS (Status);
00274         }
00275 
00276         /* Table not found, return an Integer=0 and AE_OK */
00277 
00278         DdbHandle = AcpiUtCreateIntegerObject ((UINT64) 0);
00279         if (!DdbHandle)
00280         {
00281             return_ACPI_STATUS (AE_NO_MEMORY);
00282         }
00283 
00284         *ReturnDesc = DdbHandle;
00285         return_ACPI_STATUS (AE_OK);
00286     }
00287 
00288     /* Default nodes */
00289 
00290     StartNode = WalkState->ScopeInfo->Scope.Node;
00291     ParentNode = AcpiGbl_RootNode;
00292 
00293     /* RootPath (optional parameter) */
00294 
00295     if (Operand[3]->String.Length > 0)
00296     {
00297         /*
00298          * Find the node referenced by the RootPathString.  This is the
00299          * location within the namespace where the table will be loaded.
00300          */
00301         Status = AcpiNsGetNode (StartNode, Operand[3]->String.Pointer,
00302                     ACPI_NS_SEARCH_PARENT, &ParentNode);
00303         if (ACPI_FAILURE (Status))
00304         {
00305             return_ACPI_STATUS (Status);
00306         }
00307     }
00308 
00309     /* ParameterPath (optional parameter) */
00310 
00311     if (Operand[4]->String.Length > 0)
00312     {
00313         if ((Operand[4]->String.Pointer[0] != '\\') &&
00314             (Operand[4]->String.Pointer[0] != '^'))
00315         {
00316             /*
00317              * Path is not absolute, so it will be relative to the node
00318              * referenced by the RootPathString (or the NS root if omitted)
00319              */
00320             StartNode = ParentNode;
00321         }
00322 
00323         /* Find the node referenced by the ParameterPathString */
00324 
00325         Status = AcpiNsGetNode (StartNode, Operand[4]->String.Pointer,
00326                     ACPI_NS_SEARCH_PARENT, &ParameterNode);
00327         if (ACPI_FAILURE (Status))
00328         {
00329             return_ACPI_STATUS (Status);
00330         }
00331     }
00332 
00333     /* Load the table into the namespace */
00334 
00335     Status = AcpiExAddTable (TableIndex, ParentNode, &DdbHandle);
00336     if (ACPI_FAILURE (Status))
00337     {
00338         return_ACPI_STATUS (Status);
00339     }
00340 
00341     /* Parameter Data (optional) */
00342 
00343     if (ParameterNode)
00344     {
00345         /* Store the parameter data into the optional parameter object */
00346 
00347         Status = AcpiExStore (Operand[5],
00348                     ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParameterNode),
00349                     WalkState);
00350         if (ACPI_FAILURE (Status))
00351         {
00352             (void) AcpiExUnloadTable (DdbHandle);
00353 
00354             AcpiUtRemoveReference (DdbHandle);
00355             return_ACPI_STATUS (Status);
00356         }
00357     }
00358 
00359     Status = AcpiGetTableByIndex (TableIndex, &Table);
00360     if (ACPI_SUCCESS (Status))
00361     {
00362         ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:"));
00363         AcpiTbPrintTableHeader (0, Table);
00364     }
00365 
00366     /* Invoke table handler if present */
00367 
00368     if (AcpiGbl_TableHandler)
00369     {
00370         (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
00371                     AcpiGbl_TableHandlerContext);
00372     }
00373 
00374     *ReturnDesc = DdbHandle;
00375     return_ACPI_STATUS  (Status);
00376 }
00377 
00378 
00379 /*******************************************************************************
00380  *
00381  * FUNCTION:    AcpiExRegionRead
00382  *
00383  * PARAMETERS:  ObjDesc         - Region descriptor
00384  *              Length          - Number of bytes to read
00385  *              Buffer          - Pointer to where to put the data
00386  *
00387  * RETURN:      Status
00388  *
00389  * DESCRIPTION: Read data from an operation region. The read starts from the
00390  *              beginning of the region.
00391  *
00392  ******************************************************************************/
00393 
00394 static ACPI_STATUS
00395 AcpiExRegionRead (
00396     ACPI_OPERAND_OBJECT     *ObjDesc,
00397     UINT32                  Length,
00398     UINT8                   *Buffer)
00399 {
00400     ACPI_STATUS             Status;
00401     UINT64                  Value;
00402     UINT32                  RegionOffset = 0;
00403     UINT32                  i;
00404 
00405 
00406     /* Bytewise reads */
00407 
00408     for (i = 0; i < Length; i++)
00409     {
00410         Status = AcpiEvAddressSpaceDispatch (ObjDesc, ACPI_READ,
00411                     RegionOffset, 8, &Value);
00412         if (ACPI_FAILURE (Status))
00413         {
00414             return (Status);
00415         }
00416 
00417         *Buffer = (UINT8) Value;
00418         Buffer++;
00419         RegionOffset++;
00420     }
00421 
00422     return (AE_OK);
00423 }
00424 
00425 
00426 /*******************************************************************************
00427  *
00428  * FUNCTION:    AcpiExLoadOp
00429  *
00430  * PARAMETERS:  ObjDesc         - Region or Buffer/Field where the table will be
00431  *                                obtained
00432  *              Target          - Where a handle to the table will be stored
00433  *              WalkState       - Current state
00434  *
00435  * RETURN:      Status
00436  *
00437  * DESCRIPTION: Load an ACPI table from a field or operation region
00438  *
00439  * NOTE: Region Fields (Field, BankField, IndexFields) are resolved to buffer
00440  *       objects before this code is reached.
00441  *
00442  *       If source is an operation region, it must refer to SystemMemory, as
00443  *       per the ACPI specification.
00444  *
00445  ******************************************************************************/
00446 
00447 ACPI_STATUS
00448 AcpiExLoadOp (
00449     ACPI_OPERAND_OBJECT     *ObjDesc,
00450     ACPI_OPERAND_OBJECT     *Target,
00451     ACPI_WALK_STATE         *WalkState)
00452 {
00453     ACPI_OPERAND_OBJECT     *DdbHandle;
00454     ACPI_TABLE_HEADER       *Table;
00455     ACPI_TABLE_DESC         TableDesc;
00456     UINT32                  TableIndex;
00457     ACPI_STATUS             Status;
00458     UINT32                  Length;
00459 
00460 
00461     ACPI_FUNCTION_TRACE (ExLoadOp);
00462 
00463 
00464     ACPI_MEMSET (&TableDesc, 0, sizeof (ACPI_TABLE_DESC));
00465 
00466     /* Source Object can be either an OpRegion or a Buffer/Field */
00467 
00468     switch (ObjDesc->Common.Type)
00469     {
00470     case ACPI_TYPE_REGION:
00471 
00472         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
00473             "Load table from Region %p\n", ObjDesc));
00474 
00475         /* Region must be SystemMemory (from ACPI spec) */
00476 
00477         if (ObjDesc->Region.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY)
00478         {
00479             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
00480         }
00481 
00482         /*
00483          * If the Region Address and Length have not been previously evaluated,
00484          * evaluate them now and save the results.
00485          */
00486         if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
00487         {
00488             Status = AcpiDsGetRegionArguments (ObjDesc);
00489             if (ACPI_FAILURE (Status))
00490             {
00491                 return_ACPI_STATUS (Status);
00492             }
00493         }
00494 
00495         /* Get the table header first so we can get the table length */
00496 
00497         Table = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER));
00498         if (!Table)
00499         {
00500             return_ACPI_STATUS (AE_NO_MEMORY);
00501         }
00502 
00503         Status = AcpiExRegionRead (ObjDesc, sizeof (ACPI_TABLE_HEADER),
00504                     ACPI_CAST_PTR (UINT8, Table));
00505         Length = Table->Length;
00506         ACPI_FREE (Table);
00507 
00508         if (ACPI_FAILURE (Status))
00509         {
00510             return_ACPI_STATUS (Status);
00511         }
00512 
00513         /* Must have at least an ACPI table header */
00514 
00515         if (Length < sizeof (ACPI_TABLE_HEADER))
00516         {
00517             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
00518         }
00519 
00520         /*
00521          * The original implementation simply mapped the table, with no copy.
00522          * However, the memory region is not guaranteed to remain stable and
00523          * we must copy the table to a local buffer. For example, the memory
00524          * region is corrupted after suspend on some machines. Dynamically
00525          * loaded tables are usually small, so this overhead is minimal.
00526          *
00527          * The latest implementation (5/2009) does not use a mapping at all.
00528          * We use the low-level operation region interface to read the table
00529          * instead of the obvious optimization of using a direct mapping.
00530          * This maintains a consistent use of operation regions across the
00531          * entire subsystem. This is important if additional processing must
00532          * be performed in the (possibly user-installed) operation region
00533          * handler. For example, AcpiExec and ASLTS depend on this.
00534          */
00535 
00536         /* Allocate a buffer for the table */
00537 
00538         TableDesc.Pointer = ACPI_ALLOCATE (Length);
00539         if (!TableDesc.Pointer)
00540         {
00541             return_ACPI_STATUS (AE_NO_MEMORY);
00542         }
00543 
00544         /* Read the entire table */
00545 
00546         Status = AcpiExRegionRead (ObjDesc, Length,
00547                     ACPI_CAST_PTR (UINT8, TableDesc.Pointer));
00548         if (ACPI_FAILURE (Status))
00549         {
00550             ACPI_FREE (TableDesc.Pointer);
00551             return_ACPI_STATUS (Status);
00552         }
00553 
00554         TableDesc.Address = ObjDesc->Region.Address;
00555         break;
00556 
00557 
00558     case ACPI_TYPE_BUFFER: /* Buffer or resolved RegionField */
00559 
00560         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
00561             "Load table from Buffer or Field %p\n", ObjDesc));
00562 
00563         /* Must have at least an ACPI table header */
00564 
00565         if (ObjDesc->Buffer.Length < sizeof (ACPI_TABLE_HEADER))
00566         {
00567             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
00568         }
00569 
00570         /* Get the actual table length from the table header */
00571 
00572         Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer);
00573         Length = Table->Length;
00574 
00575         /* Table cannot extend beyond the buffer */
00576 
00577         if (Length > ObjDesc->Buffer.Length)
00578         {
00579             return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
00580         }
00581         if (Length < sizeof (ACPI_TABLE_HEADER))
00582         {
00583             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
00584         }
00585 
00586         /*
00587          * Copy the table from the buffer because the buffer could be modified
00588          * or even deleted in the future
00589          */
00590         TableDesc.Pointer = ACPI_ALLOCATE (Length);
00591         if (!TableDesc.Pointer)
00592         {
00593             return_ACPI_STATUS (AE_NO_MEMORY);
00594         }
00595 
00596         ACPI_MEMCPY (TableDesc.Pointer, Table, Length);
00597         TableDesc.Address = ACPI_TO_INTEGER (TableDesc.Pointer);
00598         break;
00599 
00600 
00601     default:
00602         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
00603     }
00604 
00605     /* Validate table checksum (will not get validated in TbAddTable) */
00606 
00607     Status = AcpiTbVerifyChecksum (TableDesc.Pointer, Length);
00608     if (ACPI_FAILURE (Status))
00609     {
00610         ACPI_FREE (TableDesc.Pointer);
00611         return_ACPI_STATUS (Status);
00612     }
00613 
00614     /* Complete the table descriptor */
00615 
00616     TableDesc.Length = Length;
00617     TableDesc.Flags = ACPI_TABLE_ORIGIN_ALLOCATED;
00618 
00619     /* Install the new table into the local data structures */
00620 
00621     Status = AcpiTbAddTable (&TableDesc, &TableIndex);
00622     if (ACPI_FAILURE (Status))
00623     {
00624         /* Delete allocated table buffer */
00625 
00626         AcpiTbDeleteTable (&TableDesc);
00627         return_ACPI_STATUS (Status);
00628     }
00629 
00630     /*
00631      * Add the table to the namespace.
00632      *
00633      * Note: Load the table objects relative to the root of the namespace.
00634      * This appears to go against the ACPI specification, but we do it for
00635      * compatibility with other ACPI implementations.
00636      */
00637     Status = AcpiExAddTable (TableIndex, AcpiGbl_RootNode, &DdbHandle);
00638     if (ACPI_FAILURE (Status))
00639     {
00640         /* On error, TablePtr was deallocated above */
00641 
00642         return_ACPI_STATUS (Status);
00643     }
00644 
00645     /* Store the DdbHandle into the Target operand */
00646 
00647     Status = AcpiExStore (DdbHandle, Target, WalkState);
00648     if (ACPI_FAILURE (Status))
00649     {
00650         (void) AcpiExUnloadTable (DdbHandle);
00651 
00652         /* TablePtr was deallocated above */
00653 
00654         AcpiUtRemoveReference (DdbHandle);
00655         return_ACPI_STATUS (Status);
00656     }
00657 
00658     ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:"));
00659     AcpiTbPrintTableHeader (0, TableDesc.Pointer);
00660 
00661     /* Remove the reference by added by AcpiExStore above */
00662 
00663     AcpiUtRemoveReference (DdbHandle);
00664 
00665     /* Invoke table handler if present */
00666 
00667     if (AcpiGbl_TableHandler)
00668     {
00669         (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, TableDesc.Pointer,
00670                     AcpiGbl_TableHandlerContext);
00671     }
00672 
00673     return_ACPI_STATUS (Status);
00674 }
00675 
00676 
00677 /*******************************************************************************
00678  *
00679  * FUNCTION:    AcpiExUnloadTable
00680  *
00681  * PARAMETERS:  DdbHandle           - Handle to a previously loaded table
00682  *
00683  * RETURN:      Status
00684  *
00685  * DESCRIPTION: Unload an ACPI table
00686  *
00687  ******************************************************************************/
00688 
00689 ACPI_STATUS
00690 AcpiExUnloadTable (
00691     ACPI_OPERAND_OBJECT     *DdbHandle)
00692 {
00693     ACPI_STATUS             Status = AE_OK;
00694     ACPI_OPERAND_OBJECT     *TableDesc = DdbHandle;
00695     UINT32                  TableIndex;
00696     ACPI_TABLE_HEADER       *Table;
00697 
00698 
00699     ACPI_FUNCTION_TRACE (ExUnloadTable);
00700 
00701 
00702     /*
00703      * Validate the handle
00704      * Although the handle is partially validated in AcpiExReconfiguration()
00705      * when it calls AcpiExResolveOperands(), the handle is more completely
00706      * validated here.
00707      *
00708      * Handle must be a valid operand object of type reference. Also, the
00709      * DdbHandle must still be marked valid (table has not been previously
00710      * unloaded)
00711      */
00712     if ((!DdbHandle) ||
00713         (ACPI_GET_DESCRIPTOR_TYPE (DdbHandle) != ACPI_DESC_TYPE_OPERAND) ||
00714         (DdbHandle->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) ||
00715         (!(DdbHandle->Common.Flags & AOPOBJ_DATA_VALID)))
00716     {
00717         return_ACPI_STATUS (AE_BAD_PARAMETER);
00718     }
00719 
00720     /* Get the table index from the DdbHandle */
00721 
00722     TableIndex = TableDesc->Reference.Value;
00723 
00724     /* Ensure the table is still loaded */
00725 
00726     if (!AcpiTbIsTableLoaded (TableIndex))
00727     {
00728         return_ACPI_STATUS (AE_NOT_EXIST);
00729     }
00730 
00731     /* Invoke table handler if present */
00732 
00733     if (AcpiGbl_TableHandler)
00734     {
00735         Status = AcpiGetTableByIndex (TableIndex, &Table);
00736         if (ACPI_SUCCESS (Status))
00737         {
00738             (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table,
00739                         AcpiGbl_TableHandlerContext);
00740         }
00741     }
00742 
00743     /* Delete the portion of the namespace owned by this table */
00744 
00745     Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
00746     if (ACPI_FAILURE (Status))
00747     {
00748         return_ACPI_STATUS (Status);
00749     }
00750 
00751     (void) AcpiTbReleaseOwnerId (TableIndex);
00752     AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
00753 
00754     /*
00755      * Invalidate the handle. We do this because the handle may be stored
00756      * in a named object and may not be actually deleted until much later.
00757      */
00758     DdbHandle->Common.Flags &= ~AOPOBJ_DATA_VALID;
00759     return_ACPI_STATUS (AE_OK);
00760 }
00761 

Generated on Thu May 24 2012 04:27:46 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.