void AcpiNsTerminate ( void) { ACPI_STATUS Status; ACPI_FUNCTION_TRACE (NsTerminate); /* * Free the entire namespace -- all nodes and all objects * attached to the nodes */ AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); /* Delete any objects attached to the root node */ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return_VOID; } AcpiNsDeleteNode (AcpiGbl_RootNode); (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); return_VOID; }
void AcpiNsRemoveNode ( ACPI_NAMESPACE_NODE *Node) { ACPI_NAMESPACE_NODE *ParentNode; ACPI_NAMESPACE_NODE *PrevNode; ACPI_NAMESPACE_NODE *NextNode; ACPI_FUNCTION_TRACE_PTR (NsRemoveNode, Node); ParentNode = AcpiNsGetParentNode (Node); PrevNode = NULL; NextNode = ParentNode->Child; /* Find the node that is the previous peer in the parent's child list */ while (NextNode != Node) { PrevNode = NextNode; NextNode = PrevNode->Peer; } if (PrevNode) { /* Node is not first child, unlink it */ PrevNode->Peer = NextNode->Peer; if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) { PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST; } } else { /* Node is first child (has no previous peer) */ if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) { /* No peers at all */ ParentNode->Child = NULL; } else { /* Link peer list to parent */ ParentNode->Child = NextNode->Peer; } } /* Delete the node and any attached objects */ AcpiNsDeleteNode (Node); return_VOID; }
void AcpiNsDeleteChildren ( ACPI_NAMESPACE_NODE *ParentNode) { ACPI_NAMESPACE_NODE *ChildNode; ACPI_NAMESPACE_NODE *NextNode; UINT8 Flags; ACPI_FUNCTION_TRACE_PTR (NsDeleteChildren, ParentNode); if (!ParentNode) { return_VOID; } /* If no children, all done! */ ChildNode = ParentNode->Child; if (!ChildNode) { return_VOID; } /* Deallocate all children at this level */ do { /* Get the things we need */ NextNode = ChildNode->Peer; Flags = ChildNode->Flags; /* Grandchildren should have all been deleted already */ if (ChildNode->Child) { ACPI_ERROR ((AE_INFO, "Found a grandchild! P=%p C=%p", ParentNode, ChildNode)); } /* * 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. */ AcpiNsDeleteNode (ChildNode); ChildNode = NextNode; } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); /* Clear the parent's child pointer */ ParentNode->Child = NULL; return_VOID; }
void AcpiNsTerminate ( void) { ACPI_STATUS Status; ACPI_FUNCTION_TRACE (NsTerminate); #ifdef ACPI_EXEC_APP { ACPI_OPERAND_OBJECT *Prev; ACPI_OPERAND_OBJECT *Next; /* Delete any module-level code blocks */ Next = AcpiGbl_ModuleCodeList; while (Next) { Prev = Next; Next = Next->Method.Mutex; Prev->Method.Mutex = NULL; /* Clear the Mutex (cheated) field */ AcpiUtRemoveReference (Prev); } } #endif /* * Free the entire namespace -- all nodes and all objects * attached to the nodes */ AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); /* Delete any objects attached to the root node */ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return_VOID; } AcpiNsDeleteNode (AcpiGbl_RootNode); (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); return_VOID; }
void AcpiNsRemoveNode ( ACPI_NAMESPACE_NODE *Node) { ACPI_NAMESPACE_NODE *ParentNode; ACPI_NAMESPACE_NODE *PrevNode; ACPI_NAMESPACE_NODE *NextNode; ACPI_FUNCTION_TRACE_PTR (NsRemoveNode, Node); ParentNode = Node->Parent; PrevNode = NULL; NextNode = ParentNode->Child; /* Find the node that is the previous peer in the parent's child list */ while (NextNode != Node) { PrevNode = NextNode; NextNode = NextNode->Peer; } if (PrevNode) { /* Node is not first child, unlink it */ PrevNode->Peer = Node->Peer; } else { /* * Node is first child (has no previous peer). * Link peer list to parent */ ParentNode->Child = Node->Peer; } /* Delete the node and any attached objects */ AcpiNsDeleteNode (Node); return_VOID; }
void AcpiNsDeleteChildren ( ACPI_NAMESPACE_NODE *ParentNode) { ACPI_NAMESPACE_NODE *NextNode; ACPI_NAMESPACE_NODE *NodeToDelete; ACPI_FUNCTION_TRACE_PTR (NsDeleteChildren, ParentNode); if (!ParentNode) { return_VOID; } /* Deallocate all children at this level */ NextNode = ParentNode->Child; while (NextNode) { /* Grandchildren should have all been deleted already */ if (NextNode->Child) { ACPI_ERROR ((AE_INFO, "Found a grandchild! P=%p C=%p", 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. */ NodeToDelete = NextNode; NextNode = NextNode->Peer; AcpiNsDeleteNode (NodeToDelete); }; /* Clear the parent's child pointer */ ParentNode->Child = NULL; return_VOID; }
static ACPI_STATUS AcpiNsDeleteSubtree ( ACPI_HANDLE StartHandle) { ACPI_STATUS Status; ACPI_HANDLE ChildHandle; ACPI_HANDLE ParentHandle; ACPI_HANDLE NextChildHandle; ACPI_HANDLE Dummy; UINT32 Level; ACPI_FUNCTION_TRACE (NsDeleteSubtree); ParentHandle = StartHandle; ChildHandle = NULL; Level = 1; /* * Traverse the tree of objects until we bubble back up * to where we started. */ while (Level > 0) { /* Attempt to get the next object in this scope */ Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle, ChildHandle, &NextChildHandle); ChildHandle = NextChildHandle; /* Did we get a new object? */ if (ACPI_SUCCESS (Status)) { /* Check if this object has any children */ if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle, NULL, &Dummy))) { /* * There is at least one child of this object, * visit the object */ Level++; ParentHandle = ChildHandle; ChildHandle = NULL; } } else { /* * No more children in this object, go back up to * the object's parent */ Level--; /* Delete all children now */ AcpiNsDeleteChildren (ChildHandle); ChildHandle = ParentHandle; Status = AcpiGetParent (ParentHandle, &ParentHandle); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } } /* Now delete the starting object, and we are done */ AcpiNsDeleteNode (ChildHandle); return_ACPI_STATUS (AE_OK); }
void AcpiNsDeleteNamespaceByOwner ( ACPI_OWNER_ID OwnerId) { ACPI_NAMESPACE_NODE *ChildNode; ACPI_NAMESPACE_NODE *DeletionNode; ACPI_NAMESPACE_NODE *ParentNode; UINT32 Level; ACPI_STATUS Status; ACPI_FUNCTION_TRACE_U32 (NsDeleteNamespaceByOwner, OwnerId); if (OwnerId == 0) { return_VOID; } /* Lock namespace for possible update */ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return_VOID; } DeletionNode = NULL; ParentNode = AcpiGbl_RootNode; ChildNode = 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 */ ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); if (DeletionNode) { AcpiNsDeleteChildren (DeletionNode); AcpiNsDeleteNode (DeletionNode); DeletionNode = NULL; } if (ChildNode) { if (ChildNode->OwnerId == OwnerId) { /* Found a matching child node - detach any attached object */ AcpiNsDetachObject (ChildNode); } /* Check if this node has any children */ if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) { /* * There is at least one child of this node, * visit the node */ Level++; ParentNode = ChildNode; ChildNode = NULL; } else if (ChildNode->OwnerId == OwnerId) { DeletionNode = ChildNode; } } else { /* * No more children of this parent node. * Move up to the grandparent. */ Level--; if (Level != 0) { if (ParentNode->OwnerId == OwnerId) { DeletionNode = ParentNode; } } /* New "last child" is this parent node */ ChildNode = ParentNode; /* Move up the tree to the grandparent */ ParentNode = AcpiNsGetParentNode (ParentNode); } } (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); return_VOID; }