patch-2.4.0-test3 linux/drivers/acpi/parser/psutils.c

Next file: linux/drivers/acpi/parser/pswalk.c
Previous file: linux/drivers/acpi/parser/pstree.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test2/linux/drivers/acpi/parser/psutils.c linux/drivers/acpi/parser/psutils.c
@@ -0,0 +1,498 @@
+/******************************************************************************
+ *
+ * Module Name: psutils - Parser miscellaneous utilities (Parser only)
+ *
+ *****************************************************************************/
+
+/*
+ *  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 "parser.h"
+#include "amlcode.h"
+
+#define _COMPONENT          PARSER
+	 MODULE_NAME         ("psutils");
+
+
+#define PARSEOP_GENERIC     1
+#define PARSEOP_NAMED       2
+#define PARSEOP_DEFERRED    3
+#define PARSEOP_BYTELIST    4
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ps_init_op
+ *
+ * PARAMETERS:  Op              - A newly allocated Op object
+ *              Opcode          - Opcode to store in the Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
+ *              opcode
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_init_op (
+	ACPI_GENERIC_OP         *op,
+	u16                     opcode)
+{
+	ACPI_OP_INFO             *aml_op;
+
+
+	op->data_type = ACPI_DESC_TYPE_PARSER;
+	op->opcode = opcode;
+
+
+	aml_op = acpi_ps_get_opcode_info (opcode);
+	if (aml_op) {
+		DEBUG_ONLY_MEMBERS (STRNCPY (op->op_name, aml_op->name,
+				   sizeof (op->op_name)));
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ps_alloc_op
+ *
+ * PARAMETERS:  Opcode          - Opcode that will be stored in the new Op
+ *
+ * RETURN:      Pointer to the new Op.
+ *
+ * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
+ *              opcode.  A cache of opcodes is available for the pure
+ *              GENERIC_OP, since this is by far the most commonly used.
+ *
+ ******************************************************************************/
+
+ACPI_GENERIC_OP*
+acpi_ps_alloc_op (
+	u16                     opcode)
+{
+	ACPI_GENERIC_OP         *op = NULL;
+	u32                     size;
+	u8                      flags;
+
+
+	/* Allocate the minimum required size object */
+
+	if (acpi_ps_is_deferred_op (opcode)) {
+		size = sizeof (ACPI_DEFERRED_OP);
+		flags = PARSEOP_DEFERRED;
+	}
+
+	else if (acpi_ps_is_named_op (opcode)) {
+		size = sizeof (ACPI_NAMED_OP);
+		flags = PARSEOP_NAMED;
+	}
+
+	else if (acpi_ps_is_bytelist_op (opcode)) {
+		size = sizeof (ACPI_BYTELIST_OP);
+		flags = PARSEOP_BYTELIST;
+	}
+
+	else {
+		size = sizeof (ACPI_GENERIC_OP);
+		flags = PARSEOP_GENERIC;
+
+		/*
+		 * The generic op is by far the most common (16 to 1), and therefore
+		 * the op cache is implemented with this type.
+		 *
+		 * Check if there is an Op already available in the cache
+		 */
+
+		acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+		acpi_gbl_parse_cache_requests++;
+		if (acpi_gbl_parse_cache) {
+			/* Extract an op from the front of the cache list */
+
+			acpi_gbl_parse_cache_depth--;
+			acpi_gbl_parse_cache_hits++;
+
+			op = acpi_gbl_parse_cache;
+			acpi_gbl_parse_cache = op->next;
+
+			/* Clear the previously used Op */
+
+			MEMSET (op, 0, sizeof (ACPI_GENERIC_OP));
+		}
+		acpi_cm_release_mutex (ACPI_MTX_CACHES);
+	}
+
+	/* Allocate a new Op if necessary */
+
+	if (!op) {
+		op = acpi_cm_callocate (size);
+	}
+
+	/* Initialize the Op */
+	if (op) {
+		acpi_ps_init_op (op, opcode);
+		op->flags = flags;
+	}
+
+	return op;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ps_free_op
+ *
+ * PARAMETERS:  Op              - Op to be freed
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Free an Op object.  Either put it on the GENERIC_OP cache list
+ *              or actually free it.
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_free_op (
+	ACPI_GENERIC_OP         *op)
+{
+
+
+	if (op->flags == PARSEOP_GENERIC) {
+		/* Is the cache full? */
+
+		if (acpi_gbl_parse_cache_depth < MAX_PARSE_CACHE_DEPTH) {
+			/* Put a GENERIC_OP back into the cache */
+
+			acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+			acpi_gbl_parse_cache_depth++;
+
+			op->next = acpi_gbl_parse_cache;
+			acpi_gbl_parse_cache = op;
+
+			acpi_cm_release_mutex (ACPI_MTX_CACHES);
+			return;
+		}
+	}
+
+	/*
+	 * Not a GENERIC OP, or the cache is full, just free the Op
+	 */
+
+	acpi_cm_free (op);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ps_delete_parse_cache
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Free all objects that are on the parse cache list.
+ *
+ ******************************************************************************/
+
+void
+acpi_ps_delete_parse_cache (
+	void)
+{
+	ACPI_GENERIC_OP         *next;
+
+
+	/* Traverse the global cache list */
+
+	while (acpi_gbl_parse_cache) {
+		/* Delete one cached state object */
+
+		next = acpi_gbl_parse_cache->next;
+		acpi_cm_free (acpi_gbl_parse_cache);
+		acpi_gbl_parse_cache = next;
+	}
+
+	return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Utility functions
+ *
+ * DESCRIPTION: Low level functions
+ *
+ * TBD: [Restructure]
+ * 1) Some of these functions should be macros
+ * 2) Some can be simplified
+ *
+ ******************************************************************************/
+
+
+/*
+ * Is "c" a namestring lead character?
+ */
+
+
+u8
+acpi_ps_is_leading_char (
+	s32                     c)
+{
+	return ((u8) (c == '_' || (c >= 'A' && c <= 'Z')));
+}
+
+
+/*
+ * Is "c" a namestring prefix character?
+ */
+u8
+acpi_ps_is_prefix_char (
+	s32                     c)
+{
+	return ((u8) (c == '\\' || c == '^'));
+}
+
+
+u8
+acpi_ps_is_namespace_object_op (
+	u16                     opcode)
+{
+	return ((u8)
+		   (opcode == AML_SCOPE_OP          ||
+			opcode == AML_DEVICE_OP         ||
+			opcode == AML_THERMAL_ZONE_OP   ||
+			opcode == AML_METHOD_OP         ||
+			opcode == AML_POWER_RES_OP      ||
+			opcode == AML_PROCESSOR_OP      ||
+			opcode == AML_DEF_FIELD_OP      ||
+			opcode == AML_INDEX_FIELD_OP    ||
+			opcode == AML_BANK_FIELD_OP     ||
+			opcode == AML_NAMEDFIELD_OP     ||
+			opcode == AML_NAME_OP           ||
+			opcode == AML_ALIAS_OP          ||
+			opcode == AML_MUTEX_OP          ||
+			opcode == AML_EVENT_OP          ||
+			opcode == AML_REGION_OP         ||
+			opcode == AML_CREATE_FIELD_OP   ||
+			opcode == AML_BIT_FIELD_OP      ||
+			opcode == AML_BYTE_FIELD_OP     ||
+			opcode == AML_WORD_FIELD_OP     ||
+			opcode == AML_DWORD_FIELD_OP    ||
+			opcode == AML_METHODCALL_OP     ||
+			opcode == AML_NAMEPATH_OP));
+}
+
+u8
+acpi_ps_is_namespace_op (
+	u16                     opcode)
+{
+	return ((u8)
+		   (opcode == AML_SCOPE_OP          ||
+			opcode == AML_DEVICE_OP         ||
+			opcode == AML_THERMAL_ZONE_OP   ||
+			opcode == AML_METHOD_OP         ||
+			opcode == AML_POWER_RES_OP      ||
+			opcode == AML_PROCESSOR_OP      ||
+			opcode == AML_DEF_FIELD_OP      ||
+			opcode == AML_INDEX_FIELD_OP    ||
+			opcode == AML_BANK_FIELD_OP     ||
+			opcode == AML_NAME_OP           ||
+			opcode == AML_ALIAS_OP          ||
+			opcode == AML_MUTEX_OP          ||
+			opcode == AML_EVENT_OP          ||
+			opcode == AML_REGION_OP         ||
+			opcode == AML_NAMEDFIELD_OP));
+}
+
+
+/*
+ * Is opcode for a named object Op?
+ * (Includes all named object opcodes)
+ *
+ * TBD: [Restructure] Need a better way than this brute force approach!
+ */
+u8
+acpi_ps_is_named_object_op (
+	u16                     opcode)
+{
+	return ((u8)
+		   (opcode == AML_SCOPE_OP          ||
+			opcode == AML_DEVICE_OP         ||
+			opcode == AML_THERMAL_ZONE_OP   ||
+			opcode == AML_METHOD_OP         ||
+			opcode == AML_POWER_RES_OP      ||
+			opcode == AML_PROCESSOR_OP      ||
+			opcode == AML_NAMEDFIELD_OP     ||
+			opcode == AML_NAME_OP           ||
+			opcode == AML_ALIAS_OP          ||
+			opcode == AML_MUTEX_OP          ||
+			opcode == AML_EVENT_OP          ||
+			opcode == AML_REGION_OP         ||
+
+
+			opcode == AML_CREATE_FIELD_OP   ||
+			opcode == AML_BIT_FIELD_OP      ||
+			opcode == AML_BYTE_FIELD_OP     ||
+			opcode == AML_WORD_FIELD_OP     ||
+			opcode == AML_DWORD_FIELD_OP    ||
+			opcode == AML_METHODCALL_OP     ||
+			opcode == AML_NAMEPATH_OP));
+}
+
+
+/*
+ * Is opcode for a named Op?
+ */
+u8
+acpi_ps_is_named_op (
+	u16                     opcode)
+{
+	return ((u8)
+		   (opcode == AML_SCOPE_OP          ||
+			opcode == AML_DEVICE_OP         ||
+			opcode == AML_THERMAL_ZONE_OP   ||
+			opcode == AML_METHOD_OP         ||
+			opcode == AML_POWER_RES_OP      ||
+			opcode == AML_PROCESSOR_OP      ||
+			opcode == AML_NAME_OP           ||
+			opcode == AML_ALIAS_OP          ||
+			opcode == AML_MUTEX_OP          ||
+			opcode == AML_EVENT_OP          ||
+			opcode == AML_REGION_OP         ||
+			opcode == AML_NAMEDFIELD_OP));
+}
+
+
+u8
+acpi_ps_is_deferred_op (
+	u16                     opcode)
+{
+	return ((u8)
+		   (opcode == AML_METHOD_OP ||
+			opcode == AML_REGION_OP));
+}
+
+
+/*
+ * Is opcode for a bytelist?
+ */
+u8
+acpi_ps_is_bytelist_op (
+	u16                     opcode)
+{
+	return ((u8) (opcode == AML_BYTELIST_OP));
+}
+
+
+/*
+ * Is opcode for a Field, Index_field, or Bank_field
+ */
+u8
+acpi_ps_is_field_op (
+	u16                     opcode)
+{
+	return ((u8)
+			  (opcode == AML_CREATE_FIELD_OP
+			|| opcode == AML_DEF_FIELD_OP
+			|| opcode == AML_INDEX_FIELD_OP
+			|| opcode == AML_BANK_FIELD_OP));
+}
+
+
+/*
+ * Is field creation op
+ */
+u8
+acpi_ps_is_create_field_op (
+	u16                     opcode)
+{
+	return ((u8)
+		   (opcode == AML_CREATE_FIELD_OP   ||
+			opcode == AML_BIT_FIELD_OP      ||
+			opcode == AML_BYTE_FIELD_OP     ||
+			opcode == AML_WORD_FIELD_OP     ||
+			opcode == AML_DWORD_FIELD_OP));
+}
+
+
+/*
+ * Cast an acpi_op to an acpi_deferred_op if possible
+ */
+ACPI_DEFERRED_OP *
+acpi_ps_to_deferred_op (
+	ACPI_GENERIC_OP         *op)
+{
+	return (acpi_ps_is_deferred_op (op->opcode)
+			? ( (ACPI_DEFERRED_OP *) op) : NULL);
+}
+
+
+/*
+ * Cast an acpi_op to an acpi_named_op if possible
+ */
+ACPI_NAMED_OP*
+acpi_ps_to_named_op (
+	ACPI_GENERIC_OP         *op)
+{
+	return (acpi_ps_is_named_op (op->opcode)
+			? ( (ACPI_NAMED_OP *) op) : NULL);
+}
+
+
+/*
+ * Cast an acpi_op to an acpi_bytelist_op if possible
+ */
+ACPI_BYTELIST_OP*
+acpi_ps_to_bytelist_op (
+	ACPI_GENERIC_OP         *op)
+{
+	return (acpi_ps_is_bytelist_op (op->opcode)
+			? ( (ACPI_BYTELIST_OP*) op) : NULL);
+}
+
+
+/*
+ * Get op's name (4-byte name segment) or 0 if unnamed
+ */
+u32
+acpi_ps_get_name (
+	ACPI_GENERIC_OP         *op)
+{
+	ACPI_NAMED_OP               *named = acpi_ps_to_named_op (op);
+
+	return (named ? named->name : 0);
+}
+
+
+/*
+ * Set op's name
+ */
+void
+acpi_ps_set_name (
+	ACPI_GENERIC_OP         *op,
+	u32                     name)
+{
+	ACPI_NAMED_OP           *named = acpi_ps_to_named_op (op);
+
+	if (named) {
+		named->name = name;
+	}
+}
+

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