📄 evregion.c
字号:
* this is a two way association. * ******************************************************************************/voidacpi_ev_disassociate_region_from_handler( acpi_operand_object *region_obj, u8 acpi_ns_is_locked){ acpi_operand_object *handler_obj; acpi_operand_object *obj_desc; acpi_operand_object **last_obj_ptr; acpi_adr_space_setup region_setup; void *region_context; acpi_status status; FUNCTION_TRACE ("Ev_disassociate_region_from_handler"); 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_VOID; } /* * 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) { 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) { acpi_ut_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_ut_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 */ 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_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 */ region_obj->region.addr_handler = NULL; return_VOID; } /* 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 */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Cannot remove region %p from address handler %p\n", region_obj, handler_obj)); return_VOID;}/******************************************************************************* * * 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_statusacpi_ev_associate_region_and_handler ( acpi_operand_object *handler_obj, acpi_operand_object *region_obj, u8 acpi_ns_is_locked){ acpi_status status; FUNCTION_TRACE ("Ev_associate_region_and_handler"); ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Adding Region %p to address handler %p [%s]\n", 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->addr_handler.region_list; handler_obj->addr_handler.region_list = region_obj; /* * set the region's handler */ region_obj->region.addr_handler = handler_obj; /* * Last thing, tell all users that this region is usable */ if (acpi_ns_is_locked) { acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); } status = acpi_ev_execute_reg_method (region_obj, 1); if (acpi_ns_is_locked) { acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); } return_ACPI_STATUS (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_statusacpi_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; PROC_NAME ("Ev_addr_handler_helper"); handler_obj = (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 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 (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 */ 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->addr_handler.space_id), obj_desc, tmp_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); } /* * 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 */ 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 + -