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

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

?? hid-core.c

?? 是關(guān)于linux2.5.1的完全源碼
?? C
?? 第 1 頁(yè) / 共 3 頁(yè)
字號(hào):
/* * $Id: hid-core.c,v 1.42 2002/01/27 00:22:46 vojtech Exp $ * *  Copyright (c) 1999 Andreas Gal *  Copyright (c) 2000-2001 Vojtech Pavlik * *  USB HID support for Linux *//* * 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/module.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/list.h>#include <linux/mm.h>#include <linux/smp_lock.h>#include <linux/spinlock.h>#include <asm/unaligned.h>#include <asm/byteorder.h>#include <linux/input.h>#undef DEBUG#undef DEBUG_DATA#include <linux/usb.h>#include "hid.h"#include <linux/hiddev.h>/* * Version Information */#define DRIVER_VERSION "v1.31"#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik <vojtech@ucw.cz>"#define DRIVER_DESC "USB HID core driver"#define DRIVER_LICENSE "GPL"static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",				"Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};/* * Register a new report for a device. */static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id){	struct hid_report_enum *report_enum = device->report_enum + type;	struct hid_report *report;	if (report_enum->report_id_hash[id])		return report_enum->report_id_hash[id];	if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL)))		return NULL;	memset(report, 0, sizeof(struct hid_report));	if (id != 0) report_enum->numbered = 1;	report->id = id;	report->type = type;	report->size = 0;	report->device = device;	report_enum->report_id_hash[id] = report;	list_add_tail(&report->list, &report_enum->report_list);	return report;}/* * Register a new field for this report. */static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values){	struct hid_field *field;	if (report->maxfield == HID_MAX_FIELDS) {		dbg("too many fields in report");		return NULL;	}	if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage)		+ values * sizeof(unsigned), GFP_KERNEL))) return NULL;	memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage)		+ values * sizeof(unsigned));	report->field[report->maxfield] = field;	field->usage = (struct hid_usage *)(field + 1);	field->value = (unsigned *)(field->usage + usages);	field->report = report;	field->index = report->maxfield++;	return field;}/* * Open a collection. The type/usage is pushed on the stack. */static int open_collection(struct hid_parser *parser, unsigned type){	struct hid_collection *collection;	unsigned usage;	usage = parser->local.usage[0];	if (type == HID_COLLECTION_APPLICATION		&& parser->device->maxapplication < HID_MAX_APPLICATIONS)			parser->device->application[parser->device->maxapplication++] = usage;	if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {		dbg("collection stack overflow");		return -1;	}	collection = parser->collection_stack + parser->collection_stack_ptr++;	collection->type = type;	collection->usage = usage;	return 0;}/* * Close a collection. */static int close_collection(struct hid_parser *parser){	if (!parser->collection_stack_ptr) {		dbg("collection stack underflow");		return -1;	}	parser->collection_stack_ptr--;	return 0;}/* * Climb up the stack, search for the specified collection type * and return the usage. */static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type){	int n;	for (n = parser->collection_stack_ptr - 1; n >= 0; n--)		if (parser->collection_stack[n].type == type)			return parser->collection_stack[n].usage;	return 0; /* we know nothing about this usage type */}/* * Add a usage to the temporary parser table. */static int hid_add_usage(struct hid_parser *parser, unsigned usage){	if (parser->local.usage_index >= HID_MAX_USAGES) {		dbg("usage index exceeded");		return -1;	}	parser->local.usage[parser->local.usage_index++] = usage;	return 0;}/* * Register a new field for this report. */static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags){	struct hid_report *report;	struct hid_field *field;	int usages;	unsigned offset;	int i;	if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {		dbg("hid_register_report failed");		return -1;	}	if (parser->global.logical_maximum <= parser->global.logical_minimum) {		dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);		return -1;	}	usages = parser->local.usage_index;	offset = report->size;	report->size += parser->global.report_size * parser->global.report_count;	if (usages == 0)		return 0; /* ignore padding fields */	if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL)		return 0;	field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL);	field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL);	field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);	for (i = 0; i < usages; i++)		field->usage[i].hid = parser->local.usage[i];	field->maxusage = usages;	field->flags = flags;	field->report_offset = offset;	field->report_type = report_type;	field->report_size = parser->global.report_size;	field->report_count = parser->global.report_count;	field->logical_minimum = parser->global.logical_minimum;	field->logical_maximum = parser->global.logical_maximum;	field->physical_minimum = parser->global.physical_minimum;	field->physical_maximum = parser->global.physical_maximum;	field->unit_exponent = parser->global.unit_exponent;	field->unit = parser->global.unit;	return 0;}/* * Read data value from item. */static __inline__ __u32 item_udata(struct hid_item *item){	switch (item->size) {		case 1: return item->data.u8;		case 2: return item->data.u16;		case 4: return item->data.u32;	}	return 0;}static __inline__ __s32 item_sdata(struct hid_item *item){	switch (item->size) {		case 1: return item->data.s8;		case 2: return item->data.s16;		case 4: return item->data.s32;	}	return 0;}/* * Process a global item. */static int hid_parser_global(struct hid_parser *parser, struct hid_item *item){	switch (item->tag) {		case HID_GLOBAL_ITEM_TAG_PUSH:			if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {				dbg("global enviroment stack overflow");				return -1;			}			memcpy(parser->global_stack + parser->global_stack_ptr++,				&parser->global, sizeof(struct hid_global));			return 0;		case HID_GLOBAL_ITEM_TAG_POP:			if (!parser->global_stack_ptr) {				dbg("global enviroment stack underflow");				return -1;			}			memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr,				sizeof(struct hid_global));			return 0;		case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:			parser->global.usage_page = item_udata(item);			return 0;		case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:			parser->global.logical_minimum = item_sdata(item);			return 0;		case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:			if (parser->global.logical_minimum < 0)				parser->global.logical_maximum = item_sdata(item);			else				parser->global.logical_maximum = item_udata(item);			return 0;		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:			parser->global.physical_minimum = item_sdata(item);			return 0;		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:			if (parser->global.physical_minimum < 0)				parser->global.physical_maximum = item_sdata(item);			else				parser->global.physical_maximum = item_udata(item);			return 0;		case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:			parser->global.unit_exponent = item_sdata(item);			return 0;		case HID_GLOBAL_ITEM_TAG_UNIT:			parser->global.unit = item_udata(item);			return 0;		case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:			if ((parser->global.report_size = item_udata(item)) > 32) {				dbg("invalid report_size %d", parser->global.report_size);				return -1;			}			return 0;		case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:			if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {				dbg("invalid report_count %d", parser->global.report_count);				return -1;			}			return 0;		case HID_GLOBAL_ITEM_TAG_REPORT_ID:			if ((parser->global.report_id = item_udata(item)) == 0) {				dbg("report_id 0 is invalid");				return -1;			}			return 0;		default:			dbg("unknown global tag 0x%x", item->tag);			return -1;	}}/* * Process a local item. */static int hid_parser_local(struct hid_parser *parser, struct hid_item *item){	__u32 data;	unsigned n;	if (item->size == 0) {		dbg("item data expected for local item");		return -1;	}	data = item_udata(item);	switch (item->tag) {		case HID_LOCAL_ITEM_TAG_DELIMITER:			if (data) {				/*				 * We treat items before the first delimiter				 * as global to all usage sets (branch 0).				 * In the moment we process only these global				 * items and the first delimiter set.				 */				if (parser->local.delimiter_depth != 0) {					dbg("nested delimiters");					return -1;				}				parser->local.delimiter_depth++;				parser->local.delimiter_branch++;			} else {				if (parser->local.delimiter_depth < 1) {					dbg("bogus close delimiter");					return -1;				}				parser->local.delimiter_depth--;			}			return 1;		case HID_LOCAL_ITEM_TAG_USAGE:			if (parser->local.delimiter_branch > 1) {				dbg("alternative usage ignored");				return 0;			}			if (item->size <= 2)				data = (parser->global.usage_page << 16) + data;			return hid_add_usage(parser, data);		case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:			if (parser->local.delimiter_branch > 1) {				dbg("alternative usage ignored");				return 0;			}			if (item->size <= 2)				data = (parser->global.usage_page << 16) + data;			parser->local.usage_minimum = data;			return 0;		case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:			if (parser->local.delimiter_branch > 1) {				dbg("alternative usage ignored");				return 0;			}			if (item->size <= 2)				data = (parser->global.usage_page << 16) + data;			for (n = parser->local.usage_minimum; n <= data; n++)				if (hid_add_usage(parser, n)) {					dbg("hid_add_usage failed\n");					return -1;				}			return 0;		default:			dbg("unknown local item tag 0x%x", item->tag);			return 0;	}	return 0;}/* * Process a main item. */static int hid_parser_main(struct hid_parser *parser, struct hid_item *item){	__u32 data;	int ret;	data = item_udata(item);	switch (item->tag) {		case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:			ret = open_collection(parser, data & 3);			break;		case HID_MAIN_ITEM_TAG_END_COLLECTION:			ret = close_collection(parser);			break;		case HID_MAIN_ITEM_TAG_INPUT:			ret = hid_add_field(parser, HID_INPUT_REPORT, data);			break;		case HID_MAIN_ITEM_TAG_OUTPUT:			ret = hid_add_field(parser, HID_OUTPUT_REPORT, data);			break;		case HID_MAIN_ITEM_TAG_FEATURE:			ret = hid_add_field(parser, HID_FEATURE_REPORT, data);			break;		default:			dbg("unknown main item tag 0x%x", item->tag);			ret = 0;	}	memset(&parser->local, 0, sizeof(parser->local));	/* Reset the local parser environment */	return ret;}/* * Process a reserved item. */static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item){	dbg("reserved item type, tag 0x%x", item->tag);	return 0;}/* * Free a report and all registered fields. The field->usage and * field->value table's are allocated behind the field, so we need * only to free(field) itself. */static void hid_free_report(struct hid_report *report){	unsigned n;	for (n = 0; n < report->maxfield; n++)		kfree(report->field[n]);	kfree(report);}

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
**网站欧美大片在线观看| 久久久久亚洲综合| 欧美三级在线播放| 精品国内片67194| 日本一区二区久久| 亚洲高清视频在线| 极品美女销魂一区二区三区免费| 国产福利一区在线| 91蝌蚪porny成人天涯| 日韩限制级电影在线观看| 欧美国产一区在线| 亚洲1区2区3区视频| 精品无码三级在线观看视频 | 91丨九色丨黑人外教| 欧美日韩精品综合在线| 国产免费观看久久| 麻豆91免费看| 欧美精品色综合| 国产精品三级av在线播放| 爽好久久久欧美精品| 北岛玲一区二区三区四区| 欧美精品1区2区3区| 亚洲精品乱码久久久久久| 国产精品1区二区.| 精品va天堂亚洲国产| 日韩精品久久理论片| 精品视频在线免费看| 亚洲人妖av一区二区| av亚洲精华国产精华| 国产日韩欧美电影| 成人免费视频一区| 中文字幕的久久| 成人免费视频免费观看| 国产欧美一区二区三区网站 | 久久精品免视看| 国产精品一区二区久激情瑜伽| 久久久久久麻豆| 成人精品国产福利| 亚洲综合偷拍欧美一区色| 91国产福利在线| 日韩黄色免费网站| 欧美日韩和欧美的一区二区| 蜜桃av噜噜一区| 国产欧美一区二区三区鸳鸯浴 | 婷婷综合久久一区二区三区| 欧美剧情片在线观看| 蜜桃在线一区二区三区| 国产精品人人做人人爽人人添| 91看片淫黄大片一级在线观看| 亚洲成人综合视频| 欧美国产综合色视频| 91蝌蚪porny九色| 夜夜嗨av一区二区三区中文字幕 | 久久精品国产在热久久| 国产精品不卡在线| 日韩久久久久久| 91免费国产在线| 国产美女精品人人做人人爽| 亚洲欧美日韩小说| 久久日韩精品一区二区五区| 欧美体内she精高潮| 国产999精品久久久久久绿帽| 亚洲高清视频中文字幕| 国产精品成人免费| 日本一区二区综合亚洲| 91精品国产综合久久久蜜臀粉嫩| 99精品欧美一区二区三区小说| 琪琪久久久久日韩精品| 午夜在线电影亚洲一区| 亚洲人亚洲人成电影网站色| 国产精品丝袜黑色高跟| 久久免费国产精品| 精品国产乱码久久久久久夜甘婷婷 | 精品国产免费一区二区三区四区| 色婷婷av一区二区三区大白胸| 成人性生交大片免费看中文| 韩国三级中文字幕hd久久精品| 麻豆91在线观看| 蜜桃av一区二区在线观看 | 美国av一区二区| 国产精品高清亚洲| 欧美va亚洲va在线观看蝴蝶网| 在线视频欧美精品| 成人动漫视频在线| 成a人片亚洲日本久久| 日本精品一级二级| 色一情一伦一子一伦一区| 色婷婷av一区二区三区大白胸| 99re这里只有精品首页| 国产精品1024久久| 99免费精品视频| 欧美曰成人黄网| 91精品国产全国免费观看| 精品电影一区二区| 综合久久综合久久| 日韩精品免费专区| 九九精品视频在线看| 成人午夜在线免费| 欧美日韩国产首页在线观看| 日韩一区二区精品在线观看| 精品av久久707| 一区二区三区中文字幕在线观看| 青青草原综合久久大伊人精品| 久久精品久久精品| 欧美图区在线视频| 国产偷国产偷亚洲高清人白洁| 亚洲精品网站在线观看| 日韩av中文字幕一区二区| 成人黄色小视频| 欧美一级日韩一级| 一区二区三区四区视频精品免费| 免费在线视频一区| 欧美综合一区二区| 亚洲欧美国产高清| 国产高清无密码一区二区三区| 色天使色偷偷av一区二区| 久久精品视频一区二区三区| 午夜精品久久久久久久久久| 99久久免费精品高清特色大片| 日韩欧美国产综合| 日韩电影免费一区| 91精品国产综合久久精品麻豆 | 色欧美日韩亚洲| 精品欧美乱码久久久久久 | 欧美色大人视频| 日韩一区在线看| 国产乱人伦偷精品视频免下载| 精品国产成人在线影院| 激情六月婷婷久久| 日韩欧美一区二区在线视频| 国产精品国产自产拍在线| 午夜一区二区三区在线观看| 狠狠色丁香久久婷婷综合丁香| 成人手机电影网| 日韩精品在线一区二区| 国产精品久久久久久久久快鸭 | 欧美日韩久久不卡| 久久久精品免费免费| 亚洲乱码国产乱码精品精的特点 | 蜜桃av一区二区| 成人国产电影网| 欧美刺激午夜性久久久久久久| 国产精品白丝在线| 久久 天天综合| 欧美电影在线免费观看| 中文字幕的久久| 国产真实乱偷精品视频免| 欧美色区777第一页| 中文字幕一区二区三区蜜月| 精品一区二区免费| 日韩一本二本av| 日韩成人一区二区| 欧洲亚洲精品在线| 午夜成人在线视频| 日韩一区国产二区欧美三区| 亚洲chinese男男1069| 欧美日韩国产区一| 综合分类小说区另类春色亚洲小说欧美| 国产精品一区二区在线看| 国产清纯白嫩初高生在线观看91| 麻豆精品精品国产自在97香蕉| 精品国产1区二区| 国产麻豆精品在线观看| 亚洲精品免费一二三区| k8久久久一区二区三区| 最新欧美精品一区二区三区| 欧美日本在线视频| 狠狠网亚洲精品| 日本一区二区三级电影在线观看| 91小视频在线观看| 日韩激情视频网站| 欧美国产亚洲另类动漫| 91久久精品日日躁夜夜躁欧美| 日精品一区二区| 中文字幕在线不卡一区| 欧美三级日韩三级国产三级| 高清beeg欧美| 久久不见久久见免费视频1| 亚洲欧洲日产国产综合网| 欧洲中文字幕精品| 99久久免费精品| 成人激情免费网站| 国产乱码精品1区2区3区| 亚洲成人免费视| 亚洲男女毛片无遮挡| 国产精品网站在线观看| 日韩精品一区二区三区三区免费| 色偷偷久久人人79超碰人人澡| 国产酒店精品激情| 国产一区二区三区av电影 | 亚洲六月丁香色婷婷综合久久| 国产午夜亚洲精品理论片色戒| 555www色欧美视频| 一本久道中文字幕精品亚洲嫩| 国产福利一区二区三区视频在线 | 成人app在线观看| 成人午夜电影小说| 欧美专区日韩专区| 色综合激情五月| 欧美综合视频在线观看|