From bb6f6bcde4e5a0ff8f5b03f0d7071ae5068905d0 Mon Sep 17 00:00:00 2001 From: aystarik Date: Wed, 29 Jun 2005 18:32:40 +0000 Subject: [PATCH] Namespace search and insert date 99.05.17.22.19.00; author rmoore1; state Exp; --- source/components/namespace/nssearch.c | 863 ++++++++++++++++--------- 1 file changed, 541 insertions(+), 322 deletions(-) diff --git a/source/components/namespace/nssearch.c b/source/components/namespace/nssearch.c index c94185ad2..318da3e55 100644 --- a/source/components/namespace/nssearch.c +++ b/source/components/namespace/nssearch.c @@ -1,460 +1,679 @@ -/******************************************************************************* - * + +/****************************************************************************** + * * Module Name: nssearch - Namespace search - * $Revision: 1.93 $ * - ******************************************************************************/ + *****************************************************************************/ /****************************************************************************** * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. - * All rights reserved. + * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights + * reserved. * * 2. License + * + * 2.1. Intel grants, free of charge, to any person ("Licensee") obtaining a + * copy of the source code appearing in this file ("Covered Code") a license + * under Intel's copyrights in the base code distributed originally by Intel + * ("Original Intel Code") to copy, make derivatives, distribute, use and + * display any portion of the Covered Code in any form; and * - * 2.1. This is your license from Intel Corp. under its intellectual property - * rights. You may have additional license terms from the party that provided - * you this software, covering your right to use that party's intellectual - * property rights. + * 2.2. Intel grants Licensee a non-exclusive and non-transferable patent + * license (without the right to sublicense), under only those claims of Intel + * patents that are infringed by the Original Intel Code, to make, use, sell, + * offer to sell, and import the Covered Code and derivative works thereof + * solely to the minimum extent necessary to exercise the above copyright + * license, and in no event shall the patent license extend to any additions to + * or modifications of the Original Intel Code. No other license or right is + * granted directly or by implication, estoppel or otherwise; * - * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a - * copy of the source code appearing in this file ("Covered Code") an - * irrevocable, perpetual, worldwide license under Intel's copyrights in the - * base code distributed originally by Intel ("Original Intel Code") to copy, - * make derivatives, distribute, use and display any portion of the Covered - * Code in any form, with the right to sublicense such rights; and - * - * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent - * license (with the right to sublicense), under only those claims of Intel - * patents that are infringed by the Original Intel Code, to make, use, sell, - * offer to sell, and import the Covered Code and derivative works thereof - * solely to the minimum extent necessary to exercise the above copyright - * license, and in no event shall the patent license extend to any additions - * to or modifications of the Original Intel Code. No other license or right - * is granted directly or by implication, estoppel or otherwise; - * - * The above copyright and patent license is granted only if the following + * the above copyright and patent license is granted only if the following * conditions are met: * - * 3. Conditions + * 3. Conditions * - * 3.1. Redistribution of Source with Rights to Further Distribute Source. - * Redistribution of source code of any substantial portion of the Covered - * Code or modification with rights to further distribute source must include - * the above Copyright Notice, the above License, this list of Conditions, - * and the following Disclaimer and Export Compliance provision. In addition, - * Licensee must cause all Covered Code to which Licensee contributes to - * contain a file documenting the changes Licensee made to create that Covered - * Code and the date of any change. Licensee must include in that file the - * documentation of any changes made by any predecessor Licensee. Licensee - * must include a prominent statement that the modification is derived, - * directly or indirectly, from Original Intel Code. + * 3.1. Redistribution of source code of any substantial portion of the Covered + * Code or modification must include the above Copyright Notice, the above + * License, this list of Conditions, and the following Disclaimer and Export + * Compliance provision. In addition, Licensee must cause all Covered Code to + * which Licensee contributes to contain a file documenting the changes + * Licensee made to create that Covered Code and the date of any change. + * Licensee must include in that file the documentation of any changes made by + * any predecessor Licensee. Licensee must include a prominent statement that + * the modification is derived, directly or indirectly, from Original Intel + * Code. * - * 3.2. Redistribution of Source with no Rights to Further Distribute Source. - * Redistribution of source code of any substantial portion of the Covered - * Code or modification without rights to further distribute source must - * include the following Disclaimer and Export Compliance provision in the - * documentation and/or other materials provided with distribution. In - * addition, Licensee may not authorize further sublicense of source of any - * portion of the Covered Code, and must include terms to the effect that the - * license from Licensee to its licensee is limited to the intellectual - * property embodied in the software Licensee provides to its licensee, and - * not to intellectual property embodied in modifications its licensee may - * make. + * 3.2. Redistribution in binary form of any substantial portion of the Covered + * Code or modification must reproduce the above Copyright Notice, and the + * following Disclaimer and Export Compliance provision in the documentation + * and/or other materials provided with the distribution. * - * 3.3. Redistribution of Executable. Redistribution in executable form of any - * substantial portion of the Covered Code or modification must reproduce the - * above Copyright Notice, and the following Disclaimer and Export Compliance - * provision in the documentation and/or other materials provided with the - * distribution. - * - * 3.4. Intel retains all right, title, and interest in and to the Original + * 3.3. Intel retains all right, title, and interest in and to the Original * Intel Code. * - * 3.5. Neither the name Intel nor any other trademark owned or controlled by - * Intel shall be used in advertising or otherwise to promote the sale, use or - * other dealings in products derived from or relating to the Covered Code + * 3.4. Neither the name Intel nor any other trademark owned or controlled by + * Intel shall be used in advertising or otherwise to promote the sale, use or + * other dealings in products derived from or relating to the Covered Code * without prior written authorization from Intel. * * 4. Disclaimer and Export Compliance * - * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED - * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE - * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, - * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY - * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A - * PARTICULAR PURPOSE. + * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED + * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE + * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, + * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY + * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A + * PARTICULAR PURPOSE. * - * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES - * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR - * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, - * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY - * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL - * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS - * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY + * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES + * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR + * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, + * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY + * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL + * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS + * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY * LIMITED REMEDY. * - * 4.3. Licensee shall not export, either directly or indirectly, any of this - * software or system incorporating such software without first obtaining any - * required license or other approval from the U. S. Department of Commerce or - * any other agency or department of the United States Government. In the - * event Licensee exports any such software from the United States or - * re-exports any such software from a foreign destination, Licensee shall - * ensure that the distribution and export/re-export of the software is in - * compliance with all laws, regulations, orders, or other restrictions of the - * U.S. Export Administration Regulations. Licensee agrees that neither it nor - * any of its subsidiaries will export/re-export any technical data, process, - * software, or service, directly or indirectly, to any country for which the - * United States government or any agency thereof requires an export license, - * other governmental approval, or letter of assurance, without first obtaining - * such license, approval or letter. + * 4.3. Licensee shall not export, either directly or indirectly, any of this + * software or system incorporating such software without first obtaining any + * required license or other approval from the U. S. Department of Commerce or + * any other agency or department of the United States Government. In the + * event Licensee exports any such software from the United States or re- + * exports any such software from a foreign destination, Licensee shall ensure + * that the distribution and export/re-export of the software is in compliance + * with all laws, regulations, orders, or other restrictions of the U.S. Export + * Administration Regulations. Licensee agrees that neither it nor any of its + * subsidiaries will export/re-export any technical data, process, software, or + * service, directly or indirectly, to any country for which the United States + * government or any agency thereof requires an export license, other + * governmental approval, or letter of assurance, without first obtaining such + * license, approval or letter. * *****************************************************************************/ + #define __NSSEARCH_C__ -#include "acpi.h" -#include "acnamesp.h" +#include +#include +#include +#include -#define _COMPONENT ACPI_NAMESPACE - ACPI_MODULE_NAME ("nssearch") +#define _THIS_MODULE "nssearch.c" +#define _COMPONENT NAMESPACE -/******************************************************************************* +static ST_KEY_DESC_TABLE KDT[] = { + {"0000", '1', "NsSearchTable: null scope passed", "NsSearchTable: null scope passed"}, + {"0001", '1', "Name Table appendage allocation failure", "Name Table appendage allocation failure"}, + {"0002", '1', "Unknown reference in name space", "Unknown reference in name space"}, + {NULL, 'I', NULL, NULL} +}; + + +/**************************************************************************** * - * FUNCTION: AcpiNsSearchNode + * FUNCTION: NsSearchOnly * - * PARAMETERS: *TargetName - Ascii ACPI name to search for - * *Node - Starting node where search will begin - * Type - Object type to match - * **ReturnNode - Where the matched Named obj is returned + * PARAMETERS: * - * RETURN: Status + * RETURN: Status and return information via NS_SEARCH_DATA * - * DESCRIPTION: Search a single level of the namespace. Performs a - * simple search of the specified level, and does not add - * entries or search parents. + * DESCRIPTION: Search a single namespace table. Performs a simple search, + * does not add entries or search parents. * - * - * Named object lists are built (and subsequently dumped) in the - * order in which the names are encountered during the namespace load; - * - * All namespace searching is linear in this implementation, but - * could be easily modified to support any improved search - * algorithm. However, the linear search was chosen for simplicity - * and because the trees are small and the other interpreter - * execution overhead is relatively high. - * - ******************************************************************************/ + ***************************************************************************/ ACPI_STATUS -AcpiNsSearchNode ( - UINT32 TargetName, - ACPI_NAMESPACE_NODE *Node, - ACPI_OBJECT_TYPE Type, - ACPI_NAMESPACE_NODE **ReturnNode) +NsSearchOnly (char *NamSeg, nte *NameTbl, NsType Type, nte **RetNte, + NS_SEARCH_DATA *RetInfo) { - ACPI_NAMESPACE_NODE *NextNode; + UINT32 TableSize; + UINT32 Position; + UINT32 Tries; + char *ScopeName; - ACPI_FUNCTION_TRACE ("NsSearchNode"); + FUNCTION_TRACE ("NsSearchOnly"); + /* Debug only */ -#ifdef ACPI_DEBUG_OUTPUT - if (ACPI_LV_NAMES & AcpiDbgLevel) - { - NATIVE_CHAR *ScopeName; + ScopeName = NsNameOfScope (NameTbl); + DEBUG_PRINT (TRACE_NAMES, + ("NsSearchOnly: search %s [%p] for %4.4s\n", + ScopeName, NameTbl, NamSeg)); - ScopeName = AcpiNsGetExternalPathname (Node); - if (ScopeName) - { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching %s [%p] For %4.4s (%s)\n", - ScopeName, Node, (char *) &TargetName, AcpiUtGetTypeName (Type))); + OsdFree (ScopeName); - ACPI_MEM_FREE (ScopeName); - } - } -#endif + /* TBD: convert to single size table */ - /* - * Search for name at this namespace level, which is to say that we - * must search for the name among the children of this object + if (NameTbl == RootObject->Scope) + TableSize = NS_ROOT_TABLE_SIZE; + else + TableSize = NS_DEFAULT_TABLE_SIZE; + + /* + * Name tables are built (and subsequently dumped) in the + * order in which the names are encountered during the namespace load; + * + * All namespace searching will be linear; If a table overflows an + * additional segment will be allocated and added (chained). + * + * Start linear search at top of table */ - NextNode = Node->Child; - while (NextNode) + Position = 0; + + /* Init return data */ + + if (RetInfo) { - /* Check for match against the name */ - - if (NextNode->Name.Integer == TargetName) - { - /* - * Found matching entry. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "Name %4.4s Type [%s] found at %p\n", - (char *) &TargetName, AcpiUtGetTypeName (NextNode->Type), NextNode)); - - *ReturnNode = NextNode; - return_ACPI_STATUS (AE_OK); - } - - /* - * The last entry in the list points back to the parent, - * so a flag is used to indicate the end-of-list - */ - if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) - { - /* Searched entire list, we are done */ - - break; - } - - /* Didn't match name, move on to the next peer object */ - - NextNode = NextNode->Peer; + RetInfo->PreviousEntry = NULL; + RetInfo->NameTbl = NameTbl; } - /* Searched entire namespace level, not found */ + /* + * Search for name in table, starting at Position. Stop searching upon + * finding an unused entry or after examining all entries in the table. + * + * Moving to the "next" entry is done at the bottom of the loop instead + * of in the iteration expression because the method used depends on + * whether or not USE_HASHING is in effect. + */ - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Name %4.4s Type [%s] not found at %p\n", - (char *) &TargetName, AcpiUtGetTypeName (Type), NextNode)); + for (Tries = TableSize; Tries && 0 != NameTbl[Position].Name; Tries--) + { + /* search for name in table */ - return_ACPI_STATUS (AE_NOT_FOUND); + CheckTrash ("top of NsSearchTable loop"); + + if (NameTbl[Position].Name == *(UINT32 *) NamSeg) + { + /* + * Found matching entry. Capture type if appropriate before + * returning the entry. + */ + + /* + * The DefFieldDefn and BankFieldDefn cases are actually + * looking up the Region in which the field will be defined + */ + + if (TYPE_DefFieldDefn == Type || TYPE_BankFieldDefn == Type) + { + Type = TYPE_Region; + } + + /* + * Scope, DefAny, and IndexFieldDefn are bogus "types" which do + * not actually have anything to do with the type of the name + * being looked up. For any other value of Type, if the type + * stored in the entry is Any (i.e. unknown), save the actual type. + */ + + if (Type != TYPE_Scope && + Type != TYPE_DefAny && + Type != TYPE_IndexFieldDefn && + NameTbl[Position].Type == TYPE_Any) + { + NameTbl[Position].Type = Type; + } + + DEBUG_PRINT (TRACE_NAMES, ("NsSearchOnly: Name %4.4s found at %p\n", + NamSeg, &NameTbl[Position])); + + CheckTrash ("leave NsSearchTable FOUND"); + *RetNte = &NameTbl[Position]; + return AE_OK; + } + + + /* Save a pointer to the last entry for back link in new entry */ + + if (RetInfo) + RetInfo->PreviousEntry = &NameTbl[Position]; + + + /* Done with this table? */ + + if ((1 == Tries) && + (NEXTSEG (NameTbl))) + { + /* + * Just examined last slot, but table has an appendage. + * All appendages, even to the root NT, contain NS_DEFAULT_TABLE_SIZE entries. + */ + + NameTbl = NEXTSEG (NameTbl); + DEBUG_PRINT (TRACE_EXEC, ("NsSearchOnly: Search appendage NameTbl=%p\n", NameTbl)); + Position = 0; + Tries += NS_DEFAULT_TABLE_SIZE; + } + + else + { + ++Position; + } + } + + + /* Searched entire table, not found */ + + DEBUG_PRINT (TRACE_NAMES, ("NsSearchOnly: Name %4.4s not found at %p\n", + NamSeg, &NameTbl[Position])); + + + if (RetInfo) + { + RetInfo->TableFull = !(Tries); /* Table is full if no more tries available */ + RetInfo->Position = Position; + RetInfo->NameTbl = NameTbl; + } + + return AE_NOT_FOUND; } -/******************************************************************************* +/**************************************************************************** * - * FUNCTION: AcpiNsSearchParentTree + * FUNCTION: NsSearchParentTree * - * PARAMETERS: *TargetName - Ascii ACPI name to search for - * *Node - Starting node where search will begin - * Type - Object type to match - * **ReturnNode - Where the matched Named Obj is returned + * PARAMETERS: * * RETURN: Status * * DESCRIPTION: Called when a name has not been found in the current namespace - * level. Before adding it or giving up, ACPI scope rules require - * searching enclosing scopes in cases identified by AcpiNsLocal(). + * table. Before adding it or giving up, ACPI scope rules require + * searching enclosing scopes in cases identified by NsLocal(). * - * "A name is located by finding the matching name in the current - * name space, and then in the parent name space. If the parent - * name space does not contain the name, the search continues - * recursively until either the name is found or the name space - * does not have a parent (the root of the name space). This - * indicates that the name is not found" (From ACPI Specification, + * "A name is located by finding the matching name in the current + * name space, and then in the parent name space. If the parent + * name space does not contain the name, the search continues + * recursively until either the name is found or the name space + * does not have a parent (the root of the name space). This + * indicates that the name is not found" (From ACPI Specification, * section 5.3) * - ******************************************************************************/ + ***************************************************************************/ -static ACPI_STATUS -AcpiNsSearchParentTree ( - UINT32 TargetName, - ACPI_NAMESPACE_NODE *Node, - ACPI_OBJECT_TYPE Type, - ACPI_NAMESPACE_NODE **ReturnNode) + +ACPI_STATUS +NsSearchParentTree (char *NamSeg, nte *NameTbl, NsType Type, nte **RetNte) { - ACPI_STATUS Status; - ACPI_NAMESPACE_NODE *ParentNode; + ACPI_STATUS Status; + nte *ParentScope; - ACPI_FUNCTION_TRACE ("NsSearchParentTree"); + FUNCTION_TRACE ("NsSearchParentTree"); - ParentNode = AcpiNsGetParentNode (Node); - - /* - * If there is no parent (i.e., we are at the root) or - * type is "local", we won't be searching the parent tree. + /* + * NameTbl[0] will be an unused entry if the table being searched is empty, + * However, its ParentScope member will have been filled in + * when the table was allocated (unless it is the root name table). */ - if (!ParentNode) + + + if (!NsLocal (Type) && + NameTbl[0].ParentScope) { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] has no parent\n", - (char *) &TargetName)); - return_ACPI_STATUS (AE_NOT_FOUND); - } + ParentScope = NameTbl[0].ParentScope; + DEBUG_PRINT (TRACE_NAMES, ("NsSearchParentTree: Searching parent for %.4s\n", NamSeg)); - if (AcpiNsLocal (Type)) - { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "[%4.4s] type [%s] must be local to this scope (no parent search)\n", - (char *) &TargetName, AcpiUtGetTypeName (Type))); - return_ACPI_STATUS (AE_NOT_FOUND); - } + /* Search parents until found or we have backed up to the root */ - /* Search the parent tree */ - - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching parent for %4.4s\n", (char *) &TargetName)); - - /* - * Search parents until found the target or we have backed up to - * the root - */ - while (ParentNode) - { - /* - * Search parent scope. Use TYPE_ANY because we don't care about the - * object type at this point, we only care about the existence of - * the actual name we are searching for. Typechecking comes later. - */ - Status = AcpiNsSearchNode (TargetName, ParentNode, - ACPI_TYPE_ANY, ReturnNode); - if (ACPI_SUCCESS (Status)) + while (ParentScope) { - return_ACPI_STATUS (Status); + /* Search parent scope */ + /* TBD: Why TYPE_Any? */ + + Status = NsSearchOnly (NamSeg, ParentScope, TYPE_Any, RetNte, NULL); + if (Status == AE_OK) + { + CheckTrash ("leave NsSearchTable FOUND in parent"); + return Status; + } + + /* Not found here, go up another level (until we reach the root) */ + + ParentScope = ParentScope->ParentScope; } + /* Not found in parent tree */ + } + + else + { /* - * Not found here, go up another level - * (until we reach the root) + * No parent, or type is "local". We won't be searching the parent tree. */ - ParentNode = AcpiNsGetParentNode (ParentNode); + + if (!NameTbl[0].ParentScope) + { + DEBUG_PRINT (TRACE_NAMES, ("NsSearchParentTree: [%.4s] has no parent\n", NamSeg)); + } + + else if (NsLocal (Type)) + { + DEBUG_PRINT (TRACE_NAMES, ("NsSearchParentTree: [%.4s] type [%s] is local (no search)\n", + NamSeg, NsTypeNames[Type])); + } } - /* Not found in parent tree */ - - return_ACPI_STATUS (AE_NOT_FOUND); + return AE_NOT_FOUND; } -/******************************************************************************* +/**************************************************************************** * - * FUNCTION: AcpiNsSearchAndEnter + * FUNCTION: NsCreateAndLinkNewTable * - * PARAMETERS: TargetName - Ascii ACPI name to search for (4 chars) - * WalkState - Current state of the walk - * *Node - Starting node where search will begin - * InterpreterMode - Add names only in ACPI_MODE_LOAD_PASS_x. - * Otherwise,search only. - * Type - Object type to match - * Flags - Flags describing the search restrictions - * **ReturnNode - Where the Node is returned + * PARAMETERS: * * RETURN: Status * - * DESCRIPTION: Search for a name segment in a single namespace level, + * DESCRIPTION: Allocate a new namespace table, initialize it, and link it + * into the parent table. + * + ***************************************************************************/ + +ACPI_STATUS +NsCreateAndLinkNewTable (nte *NameTbl, nte *PreviousEntry) +{ + nte *NewTbl; + nte *ParentScope; + + + FUNCTION_TRACE ("NsCreateAndLinkNewTable"); + + + /* first or second pass load mode and full table */ + + ParentScope = NameTbl[0].ParentScope; + + if (NEXTSEG (NameTbl)) + { + /* we should NEVER get here */ + + DEBUG_PRINT (ACPI_ERROR, + ("NsCreateAndLinkNewTable: appendage %p about to be overwritten\n", + NEXTSEG (NameTbl))); + } + + + /* Allocate and chain an appendage to the filled table */ + + NEXTSEG (NameTbl) = NsAllocateNteDesc (NS_DEFAULT_TABLE_SIZE); + if (!NEXTSEG (NameTbl)) + { + REPORT_ERROR (&KDT[1]); + return AE_NO_MEMORY; + } + + else + { + /* + * Allocation successful + * Setup the required fields. All others are already zero. + */ + + NewTbl = NEXTSEG (NameTbl); + NewTbl[0].ParentScope = ParentScope; + + /* Previous Entry MUST be valid here */ + + NewTbl[0].ParentEntry = PreviousEntry->ParentEntry; /* Same parent*/ + PreviousEntry->NextEntry = &NameTbl[0]; + + /* + * Set forward and back links. + * Important: These are the links that tie the tables together + * so that when walking the links, it is invisible that their + * are separate, disjoint tables. + */ + + NameTbl[0].PrevEntry = PreviousEntry; + NameTbl[0].NextEntry = NULL; + + DEBUG_PRINT (TRACE_EXEC, + ("NsCreateAndLinkNewTable: appendage NameTbl=%p, ParentScope=%p, Scope=%p\n", + NameTbl, ParentScope, NameTbl->Scope)); + + } +} + + + +/**************************************************************************** + * + * FUNCTION: NsInitializeEntry + * + * PARAMETERS: + * + * RETURN: Status + * + * DESCRIPTION: Initialize a new entry within a namespace table. + * + ***************************************************************************/ + +void +NsInitializeEntry (nte *NameTbl, UINT32 Position, char *NamSeg, NsType Type, + nte *PreviousEntry) +{ + nte *NewEntry; + + + FUNCTION_TRACE ("NsInitializeEntry"); + + + NewEntry = &NameTbl[Position]; + + /* first or second pass load mode, NameTbl valid */ + + CheckTrash ("NsSearchTable about to add"); + NewEntry->Name = *(UINT32 *) NamSeg; + NewEntry->ParentScope = NameTbl[0].ParentScope; + NewEntry->ParentEntry = NameTbl[0].ParentEntry; + + /* Set forward and back links */ + + if (PreviousEntry) + { + PreviousEntry->NextEntry = NewEntry; + } + + NewEntry->PrevEntry = PreviousEntry; + NewEntry->NextEntry = NULL; + + CheckTrash ("NsInitializeEntry added name"); + + /* + * If adding a name with unknown type, or having to add the region in + * order to define fields in it, we have an improper forward reference + */ + + if ((TYPE_Any == Type) || + (TYPE_DefFieldDefn == Type) || + (TYPE_BankFieldDefn == Type)) + { + /* Unknown reference in name space */ + + REPORT_ERROR (&KDT[2]); + + /* We don't want to abort here, however! */ + } + + /* + * The DefFieldDefn and BankFieldDefn cases are actually + * looking up the Region in which the field will be defined + */ + + if ((TYPE_DefFieldDefn == Type) || (TYPE_BankFieldDefn == Type)) + { + Type = TYPE_Region; + } + + /* + * Scope, DefAny, and IndexFieldDefn are bogus "types" which do + * not actually have anything to do with the type of the name + * being looked up. Save any other value of Type as the type of + * the entry. + */ + + if ((Type != TYPE_Scope) && + (Type != TYPE_DefAny) && + (Type != TYPE_IndexFieldDefn)) + { + NewEntry->Type = Type; + CheckTrashA ("NsInitializeEntry added type", + &NewEntry->Name, NewEntry->Name, Hash, + &NewEntry->Type, NewEntry->Type, Type, (void *) NameTbl); + } + + DEBUG_PRINT (TRACE_NAMES, + ("NsInitializeEntry: %.4s added to %p at %p\n", NamSeg, NameTbl, NewEntry)); + CheckTrash ("leave NsInitializeEntry ADDED"); + +} + + + + + + +/**************************************************************************** + * + * FUNCTION: NsSearchAndEnter + * + * PARAMETERS: NamSeg - name segment to find or insert + * NameTbl - name table to search + * LoadMode - Add names only in Load mode + * Type - Type associated with name + * RetNte - Where to return the found NTE + * + * RETURN: Status + * + * DESCRIPTION: Search for a name segment in a single name table, * optionally adding it if it is not found. If the passed * Type is not Any and the type previously stored in the * entry was Any (i.e. unknown), update the stored type. * - * In ACPI_IMODE_EXECUTE, search only. + * In MODE_Exec, search only. * In other modes, search and add if not found. * - ******************************************************************************/ + ***************************************************************************/ ACPI_STATUS -AcpiNsSearchAndEnter ( - UINT32 TargetName, - ACPI_WALK_STATE *WalkState, - ACPI_NAMESPACE_NODE *Node, - ACPI_INTERPRETER_MODE InterpreterMode, - ACPI_OBJECT_TYPE Type, - UINT32 Flags, - ACPI_NAMESPACE_NODE **ReturnNode) +NsSearchAndEnter (char *NamSeg, nte *NameTbl, + OpMode LoadMode, NsType Type, nte **RetNte) { - ACPI_STATUS Status; - ACPI_NAMESPACE_NODE *NewNode; + UINT32 Position; /* position in table */ + ACPI_STATUS Status; + NS_SEARCH_DATA SearchInfo; - ACPI_FUNCTION_TRACE ("NsSearchAndEnter"); + FUNCTION_TRACE ("NsSearchAndEnter"); + CheckTrash ("enter NsSearchAndEnter"); /* Parameter validation */ - if (!Node || !TargetName || !ReturnNode) + if (!NameTbl || !NamSeg || !RetNte) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null param: Node %p Name %X ReturnNode %p\n", - Node, TargetName, ReturnNode)); - - ACPI_REPORT_ERROR (("NsSearchAndEnter: Null parameter\n")); - return_ACPI_STATUS (AE_BAD_PARAMETER); + REPORT_ERROR (&KDT[0]); + return AE_BAD_PARAMETER; } + /* Name must consist of printable characters */ - if (!AcpiUtValidAcpiName (TargetName)) + if (!AmlGoodChar ((INT32) NamSeg[0]) || + !AmlGoodChar ((INT32) NamSeg[1]) || + !AmlGoodChar ((INT32) NamSeg[2]) || + !AmlGoodChar ((INT32) NamSeg[3])) { - ACPI_REPORT_ERROR (("NsSearchAndEnter: Bad character in ACPI Name: %X\n", - TargetName)); - return_ACPI_STATUS (AE_BAD_CHARACTER); + DEBUG_PRINT (ACPI_ERROR, ("NsSearchAndEnter: *** bad name %08lx *** \n", + *(UINT32 *) NamSeg)); + CheckTrash ("leave NsSearchTable BADNAME"); + return AE_BAD_CHARACTER; } - /* Try to find the name in the namespace level specified by the caller */ - *ReturnNode = ACPI_ENTRY_NOT_FOUND; - Status = AcpiNsSearchNode (TargetName, Node, Type, ReturnNode); + /* Try to find the name in the table */ + + *RetNte = NOTFOUND; + Status = NsSearchOnly (NamSeg, NameTbl, Type, RetNte, &SearchInfo); if (Status != AE_NOT_FOUND) { - /* - * If we found it AND the request specifies that a find is an error, - * return the error - */ - if ((Status == AE_OK) && - (Flags & ACPI_NS_ERROR_IF_FOUND)) - { - Status = AE_ALREADY_EXISTS; - } + /* Either found it or there was an error -- finished either way */ - /* - * Either found it or there was an error - * -- finished either way - */ - return_ACPI_STATUS (Status); + return Status; } - /* - * The name was not found. If we are NOT performing the - * first pass (name entry) of loading the namespace, search - * the parent tree (all the way to the root if necessary.) - * We don't want to perform the parent search when the - * namespace is actually being loaded. We want to perform - * the search when namespace references are being resolved - * (load pass 2) and during the execution phase. - */ - if ((InterpreterMode != ACPI_IMODE_LOAD_PASS1) && - (Flags & ACPI_NS_SEARCH_PARENT)) + + /* Not found in table - search parent tree according to ACPI specification */ + + Status = NsSearchParentTree (NamSeg, NameTbl, Type, RetNte); + if (Status == AE_OK) { - /* - * Not found at this level - search parent tree according - * to ACPI specification - */ - Status = AcpiNsSearchParentTree (TargetName, Node, - Type, ReturnNode); - if (ACPI_SUCCESS (Status)) - { - return_ACPI_STATUS (Status); - } + return Status; } + /* * In execute mode, just search, never add names. Exit now. */ - if (InterpreterMode == ACPI_IMODE_EXECUTE) - { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s Not found in %p [Not adding]\n", - (char *) &TargetName, Node)); - return_ACPI_STATUS (AE_NOT_FOUND); + if (LoadMode == MODE_Exec) + { + DEBUG_PRINT (TRACE_NAMES, ("NsSearchAndEnter: Name %.4s Not found in %p (not adding)\n", + NamSeg, NameTbl)); + CheckTrash ("leave NsSearchTable NOTFOUND"); + + return AE_NOT_FOUND; } - /* Create the new named object */ - NewNode = AcpiNsCreateNode (TargetName); - if (!NewNode) + /* Extract the pertinent info from the search result struct */ + /* NameTbl and position might now point to an appendage */ + + NameTbl = SearchInfo.NameTbl; + Position = SearchInfo.Position; + + + /* + * This block handles the case where the existing table is full. + * we must allocate a new table before we can initialize a new entry + */ + + if (SearchInfo.TableFull) { - return_ACPI_STATUS (AE_NO_MEMORY); + Status = NsCreateAndLinkNewTable (NameTbl, SearchInfo.PreviousEntry); + if (Status != AE_OK) + { + return Status; + } + + /* Point to first slot in new table */ + + Position = 0; + NameTbl = NEXTSEG (NameTbl); } - /* Install the new object into the parent's list of children */ - AcpiNsInstallNode (WalkState, Node, NewNode, Type); - *ReturnNode = NewNode; + /* + * There is room in the table (or we have just allocated a new one.) + * Initialize the new entry + */ - return_ACPI_STATUS (AE_OK); + NsInitializeEntry (NameTbl, Position, NamSeg, Type, + SearchInfo.PreviousEntry); + *RetNte = &NameTbl[Position]; + + return AE_OK; } +