⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evregion.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
 * ******************************************************************************/voidacpi_ev_detach_region(	union acpi_operand_object       *region_obj,	u8                              acpi_ns_is_locked){	union acpi_operand_object       *handler_obj;	union acpi_operand_object       *obj_desc;	union acpi_operand_object       **last_obj_ptr;	acpi_adr_space_setup            region_setup;	void                            **region_context;	union acpi_operand_object       *region_obj2;	acpi_status                     status;	ACPI_FUNCTION_TRACE ("ev_detach_region");	region_obj2 = acpi_ns_get_secondary_object (region_obj);	if (!region_obj2) {		return_VOID;	}	region_context = &region_obj2->extra.region_context;	/* Get the address handler from the region object */	handler_obj = region_obj->region.handler;	if (!handler_obj) {		/* This region has no handler, all done */		return_VOID;	}	/* Find this region in the handler's list */	obj_desc = handler_obj->address_space.region_list;	last_obj_ptr = &handler_obj->address_space.region_list;	while (obj_desc) {		/* Is this the correct Region? */		if (obj_desc == region_obj) {			ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,				"Removing Region %p from address handler %p\n",				region_obj, handler_obj));			/* This is it, remove it from the handler's list */			*last_obj_ptr = obj_desc->region.next;			obj_desc->region.next = NULL;           /* Must clear field */			if (acpi_ns_is_locked) {				status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);				if (ACPI_FAILURE (status)) {					return_VOID;				}			}			/* Now stop region accesses by executing the _REG method */			status = acpi_ev_execute_reg_method (region_obj, 0);			if (ACPI_FAILURE (status)) {				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n",					acpi_format_exception (status),					acpi_ut_get_region_name (region_obj->region.space_id)));			}			if (acpi_ns_is_locked) {				status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);				if (ACPI_FAILURE (status)) {					return_VOID;				}			}			/* Call the setup handler with the deactivate notification */			region_setup = handler_obj->address_space.setup;			status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,					  handler_obj->address_space.context, region_context);			/* Init routine may fail, Just ignore errors */			if (ACPI_FAILURE (status)) {				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n",					acpi_format_exception (status),					acpi_ut_get_region_name (region_obj->region.space_id)));			}			region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);			/*			 * Remove handler reference in the region			 *			 * NOTE: this doesn't mean that the region goes away			 * The region is just inaccessible as indicated to			 * the _REG method			 *			 * If the region is on the handler's list			 * this better be the region's handler			 */			region_obj->region.handler = NULL;			acpi_ut_remove_reference (handler_obj);			return_VOID;		}		/* Walk the linked list of handlers */		last_obj_ptr = &obj_desc->region.next;		obj_desc = obj_desc->region.next;	}	/* If we get here, the region was not in the handler's region list */	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,		"Cannot remove region %p from address handler %p\n",		region_obj, handler_obj));	return_VOID;}/******************************************************************************* * * FUNCTION:    acpi_ev_attach_region * * PARAMETERS:  handler_obj     - Handler Object *              region_obj      - Region Object *              acpi_ns_is_locked - Namespace Region Already Locked? * * RETURN:      None * * DESCRIPTION: Create the association between the handler and the region *              this is a two way association. * ******************************************************************************/acpi_statusacpi_ev_attach_region (	union acpi_operand_object       *handler_obj,	union acpi_operand_object       *region_obj,	u8                              acpi_ns_is_locked){	ACPI_FUNCTION_TRACE ("ev_attach_region");	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,		"Adding Region [%4.4s] %p to address handler %p [%s]\n",		acpi_ut_get_node_name (region_obj->region.node),		region_obj, handler_obj,		acpi_ut_get_region_name (region_obj->region.space_id)));	/* Link this region to the front of the handler's list */	region_obj->region.next = handler_obj->address_space.region_list;	handler_obj->address_space.region_list = region_obj;	/* Install the region's handler */	if (region_obj->region.handler) {		return_ACPI_STATUS (AE_ALREADY_EXISTS);	}	region_obj->region.handler = handler_obj;	acpi_ut_add_reference (handler_obj);	return_ACPI_STATUS (AE_OK);}/******************************************************************************* * * FUNCTION:    acpi_ev_install_handler * * PARAMETERS:  walk_namespace callback * * DESCRIPTION: This routine installs an address handler into objects that are *              of type Region or Device. * *              If the Object is a Device, and the device has a handler of *              the same type then the search is terminated in that branch. * *              This is because the existing handler is closer in proximity *              to any more regions than the one we are trying to install. * ******************************************************************************/acpi_statusacpi_ev_install_handler (	acpi_handle                     obj_handle,	u32                             level,	void                            *context,	void                            **return_value){	union acpi_operand_object       *handler_obj;	union acpi_operand_object       *next_handler_obj;	union acpi_operand_object       *obj_desc;	struct acpi_namespace_node      *node;	acpi_status                     status;	ACPI_FUNCTION_NAME ("ev_install_handler");	handler_obj = (union acpi_operand_object   *) context;	/* Parameter validation */	if (!handler_obj) {		return (AE_OK);	}	/* Convert and validate the device handle */	node = acpi_ns_map_handle_to_node (obj_handle);	if (!node) {		return (AE_BAD_PARAMETER);	}	/*	 * We only care about regions.and objects	 * that are allowed to have address space handlers	 */	if ((node->type != ACPI_TYPE_DEVICE) &&		(node->type != ACPI_TYPE_REGION) &&		(node != acpi_gbl_root_node)) {		return (AE_OK);	}	/* Check for an existing internal object */	obj_desc = acpi_ns_get_attached_object (node);	if (!obj_desc) {		/* No object, just exit */		return (AE_OK);	}	/* Devices are handled different than regions */	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) {		/* Check if this Device already has a handler for this address space */		next_handler_obj = obj_desc->device.handler;		while (next_handler_obj) {			/* Found a handler, is it for the same address space? */			if (next_handler_obj->address_space.space_id == handler_obj->address_space.space_id) {				ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,					"Found handler for region [%s] in device %p(%p) handler %p\n",					acpi_ut_get_region_name (handler_obj->address_space.space_id),					obj_desc, next_handler_obj, handler_obj));				/*				 * Since the object we found it on was a device, then it				 * means that someone has already installed a handler for				 * the branch of the namespace from this device on.  Just				 * bail out telling the walk routine to not traverse this				 * branch.  This preserves the scoping rule for handlers.				 */				return (AE_CTRL_DEPTH);			}			/* Walk the linked list of handlers attached to this device */			next_handler_obj = next_handler_obj->address_space.next;		}		/*		 * As long as the device didn't have a handler for this		 * space we don't care about it.  We just ignore it and		 * proceed.		 */		return (AE_OK);	}	/* Object is a Region */	if (obj_desc->region.space_id != handler_obj->address_space.space_id) {		/*		 * This region is for a different address space		 * -- just ignore it		 */		return (AE_OK);	}	/*	 * Now we have a region and it is for the handler's address	 * space type.	 *	 * First disconnect region for any previous handler (if any)	 */	acpi_ev_detach_region (obj_desc, FALSE);	/* Connect the region to the new handler */	status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE);	return (status);}/******************************************************************************* * * FUNCTION:    acpi_ev_reg_run * * PARAMETERS:  walk_namespace callback * * DESCRIPTION: Run _REg method for region objects of the requested space_iD * ******************************************************************************/acpi_statusacpi_ev_reg_run (	acpi_handle                     obj_handle,	u32                             level,	void                            *context,	void                            **return_value){	union acpi_operand_object       *handler_obj;	union acpi_operand_object       *obj_desc;	struct acpi_namespace_node      *node;	acpi_status                     status;	handler_obj = (union acpi_operand_object   *) context;	/* Parameter validation */	if (!handler_obj) {		return (AE_OK);	}	/* Convert and validate the device handle */	node = acpi_ns_map_handle_to_node (obj_handle);	if (!node) {		return (AE_BAD_PARAMETER);	}	/*	 * We only care about regions.and objects	 * that are allowed to have address space handlers	 */	if ((node->type != ACPI_TYPE_REGION) &&		(node != acpi_gbl_root_node)) {		return (AE_OK);	}	/* Check for an existing internal object */	obj_desc = acpi_ns_get_attached_object (node);	if (!obj_desc) {		/* No object, just exit */		return (AE_OK);	}	/* Object is a Region */	if (obj_desc->region.space_id != handler_obj->address_space.space_id) {		/*		 * This region is for a different address space		 * -- just ignore it		 */		return (AE_OK);	}	status = acpi_ev_execute_reg_method (obj_desc, 1);	return (status);}

⌨️ 快捷键说明

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