Fix several AcpiAttachData problems.

Handler was never invoked. Now invoked if/when host node is deleted.
Data object was not automatically deleted when host node was deleted.
Interface to handler had an unused parameter, removed it.
ACPICA BZ 778.
This commit is contained in:
Robert Moore 2009-06-19 13:23:34 -07:00
parent 64a735c120
commit ace198676c
5 changed files with 103 additions and 30 deletions

View File

@ -181,20 +181,78 @@ AcpiNsCreateNode (
*
* RETURN: None
*
* DESCRIPTION: Delete a namespace node
* 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
AcpiNsDeleteNode (
ACPI_NAMESPACE_NODE *Node)
{
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_FUNCTION_NAME (NsDeleteNode);
/* Detach an object if there is one */
AcpiNsDetachObject (Node);
/*
* Delete an attached data object if present (an object that was created
* and attached via AcpiAttachData). Note: After any normal object is
* detached above, the only possible remaining object is a data object.
*/
ObjDesc = Node->Object;
if (ObjDesc &&
(ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA))
{
/* Invoke the attached data deletion handler if present */
if (ObjDesc->Data.Handler)
{
ObjDesc->Data.Handler (Node, ObjDesc->Data.Pointer);
}
AcpiUtRemoveReference (ObjDesc);
}
/* Now we can delete the node */
(void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node);
ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++);
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n",
Node, AcpiGbl_CurrentNodeCount));
}
/*******************************************************************************
*
* FUNCTION: AcpiNsRemoveNode
*
* PARAMETERS: Node - Node to be removed/deleted
*
* RETURN: None
*
* DESCRIPTION: Remove (unlink) and delete a namespace node
*
******************************************************************************/
void
AcpiNsRemoveNode (
ACPI_NAMESPACE_NODE *Node)
{
ACPI_NAMESPACE_NODE *ParentNode;
ACPI_NAMESPACE_NODE *PrevNode;
ACPI_NAMESPACE_NODE *NextNode;
ACPI_FUNCTION_TRACE_PTR (NsDeleteNode, Node);
ACPI_FUNCTION_TRACE_PTR (NsRemoveNode, Node);
ParentNode = AcpiNsGetParentNode (Node);
@ -237,12 +295,9 @@ AcpiNsDeleteNode (
}
}
ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++);
/* Delete the node and any attached objects */
/* Detach an object if there is one, then delete the node */
AcpiNsDetachObject (Node);
(void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node);
AcpiNsDeleteNode (Node);
return_VOID;
}
@ -385,23 +440,11 @@ AcpiNsDeleteChildren (
ParentNode, ChildNode));
}
/* Now we can free this child object */
ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++);
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n",
ChildNode, AcpiGbl_CurrentNodeCount));
/* Detach an object if there is one, then free the child node */
AcpiNsDetachObject (ChildNode);
/* Now we can delete the node */
(void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, ChildNode);
/* And move on to the next child in the list */
/*
* 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));
@ -561,7 +604,7 @@ AcpiNsDeleteNamespaceByOwner (
if (DeletionNode)
{
AcpiNsDeleteChildren (DeletionNode);
AcpiNsDeleteNode (DeletionNode);
AcpiNsRemoveNode (DeletionNode);
DeletionNode = NULL;
}

View File

@ -376,8 +376,7 @@ AcpiNsDeleteSubtree (
/* Now delete the starting object, and we are done */
AcpiNsDeleteNode (ChildHandle);
AcpiNsRemoveNode (ChildHandle);
return_ACPI_STATUS (AE_OK);
}

View File

@ -240,6 +240,10 @@ void
AcpiNsDeleteNode (
ACPI_NAMESPACE_NODE *Node);
void
AcpiNsRemoveNode (
ACPI_NAMESPACE_NODE *Node);
void
AcpiNsDeleteNamespaceSubtree (
ACPI_NAMESPACE_NODE *ParentHandle);

View File

@ -1057,7 +1057,6 @@ void (*ACPI_NOTIFY_HANDLER) (
typedef
void (*ACPI_OBJECT_HANDLER) (
ACPI_HANDLE Object,
UINT32 Function,
void *Data);
typedef

View File

@ -153,6 +153,10 @@ AeRegionInit (
void *HandlerContext,
void **RegionContext);
void
AeAttachedDataHandler (
ACPI_HANDLE Object,
void *Data);
UINT32 SigintCount = 0;
AE_DEBUG_REGIONS AeRegions;
@ -446,13 +450,33 @@ UINT32
AeGpeHandler (
void *Context)
{
AcpiOsPrintf ("Received a GPE at handler\n");
return (0);
}
/******************************************************************************
*
* FUNCTION: AeAttachedDataHandler
*
* DESCRIPTION: Handler for deletion of nodes with attached data (attached via
* AcpiAttachData)
*
*****************************************************************************/
void
AeAttachedDataHandler (
ACPI_HANDLE Object,
void *Data)
{
ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
AcpiOsPrintf ("Received an attached data deletion on %4.4s\n",
Node->Name.Ascii);
}
/******************************************************************************
*
* FUNCTION: AeRegionInit
@ -569,6 +593,10 @@ AeInstallHandlers (void)
printf ("Could not install a notify handler, %s\n",
AcpiFormatException (Status));
}
Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
Status = AcpiDetachData (Handle, AeAttachedDataHandler);
Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
}
else
{