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

📄 ec.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
     */    object_name[2] = hex[((ec_q->data >> 4) & 0x0F)];    object_name[3] = hex[(ec_q->data & 0x0F)];    DEBUG_PRINT(ACPI_INFO, ("Read query data[0x%02x] from ec - evaluating [%s].\n", ec_q->data, object_name));    status = acpi_evaluate_object(ec_q->ec->acpi_handle, object_name, NULL, NULL);    kfree(ec_q);    return_VOID;}/* * handle GPE */static voidec_gpe_handler(void *context){    ACPI_STATUS             status = AE_OK;    ec_context_t            *ec = (ec_context_t *) context;    EC_QUERY_DATA           *ec_q = NULL;    EC_STATUS               ec_status = 0;    FUNCTION_TRACE("ec_gpe_handler");    if (!ec) {        DEBUG_PRINT(ACPI_INFO, ("Invalid (NULL) context.\n"));        return_VOID;    }    // GET SPINLOCK!    /*     * EC_SCI?     * -------     * Check the EC_SCI bit to see if this is an EC_SCI event.  If not (e.g.     * OBF/IBE) just return, as we already poll to detect these events.     */    ec_status = acpi_os_in8(ec->status_port);    DEBUG_PRINT(ACPI_INFO, ("EC Status Register: [0x%02x]\n", ec_status));    if (!(ec_status & EC_FLAG_SCI))        return_VOID;    DEBUG_PRINT(ACPI_INFO, ("EC_SCI detected - running QUERY.\n"));    // TODO: Need GFP_ATOMIC 'switch' for OSL interface...    ec_q = kmalloc(sizeof(EC_QUERY_DATA), GFP_ATOMIC);    if (!ec_q) {        DEBUG_PRINT(ACPI_INFO, ("Memory allocation failure.\n"));        return_VOID;    }    ec_q->ec = ec;    ec_q->data = 0;    /*     * Run Query:     * ----------     * Query the EC to find out which _Qxx method we need to evaluate.     * Note that successful completion of the query causes the EC_SCI     * bit to be cleared (and thus clearing the interrupt source).     */    status = ec_io_write(ec, ec->status_port, EC_COMMAND_QUERY, EC_EVENT_OUTPUT_BUFFER_FULL);    if (ACPI_FAILURE(status)) {        DEBUG_PRINT(ACPI_WARN, ("Unable to send 'query command' to EC.\n"));        goto End;    }    status = ec_io_read(ec, ec->data_port, &(ec_q->data), EC_EVENT_NONE);    if (ACPI_FAILURE(status)) {        DEBUG_PRINT(ACPI_WARN, ("Error reading query data.\n"));        goto End;    }    // RELEASE SPINLOCK!    if (!ec_q->data) {        DEBUG_PRINT(ACPI_WARN, ("Spurious EC SCI detected.\n"));        status = AE_ERROR;        goto End;    }    /*     * Defer _Qxx Execution:     * ---------------------     * Can't evaluate this method now 'cause we're at interrupt-level.     */    status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, ec_query_handler, ec_q);    if (ACPI_FAILURE(status)) {        DEBUG_PRINT(ACPI_ERROR, ("Unable to defer _Qxx method evaluation.\n"));        goto End;    }End:    if (ACPI_FAILURE(status))        kfree(ec_q);        return_VOID;}static ACPI_STATUSec_region_setup (    ACPI_HANDLE handle,    u32 function,    void *handler_context,    void **region_context){	FUNCTION_TRACE("acpi_ec_region_setup");	printk("acpi_ec_region_setup\n");	if (function == ACPI_REGION_DEACTIVATE)	{		if (*region_context)		{			acpi_cm_free (*region_context);			*region_context = NULL;		}		return_ACPI_STATUS (AE_OK);	}	*region_context = NULL;	return_ACPI_STATUS (AE_OK);}/***************************************************************************** *  * FUNCTION:    ec_region_handler * * PARAMETERS:  function            - Read or Write operation *              address             - Where in the space to read or write *              bit_width            - Field width in bits (8, 16, or 32) *              value               - Pointer to in or out value *              context             - context pointer * * RETURN:      <TBD> * * DESCRIPTION: Handler for the Embedded Controller (EC) address space  *              (Op Region) * ****************************************************************************/static ACPI_STATUSec_region_handler (    UINT32                  function,    ACPI_PHYSICAL_ADDRESS   address,    UINT32                  bit_width,    UINT32                  *value,    void                    *handler_context,    void                    *region_context){    ACPI_STATUS             status = AE_OK;    ec_context_t              *ec = NULL;    EC_REQUEST              ec_request;    FUNCTION_TRACE("ec_space_handler");    if (address > 0xFF || bit_width != 8 || !value || !handler_context)        return_ACPI_STATUS(AE_BAD_PARAMETER);    ec = (ec_context_t*)handler_context;    switch (function) {    case ADDRESS_SPACE_READ:        ec_request.command = EC_COMMAND_READ;        ec_request.address = address;        ec_request.data = 0;        break;    case ADDRESS_SPACE_WRITE:        ec_request.command = EC_COMMAND_WRITE;        ec_request.address = address;        ec_request.data = (UINT8)(*value);        break;    default:        DEBUG_PRINT(ACPI_WARN, ("Received request with invalid function [0x%08X].\n", function));        return_ACPI_STATUS(AE_BAD_PARAMETER);        break;    }    DEBUG_PRINT(ACPI_INFO, ("device[ec] command[0x%02X] address[0x%02X] data[0x%02X]\n", ec_request.command, ec_request.address, ec_request.data));    /*     * Perform the Transaction.     */    status = ec_transaction(ec, &ec_request);    if (ACPI_SUCCESS(status))        (*value) = (UINT32)ec_request.data;    return_ACPI_STATUS(status);}/* * Get Embedded Controller information */static ACPI_STATUSfound_ec(	ACPI_HANDLE handle,	u32 level, 	void *ctx, 	void **value){	ACPI_STATUS status;	ACPI_OBJECT obj;	ACPI_BUFFER buf;	RESOURCE *res;	ec_context_t *ec_cxt;	buf.length = 0;	buf.pointer = NULL;	if (acpi_get_current_resources(handle, &buf) != AE_BUFFER_OVERFLOW)		return AE_OK;	buf.pointer = kmalloc(buf.length, GFP_KERNEL);	if (!buf.pointer)		return AE_NO_MEMORY;	if (!ACPI_SUCCESS(acpi_get_current_resources(handle, &buf))) {		kfree(buf.pointer);		return AE_OK;	}	ec_cxt = kmalloc(sizeof(ec_context_t), GFP_KERNEL);	if (!ec_cxt) {		kfree(buf.pointer);		return AE_NO_MEMORY;	}	ec_cxt->acpi_handle = handle;	res = (RESOURCE*) buf.pointer;	ec_cxt->data_port = res->data.io.min_base_address;	res = NEXT_RESOURCE(res);	ec_cxt->status_port = (int) res->data.io.min_base_address;	kfree(buf.pointer);	/* determine GPE bit */	/* BUG: in acpi 2.0 this could return a package */	buf.length = sizeof(obj);	buf.pointer = &obj;	if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_GPE", NULL, &buf))		|| obj.type != ACPI_TYPE_NUMBER)		return AE_OK;	ec_cxt->gpe_bit = obj.number.value;	/* determine if we need the Global Lock when accessing */	buf.length = sizeof(obj);	buf.pointer = &obj;	status = acpi_evaluate_object(handle, "_GLK", NULL, &buf);	if (status == AE_NOT_FOUND)		ec_cxt->need_global_lock = 0;	else if (!ACPI_SUCCESS(status) || obj.type != ACPI_TYPE_NUMBER) {		DEBUG_PRINT(ACPI_ERROR, ("_GLK failed\n"));		return AE_OK;	}	ec_cxt->need_global_lock = obj.number.value;	printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,gpe %d GL %d)\n",		ec_cxt->data_port, ec_cxt->status_port, ec_cxt->gpe_bit,		ec_cxt->need_global_lock);	if (!ACPI_SUCCESS(acpi_install_gpe_handler(		ec_cxt->gpe_bit,		ACPI_EVENT_EDGE_TRIGGERED,		ec_gpe_handler,		ec_cxt))) {				REPORT_ERROR(("Could not install GPE handler for EC.\n"));		return AE_OK;	}	status = acpi_install_address_space_handler (handle, ADDRESS_SPACE_EC, 		    ec_region_handler, ec_region_setup, ec_cxt);	if (!ACPI_SUCCESS(status)) {		REPORT_ERROR(("Could not install EC address "			"space handler, error %s\n", acpi_cm_format_exception (status)));	}		return AE_OK;}intacpi_ec_init(void){	acpi_get_devices(ACPI_EC_HID, 			found_ec,			NULL,			NULL);	return 0;}intacpi_ec_terminate(void){	/* TODO */		/* walk list of EC's */	/* free their context and release resources */	return 0;}

⌨️ 快捷键说明

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