Commit 3067e02f authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6

* 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
  ACPICA: Update version to 20091112.
  ACPICA: Add additional module-level code support
  ACPICA: Deploy new create integer interface where appropriate
  ACPICA: New internal utility function to create Integer objects
  ACPICA: Add repair for predefined methods that must return sorted lists
  ACPICA: Fix possible fault if return Package objects contain NULL elements
  ACPICA: Add post-order callback to acpi_walk_namespace
  ACPICA: Change package length error message to an info message
  ACPICA: Reduce severity of predefined repair messages, Warning to Info
  ACPICA: Update version to 20091013
  ACPICA: Fix possible memory leak for Scope ASL operator
  ACPICA: Remove possibility of executing _REG methods twice
  ACPICA: Add repair for bad _MAT buffers
  ACPICA: Add repair for bad _BIF/_BIX packages
parents f71eaf68 b00eb796
...@@ -390,7 +390,7 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info, ...@@ -390,7 +390,7 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info,
pcidev_match.handle = NULL; pcidev_match.handle = NULL;
acpi_walk_namespace(ACPI_TYPE_DEVICE, rootbus_handle, ACPI_UINT32_MAX, acpi_walk_namespace(ACPI_TYPE_DEVICE, rootbus_handle, ACPI_UINT32_MAX,
find_matching_device, &pcidev_match, NULL); find_matching_device, NULL, &pcidev_match, NULL);
if (!pcidev_match.handle) { if (!pcidev_match.handle) {
printk(KERN_ERR printk(KERN_ERR
......
...@@ -885,7 +885,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) ...@@ -885,7 +885,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
/* Find ACPI data for processor */ /* Find ACPI data for processor */
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, &longhaul_walk_callback, ACPI_UINT32_MAX, &longhaul_walk_callback, NULL,
NULL, (void *)&pr); NULL, (void *)&pr);
/* Check ACPI support for C3 state */ /* Check ACPI support for C3 state */
......
...@@ -537,7 +537,7 @@ static int __init acpi_memory_device_init(void) ...@@ -537,7 +537,7 @@ static int __init acpi_memory_device_init(void)
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_UINT32_MAX,
acpi_memory_register_notify_handler, acpi_memory_register_notify_handler, NULL,
NULL, NULL); NULL, NULL);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
...@@ -561,7 +561,7 @@ static void __exit acpi_memory_device_exit(void) ...@@ -561,7 +561,7 @@ static void __exit acpi_memory_device_exit(void)
*/ */
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_UINT32_MAX,
acpi_memory_deregister_notify_handler, acpi_memory_deregister_notify_handler, NULL,
NULL, NULL); NULL, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
......
...@@ -28,7 +28,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o ...@@ -28,7 +28,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \
nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \
nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \
nsparse.o nspredef.o nsrepair.o nsparse.o nspredef.o nsrepair.o nsrepair2.o
acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
......
...@@ -341,6 +341,7 @@ ...@@ -341,6 +341,7 @@
#define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); #define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e);
#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e);
#define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist #define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist
#define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist
#else #else
...@@ -349,6 +350,8 @@ ...@@ -349,6 +350,8 @@
#define ACPI_ERROR_NAMESPACE(s, e) #define ACPI_ERROR_NAMESPACE(s, e)
#define ACPI_ERROR_METHOD(s, n, p, e) #define ACPI_ERROR_METHOD(s, n, p, e)
#define ACPI_WARN_PREDEFINED(plist) #define ACPI_WARN_PREDEFINED(plist)
#define ACPI_INFO_PREDEFINED(plist)
#endif /* ACPI_NO_ERROR_MESSAGES */ #endif /* ACPI_NO_ERROR_MESSAGES */
/* /*
......
...@@ -104,7 +104,8 @@ acpi_ns_walk_namespace(acpi_object_type type, ...@@ -104,7 +104,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
acpi_handle start_object, acpi_handle start_object,
u32 max_depth, u32 max_depth,
u32 flags, u32 flags,
acpi_walk_callback user_function, acpi_walk_callback pre_order_visit,
acpi_walk_callback post_order_visit,
void *context, void **return_value); void *context, void **return_value);
struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
...@@ -272,7 +273,8 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node, ...@@ -272,7 +273,8 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node,
acpi_object_handler handler, void **data); acpi_object_handler handler, void **data);
/* /*
* nsrepair - return object repair for predefined methods/objects * nsrepair - General return object repair for all
* predefined methods/objects
*/ */
acpi_status acpi_status
acpi_ns_repair_object(struct acpi_predefined_data *data, acpi_ns_repair_object(struct acpi_predefined_data *data,
...@@ -284,6 +286,16 @@ acpi_status ...@@ -284,6 +286,16 @@ acpi_status
acpi_ns_repair_package_list(struct acpi_predefined_data *data, acpi_ns_repair_package_list(struct acpi_predefined_data *data,
union acpi_operand_object **obj_desc_ptr); union acpi_operand_object **obj_desc_ptr);
/*
* nsrepair2 - Return object repair for specific
* predefined methods/objects
*/
acpi_status
acpi_ns_complex_repairs(struct acpi_predefined_data *data,
struct acpi_namespace_node *node,
acpi_status validate_status,
union acpi_operand_object **return_object_ptr);
/* /*
* nssearch - Namespace searching and entry * nssearch - Namespace searching and entry
*/ */
......
...@@ -386,6 +386,8 @@ u8 acpi_ut_valid_internal_object(void *object); ...@@ -386,6 +386,8 @@ u8 acpi_ut_valid_internal_object(void *object);
union acpi_operand_object *acpi_ut_create_package_object(u32 count); union acpi_operand_object *acpi_ut_create_package_object(u32 count);
union acpi_operand_object *acpi_ut_create_integer_object(u64 value);
union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size); union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size);
union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size); union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size);
...@@ -481,6 +483,11 @@ acpi_ut_predefined_warning(const char *module_name, ...@@ -481,6 +483,11 @@ acpi_ut_predefined_warning(const char *module_name,
char *pathname, char *pathname,
u8 node_flags, const char *format, ...); u8 node_flags, const char *format, ...);
void ACPI_INTERNAL_VAR_XFACE
acpi_ut_predefined_info(const char *module_name,
u32 line_number,
char *pathname, u8 node_flags, const char *format, ...);
/* Values for Base above (16=Hex, 10=Decimal) */ /* Values for Base above (16=Hex, 10=Decimal) */
#define ACPI_ANY_BASE 0 #define ACPI_ANY_BASE 0
......
...@@ -192,7 +192,7 @@ acpi_ds_initialize_objects(u32 table_index, ...@@ -192,7 +192,7 @@ acpi_ds_initialize_objects(u32 table_index,
status = status =
acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object, ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
&info, NULL); NULL, &info, NULL);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
} }
......
...@@ -409,13 +409,11 @@ acpi_ds_method_data_get_value(u8 type, ...@@ -409,13 +409,11 @@ acpi_ds_method_data_get_value(u8 type,
/* If slack enabled, init the local_x/arg_x to an Integer of value zero */ /* If slack enabled, init the local_x/arg_x to an Integer of value zero */
if (acpi_gbl_enable_interpreter_slack) { if (acpi_gbl_enable_interpreter_slack) {
object = object = acpi_ut_create_integer_object((u64) 0);
acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!object) { if (!object) {
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
object->integer.value = 0;
node->object = object; node->object = object;
} }
......
...@@ -486,7 +486,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, ...@@ -486,7 +486,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
* *
* Note: technically, this is an error, from ACPI spec: "It is an error * Note: technically, this is an error, from ACPI spec: "It is an error
* for NumElements to be less than the number of elements in the * for NumElements to be less than the number of elements in the
* PackageList". However, we just print an error message and * PackageList". However, we just print a message and
* no exception is returned. This provides Windows compatibility. Some * no exception is returned. This provides Windows compatibility. Some
* BIOSs will alter the num_elements on the fly, creating this type * BIOSs will alter the num_elements on the fly, creating this type
* of ill-formed package object. * of ill-formed package object.
...@@ -510,8 +510,8 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, ...@@ -510,8 +510,8 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
arg = arg->common.next; arg = arg->common.next;
} }
ACPI_WARNING((AE_INFO, ACPI_INFO((AE_INFO,
"Package List length (0x%X) larger than NumElements count (0x%X), truncated\n", "Actual Package length (0x%X) is larger than NumElements field (0x%X), truncated\n",
i, element_count)); i, element_count));
} else if (i < element_count) { } else if (i < element_count) {
/* /*
......
...@@ -639,6 +639,19 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, ...@@ -639,6 +639,19 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
break; break;
case AML_SCOPE_OP: case AML_SCOPE_OP:
/* Special case for Scope(\) -> refers to the Root node */
if (op && (op->named.node == acpi_gbl_root_node)) {
node = op->named.node;
status =
acpi_ds_scope_stack_push(node, object_type,
walk_state);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
} else {
/* /*
* The Path is an object reference to an existing object. * The Path is an object reference to an existing object.
* Don't enter the name into the namespace, but look it up * Don't enter the name into the namespace, but look it up
...@@ -647,19 +660,22 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, ...@@ -647,19 +660,22 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
status = status =
acpi_ns_lookup(walk_state->scope_info, buffer_ptr, acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
object_type, ACPI_IMODE_EXECUTE, object_type, ACPI_IMODE_EXECUTE,
ACPI_NS_SEARCH_PARENT, walk_state, &(node)); ACPI_NS_SEARCH_PARENT, walk_state,
&(node));
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
#ifdef ACPI_ASL_COMPILER #ifdef ACPI_ASL_COMPILER
if (status == AE_NOT_FOUND) { if (status == AE_NOT_FOUND) {
status = AE_OK; status = AE_OK;
} else { } else {
ACPI_ERROR_NAMESPACE(buffer_ptr, status); ACPI_ERROR_NAMESPACE(buffer_ptr,
status);
} }
#else #else
ACPI_ERROR_NAMESPACE(buffer_ptr, status); ACPI_ERROR_NAMESPACE(buffer_ptr, status);
#endif #endif
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
}
/* /*
* We must check to make sure that the target is * We must check to make sure that the target is
......
...@@ -945,8 +945,8 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, ...@@ -945,8 +945,8 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
acpi_ev_save_method_info, gpe_block, acpi_ev_save_method_info, NULL,
NULL); gpe_block, NULL);
/* Return the new block */ /* Return the new block */
...@@ -1022,8 +1022,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, ...@@ -1022,8 +1022,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
status = status =
acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
acpi_ev_match_prw_and_gpe, &gpe_info, acpi_ev_match_prw_and_gpe, NULL,
NULL); &gpe_info, NULL);
} }
/* /*
......
...@@ -51,6 +51,10 @@ ...@@ -51,6 +51,10 @@
ACPI_MODULE_NAME("evregion") ACPI_MODULE_NAME("evregion")
/* Local prototypes */ /* Local prototypes */
static u8
acpi_ev_has_default_handler(struct acpi_namespace_node *node,
acpi_adr_space_type space_id);
static acpi_status static acpi_status
acpi_ev_reg_run(acpi_handle obj_handle, acpi_ev_reg_run(acpi_handle obj_handle,
u32 level, void *context, void **return_value); u32 level, void *context, void **return_value);
...@@ -140,6 +144,50 @@ acpi_status acpi_ev_install_region_handlers(void) ...@@ -140,6 +144,50 @@ acpi_status acpi_ev_install_region_handlers(void)
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ev_has_default_handler
*
* PARAMETERS: Node - Namespace node for the device
* space_id - The address space ID
*
* RETURN: TRUE if default handler is installed, FALSE otherwise
*
* DESCRIPTION: Check if the default handler is installed for the requested
* space ID.
*
******************************************************************************/
static u8
acpi_ev_has_default_handler(struct acpi_namespace_node *node,
acpi_adr_space_type space_id)
{
union acpi_operand_object *obj_desc;
union acpi_operand_object *handler_obj;
/* Must have an existing internal object */
obj_desc = acpi_ns_get_attached_object(node);
if (obj_desc) {
handler_obj = obj_desc->device.handler;
/* Walk the linked list of handlers for this object */
while (handler_obj) {
if (handler_obj->address_space.space_id == space_id) {
if (handler_obj->address_space.handler_flags &
ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
return (TRUE);
}
}
handler_obj = handler_obj->address_space.next;
}
}
return (FALSE);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ev_initialize_op_regions * FUNCTION: acpi_ev_initialize_op_regions
...@@ -169,13 +217,19 @@ acpi_status acpi_ev_initialize_op_regions(void) ...@@ -169,13 +217,19 @@ acpi_status acpi_ev_initialize_op_regions(void)
for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
/* /*
* TBD: Make sure handler is the DEFAULT handler, otherwise * Make sure the installed handler is the DEFAULT handler. If not the
* _REG will have already been run. * default, the _REG methods will have already been run (when the
* handler was installed)
*/ */
status = acpi_ev_execute_reg_methods(acpi_gbl_root_node, if (acpi_ev_has_default_handler(acpi_gbl_root_node,
acpi_gbl_default_address_spaces
[i])) {
status =
acpi_ev_execute_reg_methods(acpi_gbl_root_node,
acpi_gbl_default_address_spaces acpi_gbl_default_address_spaces
[i]); [i]);
} }
}
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -235,23 +289,20 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) ...@@ -235,23 +289,20 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
* connection status 1 for connecting the handler, 0 for disconnecting * connection status 1 for connecting the handler, 0 for disconnecting
* the handler (Passed as a parameter) * the handler (Passed as a parameter)
*/ */
args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); args[0] =
acpi_ut_create_integer_object((u64) region_obj->region.space_id);
if (!args[0]) { if (!args[0]) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup1; goto cleanup1;
} }
args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); args[1] = acpi_ut_create_integer_object((u64) function);
if (!args[1]) { if (!args[1]) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup2; goto cleanup2;
} }
/* Setup the parameter objects */ args[2] = NULL; /* Terminate list */
args[0]->integer.value = region_obj->region.space_id;
args[1]->integer.value = function;
args[2] = NULL;
/* Execute the method, no return value */ /* Execute the method, no return value */
...@@ -971,8 +1022,8 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, ...@@ -971,8 +1022,8 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node,
*/ */
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
ACPI_NS_WALK_UNLOCK, ACPI_NS_WALK_UNLOCK,
acpi_ev_install_handler, handler_obj, acpi_ev_install_handler, NULL,
NULL); handler_obj, NULL);
unlock_and_exit: unlock_and_exit:
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
...@@ -1008,7 +1059,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, ...@@ -1008,7 +1059,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
*/ */
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX, status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
&space_id, NULL); NULL, &space_id, NULL);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
......
...@@ -170,14 +170,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, ...@@ -170,14 +170,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
/* Table not found, return an Integer=0 and AE_OK */ /* Table not found, return an Integer=0 and AE_OK */
ddb_handle = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); ddb_handle = acpi_ut_create_integer_object((u64) 0);
if (!ddb_handle) { if (!ddb_handle) {
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
ddb_handle->integer.value = 0;
*return_desc = ddb_handle; *return_desc = ddb_handle;
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
......
...@@ -167,7 +167,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, ...@@ -167,7 +167,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
/* Create a new integer */ /* Create a new integer */
return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); return_desc = acpi_ut_create_integer_object(result);
if (!return_desc) { if (!return_desc) {
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
...@@ -177,7 +177,6 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, ...@@ -177,7 +177,6 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
/* Save the Result */ /* Save the Result */
return_desc->integer.value = result;
acpi_ex_truncate_for32bit_table(return_desc); acpi_ex_truncate_for32bit_table(return_desc);
*result_desc = return_desc; *result_desc = return_desc;
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
......
...@@ -162,13 +162,12 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, ...@@ -162,13 +162,12 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
} else { } else {
/* Field will fit within an Integer (normal case) */ /* Field will fit within an Integer (normal case) */
buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); buffer_desc = acpi_ut_create_integer_object((u64) 0);
if (!buffer_desc) { if (!buffer_desc) {
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
length = acpi_gbl_integer_byte_width; length = acpi_gbl_integer_byte_width;
buffer_desc->integer.value = 0;
buffer = &buffer_desc->integer.value; buffer = &buffer_desc->integer.value;
} }
......
...@@ -100,12 +100,12 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) ...@@ -100,12 +100,12 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
/* Create a return object of type Integer */ /* Create a return object of type Integer */
return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); return_desc =
acpi_ut_create_integer_object(acpi_os_get_timer());
if (!return_desc) { if (!return_desc) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup; goto cleanup;
} }
return_desc->integer.value = acpi_os_get_timer();
break; break;
default: /* Unknown opcode */ default: /* Unknown opcode */
...@@ -599,7 +599,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) ...@@ -599,7 +599,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
switch (walk_state->opcode) { switch (walk_state->opcode) {
case AML_LNOT_OP: /* LNot (Operand) */ case AML_LNOT_OP: /* LNot (Operand) */
return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); return_desc = acpi_ut_create_integer_object((u64) 0);
if (!return_desc) { if (!return_desc) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup; goto cleanup;
...@@ -702,13 +702,11 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) ...@@ -702,13 +702,11 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
/* Allocate a descriptor to hold the type. */ /* Allocate a descriptor to hold the type. */
return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); return_desc = acpi_ut_create_integer_object((u64) type);
if (!return_desc) { if (!return_desc) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup; goto cleanup;
} }
return_desc->integer.value = type;
break; break;
case AML_SIZE_OF_OP: /* size_of (source_object) */ case AML_SIZE_OF_OP: /* size_of (source_object) */
...@@ -777,13 +775,11 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) ...@@ -777,13 +775,11 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
* Now that we have the size of the object, create a result * Now that we have the size of the object, create a result
* object to hold the value * object to hold the value
*/ */
return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); return_desc = acpi_ut_create_integer_object(value);
if (!return_desc) { if (!return_desc) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup; goto cleanup;
} }
return_desc->integer.value = value;
break; break;
case AML_REF_OF_OP: /* ref_of (source_object) */ case AML_REF_OF_OP: /* ref_of (source_object) */
...@@ -946,24 +942,24 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) ...@@ -946,24 +942,24 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
* NOTE: index into a buffer is NOT a pointer to a * NOTE: index into a buffer is NOT a pointer to a
* sub-buffer of the main buffer, it is only a pointer to a * sub-buffer of the main buffer, it is only a pointer to a
* single element (byte) of the buffer! * single element (byte) of the buffer!
*
* Since we are returning the value of the buffer at the
* indexed location, we don't need to add an additional
* reference to the buffer itself.
*/ */
return_desc = return_desc =
acpi_ut_create_internal_object acpi_ut_create_integer_object((u64)
(ACPI_TYPE_INTEGER); temp_desc->
buffer.
pointer
[operand
[0]->
reference.
value]);
if (!return_desc) { if (!return_desc) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup; goto cleanup;
} }
/*
* Since we are returning the value of the buffer at the
* indexed location, we don't need to add an additional
* reference to the buffer itself.
*/
return_desc->integer.value =
temp_desc->buffer.
pointer[operand[0]->reference.
value];
break; break;
case ACPI_TYPE_PACKAGE: case ACPI_TYPE_PACKAGE:
......
...@@ -253,18 +253,15 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) ...@@ -253,18 +253,15 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
} }
/* Create an integer for the return value */ /* Create an integer for the return value */
/* Default return value is ACPI_INTEGER_MAX if no match found */
return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); return_desc = acpi_ut_create_integer_object(ACPI_INTEGER_MAX);
if (!return_desc) { if (!return_desc) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup; goto cleanup;
} }
/* Default return value if no match found */
return_desc->integer.value = ACPI_INTEGER_MAX;
/* /*
* Examine each element until a match is found. Both match conditions * Examine each element until a match is found. Both match conditions
* must be satisfied for a match to occur. Within the loop, * must be satisfied for a match to occur. Within the loop,
......
...@@ -634,8 +634,8 @@ acpi_ns_dump_objects(acpi_object_type type, ...@@ -634,8 +634,8 @@ acpi_ns_dump_objects(acpi_object_type type,
(void)acpi_ns_walk_namespace(type, start_handle, max_depth, (void)acpi_ns_walk_namespace(type, start_handle, max_depth,
ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_NO_UNLOCK |
ACPI_NS_WALK_TEMP_NODES, ACPI_NS_WALK_TEMP_NODES,
acpi_ns_dump_one_object, (void *)&info, acpi_ns_dump_one_object, NULL,
NULL); (void *)&info, NULL);
} }
#endif /* ACPI_FUTURE_USAGE */ #endif /* ACPI_FUTURE_USAGE */
......
...@@ -131,7 +131,8 @@ void acpi_ns_dump_root_devices(void) ...@@ -131,7 +131,8 @@ void acpi_ns_dump_root_devices(void)
status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, sys_bus_handle, status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, sys_bus_handle,
ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
acpi_ns_dump_one_device, NULL, NULL); acpi_ns_dump_one_device, NULL, NULL,
NULL);
} }
#endif #endif
......
...@@ -366,33 +366,49 @@ static void ...@@ -366,33 +366,49 @@ static void
acpi_ns_exec_module_code(union acpi_operand_object *method_obj, acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
struct acpi_evaluate_info *info) struct acpi_evaluate_info *info)
{ {
union acpi_operand_object *root_obj; union acpi_operand_object *parent_obj;
struct acpi_namespace_node *parent_node;
acpi_object_type type;
acpi_status status; acpi_status status;
ACPI_FUNCTION_TRACE(ns_exec_module_code); ACPI_FUNCTION_TRACE(ns_exec_module_code);
/*
* Get the parent node. We cheat by using the next_object field
* of the method object descriptor.
*/
parent_node = ACPI_CAST_PTR(struct acpi_namespace_node,
method_obj->method.next_object);
type = acpi_ns_get_type(parent_node);
/* Must clear next_object (acpi_ns_attach_object needs the field) */
method_obj->method.next_object = NULL;
/* Initialize the evaluation information block */ /* Initialize the evaluation information block */
ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info)); ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info));
info->prefix_node = acpi_gbl_root_node; info->prefix_node = parent_node;
/* /*
* Get the currently attached root object. Add a reference, because the * Get the currently attached parent object. Add a reference, because the
* ref count will be decreased when the method object is installed to * ref count will be decreased when the method object is installed to
* the root node. * the parent node.
*/ */
root_obj = acpi_ns_get_attached_object(acpi_gbl_root_node); parent_obj = acpi_ns_get_attached_object(parent_node);
acpi_ut_add_reference(root_obj); if (parent_obj) {
acpi_ut_add_reference(parent_obj);
}
/* Install the method (module-level code) in the root node */ /* Install the method (module-level code) in the parent node */
status = acpi_ns_attach_object(acpi_gbl_root_node, method_obj, status = acpi_ns_attach_object(parent_node, method_obj,
ACPI_TYPE_METHOD); ACPI_TYPE_METHOD);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto exit; goto exit;
} }
/* Execute the root node as a control method */ /* Execute the parent node as a control method */
status = acpi_ns_evaluate(info); status = acpi_ns_evaluate(info);
...@@ -401,15 +417,19 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj, ...@@ -401,15 +417,19 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
/* Detach the temporary method object */ /* Detach the temporary method object */
acpi_ns_detach_object(acpi_gbl_root_node); acpi_ns_detach_object(parent_node);
/* Restore the original root object */ /* Restore the original parent object */
status = if (parent_obj) {
acpi_ns_attach_object(acpi_gbl_root_node, root_obj, status = acpi_ns_attach_object(parent_node, parent_obj, type);
ACPI_TYPE_DEVICE); } else {
parent_node->type = (u8)type;
}
exit: exit:
acpi_ut_remove_reference(root_obj); if (parent_obj) {
acpi_ut_remove_reference(parent_obj);
}
return_VOID; return_VOID;
} }
...@@ -96,7 +96,7 @@ acpi_status acpi_ns_initialize_objects(void) ...@@ -96,7 +96,7 @@ acpi_status acpi_ns_initialize_objects(void)
/* Walk entire namespace from the supplied root */ /* Walk entire namespace from the supplied root */
status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, acpi_ns_init_one_object, ACPI_UINT32_MAX, acpi_ns_init_one_object, NULL,
&info, NULL); &info, NULL);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
...@@ -156,7 +156,8 @@ acpi_status acpi_ns_initialize_devices(void) ...@@ -156,7 +156,8 @@ acpi_status acpi_ns_initialize_devices(void)
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, FALSE, ACPI_UINT32_MAX, FALSE,
acpi_ns_find_ini_methods, &info, NULL); acpi_ns_find_ini_methods, NULL, &info,
NULL);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto error_exit; goto error_exit;
} }
...@@ -189,7 +190,8 @@ acpi_status acpi_ns_initialize_devices(void) ...@@ -189,7 +190,8 @@ acpi_status acpi_ns_initialize_devices(void)
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, FALSE, ACPI_UINT32_MAX, FALSE,
acpi_ns_init_one_device, &info, NULL); acpi_ns_init_one_device, NULL, &info,
NULL);
ACPI_FREE(info.evaluate_info); ACPI_FREE(info.evaluate_info);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
......
...@@ -232,6 +232,12 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, ...@@ -232,6 +232,12 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
status = acpi_ns_check_package(data, return_object_ptr); status = acpi_ns_check_package(data, return_object_ptr);
} }
/*
* Perform additional, more complicated repairs on a per-name
* basis.
*/
status = acpi_ns_complex_repairs(data, node, status, return_object_ptr);
check_validation_status: check_validation_status:
/* /*
* If the object validation failed or if we successfully repaired one * If the object validation failed or if we successfully repaired one
...@@ -601,7 +607,8 @@ acpi_ns_check_package(struct acpi_predefined_data *data, ...@@ -601,7 +607,8 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
* there is only one entry). We may be able to repair this by * there is only one entry). We may be able to repair this by
* wrapping the returned Package with a new outer Package. * wrapping the returned Package with a new outer Package.
*/ */
if ((*elements)->common.type != ACPI_TYPE_PACKAGE) { if (*elements
&& ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
/* Create the new outer package and populate it */ /* Create the new outer package and populate it */
...@@ -673,6 +680,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data, ...@@ -673,6 +680,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
union acpi_operand_object *sub_package; union acpi_operand_object *sub_package;
union acpi_operand_object **sub_elements; union acpi_operand_object **sub_elements;
acpi_status status; acpi_status status;
u8 non_trailing_null = FALSE;
u32 expected_count; u32 expected_count;
u32 i; u32 i;
u32 j; u32 j;
...@@ -680,6 +688,45 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data, ...@@ -680,6 +688,45 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
/* Validate each sub-Package in the parent Package */ /* Validate each sub-Package in the parent Package */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
/*
* Handling for NULL package elements. For now, we will simply allow
* a parent package with trailing NULL elements. This can happen if
* the package was defined to be longer than the initializer list.
* This is legal as per the ACPI specification. It is often used
* to allow for dynamic initialization of a Package.
*
* A future enhancement may be to simply truncate the package to
* remove the trailing NULL elements.
*/
if (!(*elements)) {
if (!non_trailing_null) {
/* Ensure the remaining elements are all NULL */
for (j = 1; j < (count - i + 1); j++) {
if (elements[j]) {
non_trailing_null = TRUE;
}
}
if (!non_trailing_null) {
/* Ignore the trailing NULL elements */
return (AE_OK);
}
}
/* There are trailing non-null elements, issue warning */
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
data->node_flags,
"Found NULL element at package index %u",
i));
elements++;
continue;
}
sub_package = *elements; sub_package = *elements;
sub_elements = sub_package->package.elements; sub_elements = sub_package->package.elements;
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <acpi/acpi.h> #include <acpi/acpi.h>
#include "accommon.h" #include "accommon.h"
#include "acnamesp.h" #include "acnamesp.h"
#include "acinterp.h"
#include "acpredef.h" #include "acpredef.h"
#define _COMPONENT ACPI_NAMESPACE #define _COMPONENT ACPI_NAMESPACE
...@@ -76,7 +77,13 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, ...@@ -76,7 +77,13 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
union acpi_operand_object *return_object = *return_object_ptr; union acpi_operand_object *return_object = *return_object_ptr;
union acpi_operand_object *new_object; union acpi_operand_object *new_object;
acpi_size length; acpi_size length;
acpi_status status;
/*
* At this point, we know that the type of the returned object was not
* one of the expected types for this predefined name. Attempt to
* repair the object. Only a limited number of repairs are possible.
*/
switch (return_object->common.type) { switch (return_object->common.type) {
case ACPI_TYPE_BUFFER: case ACPI_TYPE_BUFFER:
...@@ -111,6 +118,58 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, ...@@ -111,6 +118,58 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
*/ */
ACPI_MEMCPY(new_object->string.pointer, ACPI_MEMCPY(new_object->string.pointer,
return_object->buffer.pointer, length); return_object->buffer.pointer, length);
break;
case ACPI_TYPE_INTEGER:
/* 1) Does the method/object legally return a buffer? */
if (expected_btypes & ACPI_RTYPE_BUFFER) {
/*
* Convert the Integer to a packed-byte buffer. _MAT needs
* this sometimes, if a read has been performed on a Field
* object that is less than or equal to the global integer
* size (32 or 64 bits).
*/
status =
acpi_ex_convert_to_buffer(return_object,
&new_object);
if (ACPI_FAILURE(status)) {
return (status);
}
}
/* 2) Does the method/object legally return a string? */
else if (expected_btypes & ACPI_RTYPE_STRING) {
/*
* The only supported Integer-to-String conversion is to convert
* an integer of value 0 to a NULL string. The last element of
* _BIF and _BIX packages occasionally need this fix.
*/
if (return_object->integer.value != 0) {
return (AE_AML_OPERAND_TYPE);
}
/* Allocate a new NULL string object */
new_object = acpi_ut_create_string_object(0);
if (!new_object) {
return (AE_NO_MEMORY);
}
} else {
return (AE_AML_OPERAND_TYPE);
}
break;
default:
/* We cannot repair this object */
return (AE_AML_OPERAND_TYPE);
}
/* Object was successfully repaired */
/* /*
* If the original object is a package element, we need to: * If the original object is a package element, we need to:
...@@ -126,14 +185,19 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, ...@@ -126,14 +185,19 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
return_object->common.reference_count--; return_object->common.reference_count--;
} }
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
data->node_flags, "Converted %s to expected %s at index %u",
"Converted Buffer to expected String at index %u", acpi_ut_get_object_type_name
(return_object),
acpi_ut_get_object_type_name(new_object),
package_index)); package_index));
} else { } else {
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
data->node_flags, "Converted %s to expected %s",
"Converted Buffer to expected String")); acpi_ut_get_object_type_name
(return_object),
acpi_ut_get_object_type_name
(new_object)));
} }
/* Delete old object, install the new return object */ /* Delete old object, install the new return object */
...@@ -142,12 +206,6 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, ...@@ -142,12 +206,6 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
*return_object_ptr = new_object; *return_object_ptr = new_object;
data->flags |= ACPI_OBJECT_REPAIRED; data->flags |= ACPI_OBJECT_REPAIRED;
return (AE_OK); return (AE_OK);
default:
break;
}
return (AE_AML_OPERAND_TYPE);
} }
/******************************************************************************* /*******************************************************************************
...@@ -196,8 +254,8 @@ acpi_ns_repair_package_list(struct acpi_predefined_data *data, ...@@ -196,8 +254,8 @@ acpi_ns_repair_package_list(struct acpi_predefined_data *data,
*obj_desc_ptr = pkg_obj_desc; *obj_desc_ptr = pkg_obj_desc;
data->flags |= ACPI_OBJECT_REPAIRED; data->flags |= ACPI_OBJECT_REPAIRED;
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
"Incorrectly formed Package, attempting repair")); "Repaired Incorrectly formed Package"));
return (AE_OK); return (AE_OK);
} }
/******************************************************************************
*
* Module Name: nsrepair2 - Repair for objects returned by specific
* predefined methods
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2009, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include <acpi/acpi.h>
#include "accommon.h"
#include "acnamesp.h"
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsrepair2")
/*
* Information structure and handler for ACPI predefined names that can
* be repaired on a per-name basis.
*/
typedef
acpi_status(*acpi_repair_function) (struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr);
typedef struct acpi_repair_info {
char name[ACPI_NAME_SIZE];
acpi_repair_function repair_function;
} acpi_repair_info;
/* Local prototypes */
static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct
acpi_namespace_node
*node);
static acpi_status
acpi_ns_repair_ALR(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr);
static acpi_status
acpi_ns_repair_PSS(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr);
static acpi_status
acpi_ns_repair_TSS(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr);
static acpi_status
acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
union acpi_operand_object *return_object,
u32 expected_count,
u32 sort_index,
u8 sort_direction, char *sort_key_name);
static acpi_status
acpi_ns_remove_null_elements(union acpi_operand_object *package);
static acpi_status
acpi_ns_sort_list(union acpi_operand_object **elements,
u32 count, u32 index, u8 sort_direction);
/* Values for sort_direction above */
#define ACPI_SORT_ASCENDING 0
#define ACPI_SORT_DESCENDING 1
/*
* This table contains the names of the predefined methods for which we can
* perform more complex repairs.
*
* _ALR: Sort the list ascending by ambient_illuminance if necessary
* _PSS: Sort the list descending by Power if necessary
* _TSS: Sort the list descending by Power if necessary
*/
static const struct acpi_repair_info acpi_ns_repairable_names[] = {
{"_ALR", acpi_ns_repair_ALR},
{"_PSS", acpi_ns_repair_PSS},
{"_TSS", acpi_ns_repair_TSS},
{{0, 0, 0, 0}, NULL} /* Table terminator */
};
/******************************************************************************
*
* FUNCTION: acpi_ns_complex_repairs
*
* PARAMETERS: Data - Pointer to validation data structure
* Node - Namespace node for the method/object
* validate_status - Original status of earlier validation
* return_object_ptr - Pointer to the object returned from the
* evaluation of a method or object
*
* RETURN: Status. AE_OK if repair was successful. If name is not
* matched, validate_status is returned.
*
* DESCRIPTION: Attempt to repair/convert a return object of a type that was
* not expected.
*
*****************************************************************************/
acpi_status
acpi_ns_complex_repairs(struct acpi_predefined_data *data,
struct acpi_namespace_node *node,
acpi_status validate_status,
union acpi_operand_object **return_object_ptr)
{
const struct acpi_repair_info *predefined;
acpi_status status;
/* Check if this name is in the list of repairable names */
predefined = acpi_ns_match_repairable_name(node);
if (!predefined) {
return (validate_status);
}
status = predefined->repair_function(data, return_object_ptr);
return (status);
}
/******************************************************************************
*
* FUNCTION: acpi_ns_match_repairable_name
*
* PARAMETERS: Node - Namespace node for the method/object
*
* RETURN: Pointer to entry in repair table. NULL indicates not found.
*
* DESCRIPTION: Check an object name against the repairable object list.
*
*****************************************************************************/
static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct
acpi_namespace_node
*node)
{
const struct acpi_repair_info *this_name;
/* Search info table for a repairable predefined method/object name */
this_name = acpi_ns_repairable_names;
while (this_name->repair_function) {
if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) {
return (this_name);
}
this_name++;
}
return (NULL); /* Not found */
}
/******************************************************************************
*
* FUNCTION: acpi_ns_repair_ALR
*
* PARAMETERS: Data - Pointer to validation data structure
* return_object_ptr - Pointer to the object returned from the
* evaluation of a method or object
*
* RETURN: Status. AE_OK if object is OK or was repaired successfully
*
* DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
* ascending by the ambient illuminance values.
*
*****************************************************************************/
static acpi_status
acpi_ns_repair_ALR(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr)
{
union acpi_operand_object *return_object = *return_object_ptr;
acpi_status status;
status = acpi_ns_check_sorted_list(data, return_object, 2, 1,
ACPI_SORT_ASCENDING,
"AmbientIlluminance");
return (status);
}
/******************************************************************************
*
* FUNCTION: acpi_ns_repair_TSS
*
* PARAMETERS: Data - Pointer to validation data structure
* return_object_ptr - Pointer to the object returned from the
* evaluation of a method or object
*
* RETURN: Status. AE_OK if object is OK or was repaired successfully
*
* DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
* descending by the power dissipation values.
*
*****************************************************************************/
static acpi_status
acpi_ns_repair_TSS(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr)
{
union acpi_operand_object *return_object = *return_object_ptr;
acpi_status status;
status = acpi_ns_check_sorted_list(data, return_object, 5, 1,
ACPI_SORT_DESCENDING,
"PowerDissipation");
return (status);
}
/******************************************************************************
*
* FUNCTION: acpi_ns_repair_PSS
*
* PARAMETERS: Data - Pointer to validation data structure
* return_object_ptr - Pointer to the object returned from the
* evaluation of a method or object
*
* RETURN: Status. AE_OK if object is OK or was repaired successfully
*
* DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
* by the CPU frequencies. Check that the power dissipation values
* are all proportional to CPU frequency (i.e., sorting by
* frequency should be the same as sorting by power.)
*
*****************************************************************************/
static acpi_status
acpi_ns_repair_PSS(struct acpi_predefined_data *data,
union acpi_operand_object **return_object_ptr)
{
union acpi_operand_object *return_object = *return_object_ptr;
union acpi_operand_object **outer_elements;
u32 outer_element_count;
union acpi_operand_object **elements;
union acpi_operand_object *obj_desc;
u32 previous_value;
acpi_status status;
u32 i;
/*
* Entries (sub-packages) in the _PSS Package must be sorted by power
* dissipation, in descending order. If it appears that the list is
* incorrectly sorted, sort it. We sort by cpu_frequency, since this
* should be proportional to the power.
*/
status = acpi_ns_check_sorted_list(data, return_object, 6, 0,
ACPI_SORT_DESCENDING,
"CpuFrequency");
if (ACPI_FAILURE(status)) {
return (status);
}
/*
* We now know the list is correctly sorted by CPU frequency. Check if
* the power dissipation values are proportional.
*/
previous_value = ACPI_UINT32_MAX;
outer_elements = return_object->package.elements;
outer_element_count = return_object->package.count;
for (i = 0; i < outer_element_count; i++) {
elements = (*outer_elements)->package.elements;
obj_desc = elements[1]; /* Index1 = power_dissipation */
if ((u32) obj_desc->integer.value > previous_value) {
ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
data->node_flags,
"SubPackage[%u,%u] - suspicious power dissipation values",
i - 1, i));
}
previous_value = (u32) obj_desc->integer.value;
outer_elements++;
}
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: acpi_ns_check_sorted_list
*
* PARAMETERS: Data - Pointer to validation data structure
* return_object - Pointer to the top-level returned object
* expected_count - Minimum length of each sub-package
* sort_index - Sub-package entry to sort on
* sort_direction - Ascending or descending
* sort_key_name - Name of the sort_index field
*
* RETURN: Status. AE_OK if the list is valid and is sorted correctly or
* has been repaired by sorting the list.
*
* DESCRIPTION: Check if the package list is valid and sorted correctly by the
* sort_index. If not, then sort the list.
*
*****************************************************************************/
static acpi_status
acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
union acpi_operand_object *return_object,
u32 expected_count,
u32 sort_index,
u8 sort_direction, char *sort_key_name)
{
u32 outer_element_count;
union acpi_operand_object **outer_elements;
union acpi_operand_object **elements;
union acpi_operand_object *obj_desc;
u32 i;
u32 previous_value;
acpi_status status;
/* The top-level object must be a package */
if (return_object->common.type != ACPI_TYPE_PACKAGE) {
return (AE_AML_OPERAND_TYPE);
}
/*
* Detect any NULL package elements and remove them from the
* package.
*
* TBD: We may want to do this for all predefined names that
* return a variable-length package of packages.
*/
status = acpi_ns_remove_null_elements(return_object);
if (status == AE_NULL_ENTRY) {
ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
"NULL elements removed from package"));
/* Exit if package is now zero length */
if (!return_object->package.count) {
return (AE_NULL_ENTRY);
}
}
outer_elements = return_object->package.elements;
outer_element_count = return_object->package.count;
if (!outer_element_count) {
return (AE_AML_PACKAGE_LIMIT);
}
previous_value = 0;
if (sort_direction == ACPI_SORT_DESCENDING) {
previous_value = ACPI_UINT32_MAX;
}
/* Examine each subpackage */
for (i = 0; i < outer_element_count; i++) {
/* Each element of the top-level package must also be a package */
if ((*outer_elements)->common.type != ACPI_TYPE_PACKAGE) {
return (AE_AML_OPERAND_TYPE);
}
/* Each sub-package must have the minimum length */
if ((*outer_elements)->package.count < expected_count) {
return (AE_AML_PACKAGE_LIMIT);
}
elements = (*outer_elements)->package.elements;
obj_desc = elements[sort_index];
if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
return (AE_AML_OPERAND_TYPE);
}
/*
* The list must be sorted in the specified order. If we detect a
* discrepancy, issue a warning and sort the entire list
*/
if (((sort_direction == ACPI_SORT_ASCENDING) &&
(obj_desc->integer.value < previous_value)) ||
((sort_direction == ACPI_SORT_DESCENDING) &&
(obj_desc->integer.value > previous_value))) {
status =
acpi_ns_sort_list(return_object->package.elements,
outer_element_count, sort_index,
sort_direction);
if (ACPI_FAILURE(status)) {
return (status);
}
data->flags |= ACPI_OBJECT_REPAIRED;
ACPI_INFO_PREDEFINED((AE_INFO, data->pathname,
data->node_flags,
"Repaired unsorted list - now sorted by %s",
sort_key_name));
return (AE_OK);
}
previous_value = (u32) obj_desc->integer.value;
outer_elements++;
}
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: acpi_ns_remove_null_elements
*
* PARAMETERS: obj_desc - A Package object
*
* RETURN: Status. AE_NULL_ENTRY means that one or more elements were
* removed.
*
* DESCRIPTION: Remove all NULL package elements and update the package count.
*
*****************************************************************************/
static acpi_status
acpi_ns_remove_null_elements(union acpi_operand_object *obj_desc)
{
union acpi_operand_object **source;
union acpi_operand_object **dest;
acpi_status status = AE_OK;
u32 count;
u32 new_count;
u32 i;
count = obj_desc->package.count;
new_count = count;
source = obj_desc->package.elements;
dest = source;
/* Examine all elements of the package object */
for (i = 0; i < count; i++) {
if (!*source) {
status = AE_NULL_ENTRY;
new_count--;
} else {
*dest = *source;
dest++;
}
source++;
}
if (status == AE_NULL_ENTRY) {
/* NULL terminate list and update the package count */
*dest = NULL;
obj_desc->package.count = new_count;
}
return (status);
}
/******************************************************************************
*
* FUNCTION: acpi_ns_sort_list
*
* PARAMETERS: Elements - Package object element list
* Count - Element count for above
* Index - Sort by which package element
* sort_direction - Ascending or Descending sort
*
* RETURN: Status
*
* DESCRIPTION: Sort the objects that are in a package element list.
*
* NOTE: Assumes that all NULL elements have been removed from the package.
*
*****************************************************************************/
static acpi_status
acpi_ns_sort_list(union acpi_operand_object **elements,
u32 count, u32 index, u8 sort_direction)
{
union acpi_operand_object *obj_desc1;
union acpi_operand_object *obj_desc2;
union acpi_operand_object *temp_obj;
u32 i;
u32 j;
/* Simple bubble sort */
for (i = 1; i < count; i++) {
for (j = (count - 1); j >= i; j--) {
obj_desc1 = elements[j - 1]->package.elements[index];
obj_desc2 = elements[j]->package.elements[index];
if (((sort_direction == ACPI_SORT_ASCENDING) &&
(obj_desc1->integer.value >
obj_desc2->integer.value))
|| ((sort_direction == ACPI_SORT_DESCENDING)
&& (obj_desc1->integer.value <
obj_desc2->integer.value))) {
temp_obj = elements[j - 1];
elements[j - 1] = elements[j];
elements[j] = temp_obj;
}
}
}
return (AE_OK);
}
...@@ -165,24 +165,27 @@ struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, ...@@ -165,24 +165,27 @@ struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type,
* max_depth - Depth to which search is to reach * max_depth - Depth to which search is to reach
* Flags - Whether to unlock the NS before invoking * Flags - Whether to unlock the NS before invoking
* the callback routine * the callback routine
* user_function - Called when an object of "Type" is found * pre_order_visit - Called during tree pre-order visit
* Context - Passed to user function * when an object of "Type" is found
* return_value - from the user_function if terminated early. * post_order_visit - Called during tree post-order visit
* Otherwise, returns NULL. * when an object of "Type" is found
* Context - Passed to user function(s) above
* return_value - from the user_function if terminated
* early. Otherwise, returns NULL.
* RETURNS: Status * RETURNS: Status
* *
* DESCRIPTION: Performs a modified depth-first walk of the namespace tree, * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
* starting (and ending) at the node specified by start_handle. * starting (and ending) at the node specified by start_handle.
* The user_function is called whenever a node that matches * The callback function is called whenever a node that matches
* the type parameter is found. If the user function returns * the type parameter is found. If the callback function returns
* a non-zero value, the search is terminated immediately and * a non-zero value, the search is terminated immediately and
* this value is returned to the caller. * this value is returned to the caller.
* *
* The point of this procedure is to provide a generic namespace * The point of this procedure is to provide a generic namespace
* walk routine that can be called from multiple places to * walk routine that can be called from multiple places to
* provide multiple services; the User Function can be tailored * provide multiple services; the callback function(s) can be
* to each task, whether it is a print function, a compare * tailored to each task, whether it is a print function,
* function, etc. * a compare function, etc.
* *
******************************************************************************/ ******************************************************************************/
...@@ -191,7 +194,8 @@ acpi_ns_walk_namespace(acpi_object_type type, ...@@ -191,7 +194,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
acpi_handle start_node, acpi_handle start_node,
u32 max_depth, u32 max_depth,
u32 flags, u32 flags,
acpi_walk_callback user_function, acpi_walk_callback pre_order_visit,
acpi_walk_callback post_order_visit,
void *context, void **return_value) void *context, void **return_value)
{ {
acpi_status status; acpi_status status;
...@@ -200,6 +204,7 @@ acpi_ns_walk_namespace(acpi_object_type type, ...@@ -200,6 +204,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
struct acpi_namespace_node *parent_node; struct acpi_namespace_node *parent_node;
acpi_object_type child_type; acpi_object_type child_type;
u32 level; u32 level;
u8 node_previously_visited = FALSE;
ACPI_FUNCTION_TRACE(ns_walk_namespace); ACPI_FUNCTION_TRACE(ns_walk_namespace);
...@@ -212,7 +217,7 @@ acpi_ns_walk_namespace(acpi_object_type type, ...@@ -212,7 +217,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
/* Null child means "get first node" */ /* Null child means "get first node" */
parent_node = start_node; parent_node = start_node;
child_node = NULL; child_node = acpi_ns_get_next_node(parent_node, NULL);
child_type = ACPI_TYPE_ANY; child_type = ACPI_TYPE_ANY;
level = 1; level = 1;
...@@ -221,13 +226,8 @@ acpi_ns_walk_namespace(acpi_object_type type, ...@@ -221,13 +226,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
* started. When Level is zero, the loop is done because we have * started. When Level is zero, the loop is done because we have
* bubbled up to (and passed) the original parent handle (start_entry) * bubbled up to (and passed) the original parent handle (start_entry)
*/ */
while (level > 0) { while (level > 0 && child_node) {
/* Get the next node in this scope. Null if not found */
status = AE_OK; status = AE_OK;
child_node = acpi_ns_get_next_node(parent_node, child_node);
if (child_node) {
/* Found next child, get the type if we are not searching for ANY */ /* Found next child, get the type if we are not searching for ANY */
...@@ -257,25 +257,37 @@ acpi_ns_walk_namespace(acpi_object_type type, ...@@ -257,25 +257,37 @@ acpi_ns_walk_namespace(acpi_object_type type,
*/ */
if (flags & ACPI_NS_WALK_UNLOCK) { if (flags & ACPI_NS_WALK_UNLOCK) {
mutex_status = mutex_status =
acpi_ut_release_mutex acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(mutex_status)) { if (ACPI_FAILURE(mutex_status)) {
return_ACPI_STATUS return_ACPI_STATUS(mutex_status);
(mutex_status);
} }
} }
/*
* Invoke the user function, either pre-order or post-order
* or both.
*/
if (!node_previously_visited) {
if (pre_order_visit) {
status = status =
user_function(child_node, level, context, pre_order_visit(child_node, level,
context,
return_value); return_value);
}
} else {
if (post_order_visit) {
status =
post_order_visit(child_node, level,
context,
return_value);
}
}
if (flags & ACPI_NS_WALK_UNLOCK) { if (flags & ACPI_NS_WALK_UNLOCK) {
mutex_status = mutex_status =
acpi_ut_acquire_mutex acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(mutex_status)) { if (ACPI_FAILURE(mutex_status)) {
return_ACPI_STATUS return_ACPI_STATUS(mutex_status);
(mutex_status);
} }
} }
...@@ -306,17 +318,37 @@ acpi_ns_walk_namespace(acpi_object_type type, ...@@ -306,17 +318,37 @@ acpi_ns_walk_namespace(acpi_object_type type,
* reached the caller specified maximum depth or if the user * reached the caller specified maximum depth or if the user
* function has specified that the maximum depth has been reached. * function has specified that the maximum depth has been reached.
*/ */
if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { if (!node_previously_visited &&
(level < max_depth) && (status != AE_CTRL_DEPTH)) {
if (child_node->child) { if (child_node->child) {
/* There is at least one child of this node, visit it */ /* There is at least one child of this node, visit it */
level++; level++;
parent_node = child_node; parent_node = child_node;
child_node = NULL; child_node =
acpi_ns_get_next_node(parent_node, NULL);
continue;
} }
} }
} else {
/* No more children, re-visit this node */
if (!node_previously_visited) {
node_previously_visited = TRUE;
continue;
}
/* No more children, visit peers */
child_node = acpi_ns_get_next_node(parent_node, child_node);
if (child_node) {
node_previously_visited = FALSE;
}
/* No peers, re-visit parent */
else {
/* /*
* No more children of this node (acpi_ns_get_next_node failed), go * No more children of this node (acpi_ns_get_next_node failed), go
* back upwards in the namespace tree to the node's parent. * back upwards in the namespace tree to the node's parent.
...@@ -324,6 +356,8 @@ acpi_ns_walk_namespace(acpi_object_type type, ...@@ -324,6 +356,8 @@ acpi_ns_walk_namespace(acpi_object_type type,
level--; level--;
child_node = parent_node; child_node = parent_node;
parent_node = acpi_ns_get_parent_node(parent_node); parent_node = acpi_ns_get_parent_node(parent_node);
node_previously_visited = TRUE;
} }
} }
......
...@@ -433,8 +433,11 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) ...@@ -433,8 +433,11 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
* PARAMETERS: Type - acpi_object_type to search for * PARAMETERS: Type - acpi_object_type to search for
* start_object - Handle in namespace where search begins * start_object - Handle in namespace where search begins
* max_depth - Depth to which search is to reach * max_depth - Depth to which search is to reach
* user_function - Called when an object of "Type" is found * pre_order_visit - Called during tree pre-order visit
* Context - Passed to user function * when an object of "Type" is found
* post_order_visit - Called during tree post-order visit
* when an object of "Type" is found
* Context - Passed to user function(s) above
* return_value - Location where return value of * return_value - Location where return value of
* user_function is put if terminated early * user_function is put if terminated early
* *
...@@ -443,16 +446,16 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) ...@@ -443,16 +446,16 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
* *
* DESCRIPTION: Performs a modified depth-first walk of the namespace tree, * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
* starting (and ending) at the object specified by start_handle. * starting (and ending) at the object specified by start_handle.
* The user_function is called whenever an object that matches * The callback function is called whenever an object that matches
* the type parameter is found. If the user function returns * the type parameter is found. If the callback function returns
* a non-zero value, the search is terminated immediately and this * a non-zero value, the search is terminated immediately and this
* value is returned to the caller. * value is returned to the caller.
* *
* The point of this procedure is to provide a generic namespace * The point of this procedure is to provide a generic namespace
* walk routine that can be called from multiple places to * walk routine that can be called from multiple places to
* provide multiple services; the User Function can be tailored * provide multiple services; the callback function(s) can be
* to each task, whether it is a print function, a compare * tailored to each task, whether it is a print function,
* function, etc. * a compare function, etc.
* *
******************************************************************************/ ******************************************************************************/
...@@ -460,7 +463,8 @@ acpi_status ...@@ -460,7 +463,8 @@ acpi_status
acpi_walk_namespace(acpi_object_type type, acpi_walk_namespace(acpi_object_type type,
acpi_handle start_object, acpi_handle start_object,
u32 max_depth, u32 max_depth,
acpi_walk_callback user_function, acpi_walk_callback pre_order_visit,
acpi_walk_callback post_order_visit,
void *context, void **return_value) void *context, void **return_value)
{ {
acpi_status status; acpi_status status;
...@@ -469,7 +473,8 @@ acpi_walk_namespace(acpi_object_type type, ...@@ -469,7 +473,8 @@ acpi_walk_namespace(acpi_object_type type,
/* Parameter validation */ /* Parameter validation */
if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) { if ((type > ACPI_TYPE_LOCAL_MAX) ||
(!max_depth) || (!pre_order_visit && !post_order_visit)) {
return_ACPI_STATUS(AE_BAD_PARAMETER); return_ACPI_STATUS(AE_BAD_PARAMETER);
} }
...@@ -501,8 +506,9 @@ acpi_walk_namespace(acpi_object_type type, ...@@ -501,8 +506,9 @@ acpi_walk_namespace(acpi_object_type type,
} }
status = acpi_ns_walk_namespace(type, start_object, max_depth, status = acpi_ns_walk_namespace(type, start_object, max_depth,
ACPI_NS_WALK_UNLOCK, user_function, ACPI_NS_WALK_UNLOCK, pre_order_visit,
context, return_value); post_order_visit, context,
return_value);
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
...@@ -681,8 +687,8 @@ acpi_get_devices(const char *HID, ...@@ -681,8 +687,8 @@ acpi_get_devices(const char *HID,
status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
acpi_ns_get_device_callback, &info, acpi_ns_get_device_callback, NULL,
return_value); &info, return_value);
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
......
...@@ -87,7 +87,8 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, ...@@ -87,7 +87,8 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
union acpi_parse_object *op, acpi_status status); union acpi_parse_object *op, acpi_status status);
static void static void
acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id); acpi_ps_link_module_code(union acpi_parse_object *parent_op,
u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
/******************************************************************************* /*******************************************************************************
* *
...@@ -479,11 +480,14 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, ...@@ -479,11 +480,14 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
*/ */
if (walk_state->pass_number == if (walk_state->pass_number ==
ACPI_IMODE_LOAD_PASS1) { ACPI_IMODE_LOAD_PASS1) {
acpi_ps_link_module_code(aml_op_start, acpi_ps_link_module_code(op->common.
walk_state-> parent,
aml_op_start,
(u32)
(walk_state->
parser_state. parser_state.
pkg_end - pkg_end -
aml_op_start, aml_op_start),
walk_state-> walk_state->
owner_id); owner_id);
} }
...@@ -598,7 +602,8 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, ...@@ -598,7 +602,8 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
* *
* FUNCTION: acpi_ps_link_module_code * FUNCTION: acpi_ps_link_module_code
* *
* PARAMETERS: aml_start - Pointer to the AML * PARAMETERS: parent_op - Parent parser op
* aml_start - Pointer to the AML
* aml_length - Length of executable AML * aml_length - Length of executable AML
* owner_id - owner_id of module level code * owner_id - owner_id of module level code
* *
...@@ -611,11 +616,13 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, ...@@ -611,11 +616,13 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
******************************************************************************/ ******************************************************************************/
static void static void
acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id) acpi_ps_link_module_code(union acpi_parse_object *parent_op,
u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
{ {
union acpi_operand_object *prev; union acpi_operand_object *prev;
union acpi_operand_object *next; union acpi_operand_object *next;
union acpi_operand_object *method_obj; union acpi_operand_object *method_obj;
struct acpi_namespace_node *parent_node;
/* Get the tail of the list */ /* Get the tail of the list */
...@@ -639,11 +646,24 @@ acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id) ...@@ -639,11 +646,24 @@ acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
return; return;
} }
if (parent_op->common.node) {
parent_node = parent_op->common.node;
} else {
parent_node = acpi_gbl_root_node;
}
method_obj->method.aml_start = aml_start; method_obj->method.aml_start = aml_start;
method_obj->method.aml_length = aml_length; method_obj->method.aml_length = aml_length;
method_obj->method.owner_id = owner_id; method_obj->method.owner_id = owner_id;
method_obj->method.flags |= AOPOBJ_MODULE_LEVEL; method_obj->method.flags |= AOPOBJ_MODULE_LEVEL;
/*
* Save the parent node in next_object. This is cheating, but we
* don't want to expand the method object.
*/
method_obj->method.next_object =
ACPI_CAST_PTR(union acpi_operand_object, parent_node);
if (!prev) { if (!prev) {
acpi_gbl_module_code_list = method_obj; acpi_gbl_module_code_list = method_obj;
} else { } else {
......
...@@ -610,17 +610,13 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) ...@@ -610,17 +610,13 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
implicit_return_obj) { implicit_return_obj) {
previous_walk_state-> previous_walk_state->
implicit_return_obj = implicit_return_obj =
acpi_ut_create_internal_object acpi_ut_create_integer_object
(ACPI_TYPE_INTEGER); ((u64) 0);
if (!previous_walk_state-> if (!previous_walk_state->
implicit_return_obj) { implicit_return_obj) {
return_ACPI_STATUS return_ACPI_STATUS
(AE_NO_MEMORY); (AE_NO_MEMORY);
} }
previous_walk_state->
implicit_return_obj->
integer.value = 0;
} }
/* Restart the calling control method */ /* Restart the calling control method */
......
...@@ -306,14 +306,12 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) ...@@ -306,14 +306,12 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
*/ */
if (acpi_gbl_enable_interpreter_slack) { if (acpi_gbl_enable_interpreter_slack) {
walk_state->implicit_return_obj = walk_state->implicit_return_obj =
acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); acpi_ut_create_integer_object((u64) 0);
if (!walk_state->implicit_return_obj) { if (!walk_state->implicit_return_obj) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
acpi_ds_delete_walk_state(walk_state); acpi_ds_delete_walk_state(walk_state);
goto cleanup; goto cleanup;
} }
walk_state->implicit_return_obj->integer.value = 0;
} }
/* Parse the AML */ /* Parse the AML */
......
...@@ -1161,3 +1161,45 @@ acpi_ut_predefined_warning(const char *module_name, ...@@ -1161,3 +1161,45 @@ acpi_ut_predefined_warning(const char *module_name,
ACPI_COMMON_MSG_SUFFIX; ACPI_COMMON_MSG_SUFFIX;
va_end(args); va_end(args);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ut_predefined_info
*
* PARAMETERS: module_name - Caller's module name (for error output)
* line_number - Caller's line number (for error output)
* Pathname - Full pathname to the node
* node_flags - From Namespace node for the method/object
* Format - Printf format string + additional args
*
* RETURN: None
*
* DESCRIPTION: Info messages for the predefined validation module. Messages
* are only emitted the first time a problem with a particular
* method/object is detected. This prevents a flood of
* messages for methods that are repeatedly evaluated.
*
******************************************************************************/
void ACPI_INTERNAL_VAR_XFACE
acpi_ut_predefined_info(const char *module_name,
u32 line_number,
char *pathname, u8 node_flags, const char *format, ...)
{
va_list args;
/*
* Warning messages for this method/object will be disabled after the
* first time a validation fails or an object is successfully repaired.
*/
if (node_flags & ANOBJ_EVALUATED) {
return;
}
acpi_os_printf("ACPI Info for %s: ", pathname);
va_start(args, format);
acpi_os_vprintf(format, args);
ACPI_COMMON_MSG_SUFFIX;
va_end(args);
}
...@@ -188,6 +188,35 @@ union acpi_operand_object *acpi_ut_create_package_object(u32 count) ...@@ -188,6 +188,35 @@ union acpi_operand_object *acpi_ut_create_package_object(u32 count)
return_PTR(package_desc); return_PTR(package_desc);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ut_create_integer_object
*
* PARAMETERS: initial_value - Initial value for the integer
*
* RETURN: Pointer to a new Integer object, null on failure
*
* DESCRIPTION: Create an initialized integer object
*
******************************************************************************/
union acpi_operand_object *acpi_ut_create_integer_object(u64 initial_value)
{
union acpi_operand_object *integer_desc;
ACPI_FUNCTION_TRACE(ut_create_integer_object);
/* Create and initialize a new integer object */
integer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
if (!integer_desc) {
return_PTR(NULL);
}
integer_desc->integer.value = initial_value;
return_PTR(integer_desc);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ut_create_buffer_object * FUNCTION: acpi_ut_create_buffer_object
......
...@@ -258,7 +258,7 @@ static int __init acpi_container_init(void) ...@@ -258,7 +258,7 @@ static int __init acpi_container_init(void)
acpi_walk_namespace(ACPI_TYPE_DEVICE, acpi_walk_namespace(ACPI_TYPE_DEVICE,
ACPI_ROOT_OBJECT, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_UINT32_MAX,
container_walk_namespace_cb, &action, NULL); container_walk_namespace_cb, NULL, &action, NULL);
return (0); return (0);
} }
...@@ -271,7 +271,7 @@ static void __exit acpi_container_exit(void) ...@@ -271,7 +271,7 @@ static void __exit acpi_container_exit(void)
acpi_walk_namespace(ACPI_TYPE_DEVICE, acpi_walk_namespace(ACPI_TYPE_DEVICE,
ACPI_ROOT_OBJECT, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_UINT32_MAX,
container_walk_namespace_cb, &action, NULL); container_walk_namespace_cb, NULL, &action, NULL);
acpi_bus_unregister_driver(&acpi_container_driver); acpi_bus_unregister_driver(&acpi_container_driver);
......
...@@ -1030,8 +1030,8 @@ static int dock_add(acpi_handle handle) ...@@ -1030,8 +1030,8 @@ static int dock_add(acpi_handle handle)
/* Find dependent devices */ /* Find dependent devices */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_dock_devices, dock_station, ACPI_UINT32_MAX, find_dock_devices, NULL,
NULL); dock_station, NULL);
/* add the dock station as a device dependent on itself */ /* add the dock station as a device dependent on itself */
dd = alloc_dock_dependent_device(handle); dd = alloc_dock_dependent_device(handle);
...@@ -1127,11 +1127,11 @@ static int __init dock_init(void) ...@@ -1127,11 +1127,11 @@ static int __init dock_init(void)
/* look for a dock station */ /* look for a dock station */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_dock, NULL, NULL); ACPI_UINT32_MAX, find_dock, NULL, NULL, NULL);
/* look for bay */ /* look for bay */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_bay, NULL, NULL); ACPI_UINT32_MAX, find_bay, NULL, NULL, NULL);
if (!dock_station_count) { if (!dock_station_count) {
printk(KERN_INFO PREFIX "No dock devices found.\n"); printk(KERN_INFO PREFIX "No dock devices found.\n");
return 0; return 0;
......
...@@ -820,7 +820,7 @@ static int acpi_ec_add(struct acpi_device *device) ...@@ -820,7 +820,7 @@ static int acpi_ec_add(struct acpi_device *device)
/* Find and register all query methods */ /* Find and register all query methods */
acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
acpi_ec_register_query_methods, ec, NULL); acpi_ec_register_query_methods, NULL, ec, NULL);
if (!first_ec) if (!first_ec)
first_ec = ec; first_ec = ec;
......
...@@ -113,7 +113,7 @@ acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address) ...@@ -113,7 +113,7 @@ acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address)
if (!parent) if (!parent)
return NULL; return NULL;
acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
1, do_acpi_find_child, &find, NULL); 1, do_acpi_find_child, NULL, &find, NULL);
return find.handle; return find.handle;
} }
......
...@@ -219,12 +219,12 @@ walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) ...@@ -219,12 +219,12 @@ walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
dbg("p2p bridge walk, pci_bus = %x\n", dev->subordinate->number); dbg("p2p bridge walk, pci_bus = %x\n", dev->subordinate->number);
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
user_function, &child_context, NULL); user_function, NULL, &child_context, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
goto out; goto out;
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
walk_p2p_bridge, &child_context, NULL); walk_p2p_bridge, NULL, &child_context, NULL);
out: out:
pci_dev_put(dev); pci_dev_put(dev);
return AE_OK; return AE_OK;
...@@ -277,12 +277,12 @@ walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function) ...@@ -277,12 +277,12 @@ walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function)
dbg("root bridge walk, pci_bus = %x\n", pci_bus->number); dbg("root bridge walk, pci_bus = %x\n", pci_bus->number);
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
user_function, &context, NULL); user_function, NULL, &context, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return status; return status;
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
walk_p2p_bridge, &context, NULL); walk_p2p_bridge, NULL, &context, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
err("%s: walk_p2p_bridge failure - %d\n", __func__, status); err("%s: walk_p2p_bridge failure - %d\n", __func__, status);
......
...@@ -1102,7 +1102,7 @@ void acpi_processor_install_hotplug_notify(void) ...@@ -1102,7 +1102,7 @@ void acpi_processor_install_hotplug_notify(void)
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
ACPI_ROOT_OBJECT, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_UINT32_MAX,
processor_walk_namespace_cb, &action, NULL); processor_walk_namespace_cb, NULL, &action, NULL);
#endif #endif
register_hotcpu_notifier(&acpi_cpu_notifier); register_hotcpu_notifier(&acpi_cpu_notifier);
} }
...@@ -1115,7 +1115,7 @@ void acpi_processor_uninstall_hotplug_notify(void) ...@@ -1115,7 +1115,7 @@ void acpi_processor_uninstall_hotplug_notify(void)
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
ACPI_ROOT_OBJECT, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_UINT32_MAX,
processor_walk_namespace_cb, &action, NULL); processor_walk_namespace_cb, NULL, &action, NULL);
#endif #endif
unregister_hotcpu_notifier(&acpi_cpu_notifier); unregister_hotcpu_notifier(&acpi_cpu_notifier);
} }
......
...@@ -1332,7 +1332,7 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, ...@@ -1332,7 +1332,7 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops,
status = acpi_bus_check_add(handle, 0, ops, &device); status = acpi_bus_check_add(handle, 0, ops, &device);
if (ACPI_SUCCESS(status)) if (ACPI_SUCCESS(status))
acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
acpi_bus_check_add, ops, &device); acpi_bus_check_add, NULL, ops, &device);
if (child) if (child)
*child = device; *child = device;
......
...@@ -101,7 +101,7 @@ long acpi_is_video_device(struct acpi_device *device) ...@@ -101,7 +101,7 @@ long acpi_is_video_device(struct acpi_device *device)
/* Only check for backlight functionality if one of the above hit. */ /* Only check for backlight functionality if one of the above hit. */
if (video_caps) if (video_caps)
acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle, acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle,
ACPI_UINT32_MAX, acpi_backlight_cap_match, ACPI_UINT32_MAX, acpi_backlight_cap_match, NULL,
&video_caps, NULL); &video_caps, NULL);
return video_caps; return video_caps;
...@@ -151,7 +151,7 @@ long acpi_video_get_capabilities(acpi_handle graphics_handle) ...@@ -151,7 +151,7 @@ long acpi_video_get_capabilities(acpi_handle graphics_handle)
if (!graphics_handle) { if (!graphics_handle) {
/* Only do the global walk through all graphics devices once */ /* Only do the global walk through all graphics devices once */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_video, ACPI_UINT32_MAX, find_video, NULL,
&caps, NULL); &caps, NULL);
/* There might be boot param flags set already... */ /* There might be boot param flags set already... */
acpi_video_support |= caps; acpi_video_support |= caps;
...@@ -173,7 +173,7 @@ long acpi_video_get_capabilities(acpi_handle graphics_handle) ...@@ -173,7 +173,7 @@ long acpi_video_get_capabilities(acpi_handle graphics_handle)
return 0; return 0;
} }
acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle, acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle,
ACPI_UINT32_MAX, find_video, ACPI_UINT32_MAX, find_video, NULL,
&caps, NULL); &caps, NULL);
} }
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n", ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n",
......
...@@ -899,7 +899,7 @@ static int intel_lid_present(void) ...@@ -899,7 +899,7 @@ static int intel_lid_present(void)
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_UINT32_MAX,
check_lid_device, &lid_present, NULL); check_lid_device, NULL, &lid_present, NULL);
return lid_present; return lid_present;
} }
......
...@@ -363,7 +363,7 @@ static int acpi_smbus_cmi_add(struct acpi_device *device) ...@@ -363,7 +363,7 @@ static int acpi_smbus_cmi_add(struct acpi_device *device)
smbus_cmi->cap_write = 0; smbus_cmi->cap_write = 0;
acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1, acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1,
acpi_smbus_cmi_query_methods, smbus_cmi, NULL); acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL);
if (smbus_cmi->cap_info == 0) if (smbus_cmi->cap_info == 0)
goto err; goto err;
......
...@@ -471,7 +471,7 @@ int acpi_pci_detect_ejectable(acpi_handle handle) ...@@ -471,7 +471,7 @@ int acpi_pci_detect_ejectable(acpi_handle handle)
return found; return found;
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
check_hotplug, (void *)&found, NULL); check_hotplug, NULL, (void *)&found, NULL);
return found; return found;
} }
EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable); EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable);
......
...@@ -266,7 +266,7 @@ static int detect_ejectable_slots(acpi_handle handle) ...@@ -266,7 +266,7 @@ static int detect_ejectable_slots(acpi_handle handle)
int found = acpi_pci_detect_ejectable(handle); int found = acpi_pci_detect_ejectable(handle);
if (!found) { if (!found) {
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
is_pci_dock_device, (void *)&found, NULL); is_pci_dock_device, NULL, (void *)&found, NULL);
} }
return found; return found;
} }
...@@ -281,7 +281,7 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) ...@@ -281,7 +281,7 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
/* register all slot objects under this bridge */ /* register all slot objects under this bridge */
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
register_slot, bridge, NULL); register_slot, NULL, bridge, NULL);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
list_del(&bridge->list); list_del(&bridge->list);
return; return;
...@@ -447,7 +447,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) ...@@ -447,7 +447,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
/* search P2P bridges under this p2p bridge */ /* search P2P bridges under this p2p bridge */
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
find_p2p_bridge, NULL, NULL); find_p2p_bridge, NULL, NULL, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
warn("find_p2p_bridge failed (error code = 0x%x)\n", status); warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
...@@ -485,7 +485,7 @@ static int add_bridge(acpi_handle handle) ...@@ -485,7 +485,7 @@ static int add_bridge(acpi_handle handle)
/* search P2P bridges under this host bridge */ /* search P2P bridges under this host bridge */
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
find_p2p_bridge, NULL, NULL); find_p2p_bridge, NULL, NULL, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
warn("find_p2p_bridge failed (error code = 0x%x)\n", status); warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
...@@ -573,7 +573,7 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) ...@@ -573,7 +573,7 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
/* cleanup p2p bridges under this P2P bridge /* cleanup p2p bridges under this P2P bridge
in a depth-first manner */ in a depth-first manner */
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
cleanup_p2p_bridge, NULL, NULL); cleanup_p2p_bridge, NULL, NULL, NULL);
bridge = acpiphp_handle_to_bridge(handle); bridge = acpiphp_handle_to_bridge(handle);
if (bridge) if (bridge)
...@@ -589,7 +589,7 @@ static void remove_bridge(acpi_handle handle) ...@@ -589,7 +589,7 @@ static void remove_bridge(acpi_handle handle)
/* cleanup p2p bridges under this host bridge /* cleanup p2p bridges under this host bridge
in a depth-first manner */ in a depth-first manner */
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
(u32)1, cleanup_p2p_bridge, NULL, NULL); (u32)1, cleanup_p2p_bridge, NULL, NULL, NULL);
/* /*
* On root bridges with hotplug slots directly underneath (ie, * On root bridges with hotplug slots directly underneath (ie,
...@@ -778,7 +778,7 @@ static int acpiphp_configure_ioapics(acpi_handle handle) ...@@ -778,7 +778,7 @@ static int acpiphp_configure_ioapics(acpi_handle handle)
{ {
ioapic_add(handle, 0, NULL, NULL); ioapic_add(handle, 0, NULL, NULL);
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
ACPI_UINT32_MAX, ioapic_add, NULL, NULL); ACPI_UINT32_MAX, ioapic_add, NULL, NULL, NULL);
return 0; return 0;
} }
...@@ -786,7 +786,7 @@ static int acpiphp_unconfigure_ioapics(acpi_handle handle) ...@@ -786,7 +786,7 @@ static int acpiphp_unconfigure_ioapics(acpi_handle handle)
{ {
ioapic_remove(handle, 0, NULL, NULL); ioapic_remove(handle, 0, NULL, NULL);
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
ACPI_UINT32_MAX, ioapic_remove, NULL, NULL); ACPI_UINT32_MAX, ioapic_remove, NULL, NULL, NULL);
return 0; return 0;
} }
...@@ -1367,7 +1367,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont ...@@ -1367,7 +1367,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
bridge = acpiphp_handle_to_bridge(handle); bridge = acpiphp_handle_to_bridge(handle);
if (type == ACPI_NOTIFY_BUS_CHECK) { if (type == ACPI_NOTIFY_BUS_CHECK) {
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX,
count_sub_bridges, &num_sub_bridges, NULL); count_sub_bridges, NULL, &num_sub_bridges, NULL);
} }
if (!bridge && !num_sub_bridges) { if (!bridge && !num_sub_bridges) {
...@@ -1388,7 +1388,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont ...@@ -1388,7 +1388,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
} }
if (num_sub_bridges) if (num_sub_bridges)
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL); ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL);
break; break;
case ACPI_NOTIFY_DEVICE_CHECK: case ACPI_NOTIFY_DEVICE_CHECK:
...@@ -1512,7 +1512,7 @@ int __init acpiphp_glue_init(void) ...@@ -1512,7 +1512,7 @@ int __init acpiphp_glue_init(void)
int num = 0; int num = 0;
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_root_bridges, &num, NULL); ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
if (num <= 0) if (num <= 0)
return -1; return -1;
......
...@@ -434,7 +434,7 @@ static int __init ibm_acpiphp_init(void) ...@@ -434,7 +434,7 @@ static int __init ibm_acpiphp_init(void)
dbg("%s\n", __func__); dbg("%s\n", __func__);
if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ibm_find_acpi_device, ACPI_UINT32_MAX, ibm_find_acpi_device, NULL,
&ibm_acpi_handle, NULL) != FOUND_APCI) { &ibm_acpi_handle, NULL) != FOUND_APCI) {
err("%s: acpi_walk_namespace failed\n", __func__); err("%s: acpi_walk_namespace failed\n", __func__);
retval = -ENODEV; retval = -ENODEV;
......
...@@ -510,7 +510,7 @@ static int __init intel_menlow_module_init(void) ...@@ -510,7 +510,7 @@ static int __init intel_menlow_module_init(void)
/* Looking for sensors in each ACPI thermal zone */ /* Looking for sensors in each ACPI thermal zone */
status = acpi_walk_namespace(ACPI_TYPE_THERMAL, ACPI_ROOT_OBJECT, status = acpi_walk_namespace(ACPI_TYPE_THERMAL, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_UINT32_MAX,
intel_menlow_register_sensor, NULL, NULL); intel_menlow_register_sensor, NULL, NULL, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -ENODEV; return -ENODEV;
......
...@@ -1203,7 +1203,7 @@ static int sony_nc_add(struct acpi_device *device) ...@@ -1203,7 +1203,7 @@ static int sony_nc_add(struct acpi_device *device)
if (debug) { if (debug) {
status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle,
1, sony_walk_callback, NULL, NULL); 1, sony_walk_callback, NULL, NULL, NULL);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n"); printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n");
result = -ENODEV; result = -ENODEV;
......
...@@ -1087,7 +1087,7 @@ static int __init tpacpi_check_std_acpi_brightness_support(void) ...@@ -1087,7 +1087,7 @@ static int __init tpacpi_check_std_acpi_brightness_support(void)
*/ */
status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
tpacpi_acpi_walk_find_bcl, NULL, tpacpi_acpi_walk_find_bcl, NULL, NULL,
&bcl_ptr); &bcl_ptr);
if (ACPI_SUCCESS(status) && bcl_levels > 2) { if (ACPI_SUCCESS(status) && bcl_levels > 2) {
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */ /* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20090903 #define ACPI_CA_VERSION 0x20091112
#include "actypes.h" #include "actypes.h"
#include "actbl.h" #include "actbl.h"
...@@ -154,7 +154,8 @@ acpi_status ...@@ -154,7 +154,8 @@ acpi_status
acpi_walk_namespace(acpi_object_type type, acpi_walk_namespace(acpi_object_type type,
acpi_handle start_object, acpi_handle start_object,
u32 max_depth, u32 max_depth,
acpi_walk_callback user_function, acpi_walk_callback pre_order_visit,
acpi_walk_callback post_order_visit,
void *context, void **return_value); void *context, void **return_value);
acpi_status acpi_status
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment