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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? 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) {

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产99久久久精品| 国产精品一级片在线观看| 久久99久久久久| 欧美一区二区成人6969| 国产精品成人免费| 激情综合色播激情啊| 欧美一区二区三区系列电影| 一区二区三区成人在线视频| 91视频精品在这里| 欧美国产视频在线| 国产成人亚洲精品青草天美 | 欧美一级xxx| 亚洲自拍偷拍图区| 91婷婷韩国欧美一区二区| 国产三区在线成人av| 国产成a人亚洲| 久久久另类综合| 粉嫩一区二区三区在线看| 国产精品久99| 日本韩国一区二区三区| 亚洲妇女屁股眼交7| 3d动漫精品啪啪一区二区竹菊| 免费日本视频一区| 国产精品卡一卡二| 日韩一区二区在线观看视频| 不卡的av中国片| 日韩国产欧美在线观看| 欧美一级黄色大片| 成人app在线| 亚洲一区二区三区四区在线 | 2023国产精华国产精品| 国产成人高清在线| 亚洲综合免费观看高清完整版在线| 欧美日韩精品免费观看视频 | 伊人婷婷欧美激情| 日韩欧美中文字幕精品| 成人av网址在线| 午夜精品久久久久久久99水蜜桃| 欧美videofree性高清杂交| 成人国产精品免费| 成人福利电影精品一区二区在线观看 | 亚洲视频中文字幕| 欧美电影一区二区| 波多野结衣中文字幕一区| 日韩av不卡在线观看| 日韩伦理电影网| 26uuu国产电影一区二区| 欧美主播一区二区三区| 国产91综合网| 视频一区二区国产| 一区二区高清免费观看影视大全| 欧美大片在线观看一区二区| 在线看国产一区| 成人综合婷婷国产精品久久蜜臀 | 久久国产精品72免费观看| 亚洲蜜臀av乱码久久精品| 久久久亚洲高清| 欧美tickling挠脚心丨vk| 欧美美女黄视频| 欧美日韩五月天| 在线观看一区日韩| 99re成人精品视频| 99re视频精品| 麻豆传媒一区二区三区| 亚洲午夜在线电影| 国产精品福利av| 亚洲精品一区二区在线观看| 一本久久综合亚洲鲁鲁五月天| 国产激情91久久精品导航| 久久精品免费看| 视频在线在亚洲| 亚洲网友自拍偷拍| 午夜精品久久久久久久| 亚洲欧美日韩国产综合在线| 国产三级久久久| 日韩欧美中文一区二区| 在线影院国内精品| 成人激情视频网站| 国产激情91久久精品导航| 天天操天天综合网| 亚洲综合图片区| 一区二区三区加勒比av| 国产精品灌醉下药二区| 中国色在线观看另类| 精品国产成人系列| 国产婷婷色一区二区三区| 成人欧美一区二区三区小说 | 91网上在线视频| av成人动漫在线观看| www.欧美亚洲| 在线一区二区观看| 欧美一卡二卡在线观看| 欧美一区二区日韩一区二区| 欧美日韩免费在线视频| 欧美肥妇free| 精品卡一卡二卡三卡四在线| 中文字幕国产一区| 中文字幕人成不卡一区| 一区二区三区日韩欧美精品| 亚洲综合在线视频| 日av在线不卡| 国产v综合v亚洲欧| 欧美午夜精品一区二区三区| 日韩精品中午字幕| 久久精品免费在线观看| 亚洲欧洲日本在线| 亚洲成av人片一区二区三区 | www.av亚洲| 在线电影欧美成精品| 精品日韩在线一区| 中文字幕日韩精品一区| 亚洲综合无码一区二区| 青青草原综合久久大伊人精品| 国产成人啪午夜精品网站男同| 91精品在线观看入口| 中文字幕亚洲精品在线观看| 午夜一区二区三区在线观看| 激情综合一区二区三区| 日本丶国产丶欧美色综合| 国产日韩成人精品| 精品一区二区三区香蕉蜜桃| 91在线视频播放地址| 日韩欧美的一区二区| 亚洲国产va精品久久久不卡综合| 国内不卡的二区三区中文字幕| 在线这里只有精品| 亚洲视频在线观看三级| 日韩专区中文字幕一区二区| 丰满亚洲少妇av| 欧美男生操女生| 午夜影视日本亚洲欧洲精品| 一本色道久久综合精品竹菊| 国产精品色婷婷久久58| 久久激情五月婷婷| 欧美日韩成人一区二区| 亚洲三级在线看| 91亚洲大成网污www| 国产精品乱码一区二三区小蝌蚪| 国产福利91精品一区二区三区| 精品国产一二三| 国产精品一区久久久久| 中文字幕va一区二区三区| 91蜜桃网址入口| 亚洲自拍另类综合| 色综合中文字幕国产 | 欧美日韩国产首页在线观看| 亚洲一区二区三区在线播放| 91麻豆123| 一二三区精品视频| 欧美日韩国产影片| 天天影视色香欲综合网老头| 欧美福利视频导航| 国产成人精品三级麻豆| 国产午夜精品理论片a级大结局 | 亚洲伦在线观看| 91黄视频在线| 亚洲一区二区不卡免费| 日韩一级片在线播放| 国产91精品精华液一区二区三区 | 久久精品国产**网站演员| 久久精品这里都是精品| 顶级嫩模精品视频在线看| 樱花草国产18久久久久| 日韩欧美不卡一区| 成人午夜精品在线| 亚洲图片欧美色图| 精品精品国产高清一毛片一天堂| 97久久超碰国产精品| 裸体健美xxxx欧美裸体表演| 国产精品三级av| 欧美精品tushy高清| 国产精品99久久久久久久女警| 中文字幕亚洲成人| 精品久久久久久亚洲综合网| 91亚洲国产成人精品一区二区三 | av一区二区三区四区| 日韩国产欧美在线播放| 一区二区在线观看免费视频播放| 欧美成人在线直播| 色婷婷综合久色| 国产1区2区3区精品美女| 奇米精品一区二区三区在线观看 | 亚洲gay无套男同| 国产精品久久三区| 欧美一区二区在线免费观看| 91视频一区二区| 高潮精品一区videoshd| 国产成人av资源| 久久精品久久99精品久久| 亚洲成人综合网站| 亚洲一区二区在线视频| 中文字幕欧美三区| 国产婷婷色一区二区三区| 在线观看91精品国产麻豆| 欧美日韩亚洲综合在线| 不卡电影一区二区三区| 色综合久久久久网| jizz一区二区| 在线免费视频一区二区| 色狠狠一区二区|