Lines Matching full:parser
147 static int open_collection(struct hid_parser *parser, unsigned type) in open_collection() argument
153 usage = parser->local.usage[0]; in open_collection()
155 if (parser->collection_stack_ptr == parser->collection_stack_size) { in open_collection()
157 unsigned int new_size = parser->collection_stack_size + in open_collection()
160 collection_stack = krealloc(parser->collection_stack, in open_collection()
166 parser->collection_stack = collection_stack; in open_collection()
167 parser->collection_stack_size = new_size; in open_collection()
170 if (parser->device->maxcollection == parser->device->collection_size) { in open_collection()
173 parser->device->collection_size, in open_collection()
177 hid_err(parser->device, "failed to reallocate collection array\n"); in open_collection()
180 memcpy(collection, parser->device->collection, in open_collection()
182 parser->device->collection_size); in open_collection()
183 memset(collection + parser->device->collection_size, 0, in open_collection()
185 parser->device->collection_size); in open_collection()
186 kfree(parser->device->collection); in open_collection()
187 parser->device->collection = collection; in open_collection()
188 parser->device->collection_size *= 2; in open_collection()
191 parser->collection_stack[parser->collection_stack_ptr++] = in open_collection()
192 parser->device->maxcollection; in open_collection()
194 collection_index = parser->device->maxcollection++; in open_collection()
195 collection = parser->device->collection + collection_index; in open_collection()
198 collection->level = parser->collection_stack_ptr - 1; in open_collection()
200 parser->collection_stack[collection->level - 1]; in open_collection()
203 parser->device->maxapplication++; in open_collection()
212 static int close_collection(struct hid_parser *parser) in close_collection() argument
214 if (!parser->collection_stack_ptr) { in close_collection()
215 hid_err(parser->device, "collection stack underflow\n"); in close_collection()
218 parser->collection_stack_ptr--; in close_collection()
227 static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) in hid_lookup_collection() argument
229 struct hid_collection *collection = parser->device->collection; in hid_lookup_collection()
232 for (n = parser->collection_stack_ptr - 1; n >= 0; n--) { in hid_lookup_collection()
233 unsigned index = parser->collection_stack[n]; in hid_lookup_collection()
245 static void complete_usage(struct hid_parser *parser, unsigned int index) in complete_usage() argument
247 parser->local.usage[index] &= 0xFFFF; in complete_usage()
248 parser->local.usage[index] |= in complete_usage()
249 (parser->global.usage_page & 0xFFFF) << 16; in complete_usage()
253 * Add a usage to the temporary parser table.
256 static int hid_add_usage(struct hid_parser *parser, unsigned usage, u8 size) in hid_add_usage() argument
258 if (parser->local.usage_index >= HID_MAX_USAGES) { in hid_add_usage()
259 hid_err(parser->device, "usage index exceeded\n"); in hid_add_usage()
262 parser->local.usage[parser->local.usage_index] = usage; in hid_add_usage()
269 complete_usage(parser, parser->local.usage_index); in hid_add_usage()
271 parser->local.usage_size[parser->local.usage_index] = size; in hid_add_usage()
272 parser->local.collection_index[parser->local.usage_index] = in hid_add_usage()
273 parser->collection_stack_ptr ? in hid_add_usage()
274 parser->collection_stack[parser->collection_stack_ptr - 1] : 0; in hid_add_usage()
275 parser->local.usage_index++; in hid_add_usage()
283 static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) in hid_add_field() argument
293 application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); in hid_add_field()
295 report = hid_register_report(parser->device, report_type, in hid_add_field()
296 parser->global.report_id, application); in hid_add_field()
298 hid_err(parser->device, "hid_register_report failed\n"); in hid_add_field()
303 if ((parser->global.logical_minimum < 0 && in hid_add_field()
304 parser->global.logical_maximum < in hid_add_field()
305 parser->global.logical_minimum) || in hid_add_field()
306 (parser->global.logical_minimum >= 0 && in hid_add_field()
307 (__u32)parser->global.logical_maximum < in hid_add_field()
308 (__u32)parser->global.logical_minimum)) { in hid_add_field()
310 parser->global.logical_minimum, in hid_add_field()
311 parser->global.logical_maximum); in hid_add_field()
316 report->size += parser->global.report_size * parser->global.report_count; in hid_add_field()
318 if (parser->device->ll_driver->max_buffer_size) in hid_add_field()
319 max_buffer_size = parser->device->ll_driver->max_buffer_size; in hid_add_field()
323 hid_err(parser->device, "report is too long\n"); in hid_add_field()
327 if (!parser->local.usage_index) /* Ignore padding fields */ in hid_add_field()
330 usages = max_t(unsigned, parser->local.usage_index, in hid_add_field()
331 parser->global.report_count); in hid_add_field()
337 field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); in hid_add_field()
338 field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); in hid_add_field()
344 if (i >= parser->local.usage_index) in hid_add_field()
345 j = parser->local.usage_index - 1; in hid_add_field()
346 field->usage[i].hid = parser->local.usage[j]; in hid_add_field()
348 parser->local.collection_index[j]; in hid_add_field()
357 field->report_size = parser->global.report_size; in hid_add_field()
358 field->report_count = parser->global.report_count; in hid_add_field()
359 field->logical_minimum = parser->global.logical_minimum; in hid_add_field()
360 field->logical_maximum = parser->global.logical_maximum; in hid_add_field()
361 field->physical_minimum = parser->global.physical_minimum; in hid_add_field()
362 field->physical_maximum = parser->global.physical_maximum; in hid_add_field()
363 field->unit_exponent = parser->global.unit_exponent; in hid_add_field()
364 field->unit = parser->global.unit; in hid_add_field()
397 static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) in hid_parser_global() argument
403 if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { in hid_parser_global()
404 hid_err(parser->device, "global environment stack overflow\n"); in hid_parser_global()
408 memcpy(parser->global_stack + parser->global_stack_ptr++, in hid_parser_global()
409 &parser->global, sizeof(struct hid_global)); in hid_parser_global()
414 if (!parser->global_stack_ptr) { in hid_parser_global()
415 hid_err(parser->device, "global environment stack underflow\n"); in hid_parser_global()
419 memcpy(&parser->global, parser->global_stack + in hid_parser_global()
420 --parser->global_stack_ptr, sizeof(struct hid_global)); in hid_parser_global()
424 parser->global.usage_page = item_udata(item); in hid_parser_global()
428 parser->global.logical_minimum = item_sdata(item); in hid_parser_global()
432 if (parser->global.logical_minimum < 0) in hid_parser_global()
433 parser->global.logical_maximum = item_sdata(item); in hid_parser_global()
435 parser->global.logical_maximum = item_udata(item); in hid_parser_global()
439 parser->global.physical_minimum = item_sdata(item); in hid_parser_global()
443 if (parser->global.physical_minimum < 0) in hid_parser_global()
444 parser->global.physical_maximum = item_sdata(item); in hid_parser_global()
446 parser->global.physical_maximum = item_udata(item); in hid_parser_global()
456 parser->global.unit_exponent = snto32(raw_value, 4); in hid_parser_global()
458 parser->global.unit_exponent = raw_value; in hid_parser_global()
462 parser->global.unit = item_udata(item); in hid_parser_global()
466 parser->global.report_size = item_udata(item); in hid_parser_global()
467 if (parser->global.report_size > 256) { in hid_parser_global()
468 hid_err(parser->device, "invalid report_size %d\n", in hid_parser_global()
469 parser->global.report_size); in hid_parser_global()
475 parser->global.report_count = item_udata(item); in hid_parser_global()
476 if (parser->global.report_count > HID_MAX_USAGES) { in hid_parser_global()
477 hid_err(parser->device, "invalid report_count %d\n", in hid_parser_global()
478 parser->global.report_count); in hid_parser_global()
484 parser->global.report_id = item_udata(item); in hid_parser_global()
485 if (parser->global.report_id == 0 || in hid_parser_global()
486 parser->global.report_id >= HID_MAX_IDS) { in hid_parser_global()
487 hid_err(parser->device, "report_id %u is invalid\n", in hid_parser_global()
488 parser->global.report_id); in hid_parser_global()
494 hid_err(parser->device, "unknown global tag 0x%x\n", item->tag); in hid_parser_global()
503 static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) in hid_parser_local() argument
521 if (parser->local.delimiter_depth != 0) { in hid_parser_local()
522 hid_err(parser->device, "nested delimiters\n"); in hid_parser_local()
525 parser->local.delimiter_depth++; in hid_parser_local()
526 parser->local.delimiter_branch++; in hid_parser_local()
528 if (parser->local.delimiter_depth < 1) { in hid_parser_local()
529 hid_err(parser->device, "bogus close delimiter\n"); in hid_parser_local()
532 parser->local.delimiter_depth--; in hid_parser_local()
538 if (parser->local.delimiter_branch > 1) { in hid_parser_local()
543 return hid_add_usage(parser, data, item->size); in hid_parser_local()
547 if (parser->local.delimiter_branch > 1) { in hid_parser_local()
552 parser->local.usage_minimum = data; in hid_parser_local()
557 if (parser->local.delimiter_branch > 1) { in hid_parser_local()
562 count = data - parser->local.usage_minimum; in hid_parser_local()
563 if (count + parser->local.usage_index >= HID_MAX_USAGES) { in hid_parser_local()
568 if (dev_name(&parser->device->dev)) in hid_parser_local()
569 hid_warn(parser->device, in hid_parser_local()
571 data = HID_MAX_USAGES - parser->local.usage_index + in hid_parser_local()
572 parser->local.usage_minimum - 1; in hid_parser_local()
574 hid_err(parser->device, in hid_parser_local()
580 for (n = parser->local.usage_minimum; n <= data; n++) in hid_parser_local()
581 if (hid_add_usage(parser, n, item->size)) { in hid_parser_local()
597 * As per specification, 6.2.2.8: "When the parser encounters a main item it
602 static void hid_concatenate_last_usage_page(struct hid_parser *parser) in hid_concatenate_last_usage_page() argument
608 if (!parser->local.usage_index) in hid_concatenate_last_usage_page()
611 usage_page = parser->global.usage_page; in hid_concatenate_last_usage_page()
617 for (i = parser->local.usage_index - 1; i >= 0; i--) { in hid_concatenate_last_usage_page()
618 if (parser->local.usage_size[i] > 2) in hid_concatenate_last_usage_page()
622 current_page = parser->local.usage[i] >> 16; in hid_concatenate_last_usage_page()
626 complete_usage(parser, i); in hid_concatenate_last_usage_page()
634 static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) in hid_parser_main() argument
639 hid_concatenate_last_usage_page(parser); in hid_parser_main()
645 ret = open_collection(parser, data & 0xff); in hid_parser_main()
648 ret = close_collection(parser); in hid_parser_main()
651 ret = hid_add_field(parser, HID_INPUT_REPORT, data); in hid_parser_main()
654 ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); in hid_parser_main()
657 ret = hid_add_field(parser, HID_FEATURE_REPORT, data); in hid_parser_main()
660 hid_warn(parser->device, "unknown main item tag 0x%x\n", item->tag); in hid_parser_main()
664 memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ in hid_parser_main()
673 static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) in hid_parser_reserved() argument
826 static void hid_scan_input_usage(struct hid_parser *parser, u32 usage) in hid_scan_input_usage() argument
828 struct hid_device *hid = parser->device; in hid_scan_input_usage()
834 static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage) in hid_scan_feature_usage() argument
836 if (usage == 0xff0000c5 && parser->global.report_count == 256 && in hid_scan_feature_usage()
837 parser->global.report_size == 8) in hid_scan_feature_usage()
838 parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8; in hid_scan_feature_usage()
840 if (usage == 0xff0000c6 && parser->global.report_count == 1 && in hid_scan_feature_usage()
841 parser->global.report_size == 8) in hid_scan_feature_usage()
842 parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8; in hid_scan_feature_usage()
845 static void hid_scan_collection(struct hid_parser *parser, unsigned type) in hid_scan_collection() argument
847 struct hid_device *hid = parser->device; in hid_scan_collection()
850 if (((parser->global.usage_page << 16) == HID_UP_SENSOR) && in hid_scan_collection()
860 if ((parser->global.usage_page << 16) == HID_UP_GENDESK) in hid_scan_collection()
861 for (i = 0; i < parser->local.usage_index; i++) in hid_scan_collection()
862 if (parser->local.usage[i] == HID_GD_POINTER) in hid_scan_collection()
863 parser->scan_flags |= HID_SCAN_FLAG_GD_POINTER; in hid_scan_collection()
865 if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR) in hid_scan_collection()
866 parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC; in hid_scan_collection()
868 if ((parser->global.usage_page << 16) == HID_UP_GOOGLEVENDOR) in hid_scan_collection()
869 for (i = 0; i < parser->local.usage_index; i++) in hid_scan_collection()
870 if (parser->local.usage[i] == in hid_scan_collection()
872 parser->device->group = in hid_scan_collection()
876 static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) in hid_scan_main() argument
881 hid_concatenate_last_usage_page(parser); in hid_scan_main()
887 hid_scan_collection(parser, data & 0xff); in hid_scan_main()
895 for (i = 0; i < parser->local.usage_index; i++) in hid_scan_main()
896 hid_scan_input_usage(parser, parser->local.usage[i]); in hid_scan_main()
901 for (i = 0; i < parser->local.usage_index; i++) in hid_scan_main()
902 hid_scan_feature_usage(parser, parser->local.usage[i]); in hid_scan_main()
906 /* Reset the local parser environment */ in hid_scan_main()
907 memset(&parser->local, 0, sizeof(parser->local)); in hid_scan_main()
919 struct hid_parser *parser; in hid_scan_report() local
923 static int (*dispatch_type[])(struct hid_parser *parser, in hid_scan_report()
931 parser = vzalloc(sizeof(struct hid_parser)); in hid_scan_report()
932 if (!parser) in hid_scan_report()
935 parser->device = hid; in hid_scan_report()
944 dispatch_type[item.type](parser, &item); in hid_scan_report()
949 if ((parser->scan_flags & HID_SCAN_FLAG_MT_WIN_8) && in hid_scan_report()
962 if ((parser->scan_flags & HID_SCAN_FLAG_VENDOR_SPECIFIC) in hid_scan_report()
963 && (parser->scan_flags & HID_SCAN_FLAG_GD_POINTER)) in hid_scan_report()
972 kfree(parser->collection_stack); in hid_scan_report()
973 vfree(parser); in hid_scan_report()
1244 struct hid_parser *parser; in hid_open_report() local
1252 static int (*dispatch_type[])(struct hid_parser *parser, in hid_open_report()
1295 parser = vzalloc(sizeof(struct hid_parser)); in hid_open_report()
1296 if (!parser) { in hid_open_report()
1301 parser->device = device; in hid_open_report()
1324 if (dispatch_type[item.type](parser, &item)) { in hid_open_report()
1332 if (parser->collection_stack_ptr) { in hid_open_report()
1336 if (parser->local.delimiter_depth) { in hid_open_report()
1347 kfree(parser->collection_stack); in hid_open_report()
1348 vfree(parser); in hid_open_report()
1358 kfree(parser->collection_stack); in hid_open_report()
1360 vfree(parser); in hid_open_report()