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

📄 core.c

📁 h内核
💻 C
字号:
/* * pnpacpi -- PnP ACPI driver * * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> *  * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */ #include <linux/acpi.h>#include <linux/pnp.h>#include <acpi/acpi_bus.h>#include "pnpacpi.h"static int num = 0;static char __initdata excluded_id_list[] =	"PNP0C0A," /* Battery */	"PNP0C0C,PNP0C0E,PNP0C0D," /* Button */	"PNP0C09," /* EC */	"PNP0C0B," /* Fan */	"PNP0A03," /* PCI root */	"PNP0C0F," /* Link device */	"PNP0000," /* PIC */	"PNP0100," /* Timer */	;static inline int is_exclusive_device(struct acpi_device *dev){	return (!acpi_match_ids(dev, excluded_id_list));}void *pnpacpi_kmalloc(size_t size, int f){	void *p = kmalloc(size, f);	if (p)		memset(p, 0, size);	return p;}/* * Compatible Device IDs */#define TEST_HEX(c) \	if (!(('0' <= (c) && (c) <= '9') || ('A' <= (c) && (c) <= 'F'))) \		return 0#define TEST_ALPHA(c) \	if (!('@' <= (c) || (c) <= 'Z')) \		return 0static int __init ispnpidacpi(char *id){	TEST_ALPHA(id[0]);	TEST_ALPHA(id[1]);	TEST_ALPHA(id[2]);	TEST_HEX(id[3]);	TEST_HEX(id[4]);	TEST_HEX(id[5]);	TEST_HEX(id[6]);	if (id[7] != '\0')		return 0;	return 1;}static void __init pnpidacpi_to_pnpid(char *id, char *str){	str[0] = id[0];	str[1] = id[1];	str[2] = id[2];	str[3] = tolower(id[3]);	str[4] = tolower(id[4]);	str[5] = tolower(id[5]);	str[6] = tolower(id[6]);	str[7] = '\0';}static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res){	acpi_status status;	status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data, 		&dev->res);	return ACPI_FAILURE(status) ? -ENODEV : 0;}static int pnpacpi_set_resources(struct pnp_dev * dev, struct pnp_resource_table * res){	acpi_handle handle = dev->data;	struct acpi_buffer buffer;	int ret = 0;	acpi_status status;	ret = pnpacpi_build_resource_template(handle, &buffer);	if (ret)		return ret;	ret = pnpacpi_encode_resources(res, &buffer);	if (ret) {		kfree(buffer.pointer);		return ret;	}	status = acpi_set_current_resources(handle, &buffer);	if (ACPI_FAILURE(status))		ret = -EINVAL;	kfree(buffer.pointer);	return ret;}static int pnpacpi_disable_resources(struct pnp_dev *dev){	acpi_status status;		/* acpi_unregister_gsi(pnp_irq(dev, 0)); */	status = acpi_evaluate_object((acpi_handle)dev->data, 		"_DIS", NULL, NULL);	return ACPI_FAILURE(status) ? -ENODEV : 0;}struct pnp_protocol pnpacpi_protocol = {	.name	= "Plug and Play ACPI",	.get	= pnpacpi_get_resources,	.set	= pnpacpi_set_resources,	.disable = pnpacpi_disable_resources,};static int __init pnpacpi_add_device(struct acpi_device *device){	acpi_handle temp = NULL;	acpi_status status;	struct pnp_id *dev_id;	struct pnp_dev *dev;	if (!ispnpidacpi(acpi_device_hid(device)) ||		is_exclusive_device(device))		return 0;	pnp_dbg("ACPI device : hid %s", acpi_device_hid(device));	dev =  pnpacpi_kmalloc(sizeof(struct pnp_dev), GFP_KERNEL);	if (!dev) {		pnp_err("Out of memory");		return -ENOMEM;	}	dev->data = device->handle;	/* .enabled means if the device can decode the resources */	dev->active = device->status.enabled;	status = acpi_get_handle(device->handle, "_SRS", &temp);	if (ACPI_SUCCESS(status))		dev->capabilities |= PNP_CONFIGURABLE;	dev->capabilities |= PNP_READ;	if (device->flags.dynamic_status)		dev->capabilities |= PNP_WRITE;	if (device->flags.removable)		dev->capabilities |= PNP_REMOVABLE;	status = acpi_get_handle(device->handle, "_DIS", &temp);	if (ACPI_SUCCESS(status))		dev->capabilities |= PNP_DISABLE;	dev->protocol = &pnpacpi_protocol;	if (strlen(acpi_device_name(device)))		strncpy(dev->name, acpi_device_name(device), sizeof(dev->name));	else		strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));	dev->number = num;		/* set the initial values for the PnP device */	dev_id = pnpacpi_kmalloc(sizeof(struct pnp_id), GFP_KERNEL);	if (!dev_id)		goto err;	pnpidacpi_to_pnpid(acpi_device_hid(device), dev_id->id);	pnp_add_id(dev_id, dev);	if(dev->active) {		/* parse allocated resource */		status = pnpacpi_parse_allocated_resource(device->handle, &dev->res);		if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {			pnp_err("PnPACPI: METHOD_NAME__CRS failure for %s", dev_id->id);			goto err1;		}	}	if(dev->capabilities & PNP_CONFIGURABLE) {		status = pnpacpi_parse_resource_option_data(device->handle, 			dev);		if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {			pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id);			goto err1;		}	}		/* parse compatible ids */	if (device->flags.compatible_ids) {		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;		int i;		for (i = 0; i < cid_list->count; i++) {			if (!ispnpidacpi(cid_list->id[i].value))				continue;			dev_id = pnpacpi_kmalloc(sizeof(struct pnp_id), 				GFP_KERNEL);			if (!dev_id)				continue;			pnpidacpi_to_pnpid(cid_list->id[i].value, dev_id->id);			pnp_add_id(dev_id, dev);		}	}	/* clear out the damaged flags */	if (!dev->active)		pnp_init_resource_table(&dev->res);	pnp_add_device(dev);	num ++;	return AE_OK;err1:	kfree(dev_id);err:	kfree(dev);	return -EINVAL;}static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,	u32 lvl, void *context, void **rv){	struct acpi_device *device;	if (!acpi_bus_get_device(handle, &device))		pnpacpi_add_device(device);	else		return AE_CTRL_DEPTH;	return AE_OK;}int pnpacpi_disabled __initdata;int __init pnpacpi_init(void){	if (acpi_disabled || pnpacpi_disabled) {		pnp_info("PnP ACPI: disabled");		return 0;	}	pnp_info("PnP ACPI init");	pnp_register_protocol(&pnpacpi_protocol);	acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);	pnp_info("PnP ACPI: found %d devices", num);	return 0;}subsys_initcall(pnpacpi_init);static int __init pnpacpi_setup(char *str){	if (str == NULL)		return 1;	if (!strncmp(str, "off", 3))		pnpacpi_disabled = 1;	return 1;}__setup("pnpacpi=", pnpacpi_setup);EXPORT_SYMBOL(pnpacpi_protocol);

⌨️ 快捷键说明

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