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

📄 evevent.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	/* GPE Block 1 */	for (i = 0; i < gpe1_register_count; i++) {		acpi_gbl_gpe_registers[register_index].status_addr =				 (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i);		acpi_gbl_gpe_registers[register_index].enable_addr =				 (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i + gpe1_register_count);		acpi_gbl_gpe_registers[register_index].gpe_base =				 (u8) (acpi_gbl_FADT->gpe1_base + MUL_8 (i));		for (j = 0; j < 8; j++) {			gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j;			acpi_gbl_gpe_valid[gpe_number] = (u8) register_index;		}		/*		 * Clear the status/enable registers.  Note that status registers		 * are cleared by writing a '1', while enable registers are cleared		 * by writing a '0'.		 */		acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8);		acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8);		register_index++;	}	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE registers: %X@%8.8X%8.8X (Blk0) %X@%8.8X%8.8X (Blk1)\n",		gpe0register_count, HIDWORD(acpi_gbl_FADT->Xgpe0blk.address), LODWORD(acpi_gbl_FADT->Xgpe0blk.address),		gpe1_register_count, HIDWORD(acpi_gbl_FADT->Xgpe1_blk.address), LODWORD(acpi_gbl_FADT->Xgpe1_blk.address)));	return_ACPI_STATUS (AE_OK);}/******************************************************************************* * * FUNCTION:    Acpi_ev_save_method_info * * PARAMETERS:  None * * RETURN:      None * * DESCRIPTION: Called from Acpi_walk_namespace. Expects each object to be a *              control method under the _GPE portion of the namespace. *              Extract the name and GPE type from the object, saving this *              information for quick lookup during GPE dispatch * *              The name of each GPE control method is of the form: *                  "_Lnn" or "_Enn" *              Where: *                  L      - means that the GPE is level triggered *                  E      - means that the GPE is edge triggered *                  nn     - is the GPE number * ******************************************************************************/static acpi_statusacpi_ev_save_method_info (	acpi_handle             obj_handle,	u32                     level,	void                    *obj_desc,	void                    **return_value){	u32                     gpe_number;	NATIVE_CHAR             name[ACPI_NAME_SIZE + 1];	u8                      type;	PROC_NAME ("Ev_save_method_info");	/* Extract the name from the object and convert to a string */	MOVE_UNALIGNED32_TO_32 (name, &((acpi_namespace_node *) obj_handle)->name);	name[ACPI_NAME_SIZE] = 0;	/*	 * Edge/Level determination is based on the 2nd s8 of the method name	 */	if (name[1] == 'L') {		type = ACPI_EVENT_LEVEL_TRIGGERED;	}	else if (name[1] == 'E') {		type = ACPI_EVENT_EDGE_TRIGGERED;	}	else {		/* Unknown method type, just ignore it! */		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,			"Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n",			name));		return (AE_OK);	}	/* Convert the last two characters of the name to the Gpe Number */	gpe_number = STRTOUL (&name[2], NULL, 16);	if (gpe_number == ACPI_UINT32_MAX) {		/* Conversion failed; invalid method, just ignore it */		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,			"Could not extract GPE number from name: %s (name not of form _Lnn or _Enn)\n",			name));		return (AE_OK);	}	/* Ensure that we have a valid GPE number */	if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) {		/* Not valid, all we can do here is ignore it */		return (AE_OK);	}	/*	 * Now we can add this information to the Gpe_info block	 * for use during dispatch of this GPE.	 */	acpi_gbl_gpe_info [gpe_number].type         = type;	acpi_gbl_gpe_info [gpe_number].method_handle = obj_handle;	/*	 * Enable the GPE (SCIs should be disabled at this point)	 */	acpi_hw_enable_gpe (gpe_number);	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %X\n",		name, gpe_number));	return (AE_OK);}/******************************************************************************* * * FUNCTION:    Acpi_ev_init_gpe_control_methods * * PARAMETERS:  None * * RETURN:      None * * DESCRIPTION: Obtain the control methods associated with the GPEs. * *              NOTE: Must be called AFTER namespace initialization! * ******************************************************************************/acpi_statusacpi_ev_init_gpe_control_methods (void){	acpi_status             status;	FUNCTION_TRACE ("Ev_init_gpe_control_methods");	/* Get a permanent handle to the _GPE object */	status = acpi_get_handle (NULL, "\\_GPE", &acpi_gbl_gpe_obj_handle);	if (ACPI_FAILURE (status)) {		return_ACPI_STATUS (status);	}	/* Traverse the namespace under \_GPE to find all methods there */	status = acpi_walk_namespace (ACPI_TYPE_METHOD, acpi_gbl_gpe_obj_handle,			  ACPI_UINT32_MAX, acpi_ev_save_method_info,			  NULL, NULL);	return_ACPI_STATUS (status);}/******************************************************************************* * * FUNCTION:    Acpi_ev_gpe_detect * * PARAMETERS:  None * * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED * * DESCRIPTION: Detect if any GP events have occurred * ******************************************************************************/u32acpi_ev_gpe_detect (void){	u32                     int_status = INTERRUPT_NOT_HANDLED;	u32                     i;	u32                     j;	u8                      enabled_status_byte;	u8                      bit_mask;	PROC_NAME ("Ev_gpe_detect");	/*	 * Read all of the 8-bit GPE status and enable registers	 * in both of the register blocks, saving all of it.	 * Find all currently active GP events.	 */	for (i = 0; i < acpi_gbl_gpe_register_count; i++) {		acpi_os_read_port (acpi_gbl_gpe_registers[i].status_addr,				&acpi_gbl_gpe_registers[i].status, 8);		acpi_os_read_port (acpi_gbl_gpe_registers[i].enable_addr,				&acpi_gbl_gpe_registers[i].enable, 8);		ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,			"GPE block at %X - Enable %08X Status %08X\n",			acpi_gbl_gpe_registers[i].enable_addr,			acpi_gbl_gpe_registers[i].status,			acpi_gbl_gpe_registers[i].enable));		/* First check if there is anything active at all in this register */		enabled_status_byte = (u8) (acpi_gbl_gpe_registers[i].status &				   acpi_gbl_gpe_registers[i].enable);		if (!enabled_status_byte) {			/* No active GPEs in this register, move on */			continue;		}		/* Now look at the individual GPEs in this byte register */		for (j = 0, bit_mask = 1; j < 8; j++, bit_mask <<= 1) {			/* Examine one GPE bit */			if (enabled_status_byte & bit_mask) {				/*				 * Found an active GPE.  Dispatch the event to a handler				 * or method.				 */				int_status |= acpi_ev_gpe_dispatch (						  acpi_gbl_gpe_registers[i].gpe_base + j);			}		}	}	return (int_status);}/******************************************************************************* * * FUNCTION:    Acpi_ev_asynch_execute_gpe_method * * PARAMETERS:  Gpe_number      - The 0-based Gpe number * * RETURN:      None * * DESCRIPTION: Perform the actual execution of a GPE control method.  This *              function is called from an invocation of Acpi_os_queue_for_execution *              (and therefore does NOT execute at interrupt level) so that *              the control method itself is not executed in the context of *              the SCI interrupt handler. * ******************************************************************************/static voidacpi_ev_asynch_execute_gpe_method (	void                    *context){	u32                     gpe_number = (u32) context;	acpi_gpe_level_info     gpe_info;	FUNCTION_TRACE ("Ev_asynch_execute_gpe_method");	/*	 * Take a snapshot of the GPE info for this level	 */	acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);	gpe_info = acpi_gbl_gpe_info [gpe_number];	acpi_ut_release_mutex (ACPI_MTX_EVENTS);	/*	 * Method Handler (_Lxx, _Exx):	 * ----------------------------	 * Evaluate the _Lxx/_Exx control method that corresponds to this GPE.	 */	if (gpe_info.method_handle) {		acpi_ns_evaluate_by_handle (gpe_info.method_handle, NULL, NULL);	}	/*	 * Level-Triggered?	 * ----------------	 * If level-triggered we clear the GPE status bit after handling the event.	 */	if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {		acpi_hw_clear_gpe (gpe_number);	}	/*	 * Enable the GPE.	 */	acpi_hw_enable_gpe (gpe_number);	return_VOID;}/******************************************************************************* * * FUNCTION:    Acpi_ev_gpe_dispatch * * PARAMETERS:  Gpe_number      - The 0-based Gpe number * * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED * * DESCRIPTION: Handle and dispatch a General Purpose Acpi_event. *              Clears the status bit for the requested event. * * TBD: [Investigate] is this still valid or necessary: * The Gpe handler differs from the fixed events in that it clears the enable * bit rather than the status bit to clear the interrupt.  This allows * software outside of interrupt context to determine what caused the SCI and * dispatch the correct AML. * ******************************************************************************/u32acpi_ev_gpe_dispatch (	u32                     gpe_number){	acpi_gpe_level_info     gpe_info;	FUNCTION_TRACE ("Ev_gpe_dispatch");	/*	 * Valid GPE number?	 */	if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) {		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid GPE bit [%X].\n", gpe_number));		return_VALUE (INTERRUPT_NOT_HANDLED);	}	/*	 * Disable the GPE.	 */	acpi_hw_disable_gpe (gpe_number);	gpe_info = acpi_gbl_gpe_info [gpe_number];	/*	 * Edge-Triggered?	 * ---------------	 * If edge-triggered, clear the GPE status bit now.  Note that	 * level-triggered events are cleared after the GPE is serviced.	 */	if (gpe_info.type & ACPI_EVENT_EDGE_TRIGGERED) {		acpi_hw_clear_gpe (gpe_number);	}		/*		 * Function Handler (e.g. EC)?		 */	if (gpe_info.handler) {		/* Invoke function handler (at interrupt level). */		gpe_info.handler (gpe_info.context);		/* Level-Triggered? */		if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {			acpi_hw_clear_gpe (gpe_number);		}		/* Enable GPE */		acpi_hw_enable_gpe (gpe_number);	}	/*	 * Method Handler (e.g. _Exx/_Lxx)?	 */	else if (gpe_info.method_handle) {		if (ACPI_FAILURE(acpi_os_queue_for_execution (OSD_PRIORITY_GPE,			acpi_ev_asynch_execute_gpe_method, (void*) gpe_number))) {			/*			 * Shoudn't occur, but if it does report an error. Note that			 * the GPE will remain disabled until the ACPI Core Subsystem			 * is restarted, or the handler is removed/reinstalled.			 */			REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to queue handler for GPE bit [%X]\n", gpe_number));		}	}	/*	 * No Handler? Report an error and leave the GPE disabled.	 */	else {		REPORT_ERROR (("Acpi_ev_gpe_dispatch: No installed handler for GPE [%X]\n", gpe_number));		/* Level-Triggered? */		if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {			acpi_hw_clear_gpe (gpe_number);		}	}	return_VALUE (INTERRUPT_HANDLED);}

⌨️ 快捷键说明

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