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

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

?? hid-core.c

?? linux 內(nèi)核源代碼
?? C
?? 第 1 頁(yè) / 共 2 頁(yè)
字號(hào):
/* * Process a reserved item. */static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item){	dbg_hid("reserved item type, tag 0x%x\n", 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. */void hid_free_device(struct hid_device *device){	unsigned i,j;	for (i = 0; i < HID_REPORT_TYPES; i++) {		struct hid_report_enum *report_enum = device->report_enum + i;		for (j = 0; j < 256; j++) {			struct hid_report *report = report_enum->report_id_hash[j];			if (report)				hid_free_report(report);		}	}	kfree(device->rdesc);	kfree(device->collection);	kfree(device);}EXPORT_SYMBOL_GPL(hid_free_device);/* * Fetch a report description item from the data stream. We support long * items, though they are not used yet. */static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item){	u8 b;	if ((end - start) <= 0)		return NULL;	b = *start++;	item->type = (b >> 2) & 3;	item->tag  = (b >> 4) & 15;	if (item->tag == HID_ITEM_TAG_LONG) {		item->format = HID_ITEM_FORMAT_LONG;		if ((end - start) < 2)			return NULL;		item->size = *start++;		item->tag  = *start++;		if ((end - start) < item->size)			return NULL;		item->data.longdata = start;		start += item->size;		return start;	}	item->format = HID_ITEM_FORMAT_SHORT;	item->size = b & 3;	switch (item->size) {		case 0:			return start;		case 1:			if ((end - start) < 1)				return NULL;			item->data.u8 = *start++;			return start;		case 2:			if ((end - start) < 2)				return NULL;			item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start));			start = (__u8 *)((__le16 *)start + 1);			return start;		case 3:			item->size++;			if ((end - start) < 4)				return NULL;			item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start));			start = (__u8 *)((__le32 *)start + 1);			return start;	}	return NULL;}/* * Parse a report description into a hid_device structure. Reports are * enumerated, fields are attached to these reports. */struct hid_device *hid_parse_report(__u8 *start, unsigned size){	struct hid_device *device;	struct hid_parser *parser;	struct hid_item item;	__u8 *end;	unsigned i;	static int (*dispatch_type[])(struct hid_parser *parser,				      struct hid_item *item) = {		hid_parser_main,		hid_parser_global,		hid_parser_local,		hid_parser_reserved	};	if (!(device = kzalloc(sizeof(struct hid_device), GFP_KERNEL)))		return NULL;	if (!(device->collection = kzalloc(sizeof(struct hid_collection) *				   HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) {		kfree(device);		return NULL;	}	device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;	for (i = 0; i < HID_REPORT_TYPES; i++)		INIT_LIST_HEAD(&device->report_enum[i].report_list);	if (!(device->rdesc = kmalloc(size, GFP_KERNEL))) {		kfree(device->collection);		kfree(device);		return NULL;	}	memcpy(device->rdesc, start, size);	device->rsize = size;	if (!(parser = vmalloc(sizeof(struct hid_parser)))) {		kfree(device->rdesc);		kfree(device->collection);		kfree(device);		return NULL;	}	memset(parser, 0, sizeof(struct hid_parser));	parser->device = device;	end = start + size;	while ((start = fetch_item(start, end, &item)) != NULL) {		if (item.format != HID_ITEM_FORMAT_SHORT) {			dbg_hid("unexpected long global item\n");			hid_free_device(device);			vfree(parser);			return NULL;		}		if (dispatch_type[item.type](parser, &item)) {			dbg_hid("item %u %u %u %u parsing failed\n",				item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);			hid_free_device(device);			vfree(parser);			return NULL;		}		if (start == end) {			if (parser->collection_stack_ptr) {				dbg_hid("unbalanced collection at end of report description\n");				hid_free_device(device);				vfree(parser);				return NULL;			}			if (parser->local.delimiter_depth) {				dbg_hid("unbalanced delimiter at end of report description\n");				hid_free_device(device);				vfree(parser);				return NULL;			}			vfree(parser);			return device;		}	}	dbg_hid("item fetching failed at offset %d\n", (int)(end - start));	hid_free_device(device);	vfree(parser);	return NULL;}EXPORT_SYMBOL_GPL(hid_parse_report);/* * Convert a signed n-bit integer to signed 32-bit integer. Common * cases are done through the compiler, the screwed things has to be * done by hand. */static s32 snto32(__u32 value, unsigned n){	switch (n) {		case 8:  return ((__s8)value);		case 16: return ((__s16)value);		case 32: return ((__s32)value);	}	return value & (1 << (n - 1)) ? value | (-1 << n) : value;}/* * Convert a signed 32-bit integer to a signed n-bit integer. */static u32 s32ton(__s32 value, unsigned n){	s32 a = value >> (n - 1);	if (a && a != -1)		return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;	return value & ((1 << n) - 1);}/* * Extract/implement a data field from/to a little endian report (bit array). * * Code sort-of follows HID spec: *     http://www.usb.org/developers/devclass_docs/HID1_11.pdf * * While the USB HID spec allows unlimited length bit fields in "report * descriptors", most devices never use more than 16 bits. * One model of UPS is claimed to report "LINEV" as a 32-bit field. * Search linux-kernel and linux-usb-devel archives for "hid-core extract". */static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n){	u64 x;	WARN_ON(n > 32);	report += offset >> 3;  /* adjust byte index */	offset &= 7;            /* now only need bit offset into one byte */	x = le64_to_cpu(get_unaligned((__le64 *) report));	x = (x >> offset) & ((1ULL << n) - 1);  /* extract bit field */	return (u32) x;}/* * "implement" : set bits in a little endian bit stream. * Same concepts as "extract" (see comments above). * The data mangled in the bit stream remains in little endian * order the whole time. It make more sense to talk about * endianness of register values by considering a register * a "cached" copy of the little endiad bit stream. */static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value){	__le64 x;	u64 m = (1ULL << n) - 1;	WARN_ON(n > 32);	WARN_ON(value > m);	value &= m;	report += offset >> 3;	offset &= 7;	x = get_unaligned((__le64 *)report);	x &= cpu_to_le64(~(m << offset));	x |= cpu_to_le64(((u64) value) << offset);	put_unaligned(x, (__le64 *) report);}/* * Search an array for a value. */static __inline__ int search(__s32 *array, __s32 value, unsigned n){	while (n--) {		if (*array++ == value)			return 0;	}	return -1;}static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt){	hid_dump_input(usage, value);	if (hid->claimed & HID_CLAIMED_INPUT)		hidinput_hid_event(hid, field, usage, value);	if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event)		hid->hiddev_hid_event(hid, field, usage, value);}/* * Analyse a received field, and fetch the data from it. The field * content is stored for next report processing (we do differential * reporting to the layer). */void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt){	unsigned n;	unsigned count = field->report_count;	unsigned offset = field->report_offset;	unsigned size = field->report_size;	__s32 min = field->logical_minimum;	__s32 max = field->logical_maximum;	__s32 *value;	if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC)))		return;	for (n = 0; n < count; n++) {			value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) :						    extract(data, offset + n * size, size);			if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */			    && value[n] >= min && value[n] <= max			    && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)				goto exit;	}	for (n = 0; n < count; n++) {		if (HID_MAIN_ITEM_VARIABLE & field->flags) {			hid_process_event(hid, field, &field->usage[n], value[n], interrupt);			continue;		}		if (field->value[n] >= min && field->value[n] <= max			&& field->usage[field->value[n] - min].hid			&& search(value, field->value[n], count))				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);		if (value[n] >= min && value[n] <= max			&& field->usage[value[n] - min].hid			&& search(field->value, value[n], count))				hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);	}	memcpy(field->value, value, count * sizeof(__s32));exit:	kfree(value);}EXPORT_SYMBOL_GPL(hid_input_field);/* * Output the field into the report. */static void hid_output_field(struct hid_field *field, __u8 *data){	unsigned count = field->report_count;	unsigned offset = field->report_offset;	unsigned size = field->report_size;	unsigned bitsused = offset + count * size;	unsigned n;	/* make sure the unused bits in the last byte are zeros */	if (count > 0 && size > 0 && (bitsused % 8) != 0)		data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1;	for (n = 0; n < count; n++) {		if (field->logical_minimum < 0)	/* signed values */			implement(data, offset + n * size, size, s32ton(field->value[n], size));		else				/* unsigned values */			implement(data, offset + n * size, size, field->value[n]);	}}/* * Create a report. */void hid_output_report(struct hid_report *report, __u8 *data){	unsigned n;	if (report->id > 0)		*data++ = report->id;	for (n = 0; n < report->maxfield; n++)		hid_output_field(report->field[n], data);}EXPORT_SYMBOL_GPL(hid_output_report);/* * Set a field value. The report this field belongs to has to be * created and transferred to the device, to set this value in the * device. */int hid_set_field(struct hid_field *field, unsigned offset, __s32 value){	unsigned size = field->report_size;	hid_dump_input(field->usage + offset, value);	if (offset >= field->report_count) {		dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);		hid_dump_field(field, 8);		return -1;	}	if (field->logical_minimum < 0) {		if (value != snto32(s32ton(value, size), size)) {			dbg_hid("value %d is out of range\n", value);			return -1;		}	}	field->value[offset] = value;	return 0;}EXPORT_SYMBOL_GPL(hid_set_field);int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt){	struct hid_report_enum *report_enum = hid->report_enum + type;	struct hid_report *report;	int n, rsize, i;	if (!hid)		return -ENODEV;	if (!size) {		dbg_hid("empty report\n");		return -1;	}	dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");	n = 0;                          /* Normally report number is 0 */	if (report_enum->numbered) {    /* Device uses numbered reports, data[0] is report number */		n = *data++;		size--;	}	/* dump the report descriptor */	dbg_hid("report %d (size %u) = ", n, size);	for (i = 0; i < size; i++)		dbg_hid_line(" %02x", data[i]);	dbg_hid_line("\n");	if (!(report = report_enum->report_id_hash[n])) {		dbg_hid("undefined report_id %d received\n", n);		return -1;	}	rsize = ((report->size - 1) >> 3) + 1;	if (size < rsize) {		dbg_hid("report %d is too short, (%d < %d)\n", report->id, size, rsize);		memset(data + size, 0, rsize - size);	}	if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)		hid->hiddev_report_event(hid, report);	if (hid->claimed & HID_CLAIMED_HIDRAW)		hidraw_report_event(hid, data, size);	for (n = 0; n < report->maxfield; n++)		hid_input_field(hid, report->field[n], data, interrupt);	if (hid->claimed & HID_CLAIMED_INPUT)		hidinput_report_event(hid, report);	return 0;}EXPORT_SYMBOL_GPL(hid_input_report);static int __init hid_init(void){	return hidraw_init();}static void __exit hid_exit(void){	hidraw_exit();}module_init(hid_init);module_exit(hid_exit);MODULE_LICENSE(DRIVER_LICENSE);

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品女人毛片| av综合在线播放| 日本午夜精品视频在线观看| 性做久久久久久免费观看欧美| 亚洲一区二区在线免费看| 亚洲欧洲在线观看av| 成人欧美一区二区三区视频网页| 国产精品女同一区二区三区| 自拍偷拍欧美激情| 一区二区三区欧美视频| 亚洲.国产.中文慕字在线| 日本午夜一区二区| 激情综合色综合久久| 国产精品一区一区三区| 成人综合婷婷国产精品久久| 99久久er热在这里只有精品15| 9人人澡人人爽人人精品| 一本大道久久精品懂色aⅴ| 欧美日韩精品一区二区三区| 日韩视频免费直播| 日本一区二区成人| 亚洲一区二区在线播放相泽| 奇米一区二区三区| 国产二区国产一区在线观看| 99久久精品99国产精品| 欧美日韩激情在线| 久久精品欧美一区二区三区麻豆| 国产精品久久午夜| 亚洲成av人片在线观看| 国内久久婷婷综合| 99亚偷拍自图区亚洲| 欧美日韩mp4| 国产亚洲精品精华液| 亚洲精品视频一区| 免费精品视频在线| 成人精品一区二区三区四区 | 丰满少妇在线播放bd日韩电影| 99久久精品国产一区| 69堂成人精品免费视频| 国产日韩综合av| 一区二区三区中文字幕| 国产综合一区二区| 日本乱码高清不卡字幕| 精品国产免费视频| 夜夜亚洲天天久久| 国产成人小视频| 欧美精品日日鲁夜夜添| 国产欧美一区二区精品婷婷| 亚洲夂夂婷婷色拍ww47| 国产一区二区看久久| 欧美视频一区在线| 中文字幕第一区二区| 免费成人美女在线观看| 99久久久无码国产精品| 日韩精品中午字幕| 亚洲一二三四在线| 成av人片一区二区| 日韩精品在线看片z| 亚洲影院在线观看| 成人性生交大片免费看中文网站| 欧美日韩国产bt| 国产精品久久久久久亚洲毛片 | 日本视频免费一区| aa级大片欧美| 国产天堂亚洲国产碰碰| 日韩在线a电影| 91女神在线视频| 国产视频一区二区在线| 美腿丝袜一区二区三区| 欧美色综合网站| 中文字幕亚洲一区二区va在线| 激情深爱一区二区| 538在线一区二区精品国产| 亚洲色图在线播放| 丁香亚洲综合激情啪啪综合| 精品国产三级a在线观看| 首页国产欧美久久| 欧美性感一区二区三区| 最新日韩av在线| 国产99久久久久久免费看农村| 日韩区在线观看| 天堂一区二区在线| 在线精品视频免费观看| 亚洲男人的天堂网| 91在线视频观看| 中文字幕中文字幕中文字幕亚洲无线| 国产一区二区三区精品视频| 日韩视频国产视频| 免费久久精品视频| 日韩欧美在线综合网| 日韩精品一二三四| 91精品国产免费| 日本在线不卡视频一二三区| 欧美精品日韩一本| 日韩av中文在线观看| 欧美一区二区三区在| 日本视频一区二区三区| 欧美一级片在线| 免费视频一区二区| 欧美一激情一区二区三区| 日韩精品国产精品| 欧美一区二区福利在线| 麻豆成人久久精品二区三区小说| 日韩一区二区在线看片| 久草在线在线精品观看| 精品奇米国产一区二区三区| 九九**精品视频免费播放| 精品欧美一区二区久久 | 欧美日韩国产大片| 琪琪久久久久日韩精品| 日韩精品一区二区三区四区视频| 久久精品国产精品亚洲精品| 久久亚洲精精品中文字幕早川悠里 | 欧美成人女星排名| 黄色精品一二区| 久久夜色精品国产噜噜av | 欧美一级日韩免费不卡| 激情综合色综合久久综合| 国产清纯白嫩初高生在线观看91| 成人午夜av电影| 中文字幕人成不卡一区| 欧美视频一区二区| 久久99精品一区二区三区三区| 2024国产精品| 91蝌蚪porny| 午夜a成v人精品| 欧美精品一区二区高清在线观看| 国产传媒日韩欧美成人| 一区二区三区日韩欧美| 欧美精品日韩一区| 国产成人在线电影| 亚洲一级二级三级在线免费观看| 日韩亚洲欧美一区二区三区| 国产成人午夜精品5599| 亚洲精品久久久久久国产精华液| 欧美日韩精品一区二区三区蜜桃 | 日韩成人精品在线| 国产视频一区在线播放| 在线观看日韩一区| 激情欧美一区二区| 亚洲免费在线观看视频| 日韩视频中午一区| 91在线国产观看| 日本成人在线不卡视频| 国产精品免费网站在线观看| 欧美精三区欧美精三区| 成人综合婷婷国产精品久久免费| 亚洲成va人在线观看| 欧美激情在线免费观看| 欧美精品在欧美一区二区少妇| 国产传媒久久文化传媒| 天堂一区二区在线| 国产精品乱人伦一区二区| 91.com视频| 色综合夜色一区| 国产一区二区在线看| 亚洲主播在线播放| 中文字幕免费不卡| 91精品国产免费| 在线观看亚洲a| 成人av电影在线网| 久久精品国产99国产| 伊人婷婷欧美激情| 欧美激情一区二区三区四区| 欧美一级理论片| 在线一区二区三区四区| 国产精品一级在线| 日本伊人色综合网| 一级女性全黄久久生活片免费| 亚洲国产精品二十页| 精品人在线二区三区| 欧美男女性生活在线直播观看| 成人av片在线观看| 国内精品久久久久影院薰衣草| 亚洲午夜精品久久久久久久久| 国产精品萝li| 久久久高清一区二区三区| 欧美一区二视频| 色乱码一区二区三区88| 成人一级片在线观看| 国内偷窥港台综合视频在线播放| 亚洲一区二区视频| 亚洲精品乱码久久久久| 国产精品久久久久久亚洲毛片| 精品成人佐山爱一区二区| 7878成人国产在线观看| 欧美日韩中文字幕一区二区| 色久综合一二码| 一本大道久久a久久精二百| zzijzzij亚洲日本少妇熟睡| 粉嫩高潮美女一区二区三区| 国产一区二区在线看| 黄色资源网久久资源365| 麻豆国产精品视频| 久久精品999| 久久精品久久99精品久久| 免费看精品久久片| 久久er99热精品一区二区| 蓝色福利精品导航| 激情五月婷婷综合网|