nsinit.c

来自「linux 内核源代码」· C语言 代码 · 共 584 行 · 第 1/2 页

C
584
字号
		status = acpi_ds_get_buffer_arguments(obj_desc);		break;	case ACPI_TYPE_PACKAGE:		info->package_init++;		status = acpi_ds_get_package_arguments(obj_desc);		break;	default:		/* No other types can get here */		break;	}	if (ACPI_FAILURE(status)) {		ACPI_EXCEPTION((AE_INFO, status,				"Could not execute arguments for [%4.4s] (%s)",				acpi_ut_get_node_name(node),				acpi_ut_get_type_name(type)));	}	/*	 * Print a dot for each object unless we are going to print the entire	 * pathname	 */	if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {		ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));	}	/*	 * We ignore errors from above, and always return OK, since we don't want	 * to abort the walk on any single error.	 */	acpi_ex_exit_interpreter();	return (AE_OK);}/******************************************************************************* * * FUNCTION:    acpi_ns_find_ini_methods * * PARAMETERS:  acpi_walk_callback * * RETURN:      acpi_status * * DESCRIPTION: Called during namespace walk. Finds objects named _INI under *              device/processor/thermal objects, and marks the entire subtree *              with a SUBTREE_HAS_INI flag. This flag is used during the *              subsequent device initialization walk to avoid entire subtrees *              that do not contain an _INI. * ******************************************************************************/static acpi_statusacpi_ns_find_ini_methods(acpi_handle obj_handle,			 u32 nesting_level, void *context, void **return_value){	struct acpi_device_walk_info *info =	    ACPI_CAST_PTR(struct acpi_device_walk_info, context);	struct acpi_namespace_node *node;	struct acpi_namespace_node *parent_node;	/* Keep count of device/processor/thermal objects */	node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);	if ((node->type == ACPI_TYPE_DEVICE) ||	    (node->type == ACPI_TYPE_PROCESSOR) ||	    (node->type == ACPI_TYPE_THERMAL)) {		info->device_count++;		return (AE_OK);	}	/* We are only looking for methods named _INI */	if (!ACPI_COMPARE_NAME(node->name.ascii, METHOD_NAME__INI)) {		return (AE_OK);	}	/*	 * The only _INI methods that we care about are those that are	 * present under Device, Processor, and Thermal objects.	 */	parent_node = acpi_ns_get_parent_node(node);	switch (parent_node->type) {	case ACPI_TYPE_DEVICE:	case ACPI_TYPE_PROCESSOR:	case ACPI_TYPE_THERMAL:		/* Mark parent and bubble up the INI present flag to the root */		while (parent_node) {			parent_node->flags |= ANOBJ_SUBTREE_HAS_INI;			parent_node = acpi_ns_get_parent_node(parent_node);		}		break;	default:		break;	}	return (AE_OK);}/******************************************************************************* * * FUNCTION:    acpi_ns_init_one_device * * PARAMETERS:  acpi_walk_callback * * RETURN:      acpi_status * * DESCRIPTION: This is called once per device soon after ACPI is enabled *              to initialize each device. It determines if the device is *              present, and if so, calls _INI. * ******************************************************************************/static acpi_statusacpi_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));	info->prefix_node = device_node;	info->pathname = METHOD_NAME__INI;	info->parameters = NULL;	info->parameter_type = ACPI_PARAM_ARGS;	info->flags = ACPI_IGNORE_RETURN_VALUE;	/*	 * Some hardware relies on this being executed as atomically	 * as possible (without an NMI being received in the middle of	 * this) - so disable NMIs and initialize the device:	 */	acpi_nmi_disable();	status = acpi_ns_evaluate(info);	acpi_nmi_enable();	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) {		/* Ignore error and move on to next device */		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	/* 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);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?