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

📄 psmouse-base.c

📁 qq2440板子上
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (proto && (proto->detect || proto->init)) {		if (proto->detect && proto->detect(psmouse, 1) < 0)			return -1;		if (proto->init && proto->init(psmouse) < 0)			return -1;		psmouse->type = proto->type;	}	else		psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);	sprintf(psmouse->devname, "%s %s %s",		psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);	psmouse->dev.name = psmouse->devname;	psmouse->dev.phys = psmouse->phys;	psmouse->dev.id.bustype = BUS_I8042;	psmouse->dev.id.vendor = 0x0002;	psmouse->dev.id.product = psmouse->type;	psmouse->dev.id.version = psmouse->model;	return 0;}/* * psmouse_connect() is a callback from the serio module when * an unhandled serio port is found. */static int psmouse_connect(struct serio *serio, struct serio_driver *drv){	struct psmouse *psmouse, *parent = NULL;	int retval;	down(&psmouse_sem);	/*	 * If this is a pass-through port deactivate parent so the device	 * connected to this port can be successfully identified	 */	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {		parent = serio_get_drvdata(serio->parent);		psmouse_deactivate(parent);	}	if (!(psmouse = kcalloc(1, sizeof(struct psmouse), GFP_KERNEL))) {		retval = -ENOMEM;		goto out;	}	ps2_init(&psmouse->ps2dev, serio);	sprintf(psmouse->phys, "%s/input0", serio->phys);	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);	serio_set_drvdata(serio, psmouse);	retval = serio_open(serio, drv);	if (retval) {		serio_set_drvdata(serio, NULL);		kfree(psmouse);		goto out;	}	if (psmouse_probe(psmouse) < 0) {		serio_close(serio);		serio_set_drvdata(serio, NULL);		kfree(psmouse);		retval = -ENODEV;		goto out;	}	psmouse->rate = psmouse_rate;	psmouse->resolution = psmouse_resolution;	psmouse->resetafter = psmouse_resetafter;	psmouse->smartscroll = psmouse_smartscroll;	psmouse_switch_protocol(psmouse, NULL);	input_register_device(&psmouse->dev);	printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);	psmouse_initialize(psmouse);	if (parent && parent->pt_activate)		parent->pt_activate(parent);	device_create_file(&serio->dev, &psmouse_attr_protocol);	device_create_file(&serio->dev, &psmouse_attr_rate);	device_create_file(&serio->dev, &psmouse_attr_resolution);	device_create_file(&serio->dev, &psmouse_attr_resetafter);	psmouse_activate(psmouse);	retval = 0;out:	/* If this is a pass-through port the parent needs to be re-activated */	if (parent)		psmouse_activate(parent);	up(&psmouse_sem);	return retval;}static int psmouse_reconnect(struct serio *serio){	struct psmouse *psmouse = serio_get_drvdata(serio);	struct psmouse *parent = NULL;	struct serio_driver *drv = serio->drv;	int rc = -1;	if (!drv || !psmouse) {		printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");		return -1;	}	down(&psmouse_sem);	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {		parent = serio_get_drvdata(serio->parent);		psmouse_deactivate(parent);	}	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);	if (psmouse->reconnect) {		if (psmouse->reconnect(psmouse))			goto out;	} else if (psmouse_probe(psmouse) < 0 ||		   psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))		goto out;	/* ok, the device type (and capabilities) match the old one,	 * we can continue using it, complete intialization	 */	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);	psmouse_initialize(psmouse);	if (parent && parent->pt_activate)		parent->pt_activate(parent);	psmouse_activate(psmouse);	rc = 0;out:	/* If this is a pass-through port the parent waits to be activated */	if (parent)		psmouse_activate(parent);	up(&psmouse_sem);	return rc;}static struct serio_device_id psmouse_serio_ids[] = {	{		.type	= SERIO_8042,		.proto	= SERIO_ANY,		.id	= SERIO_ANY,		.extra	= SERIO_ANY,	},	{		.type	= SERIO_PS_PSTHRU,		.proto	= SERIO_ANY,		.id	= SERIO_ANY,		.extra	= SERIO_ANY,	},	{ 0 }};MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);static struct serio_driver psmouse_drv = {	.driver		= {		.name	= "psmouse",	},	.description	= DRIVER_DESC,	.id_table	= psmouse_serio_ids,	.interrupt	= psmouse_interrupt,	.connect	= psmouse_connect,	.reconnect	= psmouse_reconnect,	.disconnect	= psmouse_disconnect,	.cleanup	= psmouse_cleanup,};ssize_t psmouse_attr_show_helper(struct device *dev, char *buf,				 ssize_t (*handler)(struct psmouse *, char *)){	struct serio *serio = to_serio_port(dev);	int retval;	retval = serio_pin_driver(serio);	if (retval)		return retval;	if (serio->drv != &psmouse_drv) {		retval = -ENODEV;		goto out;	}	retval = handler(serio_get_drvdata(serio), buf);out:	serio_unpin_driver(serio);	return retval;}ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t count,				ssize_t (*handler)(struct psmouse *, const char *, size_t)){	struct serio *serio = to_serio_port(dev);	struct psmouse *psmouse = serio_get_drvdata(serio);	struct psmouse *parent = NULL;	int retval;	retval = serio_pin_driver(serio);	if (retval)		return retval;	if (serio->drv != &psmouse_drv) {		retval = -ENODEV;		goto out_unpin;	}	retval = down_interruptible(&psmouse_sem);	if (retval)		goto out_unpin;	if (psmouse->state == PSMOUSE_IGNORE) {		retval = -ENODEV;		goto out_up;	}	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {		parent = serio_get_drvdata(serio->parent);		psmouse_deactivate(parent);	}	psmouse_deactivate(psmouse);	retval = handler(psmouse, buf, count);	if (retval != -ENODEV)		psmouse_activate(psmouse);	if (parent)		psmouse_activate(parent); out_up:	up(&psmouse_sem); out_unpin:	serio_unpin_driver(serio);	return retval;}static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, char *buf){	return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name);}static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *buf, size_t count){	struct serio *serio = psmouse->ps2dev.serio;	struct psmouse *parent = NULL;	struct psmouse_protocol *proto;	int retry = 0;	if (!(proto = psmouse_protocol_by_name(buf, count)))		return -EINVAL;	if (psmouse->type == proto->type)		return count;	while (serio->child) {		if (++retry > 3) {			printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n");			return -EIO;		}		up(&psmouse_sem);		serio_unpin_driver(serio);		serio_unregister_child_port(serio);		serio_pin_driver_uninterruptible(serio);		down(&psmouse_sem);		if (serio->drv != &psmouse_drv)			return -ENODEV;		if (psmouse->type == proto->type)			return count; /* switched by other thread */	}	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {		parent = serio_get_drvdata(serio->parent);		if (parent->pt_deactivate)			parent->pt_deactivate(parent);	}	if (psmouse->disconnect)		psmouse->disconnect(psmouse);	psmouse_set_state(psmouse, PSMOUSE_IGNORE);	input_unregister_device(&psmouse->dev);	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);	if (psmouse_switch_protocol(psmouse, proto) < 0) {		psmouse_reset(psmouse);		/* default to PSMOUSE_PS2 */		psmouse_switch_protocol(psmouse, &psmouse_protocols[0]);	}	psmouse_initialize(psmouse);	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);	input_register_device(&psmouse->dev);	printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);	if (parent && parent->pt_activate)		parent->pt_activate(parent);	return count;}static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf){	return sprintf(buf, "%d\n", psmouse->rate);}static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, const char *buf, size_t count){	unsigned long value;	char *rest;	value = simple_strtoul(buf, &rest, 10);	if (*rest)		return -EINVAL;	psmouse->set_rate(psmouse, value);	return count;}static ssize_t psmouse_attr_show_resolution(struct psmouse *psmouse, char *buf){	return sprintf(buf, "%d\n", psmouse->resolution);}static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, const char *buf, size_t count){	unsigned long value;	char *rest;	value = simple_strtoul(buf, &rest, 10);	if (*rest)		return -EINVAL;	psmouse->set_resolution(psmouse, value);	return count;}static ssize_t psmouse_attr_show_resetafter(struct psmouse *psmouse, char *buf){	return sprintf(buf, "%d\n", psmouse->resetafter);}static ssize_t psmouse_attr_set_resetafter(struct psmouse *psmouse, const char *buf, size_t count){	unsigned long value;	char *rest;	value = simple_strtoul(buf, &rest, 10);	if (*rest)		return -EINVAL;	psmouse->resetafter = value;	return count;}static int psmouse_set_maxproto(const char *val, struct kernel_param *kp){	struct psmouse_protocol *proto;	if (!val)		return -EINVAL;	proto = psmouse_protocol_by_name(val, strlen(val));	if (!proto || !proto->maxproto)		return -EINVAL;	*((unsigned int *)kp->arg) = proto->type;	return 0;					\}static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp){	int type = *((unsigned int *)kp->arg);	return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name);}static int __init psmouse_init(void){	serio_register_driver(&psmouse_drv);	return 0;}static void __exit psmouse_exit(void){	serio_unregister_driver(&psmouse_drv);}module_init(psmouse_init);module_exit(psmouse_exit);

⌨️ 快捷键说明

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