diff options
author | Robert Moore <robert.moore@intel.com> | 2005-07-29 18:15:00 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-07-30 00:51:39 -0400 |
commit | 0c9938cc75057c0fca1af55a55dcfc2842436695 (patch) | |
tree | d18e809bf9e3811f20c609b6515d4d1b8520cfbc /drivers/acpi/namespace | |
parent | dd8f39bbf5154cdbfd698fc70c66faba33eafa44 (diff) |
[ACPI] ACPICA 20050729 from Bob Moore
Implemented support to ignore an attempt to install/load
a particular ACPI table more than once. Apparently there
exists BIOS code that repeatedly attempts to load the same
SSDT upon certain events. Thanks to Venkatesh Pallipadi.
Restructured the main interface to the AML parser in
order to correctly handle all exceptional conditions. This
will prevent leakage of the OwnerId resource and should
eliminate the AE_OWNER_ID_LIMIT exceptions seen on some
machines. Thanks to Alexey Starikovskiy.
Support for "module level code" has been disabled in this
version due to a number of issues that have appeared
on various machines. The support can be enabled by
defining ACPI_ENABLE_MODULE_LEVEL_CODE during subsystem
compilation. When the issues are fully resolved, the code
will be enabled by default again.
Modified the internal functions for debug print support
to define the FunctionName parameter as a (const char *)
for compatibility with compiler built-in macros such as
__FUNCTION__, etc.
Linted the entire ACPICA source tree for both 32-bit
and 64-bit.
Signed-off-by: Robert Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/namespace')
-rw-r--r-- | drivers/acpi/namespace/nsaccess.c | 13 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsalloc.c | 121 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsdump.c | 11 | ||||
-rw-r--r-- | drivers/acpi/namespace/nseval.c | 10 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsload.c | 42 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsparse.c | 2 |
6 files changed, 38 insertions, 161 deletions
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index 0bda88d18685..7589e1fdf25a 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c | |||
@@ -159,19 +159,20 @@ acpi_ns_root_initialize ( | |||
159 | obj_desc->method.param_count = (u8) ACPI_TO_INTEGER (val); | 159 | obj_desc->method.param_count = (u8) ACPI_TO_INTEGER (val); |
160 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; | 160 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; |
161 | 161 | ||
162 | #if defined (ACPI_ASL_COMPILER) || defined (ACPI_DUMP_App) | 162 | #if defined (ACPI_ASL_COMPILER) |
163 | 163 | ||
164 | /* | 164 | /* save the parameter count for the i_aSL compiler */ |
165 | * i_aSL Compiler cheats by putting parameter count | 165 | |
166 | * in the owner_iD (param_count max is 7) | 166 | new_node->value = obj_desc->method.param_count; |
167 | */ | ||
168 | new_node->owner_id = obj_desc->method.param_count; | ||
169 | #else | 167 | #else |
170 | /* Mark this as a very SPECIAL method */ | 168 | /* Mark this as a very SPECIAL method */ |
171 | 169 | ||
172 | obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY; | 170 | obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY; |
171 | |||
172 | #ifndef ACPI_DUMP_APP | ||
173 | obj_desc->method.implementation = acpi_ut_osi_implementation; | 173 | obj_desc->method.implementation = acpi_ut_osi_implementation; |
174 | #endif | 174 | #endif |
175 | #endif | ||
175 | break; | 176 | break; |
176 | 177 | ||
177 | case ACPI_TYPE_INTEGER: | 178 | case ACPI_TYPE_INTEGER: |
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index edbf1db36b68..21d560decbf9 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c | |||
@@ -176,10 +176,9 @@ acpi_ns_delete_node ( | |||
176 | * DESCRIPTION: Initialize a new namespace node and install it amongst | 176 | * DESCRIPTION: Initialize a new namespace node and install it amongst |
177 | * its peers. | 177 | * its peers. |
178 | * | 178 | * |
179 | * Note: Current namespace lookup is linear search. However, the | 179 | * Note: Current namespace lookup is linear search. This appears |
180 | * nodes are linked in alphabetical order to 1) put all reserved | 180 | * to be sufficient as namespace searches consume only a small |
181 | * names (start with underscore) first, and to 2) make a readable | 181 | * fraction of the execution time of the ACPI subsystem. |
182 | * namespace dump. | ||
183 | * | 182 | * |
184 | ******************************************************************************/ | 183 | ******************************************************************************/ |
185 | 184 | ||
@@ -192,10 +191,6 @@ acpi_ns_install_node ( | |||
192 | { | 191 | { |
193 | acpi_owner_id owner_id = 0; | 192 | acpi_owner_id owner_id = 0; |
194 | struct acpi_namespace_node *child_node; | 193 | struct acpi_namespace_node *child_node; |
195 | #ifdef ACPI_ALPHABETIC_NAMESPACE | ||
196 | |||
197 | struct acpi_namespace_node *previous_child_node; | ||
198 | #endif | ||
199 | 194 | ||
200 | 195 | ||
201 | ACPI_FUNCTION_TRACE ("ns_install_node"); | 196 | ACPI_FUNCTION_TRACE ("ns_install_node"); |
@@ -219,57 +214,6 @@ acpi_ns_install_node ( | |||
219 | node->peer = parent_node; | 214 | node->peer = parent_node; |
220 | } | 215 | } |
221 | else { | 216 | else { |
222 | #ifdef ACPI_ALPHABETIC_NAMESPACE | ||
223 | /* | ||
224 | * Walk the list whilst searching for the correct | ||
225 | * alphabetic placement. | ||
226 | */ | ||
227 | previous_child_node = NULL; | ||
228 | while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node), | ||
229 | acpi_ut_get_node_name (node)) < 0) { | ||
230 | if (child_node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
231 | /* Last peer; Clear end-of-list flag */ | ||
232 | |||
233 | child_node->flags &= ~ANOBJ_END_OF_PEER_LIST; | ||
234 | |||
235 | /* This node is the new peer to the child node */ | ||
236 | |||
237 | child_node->peer = node; | ||
238 | |||
239 | /* This node is the new end-of-list */ | ||
240 | |||
241 | node->flags |= ANOBJ_END_OF_PEER_LIST; | ||
242 | node->peer = parent_node; | ||
243 | break; | ||
244 | } | ||
245 | |||
246 | /* Get next peer */ | ||
247 | |||
248 | previous_child_node = child_node; | ||
249 | child_node = child_node->peer; | ||
250 | } | ||
251 | |||
252 | /* Did the node get inserted at the end-of-list? */ | ||
253 | |||
254 | if (!(node->flags & ANOBJ_END_OF_PEER_LIST)) { | ||
255 | /* | ||
256 | * Loop above terminated without reaching the end-of-list. | ||
257 | * Insert the new node at the current location | ||
258 | */ | ||
259 | if (previous_child_node) { | ||
260 | /* Insert node alphabetically */ | ||
261 | |||
262 | node->peer = child_node; | ||
263 | previous_child_node->peer = node; | ||
264 | } | ||
265 | else { | ||
266 | /* Insert node alphabetically at start of list */ | ||
267 | |||
268 | node->peer = child_node; | ||
269 | parent_node->child = node; | ||
270 | } | ||
271 | } | ||
272 | #else | ||
273 | while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) { | 217 | while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) { |
274 | child_node = child_node->peer; | 218 | child_node = child_node->peer; |
275 | } | 219 | } |
@@ -279,9 +223,8 @@ acpi_ns_install_node ( | |||
279 | /* Clear end-of-list flag */ | 223 | /* Clear end-of-list flag */ |
280 | 224 | ||
281 | child_node->flags &= ~ANOBJ_END_OF_PEER_LIST; | 225 | child_node->flags &= ~ANOBJ_END_OF_PEER_LIST; |
282 | node->flags |= ANOBJ_END_OF_PEER_LIST; | 226 | node->flags |= ANOBJ_END_OF_PEER_LIST; |
283 | node->peer = parent_node; | 227 | node->peer = parent_node; |
284 | #endif | ||
285 | } | 228 | } |
286 | 229 | ||
287 | /* Init the new entry */ | 230 | /* Init the new entry */ |
@@ -570,6 +513,10 @@ acpi_ns_delete_namespace_by_owner ( | |||
570 | ACPI_FUNCTION_TRACE_U32 ("ns_delete_namespace_by_owner", owner_id); | 513 | ACPI_FUNCTION_TRACE_U32 ("ns_delete_namespace_by_owner", owner_id); |
571 | 514 | ||
572 | 515 | ||
516 | if (owner_id == 0) { | ||
517 | return_VOID; | ||
518 | } | ||
519 | |||
573 | parent_node = acpi_gbl_root_node; | 520 | parent_node = acpi_gbl_root_node; |
574 | child_node = NULL; | 521 | child_node = NULL; |
575 | deletion_node = NULL; | 522 | deletion_node = NULL; |
@@ -635,59 +582,7 @@ acpi_ns_delete_namespace_by_owner ( | |||
635 | } | 582 | } |
636 | } | 583 | } |
637 | 584 | ||
638 | (void) acpi_ut_release_owner_id (owner_id); | ||
639 | return_VOID; | 585 | return_VOID; |
640 | } | 586 | } |
641 | 587 | ||
642 | 588 | ||
643 | #ifdef ACPI_ALPHABETIC_NAMESPACE | ||
644 | /******************************************************************************* | ||
645 | * | ||
646 | * FUNCTION: acpi_ns_compare_names | ||
647 | * | ||
648 | * PARAMETERS: Name1 - First name to compare | ||
649 | * Name2 - Second name to compare | ||
650 | * | ||
651 | * RETURN: value from strncmp | ||
652 | * | ||
653 | * DESCRIPTION: Compare two ACPI names. Names that are prefixed with an | ||
654 | * underscore are forced to be alphabetically first. | ||
655 | * | ||
656 | ******************************************************************************/ | ||
657 | |||
658 | int | ||
659 | acpi_ns_compare_names ( | ||
660 | char *name1, | ||
661 | char *name2) | ||
662 | { | ||
663 | char reversed_name1[ACPI_NAME_SIZE]; | ||
664 | char reversed_name2[ACPI_NAME_SIZE]; | ||
665 | u32 i; | ||
666 | u32 j; | ||
667 | |||
668 | |||
669 | /* | ||
670 | * Replace all instances of "underscore" with a value that is smaller so | ||
671 | * that all names that are prefixed with underscore(s) are alphabetically | ||
672 | * first. | ||
673 | * | ||
674 | * Reverse the name bytewise so we can just do a 32-bit compare instead | ||
675 | * of a strncmp. | ||
676 | */ | ||
677 | for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) { | ||
678 | reversed_name1[j] = name1[i]; | ||
679 | if (name1[i] == '_') { | ||
680 | reversed_name1[j] = '*'; | ||
681 | } | ||
682 | |||
683 | reversed_name2[j] = name2[i]; | ||
684 | if (name2[i] == '_') { | ||
685 | reversed_name2[j] = '*'; | ||
686 | } | ||
687 | } | ||
688 | |||
689 | return (*(int *) reversed_name1 - *(int *) reversed_name2); | ||
690 | } | ||
691 | #endif | ||
692 | |||
693 | |||
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index d86ccbc8a134..5d25add6b031 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c | |||
@@ -85,6 +85,9 @@ acpi_ns_print_pathname ( | |||
85 | u32 num_segments, | 85 | u32 num_segments, |
86 | char *pathname) | 86 | char *pathname) |
87 | { | 87 | { |
88 | acpi_native_uint i; | ||
89 | |||
90 | |||
88 | ACPI_FUNCTION_NAME ("ns_print_pathname"); | 91 | ACPI_FUNCTION_NAME ("ns_print_pathname"); |
89 | 92 | ||
90 | 93 | ||
@@ -97,9 +100,13 @@ acpi_ns_print_pathname ( | |||
97 | ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[")); | 100 | ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[")); |
98 | 101 | ||
99 | while (num_segments) { | 102 | while (num_segments) { |
100 | acpi_os_printf ("%4.4s", pathname); | 103 | for (i = 0; i < 4; i++) { |
101 | pathname += ACPI_NAME_SIZE; | 104 | ACPI_IS_PRINT (pathname[i]) ? |
105 | acpi_os_printf ("%c", pathname[i]) : | ||
106 | acpi_os_printf ("?"); | ||
107 | } | ||
102 | 108 | ||
109 | pathname += ACPI_NAME_SIZE; | ||
103 | num_segments--; | 110 | num_segments--; |
104 | if (num_segments) { | 111 | if (num_segments) { |
105 | acpi_os_printf ("."); | 112 | acpi_os_printf ("."); |
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 1ae89a1c8826..908cffd5e720 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c | |||
@@ -365,6 +365,7 @@ acpi_ns_evaluate_by_handle ( | |||
365 | * | 365 | * |
366 | * PARAMETERS: Info - Method info block, contains: | 366 | * PARAMETERS: Info - Method info block, contains: |
367 | * Node - Method Node to execute | 367 | * Node - Method Node to execute |
368 | * obj_desc - Method object | ||
368 | * Parameters - List of parameters to pass to the method, | 369 | * Parameters - List of parameters to pass to the method, |
369 | * terminated by NULL. Params itself may be | 370 | * terminated by NULL. Params itself may be |
370 | * NULL if no parameters are being passed. | 371 | * NULL if no parameters are being passed. |
@@ -387,7 +388,6 @@ acpi_ns_execute_control_method ( | |||
387 | struct acpi_parameter_info *info) | 388 | struct acpi_parameter_info *info) |
388 | { | 389 | { |
389 | acpi_status status; | 390 | acpi_status status; |
390 | union acpi_operand_object *obj_desc; | ||
391 | 391 | ||
392 | 392 | ||
393 | ACPI_FUNCTION_TRACE ("ns_execute_control_method"); | 393 | ACPI_FUNCTION_TRACE ("ns_execute_control_method"); |
@@ -395,8 +395,8 @@ acpi_ns_execute_control_method ( | |||
395 | 395 | ||
396 | /* Verify that there is a method associated with this object */ | 396 | /* Verify that there is a method associated with this object */ |
397 | 397 | ||
398 | obj_desc = acpi_ns_get_attached_object (info->node); | 398 | info->obj_desc = acpi_ns_get_attached_object (info->node); |
399 | if (!obj_desc) { | 399 | if (!info->obj_desc) { |
400 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n")); | 400 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n")); |
401 | 401 | ||
402 | (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); | 402 | (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); |
@@ -407,7 +407,7 @@ acpi_ns_execute_control_method ( | |||
407 | ACPI_LV_INFO, _COMPONENT); | 407 | ACPI_LV_INFO, _COMPONENT); |
408 | 408 | ||
409 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n", | 409 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n", |
410 | obj_desc->method.aml_start + 1, obj_desc->method.aml_length - 1)); | 410 | info->obj_desc->method.aml_start + 1, info->obj_desc->method.aml_length - 1)); |
411 | 411 | ||
412 | /* | 412 | /* |
413 | * Unlock the namespace before execution. This allows namespace access | 413 | * Unlock the namespace before execution. This allows namespace access |
@@ -430,7 +430,7 @@ acpi_ns_execute_control_method ( | |||
430 | return_ACPI_STATUS (status); | 430 | return_ACPI_STATUS (status); |
431 | } | 431 | } |
432 | 432 | ||
433 | status = acpi_psx_execute (info); | 433 | status = acpi_ps_execute_method (info); |
434 | acpi_ex_exit_interpreter (); | 434 | acpi_ex_exit_interpreter (); |
435 | 435 | ||
436 | return_ACPI_STATUS (status); | 436 | return_ACPI_STATUS (status); |
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index 34e497016601..1428a84a31e6 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c | |||
@@ -198,7 +198,7 @@ acpi_ns_load_table_by_type ( | |||
198 | switch (table_type) { | 198 | switch (table_type) { |
199 | case ACPI_TABLE_DSDT: | 199 | case ACPI_TABLE_DSDT: |
200 | 200 | ||
201 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n")); | 201 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace load: DSDT\n")); |
202 | 202 | ||
203 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next; | 203 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next; |
204 | 204 | ||
@@ -218,17 +218,18 @@ acpi_ns_load_table_by_type ( | |||
218 | 218 | ||
219 | 219 | ||
220 | case ACPI_TABLE_SSDT: | 220 | case ACPI_TABLE_SSDT: |
221 | case ACPI_TABLE_PSDT: | ||
221 | 222 | ||
222 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n", | 223 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace load: %d SSDT or PSDTs\n", |
223 | acpi_gbl_table_lists[ACPI_TABLE_SSDT].count)); | 224 | acpi_gbl_table_lists[table_type].count)); |
224 | 225 | ||
225 | /* | 226 | /* |
226 | * Traverse list of SSDT tables | 227 | * Traverse list of SSDT or PSDT tables |
227 | */ | 228 | */ |
228 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_SSDT].next; | 229 | table_desc = acpi_gbl_table_lists[table_type].next; |
229 | for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_SSDT].count; i++) { | 230 | for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) { |
230 | /* | 231 | /* |
231 | * Only attempt to load table if it is not | 232 | * Only attempt to load table into namespace if it is not |
232 | * already loaded! | 233 | * already loaded! |
233 | */ | 234 | */ |
234 | if (!table_desc->loaded_into_namespace) { | 235 | if (!table_desc->loaded_into_namespace) { |
@@ -245,33 +246,6 @@ acpi_ns_load_table_by_type ( | |||
245 | break; | 246 | break; |
246 | 247 | ||
247 | 248 | ||
248 | case ACPI_TABLE_PSDT: | ||
249 | |||
250 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n", | ||
251 | acpi_gbl_table_lists[ACPI_TABLE_PSDT].count)); | ||
252 | |||
253 | /* | ||
254 | * Traverse list of PSDT tables | ||
255 | */ | ||
256 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_PSDT].next; | ||
257 | |||
258 | for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_PSDT].count; i++) { | ||
259 | /* Only attempt to load table if it is not already loaded! */ | ||
260 | |||
261 | if (!table_desc->loaded_into_namespace) { | ||
262 | status = acpi_ns_load_table (table_desc, acpi_gbl_root_node); | ||
263 | if (ACPI_FAILURE (status)) { | ||
264 | break; | ||
265 | } | ||
266 | |||
267 | table_desc->loaded_into_namespace = TRUE; | ||
268 | } | ||
269 | |||
270 | table_desc = table_desc->next; | ||
271 | } | ||
272 | break; | ||
273 | |||
274 | |||
275 | default: | 249 | default: |
276 | status = AE_SUPPORT; | 250 | status = AE_SUPPORT; |
277 | break; | 251 | break; |
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index 64e0b2b9f55c..24bed931d39d 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c | |||
@@ -67,7 +67,7 @@ | |||
67 | 67 | ||
68 | acpi_status | 68 | acpi_status |
69 | acpi_ns_one_complete_parse ( | 69 | acpi_ns_one_complete_parse ( |
70 | u32 pass_number, | 70 | u8 pass_number, |
71 | struct acpi_table_desc *table_desc) | 71 | struct acpi_table_desc *table_desc) |
72 | { | 72 | { |
73 | union acpi_parse_object *parse_root; | 73 | union acpi_parse_object *parse_root; |