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

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

?? hid.c

?? 講述linux的初始化過程
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* * $Id: hid.c,v 1.16 2000/09/18 21:38:55 vojtech Exp $ * *  Copyright (c) 1999 Andreas Gal *  Copyright (c) 2000 Vojtech Pavlik * *  USB HID support for the Linux input drivers * *  Sponsored by SuSE *//* * 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@suse.cz>, or by paper mail: * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic */#include <linux/module.h>#include <linux/malloc.h>#include <linux/input.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>#undef DEBUG#undef DEBUG_DATA#include <linux/usb.h>#include <asm/unaligned.h>#include "hid.h"#ifdef DEBUG#include "hid-debug.h"#else#define hid_dump_input(a,b)	do { } while (0)#define hid_dump_device(c)	do { } while (0)#endif#define unk	KEY_UNKNOWNstatic unsigned char hid_keyboard[256] = {	  0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,	 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,	  4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,	 27, 43, 84, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,	 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,	105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,	 72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95,	120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113,	115,114,unk,unk,unk,124,unk,181,182,183,184,185,186,187,188,189,	190,191,192,193,194,195,196,197,198,unk,unk,unk,unk,unk,unk,unk,	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,	 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,	150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk};static struct {	__s32 x;	__s32 y;}  hid_hat_to_axis[] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}, { 0, 0}};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){	if (report->maxfield < HID_MAX_FIELDS) {		struct hid_field *field;		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;		return field;	}	dbg("too many fields in report");	return NULL;}/* * Open a collection. The type/usage is pushed on the stack. */static int open_collection(struct hid_parser *parser, unsigned type){	unsigned usage;	usage = parser->local.usage[0];	if (type == HID_COLLECTION_APPLICATION && !parser->device->application)		parser->device->application = usage;	if (parser->collection_stack_ptr < HID_COLLECTION_STACK_SIZE) { /* PUSH on stack */		struct hid_collection *collection = parser->collection_stack + parser->collection_stack_ptr++;		collection->type = type;		collection->usage = usage;		return 0;	}	dbg("collection stack overflow");	return -1;}/* * Close a collection. */static int close_collection(struct hid_parser *parser){	if (parser->collection_stack_ptr > 0) {	/* POP from stack */		parser->collection_stack_ptr--;		return 0;	}	dbg("collection stack underflow");	return -1;}/* * 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 (HID_MAIN_ITEM_VARIABLE & ~flags) { /* ARRAY */		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;		/* Hint: we can assume usages < MAX_USAGE here */	} else { /* VARIABLE */		usages = parser->global.report_count;	}	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);	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) {				memcpy(parser->global_stack + parser->global_stack_ptr++,					&parser->global, sizeof(struct hid_global));				return 0;			}			dbg("global enviroment stack overflow");			return -1;		case HID_GLOBAL_ITEM_TAG_POP:			if (parser->global_stack_ptr > 0) {				memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr,					sizeof(struct hid_global));				return 0;			}			dbg("global enviroment stack underflow");			return -1;		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:			parser->global.logical_maximum = item_sdata(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:			parser->global.physical_maximum = item_sdata(item);			return 0;		case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:			parser->global.unit_exponent = item_udata(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;	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 < 2) {				if (item->size <= 2)					data = (parser->global.usage_page << 16) + data;				return hid_add_usage(parser, data);			}			dbg("alternative usage ignored");			return 0;		case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:			if (parser->local.delimiter_branch < 2) {				if (item->size <= 2)					data = (parser->global.usage_page << 16) + data;				parser->local.usage_minimum = data;				return 0;			}			dbg("alternative usage ignored");			return 0;		case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:			if (parser->local.delimiter_branch < 2) {				unsigned n;				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;			}			dbg("alternative usage ignored");			return 0;		default:			dbg("unknown local item tag 0x%x", item->tag);			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);}/* * Free a device structure, all reports, and all fields. */static void hid_free_device(struct hid_device *device){	unsigned i,j;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美激情一区在线观看| 欧美羞羞免费网站| 裸体一区二区三区| 九九视频精品免费| 欧美精品丝袜中出| 国产在线麻豆精品观看| 亚洲精品中文在线| 午夜视频一区二区三区| 欧美在线观看视频一区二区 | 欧美视频第二页| 国产成人在线色| 天堂精品中文字幕在线| 18成人在线观看| 91香蕉国产在线观看软件| 亚洲国产精品影院| 欧美日韩小视频| 五月婷婷欧美视频| 欧美性猛交xxxx黑人交| 亚洲自拍偷拍九九九| 成人激情开心网| 亚洲精品videosex极品| 在线欧美日韩精品| 水蜜桃久久夜色精品一区的特点| 欧美少妇xxx| 精品一区二区三区在线视频| 亚洲第一成人在线| 欧美tk—视频vk| av男人天堂一区| 亚洲女人小视频在线观看| 欧美日韩精品一区二区天天拍小说 | 在线观看日韩国产| 日韩中文欧美在线| 538prom精品视频线放| 97se亚洲国产综合自在线观| 日本大胆欧美人术艺术动态| 欧美日韩电影在线| 中文字幕一区二区在线播放| 色婷婷久久久久swag精品| 美女www一区二区| 国产在线国偷精品免费看| 99久久精品国产一区| 成人精品一区二区三区四区| 激情欧美一区二区三区在线观看| 91丨porny丨首页| 91麻豆国产福利精品| 91丝袜呻吟高潮美腿白嫩在线观看| 盗摄精品av一区二区三区| 大白屁股一区二区视频| 丰满岳乱妇一区二区三区| 婷婷成人综合网| 国产精品久久久久久久午夜片| 911国产精品| 91捆绑美女网站| 成人永久免费视频| 麻豆一区二区三区| 亚洲美女精品一区| 国产精品九色蝌蚪自拍| 国产精品网站在线观看| 国产欧美日韩麻豆91| 日韩三级视频在线观看| 欧美一区二区三区婷婷月色| 欧美专区亚洲专区| 欧美自拍偷拍午夜视频| 欧美日韩综合一区| 91精品欧美综合在线观看最新| 国产精品美日韩| 99久久婷婷国产精品综合| 成人的网站免费观看| 懂色av一区二区三区蜜臀| 国产91精品精华液一区二区三区| 成人综合在线观看| 色综合一个色综合亚洲| 在线免费视频一区二区| 制服丝袜亚洲色图| 亚洲欧美偷拍三级| 日韩精品一区二区三区视频在线观看 | 亚洲美女免费视频| 日韩精品专区在线| 日韩美一区二区三区| 久久亚洲欧美国产精品乐播| 三级久久三级久久久| 亚洲精品在线观| 日本欧美久久久久免费播放网| 精品一区二区三区久久| 欧美剧情片在线观看| 久久久久国产精品麻豆| 亚洲视频一二三| 麻豆一区二区在线| heyzo一本久久综合| 日韩欧美激情在线| 亚洲欧洲国产日本综合| 亚洲一区二区三区爽爽爽爽爽| 综合色中文字幕| 视频一区在线视频| 黄色小说综合网站| 欧美三级中文字幕| 久久网站最新地址| 亚洲码国产岛国毛片在线| 日韩国产欧美在线视频| 丝袜美腿亚洲综合| 久久丁香综合五月国产三级网站| 久久99精品国产.久久久久久| 国产凹凸在线观看一区二区| 欧美在线小视频| 国产日本欧洲亚洲| 午夜久久久久久久久久一区二区| 久久99久久精品欧美| 欧美性色综合网| 国产精品久久久久婷婷 | 国产欧美一区二区精品性色超碰| 国产精品私人影院| 亚洲18女电影在线观看| 成人av电影在线观看| 91精品国产91久久久久久一区二区 | 伦理电影国产精品| 国产传媒久久文化传媒| 国产在线不卡一卡二卡三卡四卡| 成人av小说网| 精品无码三级在线观看视频| 日本最新不卡在线| 成人一道本在线| 欧美videofree性高清杂交| 亚洲精品视频在线观看免费| 岛国精品一区二区| 精品国产一区二区三区四区四| 午夜欧美在线一二页| 精品久久久久一区| 免费观看一级欧美片| 欧美在线免费观看视频| 欧美精品一区二区不卡| 日韩黄色片在线观看| 成人app网站| 亚洲激情在线激情| 日本福利一区二区| 精品成人佐山爱一区二区| 蜜桃一区二区三区四区| 精品国产一二三区| 国产一区二区美女| 中文字幕欧美三区| 国产呦精品一区二区三区网站| 日韩免费高清视频| 国产在线视视频有精品| 欧美videos大乳护士334| 国产jizzjizz一区二区| 一色屋精品亚洲香蕉网站| 成人av网址在线观看| 亚洲黄色免费电影| 色噜噜久久综合| 午夜视频一区二区三区| 精品女同一区二区| av电影在线观看完整版一区二区| 亚洲欧美另类图片小说| 欧美喷水一区二区| 亚洲一区视频在线| 欧美精品一区二区三| 91视视频在线直接观看在线看网页在线看| 国产精品乱人伦一区二区| 91福利精品第一导航| 亚洲福利一区二区| 欧美国产禁国产网站cc| 欧美探花视频资源| 99久久99久久精品国产片果冻| 亚洲精品ww久久久久久p站| 国产精品的网站| 国产欧美日韩三级| 久久精品日产第一区二区三区高清版| 91视频在线看| 图片区小说区区亚洲影院| 欧美一区二区三区爱爱| 色综合久久六月婷婷中文字幕| 制服丝袜中文字幕亚洲| 无码av中文一区二区三区桃花岛| 久久综合久久综合久久| 国内精品自线一区二区三区视频| 久久精品视频免费| 国产.精品.日韩.另类.中文.在线.播放| 欧美成人一区二区| 蜜臀久久99精品久久久画质超高清| 精品国产sm最大网站免费看| 欧美电影一区二区| 国产精品一级在线| 亚洲另类一区二区| 26uuuu精品一区二区| 日本va欧美va精品发布| 一卡二卡三卡日韩欧美| 国产精品不卡在线| 日韩毛片视频在线看| 亚洲欧美中日韩| 亚洲免费观看高清| 午夜精品国产更新| 日韩不卡在线观看日韩不卡视频| 亚洲一区二区在线免费看| 亚洲日本在线视频观看| 亚洲精品第一国产综合野| 国产精品九色蝌蚪自拍| 亚洲欧美日韩电影| 亚洲一二三区视频在线观看| 亚洲成a人片在线观看中文| 亚洲美女淫视频| 视频一区中文字幕|