📄 evregion.c
字号:
ACPI_OPERAND_OBJECT *obj_desc;
ACPI_OPERAND_OBJECT **last_obj_ptr;
ADDRESS_SPACE_SETUP region_setup;
void *region_context;
ACPI_STATUS status;
region_context = region_obj->region.extra->extra.region_context;
/*
* Get the address handler from the region object
*/
handler_obj = region_obj->region.addr_handler;
if (!handler_obj) {
/*
* This region has no handler, all done
*/
return;
}
/*
* Find this region in the handler's list
*/
obj_desc = handler_obj->addr_handler.region_list;
last_obj_ptr = &handler_obj->addr_handler.region_list;
while (obj_desc) {
/*
* See if this is the one
*/
if (obj_desc == region_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) {
acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
}
/*
* Now stop region accesses by executing the _REG method
*/
acpi_ev_execute_reg_method (region_obj, 0);
if (acpi_ns_is_locked) {
acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
}
/*
* Call the setup handler with the deactivate notification
*/
region_setup = handler_obj->addr_handler.setup;
status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,
handler_obj->addr_handler.context,
®ion_context);
/*
* Init routine may fail, Just ignore errors
*/
region_obj->region.flags &= ~(AOPOBJ_INITIALIZED);
/*
* 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
*/
ACPI_ASSERT (region_obj->region.addr_handler == handler_obj);
region_obj->region.addr_handler = NULL;
return;
} /* found the right handler */
/*
* Move through 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
*/
return;
}
/******************************************************************************
*
* FUNCTION: Acpi_ev_associate_region_and_handler
*
* 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_STATUS
acpi_ev_associate_region_and_handler (
ACPI_OPERAND_OBJECT *handler_obj,
ACPI_OPERAND_OBJECT *region_obj,
u8 acpi_ns_is_locked)
{
ACPI_STATUS status;
ACPI_ASSERT (region_obj->region.space_id == handler_obj->addr_handler.space_id);
ACPI_ASSERT (region_obj->region.addr_handler == 0);
/*
* Link this region to the front of the handler's list
*/
region_obj->region.next = handler_obj->addr_handler.region_list;
handler_obj->addr_handler.region_list = region_obj;
/*
* set the region's handler
*/
/*
Handler_obj->Common.Reference_count =
(u16) (Handler_obj->Common.Reference_count +
Region_obj->Common.Reference_count - 1);
*/
region_obj->region.addr_handler = handler_obj;
/*
* Last thing, tell all users that this region is usable
*/
if (acpi_ns_is_locked) {
acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
}
status = acpi_ev_execute_reg_method (region_obj, 1);
if (acpi_ns_is_locked) {
acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
}
return (status);
}
/****************************************************************************
*
* FUNCTION: Acpi_ev_addr_handler_helper
*
* PARAMETERS: Handle - Node to be dumped
* Level - Nesting level of the handle
* Context - Passed into Acpi_ns_walk_namespace
*
* DESCRIPTION: This routine checks to see if the object is a Region if it
* is then the address handler is installed in it.
*
* 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_STATUS
acpi_ev_addr_handler_helper (
ACPI_HANDLE obj_handle,
u32 level,
void *context,
void **return_value)
{
ACPI_OPERAND_OBJECT *handler_obj;
ACPI_OPERAND_OBJECT *tmp_obj;
ACPI_OPERAND_OBJECT *obj_desc;
ACPI_NAMESPACE_NODE *node;
ACPI_STATUS status;
handler_obj = (ACPI_OPERAND_OBJECT *) context;
/* Parameter validation */
if (!handler_obj) {
return (AE_OK);
}
/* Convert and validate the device handle */
node = acpi_ns_convert_handle_to_entry (obj_handle);
if (!node) {
return (AE_BAD_PARAMETER);
}
/*
* We only care about regions.and objects
* that can have address 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 ((ACPI_HANDLE) node);
if (!obj_desc) {
/*
* The object DNE, we don't care about it
*/
return (AE_OK);
}
/*
* Devices are handled different than regions
*/
if (IS_THIS_OBJECT_TYPE (obj_desc, ACPI_TYPE_DEVICE)) {
/*
* See if this guy has any handlers
*/
tmp_obj = obj_desc->device.addr_handler;
while (tmp_obj) {
/*
* Now let's see if it's for the same address space.
*/
if (tmp_obj->addr_handler.space_id == handler_obj->addr_handler.space_id) {
/*
* It's for the same address space
*/
/*
* 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);
}
/*
* Move through the linked list of handlers
*/
tmp_obj = tmp_obj->addr_handler.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);
}
/*
* Only here if it was a region
*/
ACPI_ASSERT (obj_desc->common.type == ACPI_TYPE_REGION);
if (obj_desc->region.space_id != handler_obj->addr_handler.space_id) {
/*
* This region is for a different address space
* 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_disassociate_region_from_handler (obj_desc, FALSE);
/*
* Then connect the region to the new handler
*/
status = acpi_ev_associate_region_and_handler (handler_obj, obj_desc, FALSE);
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -