diff options
author | Bob Moore <robert.moore@intel.com> | 2006-05-26 16:36:00 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-06-14 02:44:35 -0400 |
commit | 4119532c95547821dbe72d6916dfa1b2148475b3 (patch) | |
tree | 564eb8f69924fb7dc72e93526faf1547acac7d30 /drivers/acpi/namespace/nsxfeval.c | |
parent | b8d35192c55fb055792ff0641408eaaec7c88988 (diff) |
ACPI: ACPICA 20060526
Restructured, flattened, and simplified the internal
interfaces for namespace object evaluation - resulting
in smaller code, less CPU stack use, and fewer
interfaces. (With assistance from Mikhail Kouzmich)
Fixed a problem with the CopyObject operator where the
first parameter was not typed correctly for the parser,
interpreter, compiler, and disassembler. Caused various
errors and unexpected behavior.
Fixed a problem where a ShiftLeft or ShiftRight of
more than 64 bits produced incorrect results with some
C compilers. Since the behavior of C compilers when
the shift value is larger than the datatype width is
apparently not well defined, the interpreter now detects
this condition and simply returns zero as expected in all
such cases. (BZ 395)
Fixed problem reports (Valery Podrezov) integrated: -
Update String-to-Integer conversion to match ACPI 3.0A spec
http://bugzilla.kernel.org/show_bug.cgi?id=5329
Allow interpreter to handle nested method declarations
http://bugzilla.kernel.org/show_bug.cgi?id=5361
Fixed problem reports (Fiodor Suietov) integrated: -
acpi_terminate() doesn't free debug memory allocation
list objects (BZ 355) - After Core Subsystem
shutdown, acpi_subsystem_status() returns AE_OK (BZ 356) -
acpi_os_unmap_memory() for RSDP can be invoked inconsistently
(BZ 357) - Resource Manager should return AE_TYPE for
non-device objects (BZ 358) - Incomplete cleanup branch
in AcpiNsEvaluateRelative (BZ 359) - Use acpi_os_free()
instead of ACPI_FREE in acpi_rs_set_srs_method_data (BZ 360)
- Incomplete cleanup branch in acpi_ps_parse_aml (BZ 361) -
Incomplete cleanup branch in acpi_ds_delete_walk_state (BZ 362)
- acpi_get_table_header returns AE_NO_ACPI_TABLES until DSDT
is loaded (BZ 365) - Status of the Global Initialization
Handler call not used (BZ 366) - Incorrect object parameter
to Global Initialization Handler (BZ 367)
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/namespace/nsxfeval.c')
-rw-r--r-- | drivers/acpi/namespace/nsxfeval.c | 119 |
1 files changed, 59 insertions, 60 deletions
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index 998b29611b19..6d9bd45af30a 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c | |||
@@ -171,51 +171,61 @@ acpi_evaluate_object(acpi_handle handle, | |||
171 | { | 171 | { |
172 | acpi_status status; | 172 | acpi_status status; |
173 | acpi_status status2; | 173 | acpi_status status2; |
174 | struct acpi_parameter_info info; | 174 | struct acpi_evaluate_info *info; |
175 | acpi_size buffer_space_needed; | 175 | acpi_size buffer_space_needed; |
176 | u32 i; | 176 | u32 i; |
177 | 177 | ||
178 | ACPI_FUNCTION_TRACE(acpi_evaluate_object); | 178 | ACPI_FUNCTION_TRACE(acpi_evaluate_object); |
179 | 179 | ||
180 | info.node = handle; | 180 | /* Allocate and initialize the evaluation information block */ |
181 | info.parameters = NULL; | 181 | |
182 | info.return_object = NULL; | 182 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); |
183 | info.parameter_type = ACPI_PARAM_ARGS; | 183 | if (!info) { |
184 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
185 | } | ||
186 | |||
187 | info->pathname = pathname; | ||
188 | info->parameter_type = ACPI_PARAM_ARGS; | ||
189 | |||
190 | /* Convert and validate the device handle */ | ||
191 | |||
192 | info->prefix_node = acpi_ns_map_handle_to_node(handle); | ||
193 | if (!info->prefix_node) { | ||
194 | status = AE_BAD_PARAMETER; | ||
195 | goto cleanup; | ||
196 | } | ||
184 | 197 | ||
185 | /* | 198 | /* |
186 | * If there are parameters to be passed to the object | 199 | * If there are parameters to be passed to a control method, the external |
187 | * (which must be a control method), the external objects | 200 | * objects must all be converted to internal objects |
188 | * must be converted to internal objects | ||
189 | */ | 201 | */ |
190 | if (external_params && external_params->count) { | 202 | if (external_params && external_params->count) { |
191 | /* | 203 | /* |
192 | * Allocate a new parameter block for the internal objects | 204 | * Allocate a new parameter block for the internal objects |
193 | * Add 1 to count to allow for null terminated internal list | 205 | * Add 1 to count to allow for null terminated internal list |
194 | */ | 206 | */ |
195 | info.parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) | 207 | info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) |
196 | external_params->count + | 208 | external_params-> |
197 | 1) * sizeof(void *)); | 209 | count + |
198 | if (!info.parameters) { | 210 | 1) * sizeof(void *)); |
199 | return_ACPI_STATUS(AE_NO_MEMORY); | 211 | if (!info->parameters) { |
212 | status = AE_NO_MEMORY; | ||
213 | goto cleanup; | ||
200 | } | 214 | } |
201 | 215 | ||
202 | /* | 216 | /* Convert each external object in the list to an internal object */ |
203 | * Convert each external object in the list to an | 217 | |
204 | * internal object | ||
205 | */ | ||
206 | for (i = 0; i < external_params->count; i++) { | 218 | for (i = 0; i < external_params->count; i++) { |
207 | status = | 219 | status = |
208 | acpi_ut_copy_eobject_to_iobject(&external_params-> | 220 | acpi_ut_copy_eobject_to_iobject(&external_params-> |
209 | pointer[i], | 221 | pointer[i], |
210 | &info. | 222 | &info-> |
211 | parameters[i]); | 223 | parameters[i]); |
212 | if (ACPI_FAILURE(status)) { | 224 | if (ACPI_FAILURE(status)) { |
213 | acpi_ut_delete_internal_object_list(info. | 225 | goto cleanup; |
214 | parameters); | ||
215 | return_ACPI_STATUS(status); | ||
216 | } | 226 | } |
217 | } | 227 | } |
218 | info.parameters[external_params->count] = NULL; | 228 | info->parameters[external_params->count] = NULL; |
219 | } | 229 | } |
220 | 230 | ||
221 | /* | 231 | /* |
@@ -228,12 +238,13 @@ acpi_evaluate_object(acpi_handle handle, | |||
228 | 238 | ||
229 | /* The path is fully qualified, just evaluate by name */ | 239 | /* The path is fully qualified, just evaluate by name */ |
230 | 240 | ||
231 | status = acpi_ns_evaluate_by_name(pathname, &info); | 241 | info->prefix_node = NULL; |
242 | status = acpi_ns_evaluate(info); | ||
232 | } else if (!handle) { | 243 | } else if (!handle) { |
233 | /* | 244 | /* |
234 | * A handle is optional iff a fully qualified pathname | 245 | * A handle is optional iff a fully qualified pathname is specified. |
235 | * is specified. Since we've already handled fully | 246 | * Since we've already handled fully qualified names above, this is |
236 | * qualified names above, this is an error | 247 | * an error |
237 | */ | 248 | */ |
238 | if (!pathname) { | 249 | if (!pathname) { |
239 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 250 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -246,22 +257,9 @@ acpi_evaluate_object(acpi_handle handle, | |||
246 | 257 | ||
247 | status = AE_BAD_PARAMETER; | 258 | status = AE_BAD_PARAMETER; |
248 | } else { | 259 | } else { |
249 | /* | 260 | /* We have a namespace a node and a possible relative path */ |
250 | * We get here if we have a handle -- and if we have a | ||
251 | * pathname it is relative. The handle will be validated | ||
252 | * in the lower procedures | ||
253 | */ | ||
254 | if (!pathname) { | ||
255 | /* | ||
256 | * The null pathname case means the handle is for | ||
257 | * the actual object to be evaluated | ||
258 | */ | ||
259 | status = acpi_ns_evaluate_by_handle(&info); | ||
260 | } else { | ||
261 | /* Both a Handle and a relative Pathname */ | ||
262 | 261 | ||
263 | status = acpi_ns_evaluate_relative(pathname, &info); | 262 | status = acpi_ns_evaluate(info); |
264 | } | ||
265 | } | 263 | } |
266 | 264 | ||
267 | /* | 265 | /* |
@@ -269,10 +267,10 @@ acpi_evaluate_object(acpi_handle handle, | |||
269 | * copy the return value to an external object. | 267 | * copy the return value to an external object. |
270 | */ | 268 | */ |
271 | if (return_buffer) { | 269 | if (return_buffer) { |
272 | if (!info.return_object) { | 270 | if (!info->return_object) { |
273 | return_buffer->length = 0; | 271 | return_buffer->length = 0; |
274 | } else { | 272 | } else { |
275 | if (ACPI_GET_DESCRIPTOR_TYPE(info.return_object) == | 273 | if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) == |
276 | ACPI_DESC_TYPE_NAMED) { | 274 | ACPI_DESC_TYPE_NAMED) { |
277 | /* | 275 | /* |
278 | * If we received a NS Node as a return object, this means that | 276 | * If we received a NS Node as a return object, this means that |
@@ -283,17 +281,16 @@ acpi_evaluate_object(acpi_handle handle, | |||
283 | * support for various types at a later date if necessary. | 281 | * support for various types at a later date if necessary. |
284 | */ | 282 | */ |
285 | status = AE_TYPE; | 283 | status = AE_TYPE; |
286 | info.return_object = NULL; /* No need to delete a NS Node */ | 284 | info->return_object = NULL; /* No need to delete a NS Node */ |
287 | return_buffer->length = 0; | 285 | return_buffer->length = 0; |
288 | } | 286 | } |
289 | 287 | ||
290 | if (ACPI_SUCCESS(status)) { | 288 | if (ACPI_SUCCESS(status)) { |
291 | /* | 289 | |
292 | * Find out how large a buffer is needed | 290 | /* Get the size of the returned object */ |
293 | * to contain the returned object | 291 | |
294 | */ | ||
295 | status = | 292 | status = |
296 | acpi_ut_get_object_size(info.return_object, | 293 | acpi_ut_get_object_size(info->return_object, |
297 | &buffer_space_needed); | 294 | &buffer_space_needed); |
298 | if (ACPI_SUCCESS(status)) { | 295 | if (ACPI_SUCCESS(status)) { |
299 | 296 | ||
@@ -319,7 +316,7 @@ acpi_evaluate_object(acpi_handle handle, | |||
319 | 316 | ||
320 | status = | 317 | status = |
321 | acpi_ut_copy_iobject_to_eobject | 318 | acpi_ut_copy_iobject_to_eobject |
322 | (info.return_object, | 319 | (info->return_object, |
323 | return_buffer); | 320 | return_buffer); |
324 | } | 321 | } |
325 | } | 322 | } |
@@ -327,31 +324,33 @@ acpi_evaluate_object(acpi_handle handle, | |||
327 | } | 324 | } |
328 | } | 325 | } |
329 | 326 | ||
330 | if (info.return_object) { | 327 | if (info->return_object) { |
331 | /* | 328 | /* |
332 | * Delete the internal return object. NOTE: Interpreter | 329 | * Delete the internal return object. NOTE: Interpreter must be |
333 | * must be locked to avoid race condition. | 330 | * locked to avoid race condition. |
334 | */ | 331 | */ |
335 | status2 = acpi_ex_enter_interpreter(); | 332 | status2 = acpi_ex_enter_interpreter(); |
336 | if (ACPI_SUCCESS(status2)) { | 333 | if (ACPI_SUCCESS(status2)) { |
337 | /* | 334 | |
338 | * Delete the internal return object. (Or at least | 335 | /* Remove one reference on the return object (should delete it) */ |
339 | * decrement the reference count by one) | 336 | |
340 | */ | 337 | acpi_ut_remove_reference(info->return_object); |
341 | acpi_ut_remove_reference(info.return_object); | ||
342 | acpi_ex_exit_interpreter(); | 338 | acpi_ex_exit_interpreter(); |
343 | } | 339 | } |
344 | } | 340 | } |
345 | 341 | ||
342 | cleanup: | ||
343 | |||
346 | /* Free the input parameter list (if we created one) */ | 344 | /* Free the input parameter list (if we created one) */ |
347 | 345 | ||
348 | if (info.parameters) { | 346 | if (info->parameters) { |
349 | 347 | ||
350 | /* Free the allocated parameter block */ | 348 | /* Free the allocated parameter block */ |
351 | 349 | ||
352 | acpi_ut_delete_internal_object_list(info.parameters); | 350 | acpi_ut_delete_internal_object_list(info->parameters); |
353 | } | 351 | } |
354 | 352 | ||
353 | ACPI_FREE(info); | ||
355 | return_ACPI_STATUS(status); | 354 | return_ACPI_STATUS(status); |
356 | } | 355 | } |
357 | 356 | ||