[BACK]Return to exconfig.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / external / bsd / acpica / dist / executer

Annotation of src/sys/external/bsd/acpica/dist/executer/exconfig.c, Revision 1.5.2.1

1.1       jruoho      1: /******************************************************************************
                      2:  *
                      3:  * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
                      4:  *
                      5:  *****************************************************************************/
                      6:
1.3       jruoho      7: /*
1.5.2.1 ! skrll       8:  * Copyright (C) 2000 - 2015, Intel Corp.
1.1       jruoho      9:  * All rights reserved.
                     10:  *
1.3       jruoho     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions, and the following disclaimer,
                     16:  *    without modification.
                     17:  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
                     18:  *    substantially similar to the "NO WARRANTY" disclaimer below
                     19:  *    ("Disclaimer") and any redistribution must be conditioned upon
                     20:  *    including a substantially similar Disclaimer requirement for further
                     21:  *    binary redistribution.
                     22:  * 3. Neither the names of the above-listed copyright holders nor the names
                     23:  *    of any contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * Alternatively, this software may be distributed under the terms of the
                     27:  * GNU General Public License ("GPL") version 2 as published by the Free
                     28:  * Software Foundation.
                     29:  *
                     30:  * NO WARRANTY
                     31:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
                     32:  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     33:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
                     34:  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
                     35:  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     36:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     37:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     38:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     39:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
                     40:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     41:  * POSSIBILITY OF SUCH DAMAGES.
                     42:  */
1.1       jruoho     43:
                     44: #include "acpi.h"
                     45: #include "accommon.h"
                     46: #include "acinterp.h"
                     47: #include "acnamesp.h"
                     48: #include "actables.h"
                     49: #include "acdispat.h"
                     50: #include "acevents.h"
1.4       christos   51: #include "amlcode.h"
1.1       jruoho     52:
                     53:
                     54: #define _COMPONENT          ACPI_EXECUTER
                     55:         ACPI_MODULE_NAME    ("exconfig")
                     56:
                     57: /* Local prototypes */
                     58:
                     59: static ACPI_STATUS
                     60: AcpiExAddTable (
                     61:     UINT32                  TableIndex,
                     62:     ACPI_NAMESPACE_NODE     *ParentNode,
                     63:     ACPI_OPERAND_OBJECT     **DdbHandle);
                     64:
                     65: static ACPI_STATUS
                     66: AcpiExRegionRead (
                     67:     ACPI_OPERAND_OBJECT     *ObjDesc,
                     68:     UINT32                  Length,
                     69:     UINT8                   *Buffer);
                     70:
                     71:
                     72: /*******************************************************************************
                     73:  *
                     74:  * FUNCTION:    AcpiExAddTable
                     75:  *
                     76:  * PARAMETERS:  Table               - Pointer to raw table
                     77:  *              ParentNode          - Where to load the table (scope)
                     78:  *              DdbHandle           - Where to return the table handle.
                     79:  *
                     80:  * RETURN:      Status
                     81:  *
                     82:  * DESCRIPTION: Common function to Install and Load an ACPI table with a
                     83:  *              returned table handle.
                     84:  *
                     85:  ******************************************************************************/
                     86:
                     87: static ACPI_STATUS
                     88: AcpiExAddTable (
                     89:     UINT32                  TableIndex,
                     90:     ACPI_NAMESPACE_NODE     *ParentNode,
                     91:     ACPI_OPERAND_OBJECT     **DdbHandle)
                     92: {
                     93:     ACPI_OPERAND_OBJECT     *ObjDesc;
                     94:     ACPI_STATUS             Status;
                     95:     ACPI_OWNER_ID           OwnerId;
                     96:
                     97:
                     98:     ACPI_FUNCTION_TRACE (ExAddTable);
                     99:
                    100:
                    101:     /* Create an object to be the table handle */
                    102:
                    103:     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
                    104:     if (!ObjDesc)
                    105:     {
                    106:         return_ACPI_STATUS (AE_NO_MEMORY);
                    107:     }
                    108:
                    109:     /* Init the table handle */
                    110:
                    111:     ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
                    112:     ObjDesc->Reference.Class = ACPI_REFCLASS_TABLE;
                    113:     *DdbHandle = ObjDesc;
                    114:
                    115:     /* Install the new table into the local data structures */
                    116:
                    117:     ObjDesc->Reference.Value = TableIndex;
                    118:
                    119:     /* Add the table to the namespace */
                    120:
                    121:     Status = AcpiNsLoadTable (TableIndex, ParentNode);
                    122:     if (ACPI_FAILURE (Status))
                    123:     {
                    124:         AcpiUtRemoveReference (ObjDesc);
                    125:         *DdbHandle = NULL;
                    126:         return_ACPI_STATUS (Status);
                    127:     }
                    128:
                    129:     /* Execute any module-level code that was found in the table */
                    130:
                    131:     AcpiExExitInterpreter ();
                    132:     AcpiNsExecModuleCodeList ();
                    133:     AcpiExEnterInterpreter ();
                    134:
1.3       jruoho    135:     /*
                    136:      * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
                    137:      * responsible for discovering any new wake GPEs by running _PRW methods
                    138:      * that may have been loaded by this table.
                    139:      */
1.1       jruoho    140:     Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
                    141:     if (ACPI_SUCCESS (Status))
                    142:     {
                    143:         AcpiEvUpdateGpes (OwnerId);
                    144:     }
                    145:
                    146:     return_ACPI_STATUS (AE_OK);
                    147: }
                    148:
                    149:
                    150: /*******************************************************************************
                    151:  *
                    152:  * FUNCTION:    AcpiExLoadTableOp
                    153:  *
                    154:  * PARAMETERS:  WalkState           - Current state with operands
                    155:  *              ReturnDesc          - Where to store the return object
                    156:  *
                    157:  * RETURN:      Status
                    158:  *
                    159:  * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
                    160:  *
                    161:  ******************************************************************************/
                    162:
                    163: ACPI_STATUS
                    164: AcpiExLoadTableOp (
                    165:     ACPI_WALK_STATE         *WalkState,
                    166:     ACPI_OPERAND_OBJECT     **ReturnDesc)
                    167: {
                    168:     ACPI_STATUS             Status;
                    169:     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
                    170:     ACPI_NAMESPACE_NODE     *ParentNode;
                    171:     ACPI_NAMESPACE_NODE     *StartNode;
                    172:     ACPI_NAMESPACE_NODE     *ParameterNode = NULL;
                    173:     ACPI_OPERAND_OBJECT     *DdbHandle;
                    174:     ACPI_TABLE_HEADER       *Table;
                    175:     UINT32                  TableIndex;
                    176:
                    177:
                    178:     ACPI_FUNCTION_TRACE (ExLoadTableOp);
                    179:
                    180:
1.4       christos  181:     /* Validate lengths for the Signature, OemId, and OemTableId strings */
1.1       jruoho    182:
                    183:     if ((Operand[0]->String.Length > ACPI_NAME_SIZE) ||
                    184:         (Operand[1]->String.Length > ACPI_OEM_ID_SIZE) ||
                    185:         (Operand[2]->String.Length > ACPI_OEM_TABLE_ID_SIZE))
                    186:     {
1.4       christos  187:         return_ACPI_STATUS (AE_AML_STRING_LIMIT);
1.1       jruoho    188:     }
                    189:
                    190:     /* Find the ACPI table in the RSDT/XSDT */
                    191:
1.4       christos  192:     Status = AcpiTbFindTable (
                    193:                 Operand[0]->String.Pointer,
                    194:                 Operand[1]->String.Pointer,
                    195:                 Operand[2]->String.Pointer, &TableIndex);
1.1       jruoho    196:     if (ACPI_FAILURE (Status))
                    197:     {
                    198:         if (Status != AE_NOT_FOUND)
                    199:         {
                    200:             return_ACPI_STATUS (Status);
                    201:         }
                    202:
                    203:         /* Table not found, return an Integer=0 and AE_OK */
                    204:
                    205:         DdbHandle = AcpiUtCreateIntegerObject ((UINT64) 0);
                    206:         if (!DdbHandle)
                    207:         {
                    208:             return_ACPI_STATUS (AE_NO_MEMORY);
                    209:         }
                    210:
                    211:         *ReturnDesc = DdbHandle;
                    212:         return_ACPI_STATUS (AE_OK);
                    213:     }
                    214:
                    215:     /* Default nodes */
                    216:
                    217:     StartNode = WalkState->ScopeInfo->Scope.Node;
                    218:     ParentNode = AcpiGbl_RootNode;
                    219:
                    220:     /* RootPath (optional parameter) */
                    221:
                    222:     if (Operand[3]->String.Length > 0)
                    223:     {
                    224:         /*
1.4       christos  225:          * Find the node referenced by the RootPathString. This is the
1.1       jruoho    226:          * location within the namespace where the table will be loaded.
                    227:          */
                    228:         Status = AcpiNsGetNode (StartNode, Operand[3]->String.Pointer,
                    229:                     ACPI_NS_SEARCH_PARENT, &ParentNode);
                    230:         if (ACPI_FAILURE (Status))
                    231:         {
                    232:             return_ACPI_STATUS (Status);
                    233:         }
                    234:     }
                    235:
                    236:     /* ParameterPath (optional parameter) */
                    237:
                    238:     if (Operand[4]->String.Length > 0)
                    239:     {
1.4       christos  240:         if ((Operand[4]->String.Pointer[0] != AML_ROOT_PREFIX) &&
                    241:             (Operand[4]->String.Pointer[0] != AML_PARENT_PREFIX))
1.1       jruoho    242:         {
                    243:             /*
                    244:              * Path is not absolute, so it will be relative to the node
                    245:              * referenced by the RootPathString (or the NS root if omitted)
                    246:              */
                    247:             StartNode = ParentNode;
                    248:         }
                    249:
                    250:         /* Find the node referenced by the ParameterPathString */
                    251:
                    252:         Status = AcpiNsGetNode (StartNode, Operand[4]->String.Pointer,
                    253:                     ACPI_NS_SEARCH_PARENT, &ParameterNode);
                    254:         if (ACPI_FAILURE (Status))
                    255:         {
                    256:             return_ACPI_STATUS (Status);
                    257:         }
                    258:     }
                    259:
                    260:     /* Load the table into the namespace */
                    261:
                    262:     Status = AcpiExAddTable (TableIndex, ParentNode, &DdbHandle);
                    263:     if (ACPI_FAILURE (Status))
                    264:     {
                    265:         return_ACPI_STATUS (Status);
                    266:     }
                    267:
                    268:     /* Parameter Data (optional) */
                    269:
                    270:     if (ParameterNode)
                    271:     {
                    272:         /* Store the parameter data into the optional parameter object */
                    273:
                    274:         Status = AcpiExStore (Operand[5],
                    275:                     ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParameterNode),
                    276:                     WalkState);
                    277:         if (ACPI_FAILURE (Status))
                    278:         {
                    279:             (void) AcpiExUnloadTable (DdbHandle);
                    280:
                    281:             AcpiUtRemoveReference (DdbHandle);
                    282:             return_ACPI_STATUS (Status);
                    283:         }
                    284:     }
                    285:
                    286:     Status = AcpiGetTableByIndex (TableIndex, &Table);
                    287:     if (ACPI_SUCCESS (Status))
                    288:     {
1.2       jruoho    289:         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Dynamic OEM Table Load:"));
1.1       jruoho    290:         AcpiTbPrintTableHeader (0, Table);
                    291:     }
                    292:
                    293:     /* Invoke table handler if present */
                    294:
                    295:     if (AcpiGbl_TableHandler)
                    296:     {
                    297:         (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
                    298:                     AcpiGbl_TableHandlerContext);
                    299:     }
                    300:
                    301:     *ReturnDesc = DdbHandle;
1.4       christos  302:     return_ACPI_STATUS (Status);
1.1       jruoho    303: }
                    304:
                    305:
                    306: /*******************************************************************************
                    307:  *
                    308:  * FUNCTION:    AcpiExRegionRead
                    309:  *
                    310:  * PARAMETERS:  ObjDesc         - Region descriptor
                    311:  *              Length          - Number of bytes to read
                    312:  *              Buffer          - Pointer to where to put the data
                    313:  *
                    314:  * RETURN:      Status
                    315:  *
                    316:  * DESCRIPTION: Read data from an operation region. The read starts from the
                    317:  *              beginning of the region.
                    318:  *
                    319:  ******************************************************************************/
                    320:
                    321: static ACPI_STATUS
                    322: AcpiExRegionRead (
                    323:     ACPI_OPERAND_OBJECT     *ObjDesc,
                    324:     UINT32                  Length,
                    325:     UINT8                   *Buffer)
                    326: {
                    327:     ACPI_STATUS             Status;
                    328:     UINT64                  Value;
                    329:     UINT32                  RegionOffset = 0;
                    330:     UINT32                  i;
                    331:
                    332:
                    333:     /* Bytewise reads */
                    334:
                    335:     for (i = 0; i < Length; i++)
                    336:     {
1.4       christos  337:         Status = AcpiEvAddressSpaceDispatch (ObjDesc, NULL, ACPI_READ,
1.1       jruoho    338:                     RegionOffset, 8, &Value);
                    339:         if (ACPI_FAILURE (Status))
                    340:         {
                    341:             return (Status);
                    342:         }
                    343:
                    344:         *Buffer = (UINT8) Value;
                    345:         Buffer++;
                    346:         RegionOffset++;
                    347:     }
                    348:
                    349:     return (AE_OK);
                    350: }
                    351:
                    352:
                    353: /*******************************************************************************
                    354:  *
                    355:  * FUNCTION:    AcpiExLoadOp
                    356:  *
                    357:  * PARAMETERS:  ObjDesc         - Region or Buffer/Field where the table will be
                    358:  *                                obtained
                    359:  *              Target          - Where a handle to the table will be stored
                    360:  *              WalkState       - Current state
                    361:  *
                    362:  * RETURN:      Status
                    363:  *
                    364:  * DESCRIPTION: Load an ACPI table from a field or operation region
                    365:  *
                    366:  * NOTE: Region Fields (Field, BankField, IndexFields) are resolved to buffer
                    367:  *       objects before this code is reached.
                    368:  *
                    369:  *       If source is an operation region, it must refer to SystemMemory, as
                    370:  *       per the ACPI specification.
                    371:  *
                    372:  ******************************************************************************/
                    373:
                    374: ACPI_STATUS
                    375: AcpiExLoadOp (
                    376:     ACPI_OPERAND_OBJECT     *ObjDesc,
                    377:     ACPI_OPERAND_OBJECT     *Target,
                    378:     ACPI_WALK_STATE         *WalkState)
                    379: {
                    380:     ACPI_OPERAND_OBJECT     *DdbHandle;
1.5       christos  381:     ACPI_TABLE_HEADER       *TableHeader;
1.1       jruoho    382:     ACPI_TABLE_HEADER       *Table;
                    383:     UINT32                  TableIndex;
                    384:     ACPI_STATUS             Status;
                    385:     UINT32                  Length;
                    386:
                    387:
                    388:     ACPI_FUNCTION_TRACE (ExLoadOp);
                    389:
                    390:
                    391:     /* Source Object can be either an OpRegion or a Buffer/Field */
                    392:
                    393:     switch (ObjDesc->Common.Type)
                    394:     {
                    395:     case ACPI_TYPE_REGION:
                    396:
                    397:         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
                    398:             "Load table from Region %p\n", ObjDesc));
                    399:
                    400:         /* Region must be SystemMemory (from ACPI spec) */
                    401:
                    402:         if (ObjDesc->Region.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY)
                    403:         {
                    404:             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
                    405:         }
                    406:
                    407:         /*
                    408:          * If the Region Address and Length have not been previously evaluated,
                    409:          * evaluate them now and save the results.
                    410:          */
                    411:         if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
                    412:         {
                    413:             Status = AcpiDsGetRegionArguments (ObjDesc);
                    414:             if (ACPI_FAILURE (Status))
                    415:             {
                    416:                 return_ACPI_STATUS (Status);
                    417:             }
                    418:         }
                    419:
                    420:         /* Get the table header first so we can get the table length */
                    421:
1.5       christos  422:         TableHeader = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER));
                    423:         if (!TableHeader)
1.1       jruoho    424:         {
                    425:             return_ACPI_STATUS (AE_NO_MEMORY);
                    426:         }
                    427:
                    428:         Status = AcpiExRegionRead (ObjDesc, sizeof (ACPI_TABLE_HEADER),
1.5       christos  429:                     ACPI_CAST_PTR (UINT8, TableHeader));
                    430:         Length = TableHeader->Length;
                    431:         ACPI_FREE (TableHeader);
1.1       jruoho    432:
                    433:         if (ACPI_FAILURE (Status))
                    434:         {
                    435:             return_ACPI_STATUS (Status);
                    436:         }
                    437:
                    438:         /* Must have at least an ACPI table header */
                    439:
                    440:         if (Length < sizeof (ACPI_TABLE_HEADER))
                    441:         {
                    442:             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
                    443:         }
                    444:
                    445:         /*
                    446:          * The original implementation simply mapped the table, with no copy.
                    447:          * However, the memory region is not guaranteed to remain stable and
                    448:          * we must copy the table to a local buffer. For example, the memory
                    449:          * region is corrupted after suspend on some machines. Dynamically
                    450:          * loaded tables are usually small, so this overhead is minimal.
                    451:          *
                    452:          * The latest implementation (5/2009) does not use a mapping at all.
                    453:          * We use the low-level operation region interface to read the table
                    454:          * instead of the obvious optimization of using a direct mapping.
                    455:          * This maintains a consistent use of operation regions across the
                    456:          * entire subsystem. This is important if additional processing must
                    457:          * be performed in the (possibly user-installed) operation region
                    458:          * handler. For example, AcpiExec and ASLTS depend on this.
                    459:          */
                    460:
                    461:         /* Allocate a buffer for the table */
                    462:
1.5       christos  463:         Table = ACPI_ALLOCATE (Length);
                    464:         if (!Table)
1.1       jruoho    465:         {
                    466:             return_ACPI_STATUS (AE_NO_MEMORY);
                    467:         }
                    468:
                    469:         /* Read the entire table */
                    470:
                    471:         Status = AcpiExRegionRead (ObjDesc, Length,
1.5       christos  472:                     ACPI_CAST_PTR (UINT8, Table));
1.1       jruoho    473:         if (ACPI_FAILURE (Status))
                    474:         {
1.5       christos  475:             ACPI_FREE (Table);
1.1       jruoho    476:             return_ACPI_STATUS (Status);
                    477:         }
                    478:         break;
                    479:
                    480:     case ACPI_TYPE_BUFFER: /* Buffer or resolved RegionField */
                    481:
                    482:         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
                    483:             "Load table from Buffer or Field %p\n", ObjDesc));
                    484:
                    485:         /* Must have at least an ACPI table header */
                    486:
                    487:         if (ObjDesc->Buffer.Length < sizeof (ACPI_TABLE_HEADER))
                    488:         {
                    489:             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
                    490:         }
                    491:
                    492:         /* Get the actual table length from the table header */
                    493:
1.5       christos  494:         TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer);
                    495:         Length = TableHeader->Length;
1.1       jruoho    496:
                    497:         /* Table cannot extend beyond the buffer */
                    498:
                    499:         if (Length > ObjDesc->Buffer.Length)
                    500:         {
                    501:             return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
                    502:         }
                    503:         if (Length < sizeof (ACPI_TABLE_HEADER))
                    504:         {
                    505:             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
                    506:         }
                    507:
                    508:         /*
                    509:          * Copy the table from the buffer because the buffer could be modified
                    510:          * or even deleted in the future
                    511:          */
1.5       christos  512:         Table = ACPI_ALLOCATE (Length);
                    513:         if (!Table)
1.1       jruoho    514:         {
                    515:             return_ACPI_STATUS (AE_NO_MEMORY);
                    516:         }
                    517:
1.5       christos  518:         ACPI_MEMCPY (Table, TableHeader, Length);
1.1       jruoho    519:         break;
                    520:
1.4       christos  521:     default:
1.1       jruoho    522:
                    523:         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
                    524:     }
                    525:
1.5       christos  526:     /* Install the new table into the local data structures */
                    527:
                    528:     ACPI_INFO ((AE_INFO, "Dynamic OEM Table Load:"));
                    529:     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
                    530:
                    531:     Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table),
                    532:                 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, TRUE, TRUE,
                    533:                 &TableIndex);
1.1       jruoho    534:
1.5       christos  535:     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1.1       jruoho    536:     if (ACPI_FAILURE (Status))
                    537:     {
1.5       christos  538:         /* Delete allocated table buffer */
                    539:
                    540:         ACPI_FREE (Table);
1.1       jruoho    541:         return_ACPI_STATUS (Status);
                    542:     }
                    543:
1.5       christos  544:     /*
                    545:      * Note: Now table is "INSTALLED", it must be validated before
                    546:      * loading.
                    547:      */
                    548:     Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
1.1       jruoho    549:     if (ACPI_FAILURE (Status))
                    550:     {
                    551:         return_ACPI_STATUS (Status);
                    552:     }
                    553:
                    554:     /*
                    555:      * Add the table to the namespace.
                    556:      *
                    557:      * Note: Load the table objects relative to the root of the namespace.
                    558:      * This appears to go against the ACPI specification, but we do it for
                    559:      * compatibility with other ACPI implementations.
                    560:      */
                    561:     Status = AcpiExAddTable (TableIndex, AcpiGbl_RootNode, &DdbHandle);
                    562:     if (ACPI_FAILURE (Status))
                    563:     {
                    564:         /* On error, TablePtr was deallocated above */
                    565:
                    566:         return_ACPI_STATUS (Status);
                    567:     }
                    568:
                    569:     /* Store the DdbHandle into the Target operand */
                    570:
                    571:     Status = AcpiExStore (DdbHandle, Target, WalkState);
                    572:     if (ACPI_FAILURE (Status))
                    573:     {
                    574:         (void) AcpiExUnloadTable (DdbHandle);
                    575:
                    576:         /* TablePtr was deallocated above */
                    577:
                    578:         AcpiUtRemoveReference (DdbHandle);
                    579:         return_ACPI_STATUS (Status);
                    580:     }
                    581:
                    582:     /* Remove the reference by added by AcpiExStore above */
                    583:
                    584:     AcpiUtRemoveReference (DdbHandle);
                    585:
                    586:     /* Invoke table handler if present */
                    587:
                    588:     if (AcpiGbl_TableHandler)
                    589:     {
1.5       christos  590:         (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
1.1       jruoho    591:                     AcpiGbl_TableHandlerContext);
                    592:     }
                    593:
                    594:     return_ACPI_STATUS (Status);
                    595: }
                    596:
                    597:
                    598: /*******************************************************************************
                    599:  *
                    600:  * FUNCTION:    AcpiExUnloadTable
                    601:  *
                    602:  * PARAMETERS:  DdbHandle           - Handle to a previously loaded table
                    603:  *
                    604:  * RETURN:      Status
                    605:  *
                    606:  * DESCRIPTION: Unload an ACPI table
                    607:  *
                    608:  ******************************************************************************/
                    609:
                    610: ACPI_STATUS
                    611: AcpiExUnloadTable (
                    612:     ACPI_OPERAND_OBJECT     *DdbHandle)
                    613: {
                    614:     ACPI_STATUS             Status = AE_OK;
                    615:     ACPI_OPERAND_OBJECT     *TableDesc = DdbHandle;
                    616:     UINT32                  TableIndex;
                    617:     ACPI_TABLE_HEADER       *Table;
                    618:
                    619:
                    620:     ACPI_FUNCTION_TRACE (ExUnloadTable);
                    621:
                    622:
                    623:     /*
1.5       christos  624:      * Temporarily emit a warning so that the ASL for the machine can be
                    625:      * hopefully obtained. This is to say that the Unload() operator is
                    626:      * extremely rare if not completely unused.
                    627:      */
                    628:     ACPI_WARNING ((AE_INFO,
                    629:         "Received request to unload an ACPI table"));
                    630:
                    631:     /*
1.1       jruoho    632:      * Validate the handle
                    633:      * Although the handle is partially validated in AcpiExReconfiguration()
                    634:      * when it calls AcpiExResolveOperands(), the handle is more completely
                    635:      * validated here.
                    636:      *
                    637:      * Handle must be a valid operand object of type reference. Also, the
                    638:      * DdbHandle must still be marked valid (table has not been previously
                    639:      * unloaded)
                    640:      */
                    641:     if ((!DdbHandle) ||
                    642:         (ACPI_GET_DESCRIPTOR_TYPE (DdbHandle) != ACPI_DESC_TYPE_OPERAND) ||
                    643:         (DdbHandle->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) ||
                    644:         (!(DdbHandle->Common.Flags & AOPOBJ_DATA_VALID)))
                    645:     {
1.4       christos  646:         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
1.1       jruoho    647:     }
                    648:
                    649:     /* Get the table index from the DdbHandle */
                    650:
                    651:     TableIndex = TableDesc->Reference.Value;
                    652:
                    653:     /* Ensure the table is still loaded */
                    654:
                    655:     if (!AcpiTbIsTableLoaded (TableIndex))
                    656:     {
                    657:         return_ACPI_STATUS (AE_NOT_EXIST);
                    658:     }
                    659:
                    660:     /* Invoke table handler if present */
                    661:
                    662:     if (AcpiGbl_TableHandler)
                    663:     {
                    664:         Status = AcpiGetTableByIndex (TableIndex, &Table);
                    665:         if (ACPI_SUCCESS (Status))
                    666:         {
                    667:             (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table,
                    668:                         AcpiGbl_TableHandlerContext);
                    669:         }
                    670:     }
                    671:
                    672:     /* Delete the portion of the namespace owned by this table */
                    673:
                    674:     Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
                    675:     if (ACPI_FAILURE (Status))
                    676:     {
                    677:         return_ACPI_STATUS (Status);
                    678:     }
                    679:
                    680:     (void) AcpiTbReleaseOwnerId (TableIndex);
                    681:     AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
                    682:
                    683:     /*
                    684:      * Invalidate the handle. We do this because the handle may be stored
                    685:      * in a named object and may not be actually deleted until much later.
                    686:      */
                    687:     DdbHandle->Common.Flags &= ~AOPOBJ_DATA_VALID;
                    688:     return_ACPI_STATUS (AE_OK);
                    689: }

CVSweb <webmaster@jp.NetBSD.org>