acpi_status acpi_ns_search_one_scope(u32 target_name, struct acpi_namespace_node *parent_node, acpi_object_type type, struct acpi_namespace_node **return_node) { struct acpi_namespace_node *node; ACPI_FUNCTION_TRACE(ns_search_one_scope); #ifdef ACPI_DEBUG_OUTPUT if (ACPI_LV_NAMES & acpi_dbg_level) { char *scope_name; scope_name = acpi_ns_get_normalized_pathname(parent_node, TRUE); if (scope_name) { ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Searching %s (%p) For [%4.4s] (%s)\n", scope_name, parent_node, ACPI_CAST_PTR(char, &target_name), acpi_ut_get_type_name(type))); ACPI_FREE(scope_name); } }
/******************************************************************************* * * FUNCTION: acpi_ns_get_external_pathname * * PARAMETERS: node - Namespace node whose pathname is needed * * RETURN: Pointer to storage containing the fully qualified name of * the node, In external format (name segments separated by path * separators.) * * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually * for error and debug statements. * ******************************************************************************/ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) { char *name_buffer; ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node); name_buffer = acpi_ns_get_normalized_pathname(node, FALSE); return_PTR(name_buffer); }
void acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node, union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { acpi_status status; char *pathname = NULL; u8 enabled; ACPI_FUNCTION_NAME(ex_stop_trace_method); if (method_node) { pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); } status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { goto exit_path; } enabled = acpi_ex_interpreter_trace_enabled(NULL); (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (enabled) { ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, FALSE, obj_desc ? obj_desc->method.aml_start : NULL, pathname); } status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { goto exit_path; } /* Check whether the tracer should be stopped */ if (acpi_gbl_trace_method_object == obj_desc) { /* Disable further tracing if type is one-shot */ if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) { acpi_gbl_trace_method_name = NULL; } acpi_dbg_level = acpi_gbl_original_dbg_level; acpi_dbg_layer = acpi_gbl_original_dbg_layer; acpi_gbl_trace_method_object = NULL; } (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); exit_path: if (pathname) { ACPI_FREE(pathname); } }
static acpi_status acpi_db_walk_for_predefined_names(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { struct acpi_namespace_node *node = (struct acpi_namespace_node *)obj_handle; u32 *count = (u32 *)context; const union acpi_predefined_info *predefined; const union acpi_predefined_info *package = NULL; char *pathname; char string_buffer[48]; predefined = acpi_ut_match_predefined_method(node->name.ascii); if (!predefined) { return (AE_OK); } pathname = acpi_ns_get_normalized_pathname(node, TRUE); if (!pathname) { return (AE_OK); } /* If method returns a package, the info is in the next table entry */ if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) { package = predefined + 1; } acpi_ut_get_expected_return_types(string_buffer, predefined->info.expected_btypes); acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname, METHOD_GET_ARG_COUNT(predefined->info.argument_list), string_buffer); if (package) { acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)", package->ret_info.type, package->ret_info.object_type1, package->ret_info.count1); } acpi_os_printf("\n"); /* Check that the declared argument count matches the ACPI spec */ acpi_ns_check_acpi_compliance(pathname, node, predefined); ACPI_FREE(pathname); (*count)++; return (AE_OK); }
void acpi_ex_start_trace_method(struct acpi_namespace_node *method_node, union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { acpi_status status; char *pathname = NULL; u8 enabled = FALSE; ACPI_FUNCTION_NAME(ex_start_trace_method); if (method_node) { pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); } status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { goto exit; } enabled = acpi_ex_interpreter_trace_enabled(pathname); if (enabled && !acpi_gbl_trace_method_object) { acpi_gbl_trace_method_object = obj_desc; acpi_gbl_original_dbg_level = acpi_dbg_level; acpi_gbl_original_dbg_layer = acpi_dbg_layer; acpi_dbg_level = ACPI_TRACE_LEVEL_ALL; acpi_dbg_layer = ACPI_TRACE_LAYER_ALL; if (acpi_gbl_trace_dbg_level) { acpi_dbg_level = acpi_gbl_trace_dbg_level; } if (acpi_gbl_trace_dbg_layer) { acpi_dbg_layer = acpi_gbl_trace_dbg_layer; } } (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); exit: if (enabled) { ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, TRUE, obj_desc ? obj_desc->method.aml_start : NULL, pathname); } if (pathname) { ACPI_FREE(pathname); } }
static acpi_status acpi_db_display_non_root_handlers(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { struct acpi_namespace_node *node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); union acpi_operand_object *obj_desc; union acpi_operand_object *handler_obj; char *pathname; obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { return (AE_OK); } pathname = acpi_ns_get_normalized_pathname(node, TRUE); if (!pathname) { return (AE_OK); } /* Display all handlers associated with this device */ handler_obj = obj_desc->common_notify.handler; while (handler_obj) { acpi_os_printf(ACPI_PREDEFINED_PREFIX, acpi_ut_get_region_name((u8)handler_obj-> address_space.space_id), handler_obj->address_space.space_id); acpi_os_printf(ACPI_HANDLER_PRESENT_STRING2, (handler_obj->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default" : "User", handler_obj->address_space.handler); acpi_os_printf(" Device Name: %s (%p)\n", pathname, node); handler_obj = handler_obj->address_space.next; } ACPI_FREE(pathname); return (AE_OK); }
static acpi_status acpi_ns_dump_one_object_path(acpi_handle obj_handle, u32 level, void *context, void **return_value) { u32 max_level = *((u32 *)context); char *pathname; struct acpi_namespace_node *node; int path_indent; if (!obj_handle) { return (AE_OK); } node = acpi_ns_validate_handle(obj_handle); if (!node) { /* Ignore bad node during namespace walk */ return (AE_OK); } pathname = acpi_ns_get_normalized_pathname(node, TRUE); path_indent = 1; if (level <= max_level) { path_indent = max_level - level + 1; } acpi_os_printf("%2d%*s%-12s%*s", level, level, " ", acpi_ut_get_type_name(node->type), path_indent, " "); acpi_os_printf("%s\n", &pathname[1]); ACPI_FREE(pathname); return (AE_OK); }
static acpi_status acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { struct acpi_namespace_node *node = (struct acpi_namespace_node *)obj_handle; struct acpi_db_execute_walk *info = (struct acpi_db_execute_walk *)context; char *pathname; const union acpi_predefined_info *predefined; struct acpi_device_info *obj_info; struct acpi_object_list param_objects; union acpi_object params[ACPI_METHOD_NUM_ARGS]; union acpi_object *this_param; struct acpi_buffer return_obj; acpi_status status; u16 arg_type_list; u8 arg_count; u8 arg_type; u32 i; /* The name must be a predefined ACPI name */ predefined = acpi_ut_match_predefined_method(node->name.ascii); if (!predefined) { return (AE_OK); } if (node->type == ACPI_TYPE_LOCAL_SCOPE) { return (AE_OK); } pathname = acpi_ns_get_normalized_pathname(node, TRUE); if (!pathname) { return (AE_OK); } /* Get the object info for number of method parameters */ status = acpi_get_object_info(obj_handle, &obj_info); if (ACPI_FAILURE(status)) { ACPI_FREE(pathname); return (status); } param_objects.count = 0; param_objects.pointer = NULL; if (obj_info->type == ACPI_TYPE_METHOD) { /* Setup default parameters (with proper types) */ arg_type_list = predefined->info.argument_list; arg_count = METHOD_GET_ARG_COUNT(arg_type_list); /* * Setup the ACPI-required number of arguments, regardless of what * the actual method defines. If there is a difference, then the * method is wrong and a warning will be issued during execution. */ this_param = params; for (i = 0; i < arg_count; i++) { arg_type = METHOD_GET_NEXT_TYPE(arg_type_list); this_param->type = arg_type; switch (arg_type) { case ACPI_TYPE_INTEGER: this_param->integer.value = 1; break; case ACPI_TYPE_STRING: this_param->string.pointer = "This is the default argument string"; this_param->string.length = strlen(this_param->string.pointer); break; case ACPI_TYPE_BUFFER: this_param->buffer.pointer = (u8 *)params; /* just a garbage buffer */ this_param->buffer.length = 48; break; case ACPI_TYPE_PACKAGE: this_param->package.elements = NULL; this_param->package.count = 0; break; default: acpi_os_printf ("%s: Unsupported argument type: %u\n", pathname, arg_type); break; } this_param++; } param_objects.count = arg_count; param_objects.pointer = params; } ACPI_FREE(obj_info); return_obj.pointer = NULL; return_obj.length = ACPI_ALLOCATE_BUFFER; /* Do the actual method execution */ acpi_gbl_method_executing = TRUE; status = acpi_evaluate_object(node, NULL, ¶m_objects, &return_obj); acpi_os_printf("%-32s returned %s\n", pathname, acpi_format_exception(status)); acpi_gbl_method_executing = FALSE; ACPI_FREE(pathname); /* Ignore status from method execution */ status = AE_OK; /* Update count, check if we have executed enough methods */ info->count++; if (info->count >= info->max_count) { status = AE_CTRL_TERMINATE; } return (status); }
static acpi_status acpi_db_device_resources(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { struct acpi_namespace_node *node; struct acpi_namespace_node *prt_node = NULL; struct acpi_namespace_node *crs_node = NULL; struct acpi_namespace_node *prs_node = NULL; struct acpi_namespace_node *aei_node = NULL; char *parent_path; struct acpi_buffer return_buffer; acpi_status status; node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); parent_path = acpi_ns_get_normalized_pathname(node, TRUE); if (!parent_path) { return (AE_NO_MEMORY); } /* Get handles to the resource methods for this device */ (void)acpi_get_handle(node, METHOD_NAME__PRT, ACPI_CAST_PTR(acpi_handle, &prt_node)); (void)acpi_get_handle(node, METHOD_NAME__CRS, ACPI_CAST_PTR(acpi_handle, &crs_node)); (void)acpi_get_handle(node, METHOD_NAME__PRS, ACPI_CAST_PTR(acpi_handle, &prs_node)); (void)acpi_get_handle(node, METHOD_NAME__AEI, ACPI_CAST_PTR(acpi_handle, &aei_node)); if (!prt_node && !crs_node && !prs_node && !aei_node) { goto cleanup; /* Nothing to do */ } acpi_os_printf("\nDevice: %s\n", parent_path); /* Prepare for a return object of arbitrary size */ return_buffer.pointer = acpi_gbl_db_buffer; return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; /* _PRT */ if (prt_node) { acpi_os_printf("Evaluating _PRT\n"); status = acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer); if (ACPI_FAILURE(status)) { acpi_os_printf("Could not evaluate _PRT: %s\n", acpi_format_exception(status)); goto get_crs; } return_buffer.pointer = acpi_gbl_db_buffer; return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; status = acpi_get_irq_routing_table(node, &return_buffer); if (ACPI_FAILURE(status)) { acpi_os_printf("GetIrqRoutingTable failed: %s\n", acpi_format_exception(status)); goto get_crs; } acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer)); } /* _CRS */ get_crs: if (crs_node) { acpi_os_printf("Evaluating _CRS\n"); return_buffer.pointer = acpi_gbl_db_buffer; return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; status = acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer); if (ACPI_FAILURE(status)) { acpi_os_printf("Could not evaluate _CRS: %s\n", acpi_format_exception(status)); goto get_prs; } /* This code exercises the acpi_walk_resources interface */ status = acpi_walk_resources(node, METHOD_NAME__CRS, acpi_db_resource_callback, NULL); if (ACPI_FAILURE(status)) { acpi_os_printf("AcpiWalkResources failed: %s\n", acpi_format_exception(status)); goto get_prs; } /* Get the _CRS resource list (test ALLOCATE buffer) */ return_buffer.pointer = NULL; return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; status = acpi_get_current_resources(node, &return_buffer); if (ACPI_FAILURE(status)) { acpi_os_printf("AcpiGetCurrentResources failed: %s\n", acpi_format_exception(status)); goto get_prs; } /* This code exercises the acpi_walk_resource_buffer interface */ status = acpi_walk_resource_buffer(&return_buffer, acpi_db_resource_callback, NULL); if (ACPI_FAILURE(status)) { acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n", acpi_format_exception(status)); goto end_crs; } /* Dump the _CRS resource list */ acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource, return_buffer. pointer)); /* * Perform comparison of original AML to newly created AML. This * tests both the AML->Resource conversion and the Resource->AML * conversion. */ (void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS); /* Execute _SRS with the resource list */ acpi_os_printf("Evaluating _SRS\n"); status = acpi_set_current_resources(node, &return_buffer); if (ACPI_FAILURE(status)) { acpi_os_printf("AcpiSetCurrentResources failed: %s\n", acpi_format_exception(status)); goto end_crs; } end_crs: ACPI_FREE(return_buffer.pointer); } /* _PRS */ get_prs: if (prs_node) { acpi_os_printf("Evaluating _PRS\n"); return_buffer.pointer = acpi_gbl_db_buffer; return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; status = acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer); if (ACPI_FAILURE(status)) { acpi_os_printf("Could not evaluate _PRS: %s\n", acpi_format_exception(status)); goto get_aei; } return_buffer.pointer = acpi_gbl_db_buffer; return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; status = acpi_get_possible_resources(node, &return_buffer); if (ACPI_FAILURE(status)) { acpi_os_printf("AcpiGetPossibleResources failed: %s\n", acpi_format_exception(status)); goto get_aei; } acpi_rs_dump_resource_list(ACPI_CAST_PTR (struct acpi_resource, acpi_gbl_db_buffer)); } /* _AEI */ get_aei: if (aei_node) { acpi_os_printf("Evaluating _AEI\n"); return_buffer.pointer = acpi_gbl_db_buffer; return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; status = acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer); if (ACPI_FAILURE(status)) { acpi_os_printf("Could not evaluate _AEI: %s\n", acpi_format_exception(status)); goto cleanup; } return_buffer.pointer = acpi_gbl_db_buffer; return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; status = acpi_get_event_resources(node, &return_buffer); if (ACPI_FAILURE(status)) { acpi_os_printf("AcpiGetEventResources failed: %s\n", acpi_format_exception(status)); goto cleanup; } acpi_rs_dump_resource_list(ACPI_CAST_PTR (struct acpi_resource, acpi_gbl_db_buffer)); } cleanup: ACPI_FREE(parent_path); return (AE_OK); }
acpi_status acpi_ds_call_control_method(struct acpi_thread_state *thread, struct acpi_walk_state *this_walk_state, union acpi_parse_object *op) { acpi_status status; struct acpi_namespace_node *method_node; struct acpi_walk_state *next_walk_state = NULL; union acpi_operand_object *obj_desc; struct acpi_evaluate_info *info; u32 i; ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Calling method %p, currentstate=%p\n", this_walk_state->prev_op, this_walk_state)); /* * Get the namespace entry for the control method we are about to call */ method_node = this_walk_state->method_call_node; if (!method_node) { return_ACPI_STATUS(AE_NULL_ENTRY); } obj_desc = acpi_ns_get_attached_object(method_node); if (!obj_desc) { return_ACPI_STATUS(AE_NULL_OBJECT); } /* Init for new method, possibly wait on method mutex */ status = acpi_ds_begin_method_execution(method_node, obj_desc, this_walk_state); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Begin method parse/execution. Create a new walk state */ next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, obj_desc, thread); if (!next_walk_state) { status = AE_NO_MEMORY; goto cleanup; } /* * The resolved arguments were put on the previous walk state's operand * stack. Operands on the previous walk state stack always * start at index 0. Also, null terminate the list of arguments */ this_walk_state->operands[this_walk_state->num_operands] = NULL; /* * Allocate and initialize the evaluation information block * TBD: this is somewhat inefficient, should change interface to * ds_init_aml_walk. For now, keeps this struct off the CPU stack */ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); if (!info) { status = AE_NO_MEMORY; goto cleanup; } info->parameters = &this_walk_state->operands[0]; status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, obj_desc->method.aml_start, obj_desc->method.aml_length, info, ACPI_IMODE_EXECUTE); ACPI_FREE(info); if (ACPI_FAILURE(status)) { goto cleanup; } next_walk_state->method_nesting_depth = this_walk_state->method_nesting_depth + 1; /* * Delete the operands on the previous walkstate operand stack * (they were copied to new objects) */ for (i = 0; i < obj_desc->method.param_count; i++) { acpi_ut_remove_reference(this_walk_state->operands[i]); this_walk_state->operands[i] = NULL; } /* Clear the operand stack */ this_walk_state->num_operands = 0; ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "**** Begin nested execution of [%4.4s] **** WalkState=%p\n", method_node->name.ascii, next_walk_state)); this_walk_state->method_pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); this_walk_state->method_is_nested = TRUE; /* Optional object evaluation log */ ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION, "%-26s: %*s%s\n", " Nested method call", next_walk_state->method_nesting_depth * 3, " ", &this_walk_state->method_pathname[1])); /* Invoke an internal method if necessary */ if (obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) { status = obj_desc->method.dispatch.implementation(next_walk_state); if (status == AE_OK) { status = AE_CTRL_TERMINATE; } } return_ACPI_STATUS(status); cleanup: /* On error, we must terminate the method properly */ acpi_ds_terminate_control_method(obj_desc, next_walk_state); acpi_ds_delete_walk_state(next_walk_state); return_ACPI_STATUS(status); }
u32 acpi_ut_check_address_range(acpi_adr_space_type space_id, acpi_physical_address address, u32 length, u8 warn) { struct acpi_address_range *range_info; acpi_physical_address end_address; char *pathname; u32 overlap_count = 0; ACPI_FUNCTION_TRACE(ut_check_address_range); if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) && (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { return_UINT32(0); } range_info = acpi_gbl_address_range_list[space_id]; end_address = address + length - 1; /* Check entire list for all possible conflicts */ while (range_info) { /* * Check if the requested address/length overlaps this * address range. There are four cases to consider: * * 1) Input address/length is contained completely in the * address range * 2) Input address/length overlaps range at the range start * 3) Input address/length overlaps range at the range end * 4) Input address/length completely encompasses the range */ if ((address <= range_info->end_address) && (end_address >= range_info->start_address)) { /* Found an address range overlap */ overlap_count++; if (warn) { /* Optional warning message */ pathname = acpi_ns_get_normalized_pathname(range_info-> region_node, TRUE); ACPI_WARNING((AE_INFO, "%s range 0x%8.8X%8.8X-0x%8.8X%8.8X conflicts with OpRegion 0x%8.8X%8.8X-0x%8.8X%8.8X (%s)", acpi_ut_get_region_name(space_id), ACPI_FORMAT_UINT64(address), ACPI_FORMAT_UINT64(end_address), ACPI_FORMAT_UINT64(range_info-> start_address), ACPI_FORMAT_UINT64(range_info-> end_address), pathname)); ACPI_FREE(pathname); } } range_info = range_info->next; } return_UINT32(overlap_count); }
static acpi_status acpi_ns_init_one_device(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value) { struct acpi_device_walk_info *walk_info = ACPI_CAST_PTR(struct acpi_device_walk_info, context); struct acpi_evaluate_info *info = walk_info->evaluate_info; u32 flags; acpi_status status; struct acpi_namespace_node *device_node; ACPI_FUNCTION_TRACE(ns_init_one_device); /* We are interested in Devices, Processors and thermal_zones only */ device_node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); if ((device_node->type != ACPI_TYPE_DEVICE) && (device_node->type != ACPI_TYPE_PROCESSOR) && (device_node->type != ACPI_TYPE_THERMAL)) { return_ACPI_STATUS(AE_OK); } /* * Because of an earlier namespace analysis, all subtrees that contain an * _INI method are tagged. * * If this device subtree does not contain any _INI methods, we * can exit now and stop traversing this entire subtree. */ if (!(device_node->flags & ANOBJ_SUBTREE_HAS_INI)) { return_ACPI_STATUS(AE_CTRL_DEPTH); } /* * Run _STA to determine if this device is present and functioning. We * must know this information for two important reasons (from ACPI spec): * * 1) We can only run _INI if the device is present. * 2) We must abort the device tree walk on this subtree if the device is * not present and is not functional (we will not examine the children) * * The _STA method is not required to be present under the device, we * assume the device is present if _STA does not exist. */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, device_node, METHOD_NAME__STA)); status = acpi_ut_execute_STA(device_node, &flags); if (ACPI_FAILURE(status)) { /* Ignore error and move on to next device */ return_ACPI_STATUS(AE_OK); } /* * Flags == -1 means that _STA was not found. In this case, we assume that * the device is both present and functional. * * From the ACPI spec, description of _STA: * * "If a device object (including the processor object) does not have an * _STA object, then OSPM assumes that all of the above bits are set (in * other words, the device is present, ..., and functioning)" */ if (flags != ACPI_UINT32_MAX) { walk_info->num_STA++; } /* * Examine the PRESENT and FUNCTIONING status bits * * Note: ACPI spec does not seem to specify behavior for the present but * not functioning case, so we assume functioning if present. */ if (!(flags & ACPI_STA_DEVICE_PRESENT)) { /* Device is not present, we must examine the Functioning bit */ if (flags & ACPI_STA_DEVICE_FUNCTIONING) { /* * Device is not present but is "functioning". In this case, * we will not run _INI, but we continue to examine the children * of this device. * * From the ACPI spec, description of _STA: (note - no mention * of whether to run _INI or not on the device in question) * * "_STA may return bit 0 clear (not present) with bit 3 set * (device is functional). This case is used to indicate a valid * device for which no device driver should be loaded (for example, * a bridge device.) Children of this device may be present and * valid. OSPM should continue enumeration below a device whose * _STA returns this bit combination" */ return_ACPI_STATUS(AE_OK); } else { /* * Device is not present and is not functioning. We must abort the * walk of this subtree immediately -- don't look at the children * of such a device. * * From the ACPI spec, description of _INI: * * "If the _STA method indicates that the device is not present, * OSPM will not run the _INI and will not examine the children * of the device for _INI methods" */ return_ACPI_STATUS(AE_CTRL_DEPTH); } } /* * The device is present or is assumed present if no _STA exists. * Run the _INI if it exists (not required to exist) * * Note: We know there is an _INI within this subtree, but it may not be * under this particular device, it may be lower in the branch. */ if (!ACPI_COMPARE_NAME(device_node->name.ascii, "_SB_") || device_node->parent != acpi_gbl_root_node) { ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); memset(info, 0, sizeof(struct acpi_evaluate_info)); info->prefix_node = device_node; info->relative_pathname = METHOD_NAME__INI; info->parameters = NULL; info->flags = ACPI_IGNORE_RETURN_VALUE; status = acpi_ns_evaluate(info); if (ACPI_SUCCESS(status)) { walk_info->num_INI++; } #ifdef ACPI_DEBUG_OUTPUT else if (status != AE_NOT_FOUND) { /* Ignore error and move on to next device */ char *scope_name = acpi_ns_get_normalized_pathname(device_node, TRUE); ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", scope_name)); ACPI_FREE(scope_name); } #endif } /* Ignore errors from above */ status = AE_OK; /* * The _INI method has been run if present; call the Global Initialization * Handler for this device. */ if (acpi_gbl_init_handler) { status = acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI); } return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: ns_execute_table * * PARAMETERS: table_desc - An ACPI table descriptor for table to parse * start_node - Where to enter the table into the namespace * * RETURN: Status * * DESCRIPTION: Load ACPI/AML table by executing the entire table as a * term_list. * ******************************************************************************/ acpi_status acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node) { acpi_status status; struct acpi_table_header *table; acpi_owner_id owner_id; struct acpi_evaluate_info *info = NULL; u32 aml_length; u8 *aml_start; union acpi_operand_object *method_obj = NULL; ACPI_FUNCTION_TRACE(ns_execute_table); status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Table must consist of at least a complete header */ if (table->length < sizeof(struct acpi_table_header)) { return_ACPI_STATUS(AE_BAD_HEADER); } aml_start = (u8 *)table + sizeof(struct acpi_table_header); aml_length = table->length - sizeof(struct acpi_table_header); status = acpi_tb_get_owner_id(table_index, &owner_id); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Create, initialize, and link a new temporary method object */ method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); if (!method_obj) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Allocate the evaluation information block */ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); if (!info) { status = AE_NO_MEMORY; goto cleanup; } ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Create table code block: %p\n", method_obj)); method_obj->method.aml_start = aml_start; method_obj->method.aml_length = aml_length; method_obj->method.owner_id = owner_id; method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL; info->pass_number = ACPI_IMODE_EXECUTE; info->node = start_node; info->obj_desc = method_obj; info->node_flags = info->node->flags; info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE); if (!info->full_pathname) { status = AE_NO_MEMORY; goto cleanup; } status = acpi_ps_execute_table(info); cleanup: if (info) { ACPI_FREE(info->full_pathname); info->full_pathname = NULL; } ACPI_FREE(info); acpi_ut_remove_reference(method_obj); return_ACPI_STATUS(status); }
info->return_object = NULL; info->node_flags = info->node->flags; info->obj_desc = acpi_ns_get_attached_object(info->node); ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->relative_pathname, info->node, acpi_ns_get_attached_object(info->node))); /* Get info if we have a predefined name (_HID, etc.) */ info->predefined = acpi_ut_match_predefined_method(info->node->name.ascii); /* Get the full pathname to the object, for use in warning messages */ info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE); if (!info->full_pathname) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Count the number of arguments being passed in */ info->param_count = 0; if (info->parameters) { while (info->parameters[info->param_count]) { info->param_count++; } /* Warn on impossible argument count */ if (info->param_count > ACPI_METHOD_NUM_ARGS) {