Ejemplo n.º 1
0
void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
{
	struct acpi_namespace_node *child_node;
	struct acpi_namespace_node *next_node;
	u8 flags;

	ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node);

	if (!parent_node) {
		return_VOID;
	}

	/* If no children, all done! */

	child_node = parent_node->child;
	if (!child_node) {
		return_VOID;
	}

	/* Deallocate all children at this level */

	do {

		/* Get the things we need */

		next_node = child_node->peer;
		flags = child_node->flags;

		/* Grandchildren should have all been deleted already */

		if (child_node->child) {
			ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p",
				    parent_node, child_node));
		}

		/*
		 * 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.
		 */
		acpi_ns_delete_node(child_node);
		child_node = next_node;

	} while (!(flags & ANOBJ_END_OF_PEER_LIST));

	/* Clear the parent's child pointer */

	parent_node->child = NULL;
	return_VOID;
}
Ejemplo n.º 2
0
void acpi_ns_remove_node(struct acpi_namespace_node *node)
{
	struct acpi_namespace_node *parent_node;
	struct acpi_namespace_node *prev_node;
	struct acpi_namespace_node *next_node;

	ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node);

	parent_node = acpi_ns_get_parent_node(node);

	prev_node = NULL;
	next_node = parent_node->child;

	

	while (next_node != node) {
		prev_node = next_node;
		next_node = prev_node->peer;
	}

	if (prev_node) {

		

		prev_node->peer = next_node->peer;
		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
			prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
		}
	} else {
		

		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {

			

			parent_node->child = NULL;
		} else {	

			parent_node->child = next_node->peer;
		}
	}

	

	acpi_ns_delete_node(node);
	return_VOID;
}
Ejemplo n.º 3
0
void acpi_ns_remove_node(struct acpi_namespace_node *node)
{
	struct acpi_namespace_node *parent_node;
	struct acpi_namespace_node *prev_node;
	struct acpi_namespace_node *next_node;

	ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node);

	parent_node = acpi_ns_get_parent_node(node);

	prev_node = NULL;
	next_node = parent_node->child;

	/* Find the node that is the previous peer in the parent's child list */

	while (next_node != node) {
		prev_node = next_node;
		next_node = prev_node->peer;
	}

	if (prev_node) {

		/* Node is not first child, unlink it */

		prev_node->peer = next_node->peer;
		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
			prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
		}
	} else {
		/* Node is first child (has no previous peer) */

		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {

			/* No peers at all */

			parent_node->child = NULL;
		} else {	/* Link peer list to parent */

			parent_node->child = next_node->peer;
		}
	}

	/* Delete the node and any attached objects */

	acpi_ns_delete_node(node);
	return_VOID;
}
Ejemplo n.º 4
0
void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
{
	struct acpi_namespace_node *child_node;
	struct acpi_namespace_node *next_node;
	u8 flags;

	ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node);

	if (!parent_node) {
		return_VOID;
	}

	

	child_node = parent_node->child;
	if (!child_node) {
		return_VOID;
	}

	

	do {

		

		next_node = child_node->peer;
		flags = child_node->flags;

		

		if (child_node->child) {
			ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p",
				    parent_node, child_node));
		}

		
		acpi_ns_delete_node(child_node);
		child_node = next_node;

	} while (!(flags & ANOBJ_END_OF_PEER_LIST));

	

	parent_node->child = NULL;
	return_VOID;
}
Ejemplo n.º 5
0
void acpi_ns_terminate(void)
{
    acpi_status status;

    ACPI_FUNCTION_TRACE(ns_terminate);

#ifdef ACPI_EXEC_APP
    {
        union acpi_operand_object *prev;
        union acpi_operand_object *next;

        /* Delete any module-level code blocks */

        next = acpi_gbl_module_code_list;
        while (next) {
            prev = next;
            next = next->method.mutex;
            prev->method.mutex = NULL;	/* Clear the Mutex (cheated) field */
            acpi_ut_remove_reference(prev);
        }
    }
#endif

    /*
     * Free the entire namespace -- all nodes and all objects
     * attached to the nodes
     */
    acpi_ns_delete_namespace_subtree(acpi_gbl_root_node);

    /* Delete any objects attached to the root node */

    status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE(status)) {
        return_VOID;
    }

    acpi_ns_delete_node(acpi_gbl_root_node);
    (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

    ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
    return_VOID;
}
Ejemplo n.º 6
0
void acpi_ns_remove_node(struct acpi_namespace_node *node)
{
	struct acpi_namespace_node *parent_node;
	struct acpi_namespace_node *prev_node;
	struct acpi_namespace_node *next_node;

	ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node);

	parent_node = node->parent;

	prev_node = NULL;
	next_node = parent_node->child;

	/* Find the node that is the previous peer in the parent's child list */

	while (next_node != node) {
		prev_node = next_node;
		next_node = next_node->peer;
	}

	if (prev_node) {

		/* Node is not first child, unlink it */

		prev_node->peer = node->peer;
	} else {
		/*
		 * Node is first child (has no previous peer).
		 * Link peer list to parent
		 */
		parent_node->child = node->peer;
	}

	/* Delete the node and any attached objects */

	acpi_ns_delete_node(node);
	return_VOID;
}
Ejemplo n.º 7
0
void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
{
	struct acpi_namespace_node *next_node;
	struct acpi_namespace_node *node_to_delete;

	ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node);

	if (!parent_node) {
		return_VOID;
	}

	/* Deallocate all children at this level */

	next_node = parent_node->child;
	while (next_node) {

		/* Grandchildren should have all been deleted already */

		if (next_node->child) {
			ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p",
				    parent_node, next_node));
		}

		/*
		 * 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.
		 */
		node_to_delete = next_node;
		next_node = next_node->peer;
		acpi_ns_delete_node(node_to_delete);
	};

	/* Clear the parent's child pointer */

	parent_node->child = NULL;
	return_VOID;
}
Ejemplo n.º 8
0
void
acpi_ns_remove_reference (
	struct acpi_namespace_node      *node)
{
	struct acpi_namespace_node      *parent_node;
	struct acpi_namespace_node      *this_node;


	ACPI_FUNCTION_ENTRY ();


	/*
	 * Decrement the reference count(s) of this node and all
	 * nodes up to the root,  Delete anything with zero remaining references.
	 */
	this_node = node;
	while (this_node) {
		/* Prepare to move up to parent */

		parent_node = acpi_ns_get_parent_node (this_node);

		/* Decrement the reference count on this node */

		this_node->reference_count--;

		/* Delete the node if no more references */

		if (!this_node->reference_count) {
			/* Delete all children and delete the node */

			acpi_ns_delete_children (this_node);
			acpi_ns_delete_node (this_node);
		}

		this_node = parent_node;
	}
}
Ejemplo n.º 9
0
Archivo: nsload.c Proyecto: 274914765/C
static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle)
{
    acpi_status status;
    acpi_handle child_handle;
    acpi_handle parent_handle;
    acpi_handle next_child_handle;
    acpi_handle dummy;
    u32 level;

    ACPI_FUNCTION_TRACE(ns_delete_subtree);

    parent_handle = start_handle;
    child_handle = 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 = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle,
                          child_handle, &next_child_handle);

        child_handle = next_child_handle;

        /* Did we get a new object? */

        if (ACPI_SUCCESS(status)) {

            /* Check if this object has any children */

            if (ACPI_SUCCESS
                (acpi_get_next_object
                 (ACPI_TYPE_ANY, child_handle, NULL, &dummy))) {
                /*
                 * There is at least one child of this object,
                 * visit the object
                 */
                level++;
                parent_handle = child_handle;
                child_handle = NULL;
            }
        } else {
            /*
             * No more children in this object, go back up to
             * the object's parent
             */
            level--;

            /* Delete all children now */

            acpi_ns_delete_children(child_handle);

            child_handle = parent_handle;
            status = acpi_get_parent(parent_handle, &parent_handle);
            if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
            }
        }
    }

    /* Now delete the starting object, and we are done */

    acpi_ns_delete_node(child_handle);

    return_ACPI_STATUS(AE_OK);
}
Ejemplo n.º 10
0
void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
{
	struct acpi_namespace_node *child_node;
	struct acpi_namespace_node *deletion_node;
	struct acpi_namespace_node *parent_node;
	u32 level;
	acpi_status status;

	ACPI_FUNCTION_TRACE_U32(ns_delete_namespace_by_owner, owner_id);

	if (owner_id == 0) {
		return_VOID;
	}

	/* Lock namespace for possible update */

	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
		return_VOID;
	}

	deletion_node = NULL;
	parent_node = acpi_gbl_root_node;
	child_node = 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 child_node is NULL,
		 * the first child of the parent is returned
		 */
		child_node =
		    acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
					  child_node);

		if (deletion_node) {
			acpi_ns_delete_children(deletion_node);
			acpi_ns_delete_node(deletion_node);
			deletion_node = NULL;
		}

		if (child_node) {
			if (child_node->owner_id == owner_id) {

				/* Found a matching child node - detach any attached object */

				acpi_ns_detach_object(child_node);
			}

			/* Check if this node has any children */

			if (acpi_ns_get_next_node
			    (ACPI_TYPE_ANY, child_node, NULL)) {
				/*
				 * There is at least one child of this node,
				 * visit the node
				 */
				level++;
				parent_node = child_node;
				child_node = NULL;
			} else if (child_node->owner_id == owner_id) {
				deletion_node = child_node;
			}
		} else {
			/*
			 * No more children of this parent node.
			 * Move up to the grandparent.
			 */
			level--;
			if (level != 0) {
				if (parent_node->owner_id == owner_id) {
					deletion_node = parent_node;
				}
			}

			/* New "last child" is this parent node */

			child_node = parent_node;

			/* Move up the tree to the grandparent */

			parent_node = acpi_ns_get_parent_node(parent_node);
		}
	}

	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
	return_VOID;
}