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 *info = (struct acpi_device_walk_info *)context; struct acpi_parameter_info pinfo; u32 flags; acpi_status status; ACPI_FUNCTION_TRACE("ns_init_one_device"); pinfo.parameters = NULL; pinfo.parameter_type = ACPI_PARAM_ARGS; pinfo.node = acpi_ns_map_handle_to_node(obj_handle); if (!pinfo.node) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* * We will run _STA/_INI on Devices, Processors and thermal_zones only */ if ((pinfo.node->type != ACPI_TYPE_DEVICE) && (pinfo.node->type != ACPI_TYPE_PROCESSOR) && (pinfo.node->type != ACPI_TYPE_THERMAL)) { return_ACPI_STATUS(AE_OK); } if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) { ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); } info->device_count++; /* * Run _STA to determine if we can run _INI on the device. */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD, pinfo.node, METHOD_NAME__STA)); status = acpi_ut_execute_STA(pinfo.node, &flags); if (ACPI_FAILURE(status)) { if (pinfo.node->type == ACPI_TYPE_DEVICE) { /* Ignore error and move on to next device */ return_ACPI_STATUS(AE_OK); } /* _STA is not required for Processor or thermal_zone objects */ } else { info->num_STA++; if (!(flags & 0x01)) { /* Don't look at children of a not present device */ return_ACPI_STATUS(AE_CTRL_DEPTH); } } /* * The device is present. Run _INI. */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_METHOD, pinfo.node, METHOD_NAME__INI)); status = acpi_ns_evaluate_relative(METHOD_NAME__INI, &pinfo); if (ACPI_FAILURE(status)) { /* No _INI (AE_NOT_FOUND) means device requires no initialization */ if (status != AE_NOT_FOUND) { /* Ignore error and move on to next device */ #ifdef ACPI_DEBUG_OUTPUT char *scope_name = acpi_ns_get_external_pathname(pinfo.node); ACPI_DEBUG_PRINT((ACPI_DB_WARN, "%s._INI failed: %s\n", scope_name, acpi_format_exception(status))); ACPI_MEM_FREE(scope_name); #endif } status = AE_OK; } else { /* Delete any return object (especially if implicit_return is enabled) */ if (pinfo.return_object) { acpi_ut_remove_reference(pinfo.return_object); } /* Count of successful INIs */ info->num_INI++; } if (acpi_gbl_init_handler) { /* External initialization handler is present, call it */ status = acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI); } return_ACPI_STATUS(status); }
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. */ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); ACPI_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_external_pathname(info->node); 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); }
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); 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); } if (!(device_node->flags & ANOBJ_SUBTREE_HAS_INI)) { return_ACPI_STATUS(AE_CTRL_DEPTH); } 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)) { return_ACPI_STATUS(AE_OK); } if (flags != ACPI_UINT32_MAX) { walk_info->num_STA++; } if (!(flags & ACPI_STA_DEVICE_PRESENT)) { if (flags & ACPI_STA_DEVICE_FUNCTIONING) { return_ACPI_STATUS(AE_OK); } else { return_ACPI_STATUS(AE_CTRL_DEPTH); } } ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); info->prefix_node = device_node; info->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++; if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) { ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); } } #ifdef ACPI_DEBUG_OUTPUT else if (status != AE_NOT_FOUND) { char *scope_name = acpi_ns_get_external_pathname(info->resolved_node); ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", scope_name)); ACPI_FREE(scope_name); } #endif status = AE_OK; if (acpi_gbl_init_handler) { status = acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI); } return_ACPI_STATUS(status); }