/*******************************************************************************
*
* Module Name: nsalloc - Namespace allocation and deletion utilities
*
******************************************************************************/
/*
* Copyright (C) 2000 - 2016, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include "acpi.h"
#include "accommon.h"
#include "acnamesp.h"
ACPI_MODULE_NAME ("nsalloc")
/*******************************************************************************
*
* FUNCTION: AcpiNsCreateNode
*
* PARAMETERS: Name - Name of the new node (4 char ACPI name)
*
* RETURN: New namespace node (Null on failure)
*
* DESCRIPTION: Create a namespace node
*
******************************************************************************/
{
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
#endif
if (!Node)
{
return_PTR (NULL);
}
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
{
}
#endif
return_PTR (Node);
}
/*******************************************************************************
*
* FUNCTION: AcpiNsDeleteNode
*
* PARAMETERS: Node - Node to be deleted
*
* RETURN: None
*
* DESCRIPTION: Delete a namespace node. All node deletions must come through
* here. Detaches any attached objects, including any attached
* data. If a handler is associated with attached data, it is
* invoked before the node is deleted.
*
******************************************************************************/
void
{
/* Detach an object if there is one */
/*
* Delete an attached data object list if present (objects that were
* attached via AcpiAttachData). Note: After any normal object is
* detached above, the only possible remaining object(s) are data
* objects, in a linked list.
*/
while (ObjDesc &&
{
/* Invoke the attached data deletion handler if present */
{
}
}
/* Special case for the statically allocated root node */
if (Node == AcpiGbl_RootNode)
{
return;
}
/* Now we can delete the node */
}
/*******************************************************************************
*
* FUNCTION: AcpiNsRemoveNode
*
*
* RETURN: None
*
* DESCRIPTION: Remove (unlink) and delete a namespace node
*
******************************************************************************/
void
{
/* Find the node that is the previous peer in the parent's child list */
{
}
if (PrevNode)
{
/* Node is not first child, unlink it */
}
else
{
/*
* Node is first child (has no previous peer).
* Link peer list to parent
*/
}
/* Delete the node and any attached objects */
}
/*******************************************************************************
*
* FUNCTION: AcpiNsInstallNode
*
* PARAMETERS: WalkState - Current state of the walk
* ParentNode - The parent of the new Node
* Node - The new Node to install
* Type - ACPI object type of the new Node
*
* RETURN: None
*
* DESCRIPTION: Initialize a new namespace node and install it amongst
* its peers.
*
* Note: Current namespace lookup is linear search. This appears
* to be sufficient as namespace searches consume only a small
* fraction of the execution time of the ACPI subsystem.
*
******************************************************************************/
void
{
if (WalkState)
{
/*
* Get the owner ID from the Walk state. The owner ID is used to
* track table deletion and deletion of objects created by methods.
*/
if ((WalkState->MethodDesc) &&
{
/*
* A method is creating a new node that is not a child of the
* method (it is non-local). Mark the executing method as having
* modified the namespace. This is used for cleanup when the
* method exits.
*/
}
}
/* Link the new entry into the parent and existing children */
if (!ChildNode)
{
}
else
{
/* Add node to the end of the peer list */
{
}
}
/* Init the new entry */
"%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
ParentNode));
}
/*******************************************************************************
*
* FUNCTION: AcpiNsDeleteChildren
*
* PARAMETERS: ParentNode - Delete this objects children
*
* RETURN: None.
*
* DESCRIPTION: Delete all children of the parent object. In other words,
* deletes a "scope".
*
******************************************************************************/
void
{
if (!ParentNode)
{
}
/* Deallocate all children at this level */
while (NextNode)
{
/* Grandchildren should have all been deleted already */
{
ParentNode, NextNode));
}
/*
* Delete this child node and move on to the next child in the list.
* No need to unlink the node since we are deleting the entire branch.
*/
};
/* Clear the parent's child pointer */
}
/*******************************************************************************
*
* FUNCTION: AcpiNsDeleteNamespaceSubtree
*
* PARAMETERS: ParentNode - Root of the subtree to be deleted
*
* RETURN: None.
*
* DESCRIPTION: Delete a subtree of the namespace. This includes all objects
* stored within the subtree.
*
******************************************************************************/
void
{
if (!ParentNode)
{
}
/* Lock namespace for possible update */
if (ACPI_FAILURE (Status))
{
}
/*
* Traverse the tree of objects until we bubble back up
* to where we started.
*/
while (Level > 0)
{
/* Get the next node in this scope (NULL if none) */
if (ChildNode)
{
/* Found a child node - detach any attached object */
/* Check if this node has any children */
{
/*
* There is at least one child of this node,
* visit the node
*/
Level++;
}
}
else
{
/*
* No more children of this parent node.
* Move up to the grandparent.
*/
Level--;
/*
* Now delete all of the children of this parent
* all at the same time.
*/
/* New "last child" is this parent node */
/* Move up the tree to the grandparent */
}
}
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
}
/*******************************************************************************
*
* FUNCTION: AcpiNsDeleteNamespaceByOwner
*
* PARAMETERS: OwnerId - All nodes with this owner will be deleted
*
* RETURN: Status
*
* DESCRIPTION: Delete entries within the namespace that are owned by a
* specific ID. Used to delete entire ACPI tables. All
* reference counts are updated.
*
* MUTEX: Locks namespace during deletion walk.
*
******************************************************************************/
void
{
if (OwnerId == 0)
{
}
/* Lock namespace for possible update */
if (ACPI_FAILURE (Status))
{
}
DeletionNode = NULL;
Level = 1;
/*
* Traverse the tree of nodes until we bubble back up
* to where we started.
*/
while (Level > 0)
{
/*
* Get the next child of this parent node. When ChildNode is NULL,
* the first child of the parent is returned
*/
if (DeletionNode)
{
DeletionNode = NULL;
}
if (ChildNode)
{
{
/* Found a matching child node - detach any attached object */
}
/* Check if this node has any children */
{
/*
* There is at least one child of this node,
* visit the node
*/
Level++;
}
{
}
}
else
{
/*
* No more children of this parent node.
* Move up to the grandparent.
*/
Level--;
if (Level != 0)
{
{
}
}
/* New "last child" is this parent node */
/* Move up the tree to the grandparent */
}
}
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
}