patch-2.4.0-test3 linux/drivers/acpi/namespace/nsobject.c

Next file: linux/drivers/acpi/namespace/nssearch.c
Previous file: linux/drivers/acpi/namespace/nsnames.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test2/linux/drivers/acpi/namespace/nsobject.c linux/drivers/acpi/namespace/nsobject.c
@@ -0,0 +1,556 @@
+
+/******************************************************************************
+ *
+ * Module Name: nsobject - Utilities for objects attached to namespace
+ *                          table entries
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "amlcode.h"
+#include "namesp.h"
+#include "interp.h"
+#include "tables.h"
+
+
+#define _COMPONENT          NAMESPACE
+	 MODULE_NAME         ("nsobject");
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_attach_object
+ *
+ * PARAMETERS:  Handle              - Handle of nte
+ *              Object              - Object to be attached
+ *              Type                - Type of object, or ACPI_TYPE_ANY if not
+ *                                      known
+ *
+ * DESCRIPTION: Record the given object as the value associated with the
+ *              name whose ACPI_HANDLE is passed.  If Object is NULL
+ *              and Type is ACPI_TYPE_ANY, set the name as having no value.
+ *
+ * MUTEX:       Assumes namespace is locked
+ *
+ ***************************************************************************/
+
+ACPI_STATUS
+acpi_ns_attach_object (
+	ACPI_HANDLE             handle,
+	ACPI_HANDLE             object,
+	OBJECT_TYPE_INTERNAL    type)
+{
+	ACPI_NAMED_OBJECT       *this_entry = (ACPI_NAMED_OBJECT*) handle;
+	ACPI_OBJECT_INTERNAL    *obj_desc;
+	ACPI_OBJECT_INTERNAL    *previous_obj_desc;
+	OBJECT_TYPE_INTERNAL    obj_type = ACPI_TYPE_ANY;
+	u8                      flags;
+	u16                     opcode;
+
+
+	/*
+	 * Parameter validation
+	 */
+
+	if (!acpi_gbl_root_object->child_table) {
+		/* Name space not initialized  */
+
+		REPORT_ERROR ("Ns_attach_object: Name space not initialized");
+		return (AE_NO_NAMESPACE);
+	}
+
+	if (!handle) {
+		/* Invalid handle */
+
+		REPORT_ERROR ("Ns_attach_object: Null name handle");
+		return (AE_BAD_PARAMETER);
+	}
+
+	if (!object && (ACPI_TYPE_ANY != type)) {
+		/* Null object */
+
+		REPORT_ERROR ("Ns_attach_object: Null object, but type"
+				  "not ACPI_TYPE_ANY");
+		return (AE_BAD_PARAMETER);
+	}
+
+	if (!VALID_DESCRIPTOR_TYPE (handle, ACPI_DESC_TYPE_NAMED)) {
+		/* Not a name handle */
+
+		REPORT_ERROR ("Ns_attach_object: Invalid handle");
+		return (AE_BAD_PARAMETER);
+	}
+
+	/* Check if this object is already attached */
+
+	if (this_entry->object == object) {
+		return (AE_OK);
+	}
+
+
+	/* Get the current flags field of the NTE */
+
+	flags = this_entry->flags;
+	flags &= ~NTE_AML_ATTACHMENT;
+
+
+	/* If null object, we will just install it */
+
+	if (!object) {
+		obj_desc = NULL;
+		obj_type = ACPI_TYPE_ANY;
+	}
+
+	/*
+	 * If the object is an NTE with an attached object,
+	 * we will use that (attached) object
+	 */
+
+	else if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED) &&
+			((ACPI_NAMED_OBJECT*) object)->object)
+	{
+		/*
+		 * Value passed is a name handle and that name has a
+		 * non-null value.  Use that name's value and type.
+		 */
+
+		obj_desc = ((ACPI_NAMED_OBJECT*) object)->object;
+		obj_type = ((ACPI_NAMED_OBJECT*) object)->type;
+
+		/*
+		 * Copy appropriate flags
+		 */
+
+		if (((ACPI_NAMED_OBJECT*) object)->flags & NTE_AML_ATTACHMENT) {
+			flags |= NTE_AML_ATTACHMENT;
+		}
+	}
+
+
+	/*
+	 * Otherwise, we will use the parameter object, but we must type
+	 * it first
+	 */
+
+	else {
+		obj_desc = (ACPI_OBJECT_INTERNAL *) object;
+
+
+		/* If a valid type (non-ANY) was given, just use it */
+
+		if (ACPI_TYPE_ANY != type) {
+			obj_type = type;
+		}
+
+
+		/*
+		 * Type is TYPE_Any, we must try to determinte the
+		 * actual type of the object
+		 */
+
+		/*
+		 * Check if value points into the AML code
+		 */
+		else if (acpi_tb_system_table_pointer (object)) {
+			/*
+			 * Object points into the AML stream.
+			 * Set a flag bit in the NTE to indicate this
+			 */
+
+			flags |= NTE_AML_ATTACHMENT;
+
+			/*
+			 * The next byte (perhaps the next two bytes)
+			 * will be the AML opcode
+			 */
+
+			MOVE_UNALIGNED16_TO_16 (&opcode, object);
+
+			/* Check for a recognized Op_code */
+
+			switch ((u8) opcode)
+			{
+
+			case AML_OP_PREFIX:
+
+				if (opcode != AML_REVISION_OP) {
+					/*
+					 * Op_prefix is unrecognized unless part
+					 * of Revision_op
+					 */
+
+					break;
+				}
+
+				/* Else fall through to set type as Number */
+
+
+			case AML_ZERO_OP: case AML_ONES_OP: case AML_ONE_OP:
+			case AML_BYTE_OP: case AML_WORD_OP: case AML_DWORD_OP:
+
+				obj_type = ACPI_TYPE_NUMBER;
+				break;
+
+
+			case AML_STRING_OP:
+
+				obj_type = ACPI_TYPE_STRING;
+				break;
+
+
+			case AML_BUFFER_OP:
+
+				obj_type = ACPI_TYPE_BUFFER;
+				break;
+
+
+			case AML_MUTEX_OP:
+
+				obj_type = ACPI_TYPE_MUTEX;
+				break;
+
+
+			case AML_PACKAGE_OP:
+
+				obj_type = ACPI_TYPE_PACKAGE;
+				break;
+
+
+			default:
+
+				return (AE_TYPE);
+				break;
+			}
+		}
+
+		else {
+			/*
+			 * Cannot figure out the type -- set to Def_any which
+			 * will print as an error in the name table dump
+			 */
+
+
+			obj_type = INTERNAL_TYPE_DEF_ANY;
+		}
+	}
+
+
+	/*
+	 * Must increment the new value's reference count
+	 * (if it is an internal object)
+	 */
+
+	acpi_cm_add_reference (obj_desc);
+
+	/* Save the existing object (if any) for deletion later */
+
+	previous_obj_desc = this_entry->object;
+
+	/* Install the object and set the type, flags */
+
+	this_entry->object  = obj_desc;
+	this_entry->type    = (u8) obj_type;
+	this_entry->flags   = flags;
+
+
+	/*
+	 * Delete an existing attached object.
+	 */
+
+	if (previous_obj_desc) {
+		/* One for the attach to the NTE */
+		acpi_cm_remove_reference (previous_obj_desc);
+		/* Now delete */
+		acpi_cm_remove_reference (previous_obj_desc);
+	}
+
+	return (AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_attach_method
+ *
+ * PARAMETERS:  Handle              - Handle of nte to be set
+ *              Offset              - Value to be set
+ *              Length              - Length associated with value
+ *
+ * DESCRIPTION: Record the given offset and p-code length of the method
+ *              whose handle is passed
+ *
+ * MUTEX:       Assumes namespace is locked
+ *
+ ***************************************************************************/
+
+ACPI_STATUS
+acpi_ns_attach_method (
+	ACPI_HANDLE             handle,
+	u8                      *pcode_addr,
+	u32                     pcode_length)
+{
+	ACPI_OBJECT_INTERNAL    *obj_desc;
+	ACPI_OBJECT_INTERNAL    *previous_obj_desc;
+	ACPI_NAMED_OBJECT       *this_entry = (ACPI_NAMED_OBJECT*) handle;
+
+
+	/* Parameter validation */
+
+	if (!acpi_gbl_root_object->child_table) {
+		/* Name space uninitialized */
+
+		REPORT_ERROR ("Ns_attach_method: name space uninitialized");
+		return (AE_NO_NAMESPACE);
+	}
+
+	if (!handle) {
+		/* Null name handle */
+
+		REPORT_ERROR ("Ns_attach_method: null name handle");
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	/* Allocate a method descriptor */
+
+	obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_METHOD);
+	if (!obj_desc) {
+		/* Method allocation failure  */
+
+		REPORT_ERROR ("Ns_attach_method: allocation failure");
+		return (AE_NO_MEMORY);
+	}
+
+	/* Init the method info */
+
+	obj_desc->method.pcode      = pcode_addr;
+	obj_desc->method.pcode_length = pcode_length;
+
+	/* Update reference count and install */
+
+	acpi_cm_add_reference (obj_desc);
+
+	previous_obj_desc = this_entry->object;
+	this_entry->object = obj_desc;
+
+
+	/*
+	 * Delete an existing object.  Don't try to re-use in case it is shared
+	 */
+	if (previous_obj_desc) {
+		acpi_cm_remove_reference (previous_obj_desc);
+	}
+
+	return (AE_OK);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_detach_object
+ *
+ * PARAMETERS:  Object           - An object whose Value will be deleted
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Delete the Value associated with a namespace object.  If the
+ *              Value is an allocated object, it is freed.  Otherwise, the
+ *              field is simply cleared.
+ *
+ ***************************************************************************/
+
+void
+acpi_ns_detach_object (
+	ACPI_HANDLE             object)
+{
+	ACPI_NAMED_OBJECT       *entry = object;
+	ACPI_OBJECT_INTERNAL    *obj_desc;
+
+
+	obj_desc = entry->object;
+	if (!obj_desc) {
+		return;
+	}
+
+	/* Clear the entry in all cases */
+
+	entry->object = NULL;
+
+	/* Found a valid value */
+
+	/*
+	 * Not every value is an object allocated via Acpi_cm_callocate,
+	 * - must check
+	 */
+
+	if (!acpi_tb_system_table_pointer (obj_desc)) {
+		/* Attempt to delete the object (and all subobjects) */
+
+		acpi_cm_remove_reference (obj_desc);
+	}
+
+	return;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_get_attached_object
+ *
+ * PARAMETERS:  Handle              - Handle of nte to be examined
+ *
+ * RETURN:      Current value of the object field from nte whose handle is
+ *              passed
+ *
+ ***************************************************************************/
+
+void *
+acpi_ns_get_attached_object (
+	ACPI_HANDLE             handle)
+{
+
+	if (!handle) {
+		/* handle invalid */
+
+		REPORT_WARNING ("Ns_get_attached_object: Null handle");
+		return (NULL);
+	}
+
+	return (((ACPI_NAMED_OBJECT*) handle)->object);
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_compare_object
+ *
+ * PARAMETERS:  Obj_handle          - A namespace entry
+ *              Level               - Current nesting level
+ *              Obj_desc            - The value to be compared
+ *
+ * DESCRIPTION: A User_function called by Acpi_ns_walk_namespace(). It performs
+ *              a comparison for Acpi_ns_find_attached_object(). The comparison is against
+ *              the value in the value field of the Obj_handle (an NTE).
+ *              If a match is found, the handle is returned, which aborts
+ *              Acpi_ns_walk_namespace.
+ *
+ ***************************************************************************/
+
+ACPI_STATUS
+acpi_ns_compare_object (
+	ACPI_HANDLE             obj_handle,
+	u32                     level,
+	void                    *obj_desc,
+	void                    **return_value)
+{
+
+	if (((ACPI_NAMED_OBJECT*) obj_handle)->object == obj_desc) {
+		if (return_value) {
+			*return_value = obj_handle;
+		}
+
+		 /* Stop the walk */
+		return AE_CTRL_TERMINATE;
+	}
+
+	/* Not found, continue the walk */
+	return AE_OK;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_find_attached_object
+ *
+ * PARAMETERS:  *Obj_desc           - Value to be found in ptr_val field.
+ *              Start_handle        - Root of subtree to be searched, or
+ *                                    NS_ALL to search the entire namespace
+ *              Max_depth           - Maximum depth of search.  Use INT_MAX
+ *                                    for an effectively unlimited depth.
+ *
+ * DESCRIPTION: Traverse the name space until finding a name whose Value field
+ *              matches the Obj_desc parameter, and return a handle to that
+ *              name, or (ACPI_HANDLE)0 if none exists.
+ *              if Start_handle is NS_ALL (null) search from the root,
+ *              else it is a handle whose children are to be searched.
+ *
+ ***************************************************************************/
+
+ACPI_HANDLE
+acpi_ns_find_attached_object (
+	ACPI_OBJECT_INTERNAL    *obj_desc,
+	ACPI_HANDLE             start_handle,
+	s32                     max_depth)
+{
+	ACPI_HANDLE             ret_object;
+	ACPI_STATUS             status;
+
+
+	/* Parameter validation */
+
+	if (!obj_desc) {
+		return (NULL);
+	}
+
+	if (0 == max_depth) {
+		return (NULL);
+	}
+
+	if (!acpi_gbl_root_object->child_table) {
+		/*
+		 * If the name space has not been initialized,
+		 * there surely are no matching values.
+		 */
+		return (NULL);
+	}
+
+	if (NS_ALL == start_handle) {
+		start_handle = acpi_gbl_root_object;
+	}
+
+	else {
+		/*
+		 * If base is not the root and has no children,
+		 * there is nothing to search.
+		 */
+		return (NULL);
+	}
+
+
+	/*
+	 * Walk namespace until a match is found.
+	 * Either the matching object is returned, or NULL in case
+	 * of no match.
+	 */
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, start_handle,
+			   max_depth, NS_WALK_NO_UNLOCK,
+			   acpi_ns_compare_object,
+			   obj_desc, &ret_object);
+
+	if (ACPI_FAILURE (status)) {
+		ret_object = NULL;
+	}
+
+	return (ret_object);
+}
+
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)