|
||||
Warning, cross-references for /kernel/drivers/acpica/exconfig.c need to be fixed.
0001 /****************************************************************************** 0002 * 0003 * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes) 0004 * 0005 *****************************************************************************/ 0006 0007 /****************************************************************************** 0008 * 0009 * 1. Copyright Notice 0010 * 0011 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 0012 * All rights reserved. 0013 * 0014 * 2. License 0015 * 0016 * 2.1. This is your license from Intel Corp. under its intellectual property 0017 * rights. You may have additional license terms from the party that provided 0018 * you this software, covering your right to use that party's intellectual 0019 * property rights. 0020 * 0021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0022 * copy of the source code appearing in this file ("Covered Code") an 0023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0024 * base code distributed originally by Intel ("Original Intel Code") to copy, 0025 * make derivatives, distribute, use and display any portion of the Covered 0026 * Code in any form, with the right to sublicense such rights; and 0027 * 0028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0029 * license (with the right to sublicense), under only those claims of Intel 0030 * patents that are infringed by the Original Intel Code, to make, use, sell, 0031 * offer to sell, and import the Covered Code and derivative works thereof 0032 * solely to the minimum extent necessary to exercise the above copyright 0033 * license, and in no event shall the patent license extend to any additions 0034 * to or modifications of the Original Intel Code. No other license or right 0035 * is granted directly or by implication, estoppel or otherwise; 0036 * 0037 * The above copyright and patent license is granted only if the following 0038 * conditions are met: 0039 * 0040 * 3. Conditions 0041 * 0042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0043 * Redistribution of source code of any substantial portion of the Covered 0044 * Code or modification with rights to further distribute source must include 0045 * the above Copyright Notice, the above License, this list of Conditions, 0046 * and the following Disclaimer and Export Compliance provision. In addition, 0047 * Licensee must cause all Covered Code to which Licensee contributes to 0048 * contain a file documenting the changes Licensee made to create that Covered 0049 * Code and the date of any change. Licensee must include in that file the 0050 * documentation of any changes made by any predecessor Licensee. Licensee 0051 * must include a prominent statement that the modification is derived, 0052 * directly or indirectly, from Original Intel Code. 0053 * 0054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0055 * Redistribution of source code of any substantial portion of the Covered 0056 * Code or modification without rights to further distribute source must 0057 * include the following Disclaimer and Export Compliance provision in the 0058 * documentation and/or other materials provided with distribution. In 0059 * addition, Licensee may not authorize further sublicense of source of any 0060 * portion of the Covered Code, and must include terms to the effect that the 0061 * license from Licensee to its licensee is limited to the intellectual 0062 * property embodied in the software Licensee provides to its licensee, and 0063 * not to intellectual property embodied in modifications its licensee may 0064 * make. 0065 * 0066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0067 * substantial portion of the Covered Code or modification must reproduce the 0068 * above Copyright Notice, and the following Disclaimer and Export Compliance 0069 * provision in the documentation and/or other materials provided with the 0070 * distribution. 0071 * 0072 * 3.4. Intel retains all right, title, and interest in and to the Original 0073 * Intel Code. 0074 * 0075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0076 * Intel shall be used in advertising or otherwise to promote the sale, use or 0077 * other dealings in products derived from or relating to the Covered Code 0078 * without prior written authorization from Intel. 0079 * 0080 * 4. Disclaimer and Export Compliance 0081 * 0082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0086 0087 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0088 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0089 * PARTICULAR PURPOSE. 0090 * 0091 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0092 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0093 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0094 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0095 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0096 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0097 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0098 * LIMITED REMEDY. 0099 * 0100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0101 * software or system incorporating such software without first obtaining any 0102 * required license or other approval from the U. S. Department of Commerce or 0103 * any other agency or department of the United States Government. In the 0104 * event Licensee exports any such software from the United States or 0105 * re-exports any such software from a foreign destination, Licensee shall 0106 * ensure that the distribution and export/re-export of the software is in 0107 * compliance with all laws, regulations, orders, or other restrictions of the 0108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0109 * any of its subsidiaries will export/re-export any technical data, process, 0110 * software, or service, directly or indirectly, to any country for which the 0111 * United States government or any agency thereof requires an export license, 0112 * other governmental approval, or letter of assurance, without first obtaining 0113 * such license, approval or letter. 0114 * 0115 *****************************************************************************/ 0116 0117 #define __EXCONFIG_C__ 0118 0119 #include "acpi.h" 0120 #include "accommon.h" 0121 #include "acinterp.h" 0122 #include "acnamesp.h" 0123 #include "actables.h" 0124 #include "acdispat.h" 0125 #include "acevents.h" 0126 0127 0128 #define _COMPONENT ACPI_EXECUTER 0129 ACPI_MODULE_NAME ("exconfig") 0130 0131 /* Local prototypes */ 0132 0133 static ACPI_STATUS 0134 AcpiExAddTable ( 0135 UINT32 TableIndex, 0136 ACPI_NAMESPACE_NODE *ParentNode, 0137 ACPI_OPERAND_OBJECT **DdbHandle); 0138 0139 static ACPI_STATUS 0140 AcpiExRegionRead ( 0141 ACPI_OPERAND_OBJECT *ObjDesc, 0142 UINT32 Length, 0143 UINT8 *Buffer); 0144 0145 0146 /******************************************************************************* 0147 * 0148 * FUNCTION: AcpiExAddTable 0149 * 0150 * PARAMETERS: Table - Pointer to raw table 0151 * ParentNode - Where to load the table (scope) 0152 * DdbHandle - Where to return the table handle. 0153 * 0154 * RETURN: Status 0155 * 0156 * DESCRIPTION: Common function to Install and Load an ACPI table with a 0157 * returned table handle. 0158 * 0159 ******************************************************************************/ 0160 0161 static ACPI_STATUS 0162 AcpiExAddTable ( 0163 UINT32 TableIndex, 0164 ACPI_NAMESPACE_NODE *ParentNode, 0165 ACPI_OPERAND_OBJECT **DdbHandle) 0166 { 0167 ACPI_STATUS Status; 0168 ACPI_OPERAND_OBJECT *ObjDesc; 0169 0170 0171 ACPI_FUNCTION_TRACE (ExAddTable); 0172 0173 0174 /* Create an object to be the table handle */ 0175 0176 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE); 0177 if (!ObjDesc) 0178 { 0179 return_ACPI_STATUS (AE_NO_MEMORY); 0180 } 0181 0182 /* Init the table handle */ 0183 0184 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; 0185 ObjDesc->Reference.Class = ACPI_REFCLASS_TABLE; 0186 *DdbHandle = ObjDesc; 0187 0188 /* Install the new table into the local data structures */ 0189 0190 ObjDesc->Reference.Value = TableIndex; 0191 0192 /* Add the table to the namespace */ 0193 0194 Status = AcpiNsLoadTable (TableIndex, ParentNode); 0195 if (ACPI_FAILURE (Status)) 0196 { 0197 AcpiUtRemoveReference (ObjDesc); 0198 *DdbHandle = NULL; 0199 } 0200 0201 return_ACPI_STATUS (Status); 0202 } 0203 0204 0205 /******************************************************************************* 0206 * 0207 * FUNCTION: AcpiExLoadTableOp 0208 * 0209 * PARAMETERS: WalkState - Current state with operands 0210 * ReturnDesc - Where to store the return object 0211 * 0212 * RETURN: Status 0213 * 0214 * DESCRIPTION: Load an ACPI table from the RSDT/XSDT 0215 * 0216 ******************************************************************************/ 0217 0218 ACPI_STATUS 0219 AcpiExLoadTableOp ( 0220 ACPI_WALK_STATE *WalkState, 0221 ACPI_OPERAND_OBJECT **ReturnDesc) 0222 { 0223 ACPI_STATUS Status; 0224 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 0225 ACPI_NAMESPACE_NODE *ParentNode; 0226 ACPI_NAMESPACE_NODE *StartNode; 0227 ACPI_NAMESPACE_NODE *ParameterNode = NULL; 0228 ACPI_OPERAND_OBJECT *DdbHandle; 0229 ACPI_TABLE_HEADER *Table; 0230 UINT32 TableIndex; 0231 0232 0233 ACPI_FUNCTION_TRACE (ExLoadTableOp); 0234 0235 0236 /* Validate lengths for the SignatureString, OEMIDString, OEMTableID */ 0237 0238 if ((Operand[0]->String.Length > ACPI_NAME_SIZE) || 0239 (Operand[1]->String.Length > ACPI_OEM_ID_SIZE) || 0240 (Operand[2]->String.Length > ACPI_OEM_TABLE_ID_SIZE)) 0241 { 0242 return_ACPI_STATUS (AE_BAD_PARAMETER); 0243 } 0244 0245 /* Find the ACPI table in the RSDT/XSDT */ 0246 0247 Status = AcpiTbFindTable (Operand[0]->String.Pointer, 0248 Operand[1]->String.Pointer, 0249 Operand[2]->String.Pointer, &TableIndex); 0250 if (ACPI_FAILURE (Status)) 0251 { 0252 if (Status != AE_NOT_FOUND) 0253 { 0254 return_ACPI_STATUS (Status); 0255 } 0256 0257 /* Table not found, return an Integer=0 and AE_OK */ 0258 0259 DdbHandle = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 0260 if (!DdbHandle) 0261 { 0262 return_ACPI_STATUS (AE_NO_MEMORY); 0263 } 0264 0265 DdbHandle->Integer.Value = 0; 0266 *ReturnDesc = DdbHandle; 0267 0268 return_ACPI_STATUS (AE_OK); 0269 } 0270 0271 /* Default nodes */ 0272 0273 StartNode = WalkState->ScopeInfo->Scope.Node; 0274 ParentNode = AcpiGbl_RootNode; 0275 0276 /* RootPath (optional parameter) */ 0277 0278 if (Operand[3]->String.Length > 0) 0279 { 0280 /* 0281 * Find the node referenced by the RootPathString. This is the 0282 * location within the namespace where the table will be loaded. 0283 */ 0284 Status = AcpiNsGetNode (StartNode, Operand[3]->String.Pointer, 0285 ACPI_NS_SEARCH_PARENT, &ParentNode); 0286 if (ACPI_FAILURE (Status)) 0287 { 0288 return_ACPI_STATUS (Status); 0289 } 0290 } 0291 0292 /* ParameterPath (optional parameter) */ 0293 0294 if (Operand[4]->String.Length > 0) 0295 { 0296 if ((Operand[4]->String.Pointer[0] != '\\') && 0297 (Operand[4]->String.Pointer[0] != '^')) 0298 { 0299 /* 0300 * Path is not absolute, so it will be relative to the node 0301 * referenced by the RootPathString (or the NS root if omitted) 0302 */ 0303 StartNode = ParentNode; 0304 } 0305 0306 /* Find the node referenced by the ParameterPathString */ 0307 0308 Status = AcpiNsGetNode (StartNode, Operand[4]->String.Pointer, 0309 ACPI_NS_SEARCH_PARENT, &ParameterNode); 0310 if (ACPI_FAILURE (Status)) 0311 { 0312 return_ACPI_STATUS (Status); 0313 } 0314 } 0315 0316 /* Load the table into the namespace */ 0317 0318 Status = AcpiExAddTable (TableIndex, ParentNode, &DdbHandle); 0319 if (ACPI_FAILURE (Status)) 0320 { 0321 return_ACPI_STATUS (Status); 0322 } 0323 0324 /* Parameter Data (optional) */ 0325 0326 if (ParameterNode) 0327 { 0328 /* Store the parameter data into the optional parameter object */ 0329 0330 Status = AcpiExStore (Operand[5], 0331 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParameterNode), 0332 WalkState); 0333 if (ACPI_FAILURE (Status)) 0334 { 0335 (void) AcpiExUnloadTable (DdbHandle); 0336 0337 AcpiUtRemoveReference (DdbHandle); 0338 return_ACPI_STATUS (Status); 0339 } 0340 } 0341 0342 Status = AcpiGetTableByIndex (TableIndex, &Table); 0343 if (ACPI_SUCCESS (Status)) 0344 { 0345 ACPI_INFO ((AE_INFO, 0346 "Dynamic OEM Table Load - [%.4s] OemId [%.6s] OemTableId [%.8s]", 0347 Table->Signature, Table->OemId, Table->OemTableId)); 0348 } 0349 0350 /* Invoke table handler if present */ 0351 0352 if (AcpiGbl_TableHandler) 0353 { 0354 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, 0355 AcpiGbl_TableHandlerContext); 0356 } 0357 0358 *ReturnDesc = DdbHandle; 0359 return_ACPI_STATUS (Status); 0360 } 0361 0362 0363 /******************************************************************************* 0364 * 0365 * FUNCTION: AcpiExRegionRead 0366 * 0367 * PARAMETERS: ObjDesc - Region descriptor 0368 * Length - Number of bytes to read 0369 * Buffer - Pointer to where to put the data 0370 * 0371 * RETURN: Status 0372 * 0373 * DESCRIPTION: Read data from an operation region. The read starts from the 0374 * beginning of the region. 0375 * 0376 ******************************************************************************/ 0377 0378 static ACPI_STATUS 0379 AcpiExRegionRead ( 0380 ACPI_OPERAND_OBJECT *ObjDesc, 0381 UINT32 Length, 0382 UINT8 *Buffer) 0383 { 0384 ACPI_STATUS Status; 0385 ACPI_INTEGER Value; 0386 UINT32 RegionOffset = 0; 0387 UINT32 i; 0388 0389 0390 /* Bytewise reads */ 0391 0392 for (i = 0; i < Length; i++) 0393 { 0394 Status = AcpiEvAddressSpaceDispatch (ObjDesc, ACPI_READ, 0395 RegionOffset, 8, &Value); 0396 if (ACPI_FAILURE (Status)) 0397 { 0398 return (Status); 0399 } 0400 0401 *Buffer = (UINT8) Value; 0402 Buffer++; 0403 RegionOffset++; 0404 } 0405 0406 return (AE_OK); 0407 } 0408 0409 0410 /******************************************************************************* 0411 * 0412 * FUNCTION: AcpiExLoadOp 0413 * 0414 * PARAMETERS: ObjDesc - Region or Buffer/Field where the table will be 0415 * obtained 0416 * Target - Where a handle to the table will be stored 0417 * WalkState - Current state 0418 * 0419 * RETURN: Status 0420 * 0421 * DESCRIPTION: Load an ACPI table from a field or operation region 0422 * 0423 * NOTE: Region Fields (Field, BankField, IndexFields) are resolved to buffer 0424 * objects before this code is reached. 0425 * 0426 * If source is an operation region, it must refer to SystemMemory, as 0427 * per the ACPI specification. 0428 * 0429 ******************************************************************************/ 0430 0431 ACPI_STATUS 0432 AcpiExLoadOp ( 0433 ACPI_OPERAND_OBJECT *ObjDesc, 0434 ACPI_OPERAND_OBJECT *Target, 0435 ACPI_WALK_STATE *WalkState) 0436 { 0437 ACPI_OPERAND_OBJECT *DdbHandle; 0438 ACPI_TABLE_HEADER *Table; 0439 ACPI_TABLE_DESC TableDesc; 0440 UINT32 TableIndex; 0441 ACPI_STATUS Status; 0442 UINT32 Length; 0443 0444 0445 ACPI_FUNCTION_TRACE (ExLoadOp); 0446 0447 0448 ACPI_MEMSET (&TableDesc, 0, sizeof (ACPI_TABLE_DESC)); 0449 0450 /* Source Object can be either an OpRegion or a Buffer/Field */ 0451 0452 switch (ObjDesc->Common.Type) 0453 { 0454 case ACPI_TYPE_REGION: 0455 0456 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 0457 "Load table from Region %p\n", ObjDesc)); 0458 0459 /* Region must be SystemMemory (from ACPI spec) */ 0460 0461 if (ObjDesc->Region.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) 0462 { 0463 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 0464 } 0465 0466 /* 0467 * If the Region Address and Length have not been previously evaluated, 0468 * evaluate them now and save the results. 0469 */ 0470 if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)) 0471 { 0472 Status = AcpiDsGetRegionArguments (ObjDesc); 0473 if (ACPI_FAILURE (Status)) 0474 { 0475 return_ACPI_STATUS (Status); 0476 } 0477 } 0478 0479 /* Get the table header first so we can get the table length */ 0480 0481 Table = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER)); 0482 if (!Table) 0483 { 0484 return_ACPI_STATUS (AE_NO_MEMORY); 0485 } 0486 0487 Status = AcpiExRegionRead (ObjDesc, sizeof (ACPI_TABLE_HEADER), 0488 ACPI_CAST_PTR (UINT8, Table)); 0489 Length = Table->Length; 0490 ACPI_FREE (Table); 0491 0492 if (ACPI_FAILURE (Status)) 0493 { 0494 return_ACPI_STATUS (Status); 0495 } 0496 0497 /* Must have at least an ACPI table header */ 0498 0499 if (Length < sizeof (ACPI_TABLE_HEADER)) 0500 { 0501 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); 0502 } 0503 0504 /* 0505 * The original implementation simply mapped the table, with no copy. 0506 * However, the memory region is not guaranteed to remain stable and 0507 * we must copy the table to a local buffer. For example, the memory 0508 * region is corrupted after suspend on some machines. Dynamically 0509 * loaded tables are usually small, so this overhead is minimal. 0510 * 0511 * The latest implementation (5/2009) does not use a mapping at all. 0512 * We use the low-level operation region interface to read the table 0513 * instead of the obvious optimization of using a direct mapping. 0514 * This maintains a consistent use of operation regions across the 0515 * entire subsystem. This is important if additional processing must 0516 * be performed in the (possibly user-installed) operation region 0517 * handler. For example, AcpiExec and ASLTS depend on this. 0518 */ 0519 0520 /* Allocate a buffer for the table */ 0521 0522 TableDesc.Pointer = ACPI_ALLOCATE (Length); 0523 if (!TableDesc.Pointer) 0524 { 0525 return_ACPI_STATUS (AE_NO_MEMORY); 0526 } 0527 0528 /* Read the entire table */ 0529 0530 Status = AcpiExRegionRead (ObjDesc, Length, 0531 ACPI_CAST_PTR (UINT8, TableDesc.Pointer)); 0532 if (ACPI_FAILURE (Status)) 0533 { 0534 ACPI_FREE (TableDesc.Pointer); 0535 return_ACPI_STATUS (Status); 0536 } 0537 0538 TableDesc.Address = ObjDesc->Region.Address; 0539 break; 0540 0541 0542 case ACPI_TYPE_BUFFER: /* Buffer or resolved RegionField */ 0543 0544 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 0545 "Load table from Buffer or Field %p\n", ObjDesc)); 0546 0547 /* Must have at least an ACPI table header */ 0548 0549 if (ObjDesc->Buffer.Length < sizeof (ACPI_TABLE_HEADER)) 0550 { 0551 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); 0552 } 0553 0554 /* Get the actual table length from the table header */ 0555 0556 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer); 0557 Length = Table->Length; 0558 0559 /* Table cannot extend beyond the buffer */ 0560 0561 if (Length > ObjDesc->Buffer.Length) 0562 { 0563 return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); 0564 } 0565 if (Length < sizeof (ACPI_TABLE_HEADER)) 0566 { 0567 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); 0568 } 0569 0570 /* 0571 * Copy the table from the buffer because the buffer could be modified 0572 * or even deleted in the future 0573 */ 0574 TableDesc.Pointer = ACPI_ALLOCATE (Length); 0575 if (!TableDesc.Pointer) 0576 { 0577 return_ACPI_STATUS (AE_NO_MEMORY); 0578 } 0579 0580 ACPI_MEMCPY (TableDesc.Pointer, Table, Length); 0581 TableDesc.Address = ACPI_TO_INTEGER (TableDesc.Pointer); 0582 break; 0583 0584 0585 default: 0586 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 0587 } 0588 0589 /* Validate table checksum (will not get validated in TbAddTable) */ 0590 0591 Status = AcpiTbVerifyChecksum (TableDesc.Pointer, Length); 0592 if (ACPI_FAILURE (Status)) 0593 { 0594 ACPI_FREE (TableDesc.Pointer); 0595 return_ACPI_STATUS (Status); 0596 } 0597 0598 /* Complete the table descriptor */ 0599 0600 TableDesc.Length = Length; 0601 TableDesc.Flags = ACPI_TABLE_ORIGIN_ALLOCATED; 0602 0603 /* Install the new table into the local data structures */ 0604 0605 Status = AcpiTbAddTable (&TableDesc, &TableIndex); 0606 if (ACPI_FAILURE (Status)) 0607 { 0608 goto Cleanup; 0609 } 0610 0611 /* 0612 * Add the table to the namespace. 0613 * 0614 * Note: Load the table objects relative to the root of the namespace. 0615 * This appears to go against the ACPI specification, but we do it for 0616 * compatibility with other ACPI implementations. 0617 */ 0618 Status = AcpiExAddTable (TableIndex, AcpiGbl_RootNode, &DdbHandle); 0619 if (ACPI_FAILURE (Status)) 0620 { 0621 /* On error, TablePtr was deallocated above */ 0622 0623 return_ACPI_STATUS (Status); 0624 } 0625 0626 /* Store the DdbHandle into the Target operand */ 0627 0628 Status = AcpiExStore (DdbHandle, Target, WalkState); 0629 if (ACPI_FAILURE (Status)) 0630 { 0631 (void) AcpiExUnloadTable (DdbHandle); 0632 0633 /* TablePtr was deallocated above */ 0634 0635 AcpiUtRemoveReference (DdbHandle); 0636 return_ACPI_STATUS (Status); 0637 } 0638 0639 /* Remove the reference by added by AcpiExStore above */ 0640 0641 AcpiUtRemoveReference (DdbHandle); 0642 0643 /* Invoke table handler if present */ 0644 0645 if (AcpiGbl_TableHandler) 0646 { 0647 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, TableDesc.Pointer, 0648 AcpiGbl_TableHandlerContext); 0649 } 0650 0651 Cleanup: 0652 if (ACPI_FAILURE (Status)) 0653 { 0654 /* Delete allocated table buffer */ 0655 0656 AcpiTbDeleteTable (&TableDesc); 0657 } 0658 return_ACPI_STATUS (Status); 0659 } 0660 0661 0662 /******************************************************************************* 0663 * 0664 * FUNCTION: AcpiExUnloadTable 0665 * 0666 * PARAMETERS: DdbHandle - Handle to a previously loaded table 0667 * 0668 * RETURN: Status 0669 * 0670 * DESCRIPTION: Unload an ACPI table 0671 * 0672 ******************************************************************************/ 0673 0674 ACPI_STATUS 0675 AcpiExUnloadTable ( 0676 ACPI_OPERAND_OBJECT *DdbHandle) 0677 { 0678 ACPI_STATUS Status = AE_OK; 0679 ACPI_OPERAND_OBJECT *TableDesc = DdbHandle; 0680 UINT32 TableIndex; 0681 ACPI_TABLE_HEADER *Table; 0682 0683 0684 ACPI_FUNCTION_TRACE (ExUnloadTable); 0685 0686 0687 /* 0688 * Validate the handle 0689 * Although the handle is partially validated in AcpiExReconfiguration() 0690 * when it calls AcpiExResolveOperands(), the handle is more completely 0691 * validated here. 0692 * 0693 * Handle must be a valid operand object of type reference. Also, the 0694 * DdbHandle must still be marked valid (table has not been previously 0695 * unloaded) 0696 */ 0697 if ((!DdbHandle) || 0698 (ACPI_GET_DESCRIPTOR_TYPE (DdbHandle) != ACPI_DESC_TYPE_OPERAND) || 0699 (DdbHandle->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) || 0700 (!(DdbHandle->Common.Flags & AOPOBJ_DATA_VALID))) 0701 { 0702 return_ACPI_STATUS (AE_BAD_PARAMETER); 0703 } 0704 0705 /* Get the table index from the DdbHandle */ 0706 0707 TableIndex = TableDesc->Reference.Value; 0708 0709 /* Ensure the table is still loaded */ 0710 0711 if (!AcpiTbIsTableLoaded (TableIndex)) 0712 { 0713 return_ACPI_STATUS (AE_NOT_EXIST); 0714 } 0715 0716 /* Invoke table handler if present */ 0717 0718 if (AcpiGbl_TableHandler) 0719 { 0720 Status = AcpiGetTableByIndex (TableIndex, &Table); 0721 if (ACPI_SUCCESS (Status)) 0722 { 0723 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table, 0724 AcpiGbl_TableHandlerContext); 0725 } 0726 } 0727 0728 /* Delete the portion of the namespace owned by this table */ 0729 0730 Status = AcpiTbDeleteNamespaceByOwner (TableIndex); 0731 if (ACPI_FAILURE (Status)) 0732 { 0733 return_ACPI_STATUS (Status); 0734 } 0735 0736 (void) AcpiTbReleaseOwnerId (TableIndex); 0737 AcpiTbSetTableLoadedFlag (TableIndex, FALSE); 0738 0739 /* 0740 * Invalidate the handle. We do this because the handle may be stored 0741 * in a named object and may not be actually deleted until much later. 0742 */ 0743 DdbHandle->Common.Flags &= ~AOPOBJ_DATA_VALID; 0744 return_ACPI_STATUS (AE_OK); 0745 } 0746
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 1.2.0 LXR engine. |