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

📄 evgpeblk.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		goto cleanup;	}	/* Extract pointers from the input context */	gpe_device = gpe_info->gpe_device;	gpe_block = gpe_info->gpe_block;	/*	 * The _PRW object must return a package, we are only interested	 * in the first element	 */	obj_desc = pkg_desc->package.elements[0];	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {		/* Use FADT-defined GPE device (from definition of _PRW) */		target_gpe_device = acpi_gbl_fadt_gpe_device;		/* Integer is the GPE number in the FADT described GPE blocks */		gpe_number = (u32) obj_desc->integer.value;	} else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {		/* Package contains a GPE reference and GPE number within a GPE block */		if ((obj_desc->package.count < 2) ||		    (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=		     ACPI_TYPE_LOCAL_REFERENCE)		    || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=			ACPI_TYPE_INTEGER)) {			goto cleanup;		}		/* Get GPE block reference and decode */		target_gpe_device =		    obj_desc->package.elements[0]->reference.node;		gpe_number = (u32) obj_desc->package.elements[1]->integer.value;	} else {		/* Unknown type, just ignore it */		goto cleanup;	}	/*	 * Is this GPE within this block?	 *	 * TRUE iff these conditions are true:	 *     1) The GPE devices match.	 *     2) The GPE index(number) is within the range of the Gpe Block	 *          associated with the GPE device.	 */	if ((gpe_device == target_gpe_device) &&	    (gpe_number >= gpe_block->block_base_number) &&	    (gpe_number <	     gpe_block->block_base_number + (gpe_block->register_count * 8))) {		gpe_event_info =		    &gpe_block->event_info[gpe_number -					   gpe_block->block_base_number];		/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */		gpe_event_info->flags &=		    ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);		status =		    acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);		if (ACPI_FAILURE(status)) {			goto cleanup;		}		status =		    acpi_ev_update_gpe_enable_masks(gpe_event_info,						    ACPI_GPE_DISABLE);	}      cleanup:	acpi_ut_remove_reference(pkg_desc);	return_ACPI_STATUS(AE_OK);}/******************************************************************************* * * FUNCTION:    acpi_ev_get_gpe_xrupt_block * * PARAMETERS:  interrupt_number     - Interrupt for a GPE block * * RETURN:      A GPE interrupt block * * DESCRIPTION: Get or Create a GPE interrupt block.  There is one interrupt *              block per unique interrupt level used for GPEs. *              Should be called only when the GPE lists are semaphore locked *              and not subject to change. * ******************************************************************************/static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32							       interrupt_number){	struct acpi_gpe_xrupt_info *next_gpe_xrupt;	struct acpi_gpe_xrupt_info *gpe_xrupt;	acpi_status status;	u32 flags;	ACPI_FUNCTION_TRACE("ev_get_gpe_xrupt_block");	/* No need for lock since we are not changing any list elements here */	next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;	while (next_gpe_xrupt) {		if (next_gpe_xrupt->interrupt_number == interrupt_number) {			return_PTR(next_gpe_xrupt);		}		next_gpe_xrupt = next_gpe_xrupt->next;	}	/* Not found, must allocate a new xrupt descriptor */	gpe_xrupt = ACPI_MEM_CALLOCATE(sizeof(struct acpi_gpe_xrupt_info));	if (!gpe_xrupt) {		return_PTR(NULL);	}	gpe_xrupt->interrupt_number = interrupt_number;	/* Install new interrupt descriptor with spin lock */	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);	if (acpi_gbl_gpe_xrupt_list_head) {		next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;		while (next_gpe_xrupt->next) {			next_gpe_xrupt = next_gpe_xrupt->next;		}		next_gpe_xrupt->next = gpe_xrupt;		gpe_xrupt->previous = next_gpe_xrupt;	} else {		acpi_gbl_gpe_xrupt_list_head = gpe_xrupt;	}	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);	/* Install new interrupt handler if not SCI_INT */	if (interrupt_number != acpi_gbl_FADT->sci_int) {		status = acpi_os_install_interrupt_handler(interrupt_number,							   acpi_ev_gpe_xrupt_handler,							   gpe_xrupt);		if (ACPI_FAILURE(status)) {			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,					  "Could not install GPE interrupt handler at level 0x%X\n",					  interrupt_number));			return_PTR(NULL);		}	}	return_PTR(gpe_xrupt);}/******************************************************************************* * * FUNCTION:    acpi_ev_delete_gpe_xrupt * * PARAMETERS:  gpe_xrupt       - A GPE interrupt info block * * RETURN:      Status * * DESCRIPTION: Remove and free a gpe_xrupt block. Remove an associated *              interrupt handler if not the SCI interrupt. * ******************************************************************************/static acpi_statusacpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt){	acpi_status status;	u32 flags;	ACPI_FUNCTION_TRACE("ev_delete_gpe_xrupt");	/* We never want to remove the SCI interrupt handler */	if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) {		gpe_xrupt->gpe_block_list_head = NULL;		return_ACPI_STATUS(AE_OK);	}	/* Disable this interrupt */	status = acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number,						  acpi_ev_gpe_xrupt_handler);	if (ACPI_FAILURE(status)) {		return_ACPI_STATUS(status);	}	/* Unlink the interrupt block with lock */	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);	if (gpe_xrupt->previous) {		gpe_xrupt->previous->next = gpe_xrupt->next;	}	if (gpe_xrupt->next) {		gpe_xrupt->next->previous = gpe_xrupt->previous;	}	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);	/* Free the block */	ACPI_MEM_FREE(gpe_xrupt);	return_ACPI_STATUS(AE_OK);}/******************************************************************************* * * FUNCTION:    acpi_ev_install_gpe_block * * PARAMETERS:  gpe_block       - New GPE block *              interrupt_number - Xrupt to be associated with this GPE block * * RETURN:      Status * * DESCRIPTION: Install new GPE block with mutex support * ******************************************************************************/static acpi_statusacpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,			  u32 interrupt_number){	struct acpi_gpe_block_info *next_gpe_block;	struct acpi_gpe_xrupt_info *gpe_xrupt_block;	acpi_status status;	u32 flags;	ACPI_FUNCTION_TRACE("ev_install_gpe_block");	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);	if (ACPI_FAILURE(status)) {		return_ACPI_STATUS(status);	}	gpe_xrupt_block = acpi_ev_get_gpe_xrupt_block(interrupt_number);	if (!gpe_xrupt_block) {		status = AE_NO_MEMORY;		goto unlock_and_exit;	}	/* Install the new block at the end of the list with lock */	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);	if (gpe_xrupt_block->gpe_block_list_head) {		next_gpe_block = gpe_xrupt_block->gpe_block_list_head;		while (next_gpe_block->next) {			next_gpe_block = next_gpe_block->next;		}		next_gpe_block->next = gpe_block;		gpe_block->previous = next_gpe_block;	} else {		gpe_xrupt_block->gpe_block_list_head = gpe_block;	}	gpe_block->xrupt_block = gpe_xrupt_block;	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);      unlock_and_exit:	status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);	return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION:    acpi_ev_delete_gpe_block * * PARAMETERS:  gpe_block       - Existing GPE block * * RETURN:      Status * * DESCRIPTION: Remove a GPE block * ******************************************************************************/acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block){	acpi_status status;	u32 flags;	ACPI_FUNCTION_TRACE("ev_install_gpe_block");	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);	if (ACPI_FAILURE(status)) {		return_ACPI_STATUS(status);	}	/* Disable all GPEs in this block */	status = acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block);	if (!gpe_block->previous && !gpe_block->next) {		/* This is the last gpe_block on this interrupt */		status = acpi_ev_delete_gpe_xrupt(gpe_block->xrupt_block);		if (ACPI_FAILURE(status)) {			goto unlock_and_exit;		}	} else {		/* Remove the block on this interrupt with lock */		flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);		if (gpe_block->previous) {			gpe_block->previous->next = gpe_block->next;		} else {			gpe_block->xrupt_block->gpe_block_list_head =			    gpe_block->next;		}		if (gpe_block->next) {			gpe_block->next->previous = gpe_block->previous;		}		acpi_os_release_lock(acpi_gbl_gpe_lock, flags);	}	/* Free the gpe_block */	ACPI_MEM_FREE(gpe_block->register_info);	ACPI_MEM_FREE(gpe_block->event_info);	ACPI_MEM_FREE(gpe_block);      unlock_and_exit:	status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);	return_ACPI_STATUS(status);}/******************************************************************************* * * FUNCTION:    acpi_ev_create_gpe_info_blocks * * PARAMETERS:  gpe_block   - New GPE block * * RETURN:      Status * * DESCRIPTION: Create the register_info and event_info blocks for this GPE block * ******************************************************************************/static acpi_statusacpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block){	struct acpi_gpe_register_info *gpe_register_info = NULL;	struct acpi_gpe_event_info *gpe_event_info = NULL;	struct acpi_gpe_event_info *this_event;	struct acpi_gpe_register_info *this_register;	acpi_native_uint i;	acpi_native_uint j;	acpi_status status;	ACPI_FUNCTION_TRACE("ev_create_gpe_info_blocks");	/* Allocate the GPE register information block */	gpe_register_info = ACPI_MEM_CALLOCATE((acpi_size) gpe_block->					       register_count *					       sizeof(struct						      acpi_gpe_register_info));	if (!gpe_register_info) {		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,				  "Could not allocate the gpe_register_info table\n"));		return_ACPI_STATUS(AE_NO_MEMORY);	}	/*	 * Allocate the GPE event_info block. There are eight distinct GPEs	 * per register.  Initialization to zeros is sufficient.	 */	gpe_event_info = ACPI_MEM_CALLOCATE(((acpi_size) gpe_block->					     register_count *					     ACPI_GPE_REGISTER_WIDTH) *					    sizeof(struct acpi_gpe_event_info));	if (!gpe_event_info) {		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,				  "Could not allocate the gpe_event_info table\n"));		status = AE_NO_MEMORY;

⌨️ 快捷键说明

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