diff options
Diffstat (limited to 'drivers/acpi/parser/psxface.c')
-rw-r--r-- | drivers/acpi/parser/psxface.c | 251 |
1 files changed, 126 insertions, 125 deletions
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index dba893648e84..4dcbd443160e 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c | |||
@@ -41,24 +41,27 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | |||
45 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
46 | #include <acpi/acparser.h> | 45 | #include <acpi/acparser.h> |
47 | #include <acpi/acdispat.h> | 46 | #include <acpi/acdispat.h> |
48 | #include <acpi/acinterp.h> | 47 | #include <acpi/acinterp.h> |
49 | #include <acpi/acnamesp.h> | ||
50 | |||
51 | 48 | ||
52 | #define _COMPONENT ACPI_PARSER | 49 | #define _COMPONENT ACPI_PARSER |
53 | ACPI_MODULE_NAME ("psxface") | 50 | ACPI_MODULE_NAME("psxface") |
51 | |||
52 | /* Local Prototypes */ | ||
53 | static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info); | ||
54 | 54 | ||
55 | static void | ||
56 | acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action); | ||
55 | 57 | ||
56 | /******************************************************************************* | 58 | /******************************************************************************* |
57 | * | 59 | * |
58 | * FUNCTION: acpi_psx_execute | 60 | * FUNCTION: acpi_ps_execute_method |
59 | * | 61 | * |
60 | * PARAMETERS: Info - Method info block, contains: | 62 | * PARAMETERS: Info - Method info block, contains: |
61 | * Node - Method Node to execute | 63 | * Node - Method Node to execute |
64 | * obj_desc - Method object | ||
62 | * Parameters - List of parameters to pass to the method, | 65 | * Parameters - List of parameters to pass to the method, |
63 | * terminated by NULL. Params itself may be | 66 | * terminated by NULL. Params itself may be |
64 | * NULL if no parameters are being passed. | 67 | * NULL if no parameters are being passed. |
@@ -67,6 +70,7 @@ | |||
67 | * parameter_type - Type of Parameter list | 70 | * parameter_type - Type of Parameter list |
68 | * return_object - Where to put method's return value (if | 71 | * return_object - Where to put method's return value (if |
69 | * any). If NULL, no value is returned. | 72 | * any). If NULL, no value is returned. |
73 | * pass_number - Parse or execute pass | ||
70 | * | 74 | * |
71 | * RETURN: Status | 75 | * RETURN: Status |
72 | * | 76 | * |
@@ -74,173 +78,170 @@ | |||
74 | * | 78 | * |
75 | ******************************************************************************/ | 79 | ******************************************************************************/ |
76 | 80 | ||
77 | acpi_status | 81 | acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) |
78 | acpi_psx_execute ( | ||
79 | struct acpi_parameter_info *info) | ||
80 | { | 82 | { |
81 | acpi_status status; | 83 | acpi_status status; |
82 | union acpi_operand_object *obj_desc; | ||
83 | u32 i; | ||
84 | union acpi_parse_object *op; | ||
85 | struct acpi_walk_state *walk_state; | ||
86 | |||
87 | |||
88 | ACPI_FUNCTION_TRACE ("psx_execute"); | ||
89 | 84 | ||
85 | ACPI_FUNCTION_TRACE("ps_execute_method"); | ||
90 | 86 | ||
91 | /* Validate the Node and get the attached object */ | 87 | /* Validate the Info and method Node */ |
92 | 88 | ||
93 | if (!info || !info->node) { | 89 | if (!info || !info->node) { |
94 | return_ACPI_STATUS (AE_NULL_ENTRY); | 90 | return_ACPI_STATUS(AE_NULL_ENTRY); |
95 | } | ||
96 | |||
97 | obj_desc = acpi_ns_get_attached_object (info->node); | ||
98 | if (!obj_desc) { | ||
99 | return_ACPI_STATUS (AE_NULL_OBJECT); | ||
100 | } | 91 | } |
101 | 92 | ||
102 | /* Init for new method, wait on concurrency semaphore */ | 93 | /* Init for new method, wait on concurrency semaphore */ |
103 | 94 | ||
104 | status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL); | 95 | status = |
105 | if (ACPI_FAILURE (status)) { | 96 | acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL); |
106 | return_ACPI_STATUS (status); | 97 | if (ACPI_FAILURE(status)) { |
98 | return_ACPI_STATUS(status); | ||
107 | } | 99 | } |
108 | 100 | ||
109 | if ((info->parameter_type == ACPI_PARAM_ARGS) && | 101 | /* |
110 | (info->parameters)) { | 102 | * The caller "owns" the parameters, so give each one an extra |
111 | /* | 103 | * reference |
112 | * The caller "owns" the parameters, so give each one an extra | 104 | */ |
113 | * reference | 105 | acpi_ps_update_parameter_list(info, REF_INCREMENT); |
114 | */ | ||
115 | for (i = 0; info->parameters[i]; i++) { | ||
116 | acpi_ut_add_reference (info->parameters[i]); | ||
117 | } | ||
118 | } | ||
119 | 106 | ||
120 | /* | 107 | /* |
121 | * 1) Perform the first pass parse of the method to enter any | 108 | * 1) Perform the first pass parse of the method to enter any |
122 | * named objects that it creates into the namespace | 109 | * named objects that it creates into the namespace |
123 | */ | 110 | */ |
124 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | 111 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
125 | "**** Begin Method Parse **** Entry=%p obj=%p\n", | 112 | "**** Begin Method Parse **** Entry=%p obj=%p\n", |
126 | info->node, obj_desc)); | 113 | info->node, info->obj_desc)); |
127 | 114 | ||
128 | /* Create and init a Root Node */ | 115 | info->pass_number = 1; |
129 | 116 | status = acpi_ps_execute_pass(info); | |
130 | op = acpi_ps_create_scope_op (); | 117 | if (ACPI_FAILURE(status)) { |
131 | if (!op) { | 118 | goto cleanup; |
132 | status = AE_NO_MEMORY; | ||
133 | goto cleanup1; | ||
134 | } | 119 | } |
135 | 120 | ||
136 | /* | 121 | /* |
137 | * Get a new owner_id for objects created by this method. Namespace | 122 | * 2) Execute the method. Performs second pass parse simultaneously |
138 | * objects (such as Operation Regions) can be created during the | ||
139 | * first pass parse. | ||
140 | */ | 123 | */ |
141 | obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); | 124 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
125 | "**** Begin Method Execution **** Entry=%p obj=%p\n", | ||
126 | info->node, info->obj_desc)); | ||
142 | 127 | ||
143 | /* Create and initialize a new walk state */ | 128 | info->pass_number = 3; |
129 | status = acpi_ps_execute_pass(info); | ||
144 | 130 | ||
145 | walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, | 131 | cleanup: |
146 | NULL, NULL, NULL); | 132 | /* Take away the extra reference that we gave the parameters above */ |
147 | if (!walk_state) { | ||
148 | status = AE_NO_MEMORY; | ||
149 | goto cleanup2; | ||
150 | } | ||
151 | 133 | ||
152 | status = acpi_ds_init_aml_walk (walk_state, op, info->node, | 134 | acpi_ps_update_parameter_list(info, REF_DECREMENT); |
153 | obj_desc->method.aml_start, | ||
154 | obj_desc->method.aml_length, NULL, 1); | ||
155 | if (ACPI_FAILURE (status)) { | ||
156 | goto cleanup3; | ||
157 | } | ||
158 | 135 | ||
159 | /* Parse the AML */ | 136 | /* Exit now if error above */ |
160 | 137 | ||
161 | status = acpi_ps_parse_aml (walk_state); | 138 | if (ACPI_FAILURE(status)) { |
162 | acpi_ps_delete_parse_tree (op); | 139 | return_ACPI_STATUS(status); |
163 | if (ACPI_FAILURE (status)) { | ||
164 | goto cleanup1; /* Walk state is already deleted */ | ||
165 | } | 140 | } |
166 | 141 | ||
167 | /* | 142 | /* |
168 | * 2) Execute the method. Performs second pass parse simultaneously | 143 | * If the method has returned an object, signal this to the caller with |
144 | * a control exception code | ||
169 | */ | 145 | */ |
170 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | 146 | if (info->return_object) { |
171 | "**** Begin Method Execution **** Entry=%p obj=%p\n", | 147 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
172 | info->node, obj_desc)); | 148 | "Method returned obj_desc=%p\n", |
173 | 149 | info->return_object)); | |
174 | /* Create and init a Root Node */ | 150 | ACPI_DUMP_STACK_ENTRY(info->return_object); |
175 | 151 | ||
176 | op = acpi_ps_create_scope_op (); | 152 | status = AE_CTRL_RETURN_VALUE; |
177 | if (!op) { | ||
178 | status = AE_NO_MEMORY; | ||
179 | goto cleanup1; | ||
180 | } | 153 | } |
181 | 154 | ||
182 | /* Init new op with the method name and pointer back to the NS node */ | 155 | return_ACPI_STATUS(status); |
156 | } | ||
157 | |||
158 | /******************************************************************************* | ||
159 | * | ||
160 | * FUNCTION: acpi_ps_update_parameter_list | ||
161 | * | ||
162 | * PARAMETERS: Info - See struct acpi_parameter_info | ||
163 | * (Used: parameter_type and Parameters) | ||
164 | * Action - Add or Remove reference | ||
165 | * | ||
166 | * RETURN: Status | ||
167 | * | ||
168 | * DESCRIPTION: Update reference count on all method parameter objects | ||
169 | * | ||
170 | ******************************************************************************/ | ||
183 | 171 | ||
184 | acpi_ps_set_name (op, info->node->name.integer); | 172 | static void |
185 | op->common.node = info->node; | 173 | acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action) |
174 | { | ||
175 | acpi_native_uint i; | ||
186 | 176 | ||
187 | /* Create and initialize a new walk state */ | 177 | if ((info->parameter_type == ACPI_PARAM_ARGS) && (info->parameters)) { |
178 | /* Update reference count for each parameter */ | ||
188 | 179 | ||
189 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); | 180 | for (i = 0; info->parameters[i]; i++) { |
190 | if (!walk_state) { | 181 | /* Ignore errors, just do them all */ |
191 | status = AE_NO_MEMORY; | ||
192 | goto cleanup2; | ||
193 | } | ||
194 | 182 | ||
195 | status = acpi_ds_init_aml_walk (walk_state, op, info->node, | 183 | (void)acpi_ut_update_object_reference(info-> |
196 | obj_desc->method.aml_start, | 184 | parameters[i], |
197 | obj_desc->method.aml_length, info, 3); | 185 | action); |
198 | if (ACPI_FAILURE (status)) { | 186 | } |
199 | goto cleanup3; | ||
200 | } | 187 | } |
188 | } | ||
201 | 189 | ||
202 | /* The walk of the parse tree is where we actually execute the method */ | 190 | /******************************************************************************* |
203 | 191 | * | |
204 | status = acpi_ps_parse_aml (walk_state); | 192 | * FUNCTION: acpi_ps_execute_pass |
205 | goto cleanup2; /* Walk state already deleted */ | 193 | * |
194 | * PARAMETERS: Info - See struct acpi_parameter_info | ||
195 | * (Used: pass_number, Node, and obj_desc) | ||
196 | * | ||
197 | * RETURN: Status | ||
198 | * | ||
199 | * DESCRIPTION: Single AML pass: Parse or Execute a control method | ||
200 | * | ||
201 | ******************************************************************************/ | ||
206 | 202 | ||
203 | static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info) | ||
204 | { | ||
205 | acpi_status status; | ||
206 | union acpi_parse_object *op; | ||
207 | struct acpi_walk_state *walk_state; | ||
207 | 208 | ||
208 | cleanup3: | 209 | ACPI_FUNCTION_TRACE("ps_execute_pass"); |
209 | acpi_ds_delete_walk_state (walk_state); | ||
210 | 210 | ||
211 | cleanup2: | 211 | /* Create and init a Root Node */ |
212 | acpi_ps_delete_parse_tree (op); | ||
213 | 212 | ||
214 | cleanup1: | 213 | op = acpi_ps_create_scope_op(); |
215 | if ((info->parameter_type == ACPI_PARAM_ARGS) && | 214 | if (!op) { |
216 | (info->parameters)) { | 215 | return_ACPI_STATUS(AE_NO_MEMORY); |
217 | /* Take away the extra reference that we gave the parameters above */ | 216 | } |
218 | 217 | ||
219 | for (i = 0; info->parameters[i]; i++) { | 218 | /* Create and initialize a new walk state */ |
220 | /* Ignore errors, just do them all */ | ||
221 | 219 | ||
222 | (void) acpi_ut_update_object_reference ( | 220 | walk_state = |
223 | info->parameters[i], REF_DECREMENT); | 221 | acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL, |
224 | } | 222 | NULL, NULL); |
223 | if (!walk_state) { | ||
224 | status = AE_NO_MEMORY; | ||
225 | goto cleanup; | ||
225 | } | 226 | } |
226 | 227 | ||
227 | if (ACPI_FAILURE (status)) { | 228 | status = acpi_ds_init_aml_walk(walk_state, op, info->node, |
228 | return_ACPI_STATUS (status); | 229 | info->obj_desc->method.aml_start, |
230 | info->obj_desc->method.aml_length, | ||
231 | info->pass_number == 1 ? NULL : info, | ||
232 | info->pass_number); | ||
233 | if (ACPI_FAILURE(status)) { | ||
234 | acpi_ds_delete_walk_state(walk_state); | ||
235 | goto cleanup; | ||
229 | } | 236 | } |
230 | 237 | ||
231 | /* | 238 | /* Parse the AML */ |
232 | * If the method has returned an object, signal this to the caller with | ||
233 | * a control exception code | ||
234 | */ | ||
235 | if (info->return_object) { | ||
236 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n", | ||
237 | info->return_object)); | ||
238 | ACPI_DUMP_STACK_ENTRY (info->return_object); | ||
239 | |||
240 | status = AE_CTRL_RETURN_VALUE; | ||
241 | } | ||
242 | 239 | ||
243 | return_ACPI_STATUS (status); | 240 | status = acpi_ps_parse_aml(walk_state); |
244 | } | ||
245 | 241 | ||
242 | /* Walk state was deleted by parse_aml */ | ||
246 | 243 | ||
244 | cleanup: | ||
245 | acpi_ps_delete_parse_tree(op); | ||
246 | return_ACPI_STATUS(status); | ||
247 | } | ||