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