1 /******************************************************************************
3 * Module Name: psxface - Parser external interfaces
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2004, R. Byron Moore
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
45 #include <acpi/acpi.h>
46 #include <acpi/acparser.h>
47 #include <acpi/acdispat.h>
48 #include <acpi/acinterp.h>
49 #include <acpi/acnamesp.h>
52 #define _COMPONENT ACPI_PARSER
53 ACPI_MODULE_NAME ("psxface")
56 /*******************************************************************************
58 * FUNCTION: acpi_psx_execute
60 * PARAMETERS: Info->Node - A method object containing both the AML
62 * **Params - List of parameters to pass to method,
63 * terminated by NULL. Params itself may be
64 * NULL if no parameters are being passed.
65 * **return_obj_desc - Return object from execution of the
70 * DESCRIPTION: Execute a control method
72 ******************************************************************************/
76 struct acpi_parameter_info
*info
)
79 union acpi_operand_object
*obj_desc
;
81 union acpi_parse_object
*op
;
82 struct acpi_walk_state
*walk_state
;
85 ACPI_FUNCTION_TRACE ("psx_execute");
88 /* Validate the Node and get the attached object */
90 if (!info
|| !info
->node
) {
91 return_ACPI_STATUS (AE_NULL_ENTRY
);
94 obj_desc
= acpi_ns_get_attached_object (info
->node
);
96 return_ACPI_STATUS (AE_NULL_OBJECT
);
99 /* Init for new method, wait on concurrency semaphore */
101 status
= acpi_ds_begin_method_execution (info
->node
, obj_desc
, NULL
);
102 if (ACPI_FAILURE (status
)) {
103 return_ACPI_STATUS (status
);
106 if ((info
->parameter_type
== ACPI_PARAM_ARGS
) &&
107 (info
->parameters
)) {
109 * The caller "owns" the parameters, so give each one an extra
112 for (i
= 0; info
->parameters
[i
]; i
++) {
113 acpi_ut_add_reference (info
->parameters
[i
]);
118 * 1) Perform the first pass parse of the method to enter any
119 * named objects that it creates into the namespace
121 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
,
122 "**** Begin Method Parse **** Entry=%p obj=%p\n",
123 info
->node
, obj_desc
));
125 /* Create and init a Root Node */
127 op
= acpi_ps_create_scope_op ();
129 status
= AE_NO_MEMORY
;
134 * Get a new owner_id for objects created by this method. Namespace
135 * objects (such as Operation Regions) can be created during the
138 obj_desc
->method
.owning_id
= acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD
);
140 /* Create and initialize a new walk state */
142 walk_state
= acpi_ds_create_walk_state (obj_desc
->method
.owning_id
,
145 status
= AE_NO_MEMORY
;
149 status
= acpi_ds_init_aml_walk (walk_state
, op
, info
->node
,
150 obj_desc
->method
.aml_start
,
151 obj_desc
->method
.aml_length
, NULL
, 1);
152 if (ACPI_FAILURE (status
)) {
158 status
= acpi_ps_parse_aml (walk_state
);
159 acpi_ps_delete_parse_tree (op
);
160 if (ACPI_FAILURE (status
)) {
161 goto cleanup1
; /* Walk state is already deleted */
165 * 2) Execute the method. Performs second pass parse simultaneously
167 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
,
168 "**** Begin Method Execution **** Entry=%p obj=%p\n",
169 info
->node
, obj_desc
));
171 /* Create and init a Root Node */
173 op
= acpi_ps_create_scope_op ();
175 status
= AE_NO_MEMORY
;
179 /* Init new op with the method name and pointer back to the NS node */
181 acpi_ps_set_name (op
, info
->node
->name
.integer
);
182 op
->common
.node
= info
->node
;
184 /* Create and initialize a new walk state */
186 walk_state
= acpi_ds_create_walk_state (0, NULL
, NULL
, NULL
);
188 status
= AE_NO_MEMORY
;
192 status
= acpi_ds_init_aml_walk (walk_state
, op
, info
->node
,
193 obj_desc
->method
.aml_start
,
194 obj_desc
->method
.aml_length
, info
, 3);
195 if (ACPI_FAILURE (status
)) {
200 * The walk of the parse tree is where we actually execute the method
202 status
= acpi_ps_parse_aml (walk_state
);
203 goto cleanup2
; /* Walk state already deleted */
207 acpi_ds_delete_walk_state (walk_state
);
210 acpi_ps_delete_parse_tree (op
);
213 if ((info
->parameter_type
== ACPI_PARAM_ARGS
) &&
214 (info
->parameters
)) {
215 /* Take away the extra reference that we gave the parameters above */
217 for (i
= 0; info
->parameters
[i
]; i
++) {
218 /* Ignore errors, just do them all */
220 (void) acpi_ut_update_object_reference (info
->parameters
[i
], REF_DECREMENT
);
224 if (ACPI_FAILURE (status
)) {
225 return_ACPI_STATUS (status
);
229 * If the method has returned an object, signal this to the caller with
230 * a control exception code
232 if (info
->return_object
) {
233 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE
, "Method returned obj_desc=%p\n",
234 info
->return_object
));
235 ACPI_DUMP_STACK_ENTRY (info
->return_object
);
237 status
= AE_CTRL_RETURN_VALUE
;
240 return_ACPI_STATUS (status
);