亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? serio.c

?? QQ2440板子
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* *  The Serio abstraction module * *  Copyright (c) 1999-2004 Vojtech Pavlik *  Copyright (c) 2004 Dmitry Torokhov *  Copyright (c) 2003 Daniele Bellucci *//* * 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 of the License, 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 * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */#include <linux/stddef.h>#include <linux/module.h>#include <linux/serio.h>#include <linux/errno.h>#include <linux/wait.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/kthread.h>MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");MODULE_DESCRIPTION("Serio abstraction core");MODULE_LICENSE("GPL");EXPORT_SYMBOL(serio_interrupt);EXPORT_SYMBOL(__serio_register_port);EXPORT_SYMBOL(serio_unregister_port);EXPORT_SYMBOL(serio_unregister_child_port);EXPORT_SYMBOL(__serio_unregister_port_delayed);EXPORT_SYMBOL(__serio_register_driver);EXPORT_SYMBOL(serio_unregister_driver);EXPORT_SYMBOL(serio_open);EXPORT_SYMBOL(serio_close);EXPORT_SYMBOL(serio_rescan);EXPORT_SYMBOL(serio_reconnect);/* * serio_sem protects entire serio subsystem and is taken every time * serio port or driver registrered or unregistered. */static DECLARE_MUTEX(serio_sem);static LIST_HEAD(serio_list);static struct bus_type serio_bus = {	.name =	"serio",};static void serio_add_port(struct serio *serio);static void serio_destroy_port(struct serio *serio);static void serio_reconnect_port(struct serio *serio);static void serio_disconnect_port(struct serio *serio);static int serio_connect_driver(struct serio *serio, struct serio_driver *drv){	int retval;	down(&serio->drv_sem);	retval = drv->connect(serio, drv);	up(&serio->drv_sem);	return retval;}static int serio_reconnect_driver(struct serio *serio){	int retval = -1;	down(&serio->drv_sem);	if (serio->drv && serio->drv->reconnect)		retval = serio->drv->reconnect(serio);	up(&serio->drv_sem);	return retval;}static void serio_disconnect_driver(struct serio *serio){	down(&serio->drv_sem);	if (serio->drv)		serio->drv->disconnect(serio);	up(&serio->drv_sem);}static int serio_match_port(const struct serio_device_id *ids, struct serio *serio){	while (ids->type || ids->proto) {		if ((ids->type == SERIO_ANY || ids->type == serio->id.type) &&		    (ids->proto == SERIO_ANY || ids->proto == serio->id.proto) &&		    (ids->extra == SERIO_ANY || ids->extra == serio->id.extra) &&		    (ids->id == SERIO_ANY || ids->id == serio->id.id))			return 1;		ids++;	}	return 0;}/* * Basic serio -> driver core mappings */static void serio_bind_driver(struct serio *serio, struct serio_driver *drv){	down_write(&serio_bus.subsys.rwsem);	if (serio_match_port(drv->id_table, serio)) {		serio->dev.driver = &drv->driver;		if (serio_connect_driver(serio, drv)) {			serio->dev.driver = NULL;			goto out;		}		device_bind_driver(&serio->dev);	}out:	up_write(&serio_bus.subsys.rwsem);}static void serio_release_driver(struct serio *serio){	down_write(&serio_bus.subsys.rwsem);	device_release_driver(&serio->dev);	up_write(&serio_bus.subsys.rwsem);}static void serio_find_driver(struct serio *serio){	down_write(&serio_bus.subsys.rwsem);	device_attach(&serio->dev);	up_write(&serio_bus.subsys.rwsem);}/* * Serio event processing. */enum serio_event_type {	SERIO_RESCAN,	SERIO_RECONNECT,	SERIO_REGISTER_PORT,	SERIO_UNREGISTER_PORT,	SERIO_REGISTER_DRIVER,};struct serio_event {	enum serio_event_type type;	void *object;	struct module *owner;	struct list_head node;};static DEFINE_SPINLOCK(serio_event_lock);	/* protects serio_event_list */static LIST_HEAD(serio_event_list);static DECLARE_WAIT_QUEUE_HEAD(serio_wait);static struct task_struct *serio_task;static void serio_queue_event(void *object, struct module *owner,			      enum serio_event_type event_type){	unsigned long flags;	struct serio_event *event;	spin_lock_irqsave(&serio_event_lock, flags);	/*	 * Scan event list for the other events for the same serio port,	 * starting with the most recent one. If event is the same we	 * do not need add new one. If event is of different type we	 * need to add this event and should not look further because	 * we need to preseve sequence of distinct events.	 */	list_for_each_entry_reverse(event, &serio_event_list, node) {		if (event->object == object) {			if (event->type == event_type)				goto out;			break;		}	}	if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {		if (!try_module_get(owner)) {			printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type);			goto out;		}		event->type = event_type;		event->object = object;		event->owner = owner;		list_add_tail(&event->node, &serio_event_list);		wake_up(&serio_wait);	} else {		printk(KERN_ERR "serio: Not enough memory to queue event %d\n", event_type);	}out:	spin_unlock_irqrestore(&serio_event_lock, flags);}static void serio_free_event(struct serio_event *event){	module_put(event->owner);	kfree(event);}static void serio_remove_duplicate_events(struct serio_event *event){	struct list_head *node, *next;	struct serio_event *e;	unsigned long flags;	spin_lock_irqsave(&serio_event_lock, flags);	list_for_each_safe(node, next, &serio_event_list) {		e = list_entry(node, struct serio_event, node);		if (event->object == e->object) {			/*			 * If this event is of different type we should not			 * look further - we only suppress duplicate events			 * that were sent back-to-back.			 */			if (event->type != e->type)				break;			list_del_init(node);			serio_free_event(e);		}	}	spin_unlock_irqrestore(&serio_event_lock, flags);}static struct serio_event *serio_get_event(void){	struct serio_event *event;	struct list_head *node;	unsigned long flags;	spin_lock_irqsave(&serio_event_lock, flags);	if (list_empty(&serio_event_list)) {		spin_unlock_irqrestore(&serio_event_lock, flags);		return NULL;	}	node = serio_event_list.next;	event = list_entry(node, struct serio_event, node);	list_del_init(node);	spin_unlock_irqrestore(&serio_event_lock, flags);	return event;}static void serio_handle_events(void){	struct serio_event *event;	struct serio_driver *serio_drv;	down(&serio_sem);	while ((event = serio_get_event())) {		switch (event->type) {			case SERIO_REGISTER_PORT:				serio_add_port(event->object);				break;			case SERIO_UNREGISTER_PORT:				serio_disconnect_port(event->object);				serio_destroy_port(event->object);				break;			case SERIO_RECONNECT:				serio_reconnect_port(event->object);				break;			case SERIO_RESCAN:				serio_disconnect_port(event->object);				serio_find_driver(event->object);				break;			case SERIO_REGISTER_DRIVER:				serio_drv = event->object;				driver_register(&serio_drv->driver);				break;			default:				break;		}		serio_remove_duplicate_events(event);		serio_free_event(event);	}	up(&serio_sem);}/* * Remove all events that have been submitted for a given serio port. */static void serio_remove_pending_events(struct serio *serio){	struct list_head *node, *next;	struct serio_event *event;	unsigned long flags;	spin_lock_irqsave(&serio_event_lock, flags);	list_for_each_safe(node, next, &serio_event_list) {		event = list_entry(node, struct serio_event, node);		if (event->object == serio) {			list_del_init(node);			serio_free_event(event);		}	}	spin_unlock_irqrestore(&serio_event_lock, flags);}/* * Destroy child serio port (if any) that has not been fully registered yet. * * Note that we rely on the fact that port can have only one child and therefore * only one child registration request can be pending. Additionally, children * are registered by driver's connect() handler so there can't be a grandchild * pending registration together with a child. */static struct serio *serio_get_pending_child(struct serio *parent){	struct serio_event *event;	struct serio *serio, *child = NULL;	unsigned long flags;	spin_lock_irqsave(&serio_event_lock, flags);	list_for_each_entry(event, &serio_event_list, node) {		if (event->type == SERIO_REGISTER_PORT) {			serio = event->object;			if (serio->parent == parent) {				child = serio;				break;			}		}	}	spin_unlock_irqrestore(&serio_event_lock, flags);	return child;}static int serio_thread(void *nothing){	do {		serio_handle_events();		wait_event_interruptible(serio_wait,			kthread_should_stop() || !list_empty(&serio_event_list));		try_to_freeze();	} while (!kthread_should_stop());	printk(KERN_DEBUG "serio: kseriod exiting\n");	return 0;}/* * Serio port operations */static ssize_t serio_show_description(struct device *dev, struct device_attribute *attr, char *buf){	struct serio *serio = to_serio_port(dev);	return sprintf(buf, "%s\n", serio->name);}static ssize_t serio_show_modalias(struct device *dev, struct device_attribute *attr, char *buf){	struct serio *serio = to_serio_port(dev);	return sprintf(buf, "serio:ty%02Xpr%02Xid%02Xex%02X\n",			serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);}static ssize_t serio_show_id_type(struct device *dev, struct device_attribute *attr, char *buf){	struct serio *serio = to_serio_port(dev);	return sprintf(buf, "%02x\n", serio->id.type);}static ssize_t serio_show_id_proto(struct device *dev, struct device_attribute *attr, char *buf){	struct serio *serio = to_serio_port(dev);	return sprintf(buf, "%02x\n", serio->id.proto);}static ssize_t serio_show_id_id(struct device *dev, struct device_attribute *attr, char *buf){	struct serio *serio = to_serio_port(dev);	return sprintf(buf, "%02x\n", serio->id.id);}static ssize_t serio_show_id_extra(struct device *dev, struct device_attribute *attr, char *buf){	struct serio *serio = to_serio_port(dev);	return sprintf(buf, "%02x\n", serio->id.extra);}static DEVICE_ATTR(type, S_IRUGO, serio_show_id_type, NULL);static DEVICE_ATTR(proto, S_IRUGO, serio_show_id_proto, NULL);static DEVICE_ATTR(id, S_IRUGO, serio_show_id_id, NULL);static DEVICE_ATTR(extra, S_IRUGO, serio_show_id_extra, NULL);static struct attribute *serio_device_id_attrs[] = {	&dev_attr_type.attr,	&dev_attr_proto.attr,	&dev_attr_id.attr,	&dev_attr_extra.attr,	NULL};static struct attribute_group serio_id_attr_group = {	.name	= "id",	.attrs	= serio_device_id_attrs,};static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){	struct serio *serio = to_serio_port(dev);	struct device_driver *drv;	int retval;	retval = down_interruptible(&serio_sem);	if (retval)		return retval;	retval = count;	if (!strncmp(buf, "none", count)) {		serio_disconnect_port(serio);	} else if (!strncmp(buf, "reconnect", count)) {		serio_reconnect_port(serio);	} else if (!strncmp(buf, "rescan", count)) {		serio_disconnect_port(serio);		serio_find_driver(serio);	} else if ((drv = driver_find(buf, &serio_bus)) != NULL) {

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品美日韩| 国产欧美一区二区精品秋霞影院| 亚洲女与黑人做爰| 91一区二区三区在线播放| 国产精品久久久一本精品| 91在线观看美女| 亚洲一二三四区| 欧美一区二区日韩一区二区| 国产呦精品一区二区三区网站| 久久久久久久久久美女| 播五月开心婷婷综合| 亚洲永久精品国产| 欧美xxxx老人做受| 成人激情视频网站| 亚洲成av人综合在线观看| 日韩免费福利电影在线观看| 成人国产精品视频| 亚洲一级二级在线| 精品国产露脸精彩对白 | 国产欧美日韩另类一区| av一二三不卡影片| 五月天精品一区二区三区| 精品国产伦一区二区三区观看体验 | 日韩综合小视频| 精品久久久三级丝袜| 91在线你懂得| 美女久久久精品| 亚洲日本在线观看| 日韩一级高清毛片| 北条麻妃国产九九精品视频| 午夜精品国产更新| 国产日韩v精品一区二区| 精品婷婷伊人一区三区三| 国产一区 二区| 亚洲成人资源网| 欧美国产乱子伦 | 亚洲精品国产无套在线观| 欧美一区二区成人6969| 99热精品国产| 国产美女精品一区二区三区| 午夜精品视频一区| 亚洲人成网站色在线观看| 精品久久一区二区三区| 欧美性极品少妇| av一区二区久久| 国产一区二区在线影院| 午夜成人免费视频| 亚洲精品第1页| 国产精品毛片久久久久久| 欧美日韩情趣电影| 国产精品美女久久久久久久久久久 | 国产精品欧美久久久久一区二区| 欧美日韩一区二区欧美激情| 懂色一区二区三区免费观看| 蜜臀久久99精品久久久久久9| 亚洲欧美日韩一区二区| 欧美精品一区二区三区蜜桃 | 国模娜娜一区二区三区| 亚洲va欧美va人人爽午夜| 中文字幕五月欧美| 国产人成一区二区三区影院| 欧美一区二区在线不卡| 欧美日韩在线综合| 日本高清不卡在线观看| www.日韩大片| 99视频一区二区| av电影天堂一区二区在线观看| 久久激情五月激情| 日本三级亚洲精品| 天天av天天翘天天综合网| 亚洲一区在线视频| 中文字幕综合网| 亚洲免费资源在线播放| 亚洲欧洲精品一区二区三区不卡| 国产精品免费网站在线观看| 国产欧美一区视频| 国产视频一区不卡| 中文字幕第一区第二区| 中文字幕av一区 二区| 国产视频一区二区在线观看| 国产午夜亚洲精品理论片色戒| 久久久www免费人成精品| 久久综合久久综合九色| 久久久久97国产精华液好用吗| 久久久久久一级片| 国产精品久久影院| 亚洲精品乱码久久久久久黑人 | 一区二区三区日韩精品视频| 亚洲免费av高清| 亚洲国产视频直播| 首页欧美精品中文字幕| 久久超碰97人人做人人爱| 国产一区二区0| youjizz久久| 色噜噜狠狠一区二区三区果冻| 欧洲一区在线电影| 欧美一区二区在线免费观看| 久久精品人人爽人人爽| 综合自拍亚洲综合图不卡区| 亚洲综合一二区| 日本三级亚洲精品| 国产成人亚洲综合色影视| 99精品久久99久久久久| 欧美精选午夜久久久乱码6080| 日韩免费看网站| 国产精品白丝在线| 视频在线在亚洲| 国产最新精品精品你懂的| 福利电影一区二区三区| 在线观看免费亚洲| 欧美一区二区三区日韩视频| 亚洲精品一区二区精华| 亚洲精品中文字幕在线观看| 免费看欧美美女黄的网站| 国产999精品久久久久久绿帽| 色婷婷精品久久二区二区蜜臂av| 欧美在线观看一二区| 欧美哺乳videos| 亚洲欧美视频在线观看| 免费成人av在线播放| av在线播放成人| 欧美一区二区三区日韩| 欧美国产激情二区三区| 天天操天天干天天综合网| 福利一区在线观看| 欧美一区二区三区在线看| 国产亚洲精品7777| 亚洲成a人v欧美综合天堂| 国产精品1024久久| 欧美日韩mp4| 亚洲人吸女人奶水| 久久精品99久久久| 在线视频综合导航| 久久精品夜色噜噜亚洲a∨| 午夜欧美一区二区三区在线播放| 国产成人啪午夜精品网站男同| 在线免费观看日韩欧美| 国产日韩三级在线| 日本在线观看不卡视频| 欧美亚洲综合一区| 国产午夜精品久久久久久久| 丝袜美腿亚洲一区| 日本道免费精品一区二区三区| 国产欧美日韩三级| 视频一区二区不卡| 91麻豆福利精品推荐| 中文字幕不卡一区| 精品一区二区三区视频在线观看 | 蜜桃一区二区三区在线观看| 欧美视频在线不卡| 国产精品美女www爽爽爽| 国产福利91精品一区二区三区| 777午夜精品免费视频| 夜夜嗨av一区二区三区四季av| 成人一区二区三区视频| 亚洲精品一线二线三线| 蜜桃视频第一区免费观看| 欧美美女一区二区在线观看| 一区二区三区四区视频精品免费| 成人免费毛片aaaaa**| 久久综合九色综合欧美就去吻 | 成人av电影在线播放| 国产午夜精品久久久久久久 | 粉嫩aⅴ一区二区三区四区五区| 亚洲精品国产第一综合99久久| 99久久伊人久久99| 日韩美女视频19| 91麻豆免费视频| 亚洲欧美视频一区| 一本一道综合狠狠老| 亚洲靠逼com| 欧美性猛片aaaaaaa做受| 亚洲伊人伊色伊影伊综合网| 在线观看av一区| 日韩专区中文字幕一区二区| 91精品国产入口在线| 久久国产精品99久久久久久老狼| 欧美大片在线观看| 国产精品一二三在| 国产精品色一区二区三区| 99精品视频一区二区| 一个色妞综合视频在线观看| 欧美一区二区性放荡片| 美女诱惑一区二区| 26uuu亚洲婷婷狠狠天堂| 丰满岳乱妇一区二区三区| 国产精品国产馆在线真实露脸| 一本一道综合狠狠老| 亚洲国产va精品久久久不卡综合| 欧美一区二区福利在线| 国产成人精品亚洲777人妖| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆| 一本久道久久综合中文字幕 | 麻豆成人久久精品二区三区红 | 亚洲一区二区三区四区的 | 欧美午夜一区二区| 老司机免费视频一区二区| 国产欧美日韩视频一区二区| 91久久精品一区二区二区| 免费看欧美女人艹b|