File: /usr/src/linux/drivers/acpi/parser/psxface.c

1     /******************************************************************************
2      *
3      * Module Name: psxface - Parser external interfaces
4      *              $Revision: 47 $
5      *
6      *****************************************************************************/
7     
8     /*
9      *  Copyright (C) 2000, 2001 R. Byron Moore
10      *
11      *  This program is free software; you can redistribute it and/or modify
12      *  it under the terms of the GNU General Public License as published by
13      *  the Free Software Foundation; either version 2 of the License, or
14      *  (at your option) any later version.
15      *
16      *  This program is distributed in the hope that it will be useful,
17      *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18      *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19      *  GNU General Public License for more details.
20      *
21      *  You should have received a copy of the GNU General Public License
22      *  along with this program; if not, write to the Free Software
23      *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24      */
25     
26     
27     #include "acpi.h"
28     #include "acparser.h"
29     #include "acdispat.h"
30     #include "acinterp.h"
31     #include "amlcode.h"
32     #include "acnamesp.h"
33     
34     
35     #define _COMPONENT          ACPI_PARSER
36     	 MODULE_NAME         ("psxface")
37     
38     
39     /*******************************************************************************
40      *
41      * FUNCTION:    Acpi_psx_execute
42      *
43      * PARAMETERS:  Method_node         - A method object containing both the AML
44      *                                    address and length.
45      *              **Params            - List of parameters to pass to method,
46      *                                    terminated by NULL. Params itself may be
47      *                                    NULL if no parameters are being passed.
48      *              **Return_obj_desc   - Return object from execution of the
49      *                                    method.
50      *
51      * RETURN:      Status
52      *
53      * DESCRIPTION: Execute a control method
54      *
55      ******************************************************************************/
56     
57     acpi_status
58     acpi_psx_execute (
59     	acpi_namespace_node     *method_node,
60     	acpi_operand_object     **params,
61     	acpi_operand_object     **return_obj_desc)
62     {
63     	acpi_status             status;
64     	acpi_operand_object     *obj_desc;
65     	u32                     i;
66     	acpi_parse_object       *op;
67     
68     
69     	FUNCTION_TRACE ("Psx_execute");
70     
71     
72     	/* Validate the Node and get the attached object */
73     
74     	if (!method_node) {
75     		return_ACPI_STATUS (AE_NULL_ENTRY);
76     	}
77     
78     	obj_desc = acpi_ns_get_attached_object (method_node);
79     	if (!obj_desc) {
80     		return_ACPI_STATUS (AE_NULL_OBJECT);
81     	}
82     
83     	/* Init for new method, wait on concurrency semaphore */
84     
85     	status = acpi_ds_begin_method_execution (method_node, obj_desc, NULL);
86     	if (ACPI_FAILURE (status)) {
87     		return_ACPI_STATUS (status);
88     	}
89     
90     	if (params) {
91     		/*
92     		 * The caller "owns" the parameters, so give each one an extra
93     		 * reference
94     		 */
95     		for (i = 0; params[i]; i++) {
96     			acpi_ut_add_reference (params[i]);
97     		}
98     	}
99     
100     	/*
101     	 * Perform the first pass parse of the method to enter any
102     	 * named objects that it creates into the namespace
103     	 */
104     	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
105     		"**** Begin Method Execution **** Entry=%p obj=%p\n",
106     		method_node, obj_desc));
107     
108     	/* Create and init a Root Node */
109     
110     	op = acpi_ps_alloc_op (AML_SCOPE_OP);
111     	if (!op) {
112     		return_ACPI_STATUS (AE_NO_MEMORY);
113     	}
114     
115     	status = acpi_ps_parse_aml (op, obj_desc->method.pcode,
116     			  obj_desc->method.pcode_length,
117     			  ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,
118     			  method_node, params, return_obj_desc,
119     			  acpi_ds_load1_begin_op, acpi_ds_load1_end_op);
120     	acpi_ps_delete_parse_tree (op);
121     
122     	/* Create and init a Root Node */
123     
124     	op = acpi_ps_alloc_op (AML_SCOPE_OP);
125     	if (!op) {
126     		return_ACPI_STATUS (AE_NO_MEMORY);
127     	}
128     
129     
130     	/* Init new op with the method name and pointer back to the NS node */
131     
132     	acpi_ps_set_name (op, method_node->name);
133     	op->node = method_node;
134     
135     	/*
136     	 * The walk of the parse tree is where we actually execute the method
137     	 */
138     	status = acpi_ps_parse_aml (op, obj_desc->method.pcode,
139     			  obj_desc->method.pcode_length,
140     			  ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE,
141     			  method_node, params, return_obj_desc,
142     			  acpi_ds_exec_begin_op, acpi_ds_exec_end_op);
143     	acpi_ps_delete_parse_tree (op);
144     
145     	if (params) {
146     		/* Take away the extra reference that we gave the parameters above */
147     
148     		for (i = 0; params[i]; i++) {
149     			acpi_ut_update_object_reference (params[i], REF_DECREMENT);
150     		}
151     	}
152     
153     
154     	/*
155     	 * If the method has returned an object, signal this to the caller with
156     	 * a control exception code
157     	 */
158     	if (*return_obj_desc) {
159     		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Method returned Obj_desc=%X\n",
160     			*return_obj_desc));
161     		DUMP_STACK_ENTRY (*return_obj_desc);
162     
163     		status = AE_CTRL_RETURN_VALUE;
164     	}
165     
166     
167     	return_ACPI_STATUS (status);
168     }
169     
170     
171