nsinit.c

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

C
584
字号
/****************************************************************************** * * Module Name: nsinit - namespace initialization * *****************************************************************************//* * Copyright (C) 2000 - 2007, R. Byron Moore * 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 <acpi/acnamesp.h>#include <acpi/acdispat.h>#include <acpi/acinterp.h>#include <linux/nmi.h>#define _COMPONENT          ACPI_NAMESPACEACPI_MODULE_NAME("nsinit")/* Local prototypes */static acpi_statusacpi_ns_init_one_object(acpi_handle obj_handle,			u32 level, void *context, void **return_value);static acpi_statusacpi_ns_init_one_device(acpi_handle obj_handle,			u32 nesting_level, void *context, void **return_value);static acpi_statusacpi_ns_find_ini_methods(acpi_handle obj_handle,			 u32 nesting_level, void *context, void **return_value);/******************************************************************************* * * FUNCTION:    acpi_ns_initialize_objects * * PARAMETERS:  None * * RETURN:      Status * * DESCRIPTION: Walk the entire namespace and perform any necessary *              initialization on the objects found therein * ******************************************************************************/acpi_status acpi_ns_initialize_objects(void){	acpi_status status;	struct acpi_init_walk_info info;	ACPI_FUNCTION_TRACE(ns_initialize_objects);	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,			  "**** Starting initialization of namespace objects ****\n"));	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,			      "Completing Region/Field/Buffer/Package initialization:"));	/* Set all init info to zero */	ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info));	/* Walk entire namespace from the supplied root */	status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,				     ACPI_UINT32_MAX, acpi_ns_init_one_object,				     &info, NULL);	if (ACPI_FAILURE(status)) {		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));	}	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,			      "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",			      info.op_region_init, info.op_region_count,			      info.field_init, info.field_count,			      info.buffer_init, info.buffer_count,			      info.package_init, info.package_count,			      info.object_count));	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,			  "%hd Control Methods found\n", info.method_count));	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,			  "%hd Op Regions found\n", info.op_region_count));	return_ACPI_STATUS(AE_OK);}/******************************************************************************* * * FUNCTION:    acpi_ns_initialize_devices * * PARAMETERS:  None * * RETURN:      acpi_status * * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. *              This means running _INI on all present devices. * *              Note: We install PCI config space handler on region access, *              not here. * ******************************************************************************/acpi_status acpi_ns_initialize_devices(void){	acpi_status status;	struct acpi_device_walk_info info;	ACPI_FUNCTION_TRACE(ns_initialize_devices);	/* Init counters */	info.device_count = 0;	info.num_STA = 0;	info.num_INI = 0;	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,			      "Initializing Device/Processor/Thermal objects by executing _INI methods:"));	/* Tree analysis: find all subtrees that contain _INI methods */	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,					ACPI_UINT32_MAX, FALSE,					acpi_ns_find_ini_methods, &info, NULL);	if (ACPI_FAILURE(status)) {		goto error_exit;	}	/* Allocate the evaluation information block */	info.evaluate_info =	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));	if (!info.evaluate_info) {		status = AE_NO_MEMORY;		goto error_exit;	}	/* Walk namespace to execute all _INIs on present devices */	status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,					ACPI_UINT32_MAX, FALSE,					acpi_ns_init_one_device, &info, NULL);	ACPI_FREE(info.evaluate_info);	if (ACPI_FAILURE(status)) {		goto error_exit;	}	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,			      "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n",			      info.num_INI, info.num_STA, info.device_count));	return_ACPI_STATUS(status);      error_exit:	ACPI_EXCEPTION((AE_INFO, status, "During device initialization"));	return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION:    acpi_ns_init_one_object * * PARAMETERS:  obj_handle      - Node *              Level           - Current nesting level *              Context         - Points to a init info struct *              return_value    - Not used * * RETURN:      Status * * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object *              within the  namespace. * *              Currently, the only objects that require initialization are: *              1) Methods *              2) Op Regions * ******************************************************************************/static acpi_statusacpi_ns_init_one_object(acpi_handle obj_handle,			u32 level, void *context, void **return_value){	acpi_object_type type;	acpi_status status = AE_OK;	struct acpi_init_walk_info *info =	    (struct acpi_init_walk_info *)context;	struct acpi_namespace_node *node =	    (struct acpi_namespace_node *)obj_handle;	union acpi_operand_object *obj_desc;	ACPI_FUNCTION_NAME(ns_init_one_object);	info->object_count++;	/* And even then, we are only interested in a few object types */	type = acpi_ns_get_type(obj_handle);	obj_desc = acpi_ns_get_attached_object(node);	if (!obj_desc) {		return (AE_OK);	}	/* Increment counters for object types we are looking for */	switch (type) {	case ACPI_TYPE_REGION:		info->op_region_count++;		break;	case ACPI_TYPE_BUFFER_FIELD:		info->field_count++;		break;	case ACPI_TYPE_BUFFER:		info->buffer_count++;		break;	case ACPI_TYPE_PACKAGE:		info->package_count++;		break;	default:		/* No init required, just exit now */		return (AE_OK);	}	/*	 * If the object is already initialized, nothing else to do	 */	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {		return (AE_OK);	}	/*	 * Must lock the interpreter before executing AML code	 */	acpi_ex_enter_interpreter();	/*	 * Each of these types can contain executable AML code within the	 * declaration.	 */	switch (type) {	case ACPI_TYPE_REGION:		info->op_region_init++;		status = acpi_ds_get_region_arguments(obj_desc);		break;	case ACPI_TYPE_BUFFER_FIELD:		info->field_init++;		status = acpi_ds_get_buffer_field_arguments(obj_desc);		break;	case ACPI_TYPE_BUFFER:		info->buffer_init++;

⌨️ 快捷键说明

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