Rev 846 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
846 | giacomo | 1 | /* |
2 | * USB HID support for Linux |
||
3 | * |
||
4 | * Copyright (c) 1999 Andreas Gal |
||
5 | * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz> |
||
6 | */ |
||
7 | |||
8 | /* |
||
9 | * This program is free software; you can redistribute it and/or modify it |
||
10 | * under the terms of the GNU General Public License as published by the Free |
||
11 | * Software Foundation; either version 2 of the License, or (at your option) |
||
12 | * any later version. |
||
13 | */ |
||
14 | |||
15 | #include <linuxcomp.h> |
||
16 | |||
17 | #include <linux/module.h> |
||
18 | #include <linux/slab.h> |
||
19 | #include <linux/init.h> |
||
20 | #include <linux/kernel.h> |
||
21 | #include <linux/sched.h> |
||
22 | #include <linux/list.h> |
||
23 | #include <linux/mm.h> |
||
24 | #include <linux/smp_lock.h> |
||
25 | #include <linux/spinlock.h> |
||
26 | #include <asm/unaligned.h> |
||
27 | #include <asm/byteorder.h> |
||
28 | #include <linux/input.h> |
||
29 | |||
30 | #undef DEBUG |
||
31 | #undef DEBUG_DATA |
||
32 | |||
33 | #include <linux/usb.h> |
||
34 | |||
35 | #include "hid.h" |
||
36 | #include <linux/hiddev.h> |
||
37 | |||
38 | /* |
||
39 | * Version Information |
||
40 | */ |
||
41 | |||
42 | #define DRIVER_VERSION "v2.0" |
||
43 | #define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" |
||
44 | #define DRIVER_DESC "USB HID core driver" |
||
45 | #define DRIVER_LICENSE "GPL" |
||
46 | |||
47 | static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", |
||
48 | "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; |
||
49 | |||
50 | /* |
||
51 | * Register a new report for a device. |
||
52 | */ |
||
53 | |||
54 | static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) |
||
55 | { |
||
56 | struct hid_report_enum *report_enum = device->report_enum + type; |
||
57 | struct hid_report *report; |
||
58 | |||
59 | if (report_enum->report_id_hash[id]) |
||
60 | return report_enum->report_id_hash[id]; |
||
61 | |||
62 | if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL))) |
||
63 | return NULL; |
||
64 | memset(report, 0, sizeof(struct hid_report)); |
||
65 | |||
66 | if (id != 0) |
||
67 | report_enum->numbered = 1; |
||
68 | |||
69 | report->id = id; |
||
70 | report->type = type; |
||
71 | report->size = 0; |
||
72 | report->device = device; |
||
73 | report_enum->report_id_hash[id] = report; |
||
74 | |||
75 | list_add_tail(&report->list, &report_enum->report_list); |
||
76 | |||
77 | return report; |
||
78 | } |
||
79 | |||
80 | /* |
||
81 | * Register a new field for this report. |
||
82 | */ |
||
83 | |||
84 | static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) |
||
85 | { |
||
86 | struct hid_field *field; |
||
87 | |||
88 | if (report->maxfield == HID_MAX_FIELDS) { |
||
89 | dbg("too many fields in report"); |
||
90 | return NULL; |
||
91 | } |
||
92 | |||
93 | if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) |
||
94 | + values * sizeof(unsigned), GFP_KERNEL))) return NULL; |
||
95 | |||
96 | memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage) |
||
97 | + values * sizeof(unsigned)); |
||
98 | |||
99 | report->field[report->maxfield++] = field; |
||
100 | field->usage = (struct hid_usage *)(field + 1); |
||
101 | field->value = (unsigned *)(field->usage + usages); |
||
102 | field->report = report; |
||
103 | |||
104 | return field; |
||
105 | } |
||
106 | |||
107 | /* |
||
108 | * Open a collection. The type/usage is pushed on the stack. |
||
109 | */ |
||
110 | |||
111 | static int open_collection(struct hid_parser *parser, unsigned type) |
||
112 | { |
||
113 | struct hid_collection *collection; |
||
114 | unsigned usage; |
||
115 | |||
116 | usage = parser->local.usage[0]; |
||
117 | |||
118 | if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { |
||
119 | dbg("collection stack overflow"); |
||
120 | return -1; |
||
121 | } |
||
122 | |||
123 | if (parser->device->maxcollection == parser->device->collection_size) { |
||
124 | collection = kmalloc(sizeof(struct hid_collection) * |
||
125 | parser->device->collection_size * 2, |
||
126 | GFP_KERNEL); |
||
127 | if (collection == NULL) { |
||
128 | dbg("failed to reallocate collection array"); |
||
129 | return -1; |
||
130 | } |
||
131 | memcpy(collection, parser->device->collection, |
||
132 | sizeof(struct hid_collection) * |
||
133 | parser->device->collection_size); |
||
134 | memset(collection + parser->device->collection_size, 0, |
||
135 | sizeof(struct hid_collection) * |
||
136 | parser->device->collection_size); |
||
137 | kfree(parser->device->collection); |
||
138 | parser->device->collection = collection; |
||
139 | parser->device->collection_size *= 2; |
||
140 | } |
||
141 | |||
142 | parser->collection_stack[parser->collection_stack_ptr++] = |
||
143 | parser->device->maxcollection; |
||
144 | |||
145 | collection = parser->device->collection + |
||
146 | parser->device->maxcollection++; |
||
147 | collection->type = type; |
||
148 | collection->usage = usage; |
||
149 | collection->level = parser->collection_stack_ptr - 1; |
||
150 | |||
151 | if (type == HID_COLLECTION_APPLICATION) |
||
152 | parser->device->maxapplication++; |
||
153 | |||
154 | return 0; |
||
155 | } |
||
156 | |||
157 | /* |
||
158 | * Close a collection. |
||
159 | */ |
||
160 | |||
161 | static int close_collection(struct hid_parser *parser) |
||
162 | { |
||
163 | if (!parser->collection_stack_ptr) { |
||
164 | dbg("collection stack underflow"); |
||
165 | return -1; |
||
166 | } |
||
167 | parser->collection_stack_ptr--; |
||
168 | return 0; |
||
169 | } |
||
170 | |||
171 | /* |
||
172 | * Climb up the stack, search for the specified collection type |
||
173 | * and return the usage. |
||
174 | */ |
||
175 | |||
176 | static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) |
||
177 | { |
||
178 | int n; |
||
179 | for (n = parser->collection_stack_ptr - 1; n >= 0; n--) |
||
180 | if (parser->device->collection[parser->collection_stack[n]].type == type) |
||
181 | return parser->device->collection[parser->collection_stack[n]].usage; |
||
182 | return 0; /* we know nothing about this usage type */ |
||
183 | } |
||
184 | |||
185 | /* |
||
186 | * Add a usage to the temporary parser table. |
||
187 | */ |
||
188 | |||
189 | static int hid_add_usage(struct hid_parser *parser, unsigned usage) |
||
190 | { |
||
191 | if (parser->local.usage_index >= HID_MAX_USAGES) { |
||
192 | dbg("usage index exceeded"); |
||
193 | return -1; |
||
194 | } |
||
195 | parser->local.usage[parser->local.usage_index] = usage; |
||
196 | parser->local.collection_index[parser->local.usage_index] = |
||
197 | parser->collection_stack_ptr ? |
||
198 | parser->collection_stack[parser->collection_stack_ptr - 1] : 0; |
||
199 | parser->local.usage_index++; |
||
200 | return 0; |
||
201 | } |
||
202 | |||
203 | /* |
||
204 | * Register a new field for this report. |
||
205 | */ |
||
206 | |||
207 | static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) |
||
208 | { |
||
209 | struct hid_report *report; |
||
210 | struct hid_field *field; |
||
211 | int usages; |
||
212 | unsigned offset; |
||
213 | int i; |
||
214 | |||
215 | if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { |
||
216 | dbg("hid_register_report failed"); |
||
217 | return -1; |
||
218 | } |
||
219 | |||
220 | if (parser->global.logical_maximum < parser->global.logical_minimum) { |
||
221 | dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); |
||
222 | return -1; |
||
223 | } |
||
224 | usages = parser->local.usage_index; |
||
225 | |||
226 | offset = report->size; |
||
227 | report->size += parser->global.report_size * parser->global.report_count; |
||
228 | |||
229 | if (usages == 0) |
||
230 | return 0; /* ignore padding fields */ |
||
231 | |||
232 | if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) |
||
233 | return 0; |
||
234 | |||
235 | field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); |
||
236 | field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); |
||
237 | field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); |
||
238 | |||
239 | for (i = 0; i < usages; i++) { |
||
240 | field->usage[i].hid = parser->local.usage[i]; |
||
241 | field->usage[i].collection_index = |
||
242 | parser->local.collection_index[i]; |
||
243 | } |
||
244 | |||
245 | field->maxusage = usages; |
||
246 | field->flags = flags; |
||
247 | field->report_offset = offset; |
||
248 | field->report_type = report_type; |
||
249 | field->report_size = parser->global.report_size; |
||
250 | field->report_count = parser->global.report_count; |
||
251 | field->logical_minimum = parser->global.logical_minimum; |
||
252 | field->logical_maximum = parser->global.logical_maximum; |
||
253 | field->physical_minimum = parser->global.physical_minimum; |
||
254 | field->physical_maximum = parser->global.physical_maximum; |
||
255 | field->unit_exponent = parser->global.unit_exponent; |
||
256 | field->unit = parser->global.unit; |
||
257 | |||
258 | return 0; |
||
259 | } |
||
260 | |||
261 | /* |
||
262 | * Read data value from item. |
||
263 | */ |
||
264 | |||
265 | static __inline__ __u32 item_udata(struct hid_item *item) |
||
266 | { |
||
267 | switch (item->size) { |
||
268 | case 1: return item->data.u8; |
||
269 | case 2: return item->data.u16; |
||
270 | case 4: return item->data.u32; |
||
271 | } |
||
272 | return 0; |
||
273 | } |
||
274 | |||
275 | static __inline__ __s32 item_sdata(struct hid_item *item) |
||
276 | { |
||
277 | switch (item->size) { |
||
278 | case 1: return item->data.s8; |
||
279 | case 2: return item->data.s16; |
||
280 | case 4: return item->data.s32; |
||
281 | } |
||
282 | return 0; |
||
283 | } |
||
284 | |||
285 | /* |
||
286 | * Process a global item. |
||
287 | */ |
||
288 | |||
289 | static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) |
||
290 | { |
||
291 | switch (item->tag) { |
||
292 | |||
293 | case HID_GLOBAL_ITEM_TAG_PUSH: |
||
294 | |||
295 | if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { |
||
296 | dbg("global enviroment stack overflow"); |
||
297 | return -1; |
||
298 | } |
||
299 | |||
300 | memcpy(parser->global_stack + parser->global_stack_ptr++, |
||
301 | &parser->global, sizeof(struct hid_global)); |
||
302 | return 0; |
||
303 | |||
304 | case HID_GLOBAL_ITEM_TAG_POP: |
||
305 | |||
306 | if (!parser->global_stack_ptr) { |
||
307 | dbg("global enviroment stack underflow"); |
||
308 | return -1; |
||
309 | } |
||
310 | |||
311 | memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, |
||
312 | sizeof(struct hid_global)); |
||
313 | return 0; |
||
314 | |||
315 | case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: |
||
316 | parser->global.usage_page = item_udata(item); |
||
317 | return 0; |
||
318 | |||
319 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: |
||
320 | parser->global.logical_minimum = item_sdata(item); |
||
321 | return 0; |
||
322 | |||
323 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: |
||
324 | if (parser->global.logical_minimum < 0) |
||
325 | parser->global.logical_maximum = item_sdata(item); |
||
326 | else |
||
327 | parser->global.logical_maximum = item_udata(item); |
||
328 | return 0; |
||
329 | |||
330 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: |
||
331 | parser->global.physical_minimum = item_sdata(item); |
||
332 | return 0; |
||
333 | |||
334 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: |
||
335 | if (parser->global.physical_minimum < 0) |
||
336 | parser->global.physical_maximum = item_sdata(item); |
||
337 | else |
||
338 | parser->global.physical_maximum = item_udata(item); |
||
339 | return 0; |
||
340 | |||
341 | case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: |
||
342 | parser->global.unit_exponent = item_sdata(item); |
||
343 | return 0; |
||
344 | |||
345 | case HID_GLOBAL_ITEM_TAG_UNIT: |
||
346 | parser->global.unit = item_udata(item); |
||
347 | return 0; |
||
348 | |||
349 | case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: |
||
350 | if ((parser->global.report_size = item_udata(item)) > 32) { |
||
351 | dbg("invalid report_size %d", parser->global.report_size); |
||
352 | return -1; |
||
353 | } |
||
354 | return 0; |
||
355 | |||
356 | case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: |
||
357 | if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { |
||
358 | dbg("invalid report_count %d", parser->global.report_count); |
||
359 | return -1; |
||
360 | } |
||
361 | return 0; |
||
362 | |||
363 | case HID_GLOBAL_ITEM_TAG_REPORT_ID: |
||
364 | if ((parser->global.report_id = item_udata(item)) == 0) { |
||
365 | dbg("report_id 0 is invalid"); |
||
366 | return -1; |
||
367 | } |
||
368 | return 0; |
||
369 | |||
370 | default: |
||
371 | dbg("unknown global tag 0x%x", item->tag); |
||
372 | return -1; |
||
373 | } |
||
374 | } |
||
375 | |||
376 | /* |
||
377 | * Process a local item. |
||
378 | */ |
||
379 | |||
380 | static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) |
||
381 | { |
||
382 | __u32 data; |
||
383 | unsigned n; |
||
384 | |||
385 | if (item->size == 0) { |
||
386 | dbg("item data expected for local item"); |
||
387 | return -1; |
||
388 | } |
||
389 | |||
390 | data = item_udata(item); |
||
391 | |||
392 | switch (item->tag) { |
||
393 | |||
394 | case HID_LOCAL_ITEM_TAG_DELIMITER: |
||
395 | |||
396 | if (data) { |
||
397 | /* |
||
398 | * We treat items before the first delimiter |
||
399 | * as global to all usage sets (branch 0). |
||
400 | * In the moment we process only these global |
||
401 | * items and the first delimiter set. |
||
402 | */ |
||
403 | if (parser->local.delimiter_depth != 0) { |
||
404 | dbg("nested delimiters"); |
||
405 | return -1; |
||
406 | } |
||
407 | parser->local.delimiter_depth++; |
||
408 | parser->local.delimiter_branch++; |
||
409 | } else { |
||
410 | if (parser->local.delimiter_depth < 1) { |
||
411 | dbg("bogus close delimiter"); |
||
412 | return -1; |
||
413 | } |
||
414 | parser->local.delimiter_depth--; |
||
415 | } |
||
416 | return 1; |
||
417 | |||
418 | case HID_LOCAL_ITEM_TAG_USAGE: |
||
419 | |||
420 | if (parser->local.delimiter_branch > 1) { |
||
421 | dbg("alternative usage ignored"); |
||
422 | return 0; |
||
423 | } |
||
424 | |||
425 | if (item->size <= 2) |
||
426 | data = (parser->global.usage_page << 16) + data; |
||
427 | |||
428 | return hid_add_usage(parser, data); |
||
429 | |||
430 | case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: |
||
431 | |||
432 | if (parser->local.delimiter_branch > 1) { |
||
433 | dbg("alternative usage ignored"); |
||
434 | return 0; |
||
435 | } |
||
436 | |||
437 | if (item->size <= 2) |
||
438 | data = (parser->global.usage_page << 16) + data; |
||
439 | |||
440 | parser->local.usage_minimum = data; |
||
441 | return 0; |
||
442 | |||
443 | case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: |
||
444 | |||
445 | if (parser->local.delimiter_branch > 1) { |
||
446 | dbg("alternative usage ignored"); |
||
447 | return 0; |
||
448 | } |
||
449 | |||
450 | if (item->size <= 2) |
||
451 | data = (parser->global.usage_page << 16) + data; |
||
452 | |||
453 | for (n = parser->local.usage_minimum; n <= data; n++) |
||
454 | if (hid_add_usage(parser, n)) { |
||
455 | dbg("hid_add_usage failed\n"); |
||
456 | return -1; |
||
457 | } |
||
458 | return 0; |
||
459 | |||
460 | default: |
||
461 | |||
462 | dbg("unknown local item tag 0x%x", item->tag); |
||
463 | return 0; |
||
464 | } |
||
465 | return 0; |
||
466 | } |
||
467 | |||
468 | /* |
||
469 | * Process a main item. |
||
470 | */ |
||
471 | |||
472 | static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) |
||
473 | { |
||
474 | __u32 data; |
||
475 | int ret; |
||
476 | |||
477 | data = item_udata(item); |
||
478 | |||
479 | switch (item->tag) { |
||
480 | case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: |
||
481 | ret = open_collection(parser, data & 0xff); |
||
482 | break; |
||
483 | case HID_MAIN_ITEM_TAG_END_COLLECTION: |
||
484 | ret = close_collection(parser); |
||
485 | break; |
||
486 | case HID_MAIN_ITEM_TAG_INPUT: |
||
487 | ret = hid_add_field(parser, HID_INPUT_REPORT, data); |
||
488 | break; |
||
489 | case HID_MAIN_ITEM_TAG_OUTPUT: |
||
490 | ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); |
||
491 | break; |
||
492 | case HID_MAIN_ITEM_TAG_FEATURE: |
||
493 | ret = hid_add_field(parser, HID_FEATURE_REPORT, data); |
||
494 | break; |
||
495 | default: |
||
496 | dbg("unknown main item tag 0x%x", item->tag); |
||
497 | ret = 0; |
||
498 | } |
||
499 | |||
500 | memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ |
||
501 | |||
502 | return ret; |
||
503 | } |
||
504 | |||
505 | /* |
||
506 | * Process a reserved item. |
||
507 | */ |
||
508 | |||
509 | static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) |
||
510 | { |
||
511 | dbg("reserved item type, tag 0x%x", item->tag); |
||
512 | return 0; |
||
513 | } |
||
514 | |||
515 | /* |
||
516 | * Free a report and all registered fields. The field->usage and |
||
517 | * field->value table's are allocated behind the field, so we need |
||
518 | * only to free(field) itself. |
||
519 | */ |
||
520 | |||
521 | static void hid_free_report(struct hid_report *report) |
||
522 | { |
||
523 | unsigned n; |
||
524 | |||
525 | for (n = 0; n < report->maxfield; n++) |
||
526 | kfree(report->field[n]); |
||
527 | kfree(report); |
||
528 | } |
||
529 | |||
530 | /* |
||
531 | * Free a device structure, all reports, and all fields. |
||
532 | */ |
||
533 | |||
534 | static void hid_free_device(struct hid_device *device) |
||
535 | { |
||
536 | unsigned i,j; |
||
537 | |||
538 | hid_ff_exit(device); |
||
539 | |||
540 | for (i = 0; i < HID_REPORT_TYPES; i++) { |
||
541 | struct hid_report_enum *report_enum = device->report_enum + i; |
||
542 | |||
543 | for (j = 0; j < 256; j++) { |
||
544 | struct hid_report *report = report_enum->report_id_hash[j]; |
||
545 | if (report) |
||
546 | hid_free_report(report); |
||
547 | } |
||
548 | } |
||
549 | |||
550 | if (device->rdesc) |
||
551 | kfree(device->rdesc); |
||
552 | kfree(device); |
||
553 | } |
||
554 | |||
555 | /* |
||
556 | * Fetch a report description item from the data stream. We support long |
||
557 | * items, though they are not used yet. |
||
558 | */ |
||
559 | |||
560 | static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) |
||
561 | { |
||
562 | u8 b; |
||
563 | |||
564 | if ((end - start) <= 0) |
||
565 | return NULL; |
||
566 | |||
567 | b = *start++; |
||
568 | |||
569 | item->type = (b >> 2) & 3; |
||
570 | item->tag = (b >> 4) & 15; |
||
571 | |||
572 | if (item->tag == HID_ITEM_TAG_LONG) { |
||
573 | |||
574 | item->format = HID_ITEM_FORMAT_LONG; |
||
575 | |||
576 | if ((end - start) < 2) |
||
577 | return NULL; |
||
578 | |||
579 | item->size = *start++; |
||
580 | item->tag = *start++; |
||
581 | |||
582 | if ((end - start) < item->size) |
||
583 | return NULL; |
||
584 | |||
585 | item->data.longdata = start; |
||
586 | start += item->size; |
||
587 | return start; |
||
588 | } |
||
589 | |||
590 | item->format = HID_ITEM_FORMAT_SHORT; |
||
591 | item->size = b & 3; |
||
592 | |||
593 | switch (item->size) { |
||
594 | |||
595 | case 0: |
||
596 | return start; |
||
597 | |||
598 | case 1: |
||
599 | if ((end - start) < 1) |
||
600 | return NULL; |
||
601 | item->data.u8 = *start++; |
||
602 | return start; |
||
603 | |||
604 | case 2: |
||
605 | if ((end - start) < 2) |
||
606 | return NULL; |
||
607 | item->data.u16 = le16_to_cpu(get_unaligned(((__u16*)start)++)); |
||
608 | return start; |
||
609 | |||
610 | case 3: |
||
611 | item->size++; |
||
612 | if ((end - start) < 4) |
||
613 | return NULL; |
||
614 | item->data.u32 = le32_to_cpu(get_unaligned(((__u32*)start)++)); |
||
615 | return start; |
||
616 | } |
||
617 | |||
618 | return NULL; |
||
619 | } |
||
620 | |||
621 | /* |
||
622 | * Parse a report description into a hid_device structure. Reports are |
||
623 | * enumerated, fields are attached to these reports. |
||
624 | */ |
||
625 | |||
626 | static struct hid_device *hid_parse_report(__u8 *start, unsigned size) |
||
627 | { |
||
628 | struct hid_device *device; |
||
629 | struct hid_parser *parser; |
||
630 | struct hid_item item; |
||
631 | __u8 *end; |
||
632 | unsigned i; |
||
633 | static int (*dispatch_type[])(struct hid_parser *parser, |
||
634 | struct hid_item *item) = { |
||
635 | hid_parser_main, |
||
636 | hid_parser_global, |
||
637 | hid_parser_local, |
||
638 | hid_parser_reserved |
||
639 | }; |
||
640 | |||
641 | if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL))) |
||
642 | return NULL; |
||
643 | memset(device, 0, sizeof(struct hid_device)); |
||
644 | |||
645 | if (!(device->collection =kmalloc(sizeof(struct hid_collection) * |
||
646 | HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { |
||
647 | kfree(device); |
||
648 | return NULL; |
||
649 | } |
||
650 | memset(device->collection, 0, sizeof(struct hid_collection) * |
||
651 | HID_DEFAULT_NUM_COLLECTIONS); |
||
652 | device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; |
||
653 | |||
654 | for (i = 0; i < HID_REPORT_TYPES; i++) |
||
655 | INIT_LIST_HEAD(&device->report_enum[i].report_list); |
||
656 | |||
657 | if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { |
||
658 | kfree(device->collection); |
||
659 | kfree(device); |
||
660 | return NULL; |
||
661 | } |
||
662 | memcpy(device->rdesc, start, size); |
||
663 | device->rsize = size; |
||
664 | |||
665 | if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) { |
||
666 | kfree(device->rdesc); |
||
667 | kfree(device->collection); |
||
668 | kfree(device); |
||
669 | return NULL; |
||
670 | } |
||
671 | memset(parser, 0, sizeof(struct hid_parser)); |
||
672 | parser->device = device; |
||
673 | |||
674 | end = start + size; |
||
675 | while ((start = fetch_item(start, end, &item)) != 0) { |
||
676 | |||
677 | if (item.format != HID_ITEM_FORMAT_SHORT) { |
||
678 | dbg("unexpected long global item"); |
||
679 | kfree(device->collection); |
||
680 | hid_free_device(device); |
||
681 | kfree(parser); |
||
682 | return NULL; |
||
683 | } |
||
684 | |||
685 | if (dispatch_type[item.type](parser, &item)) { |
||
686 | dbg("item %u %u %u %u parsing failed\n", |
||
687 | item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); |
||
688 | kfree(device->collection); |
||
689 | hid_free_device(device); |
||
690 | kfree(parser); |
||
691 | return NULL; |
||
692 | } |
||
693 | |||
694 | if (start == end) { |
||
695 | if (parser->collection_stack_ptr) { |
||
696 | dbg("unbalanced collection at end of report description"); |
||
697 | kfree(device->collection); |
||
698 | hid_free_device(device); |
||
699 | kfree(parser); |
||
700 | return NULL; |
||
701 | } |
||
702 | if (parser->local.delimiter_depth) { |
||
703 | dbg("unbalanced delimiter at end of report description"); |
||
704 | kfree(device->collection); |
||
705 | hid_free_device(device); |
||
706 | kfree(parser); |
||
707 | return NULL; |
||
708 | } |
||
709 | kfree(parser); |
||
710 | return device; |
||
711 | } |
||
712 | } |
||
713 | |||
714 | dbg("item fetching failed at offset %d\n", (int)(end - start)); |
||
715 | kfree(device->collection); |
||
716 | hid_free_device(device); |
||
717 | kfree(parser); |
||
718 | return NULL; |
||
719 | } |
||
720 | |||
721 | /* |
||
722 | * Convert a signed n-bit integer to signed 32-bit integer. Common |
||
723 | * cases are done through the compiler, the screwed things has to be |
||
724 | * done by hand. |
||
725 | */ |
||
726 | |||
727 | static __inline__ __s32 snto32(__u32 value, unsigned n) |
||
728 | { |
||
729 | switch (n) { |
||
730 | case 8: return ((__s8)value); |
||
731 | case 16: return ((__s16)value); |
||
732 | case 32: return ((__s32)value); |
||
733 | } |
||
734 | return value & (1 << (n - 1)) ? value | (-1 << n) : value; |
||
735 | } |
||
736 | |||
737 | /* |
||
738 | * Convert a signed 32-bit integer to a signed n-bit integer. |
||
739 | */ |
||
740 | |||
741 | static __inline__ __u32 s32ton(__s32 value, unsigned n) |
||
742 | { |
||
743 | __s32 a = value >> (n - 1); |
||
744 | if (a && a != -1) |
||
745 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; |
||
746 | return value & ((1 << n) - 1); |
||
747 | } |
||
748 | |||
749 | /* |
||
750 | * Extract/implement a data field from/to a report. |
||
751 | */ |
||
752 | |||
753 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) |
||
754 | { |
||
755 | report += (offset >> 5) << 2; offset &= 31; |
||
756 | return (le64_to_cpu(get_unaligned((__u64*)report)) >> offset) & ((1 << n) - 1); |
||
757 | } |
||
758 | |||
759 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) |
||
760 | { |
||
761 | report += (offset >> 5) << 2; offset &= 31; |
||
762 | put_unaligned((get_unaligned((__u64*)report) |
||
763 | & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) |
||
764 | | cpu_to_le64((__u64)value << offset), (__u64*)report); |
||
765 | } |
||
766 | |||
767 | /* |
||
768 | * Search an array for a value. |
||
769 | */ |
||
770 | |||
771 | static __inline__ int search(__s32 *array, __s32 value, unsigned n) |
||
772 | { |
||
773 | while (n--) { |
||
774 | if (*array++ == value) |
||
775 | return 0; |
||
776 | } |
||
777 | return -1; |
||
778 | } |
||
779 | |||
780 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) |
||
781 | { |
||
782 | hid_dump_input(usage, value); |
||
783 | if (hid->claimed & HID_CLAIMED_INPUT) |
||
784 | hidinput_hid_event(hid, field, usage, value, regs); |
||
785 | if (hid->claimed & HID_CLAIMED_HIDDEV) |
||
786 | hiddev_hid_event(hid, field, usage, value, regs); |
||
787 | } |
||
788 | |||
789 | /* |
||
790 | * Analyse a received field, and fetch the data from it. The field |
||
791 | * content is stored for next report processing (we do differential |
||
792 | * reporting to the layer). |
||
793 | */ |
||
794 | |||
795 | static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs) |
||
796 | { |
||
797 | unsigned n; |
||
798 | unsigned count = field->report_count; |
||
799 | unsigned offset = field->report_offset; |
||
800 | unsigned size = field->report_size; |
||
801 | __s32 min = field->logical_minimum; |
||
802 | __s32 max = field->logical_maximum; |
||
803 | __s32 value[count]; /* WARNING: gcc specific */ |
||
804 | |||
805 | for (n = 0; n < count; n++) { |
||
806 | |||
807 | value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : |
||
808 | extract(data, offset + n * size, size); |
||
809 | |||
810 | if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ |
||
811 | && value[n] >= min && value[n] <= max |
||
812 | && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) |
||
813 | return; |
||
814 | } |
||
815 | |||
816 | for (n = 0; n < count; n++) { |
||
817 | |||
818 | if (HID_MAIN_ITEM_VARIABLE & field->flags) { |
||
819 | |||
820 | if (field->flags & HID_MAIN_ITEM_RELATIVE) { |
||
821 | if (!value[n]) |
||
822 | continue; |
||
823 | } else { |
||
824 | if (value[n] == field->value[n]) |
||
825 | continue; |
||
826 | } |
||
827 | hid_process_event(hid, field, &field->usage[n], value[n], regs); |
||
828 | continue; |
||
829 | } |
||
830 | |||
831 | if (field->value[n] >= min && field->value[n] <= max |
||
832 | && field->usage[field->value[n] - min].hid |
||
833 | && search(value, field->value[n], count)) |
||
834 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs); |
||
835 | |||
836 | if (value[n] >= min && value[n] <= max |
||
837 | && field->usage[value[n] - min].hid |
||
838 | && search(field->value, value[n], count)) |
||
839 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs); |
||
840 | } |
||
841 | |||
842 | memcpy(field->value, value, count * sizeof(__s32)); |
||
843 | } |
||
844 | |||
845 | static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) |
||
846 | { |
||
847 | struct hid_device *hid = urb->context; |
||
848 | struct hid_report_enum *report_enum = hid->report_enum + type; |
||
849 | u8 *data = urb->transfer_buffer; |
||
850 | int len = urb->actual_length; |
||
851 | struct hid_report *report; |
||
852 | int n, size; |
||
853 | |||
854 | if (!len) { |
||
855 | dbg("empty report"); |
||
856 | return -1; |
||
857 | } |
||
858 | |||
859 | #ifdef DEBUG_DATA |
||
860 | printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); |
||
861 | #endif |
||
862 | |||
863 | n = 0; /* Normally report number is 0 */ |
||
864 | if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ |
||
865 | n = *data++; |
||
866 | len--; |
||
867 | } |
||
868 | |||
869 | #ifdef DEBUG_DATA |
||
870 | { |
||
871 | int i; |
||
872 | printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); |
||
873 | for (i = 0; i < len; i++) |
||
874 | printk(" %02x", data[i]); |
||
875 | printk("\n"); |
||
876 | } |
||
877 | #endif |
||
878 | |||
879 | if (!(report = report_enum->report_id_hash[n])) { |
||
880 | dbg("undefined report_id %d received", n); |
||
881 | return -1; |
||
882 | } |
||
883 | |||
884 | size = ((report->size - 1) >> 3) + 1; |
||
885 | |||
886 | if (len < size) { |
||
887 | dbg("report %d is too short, (%d < %d)", report->id, len, size); |
||
888 | return -1; |
||
889 | } |
||
890 | |||
891 | if (hid->claimed & HID_CLAIMED_HIDDEV) |
||
892 | hiddev_report_event(hid, report); |
||
893 | |||
894 | for (n = 0; n < report->maxfield; n++) |
||
895 | hid_input_field(hid, report->field[n], data, regs); |
||
896 | |||
897 | if (hid->claimed & HID_CLAIMED_INPUT) |
||
898 | hidinput_report_event(hid, report); |
||
899 | |||
900 | return 0; |
||
901 | } |
||
902 | |||
903 | /* |
||
904 | * Input interrupt completion handler. |
||
905 | */ |
||
906 | |||
907 | static void hid_irq_in(struct urb *urb, struct pt_regs *regs) |
||
908 | { |
||
909 | struct hid_device *hid = urb->context; |
||
910 | int status; |
||
911 | |||
912 | switch (urb->status) { |
||
913 | case 0: /* success */ |
||
914 | hid_input_report(HID_INPUT_REPORT, urb, regs); |
||
915 | break; |
||
916 | case -ECONNRESET: /* unlink */ |
||
917 | case -ENOENT: |
||
918 | case -ESHUTDOWN: |
||
919 | return; |
||
920 | default: /* error */ |
||
921 | dbg("nonzero status in input irq %d", urb->status); |
||
922 | } |
||
923 | |||
924 | status = usb_submit_urb (urb, SLAB_ATOMIC); |
||
925 | if (status) |
||
926 | err ("can't resubmit intr, %s-%s/input%d, status %d", |
||
927 | hid->dev->bus->bus_name, hid->dev->devpath, |
||
928 | hid->ifnum, status); |
||
929 | } |
||
930 | |||
931 | /* |
||
932 | * Output the field into the report. |
||
933 | */ |
||
934 | |||
935 | static void hid_output_field(struct hid_field *field, __u8 *data) |
||
936 | { |
||
937 | unsigned count = field->report_count; |
||
938 | unsigned offset = field->report_offset; |
||
939 | unsigned size = field->report_size; |
||
940 | unsigned n; |
||
941 | |||
942 | for (n = 0; n < count; n++) { |
||
943 | if (field->logical_minimum < 0) /* signed values */ |
||
944 | implement(data, offset + n * size, size, s32ton(field->value[n], size)); |
||
945 | else /* unsigned values */ |
||
946 | implement(data, offset + n * size, size, field->value[n]); |
||
947 | } |
||
948 | } |
||
949 | |||
950 | /* |
||
951 | * Create a report. |
||
952 | */ |
||
953 | |||
954 | void hid_output_report(struct hid_report *report, __u8 *data) |
||
955 | { |
||
956 | unsigned n; |
||
957 | |||
958 | if (report->id > 0) |
||
959 | *data++ = report->id; |
||
960 | |||
961 | for (n = 0; n < report->maxfield; n++) |
||
962 | hid_output_field(report->field[n], data); |
||
963 | } |
||
964 | |||
965 | /* |
||
966 | * Set a field value. The report this field belongs to has to be |
||
967 | * created and transferred to the device, to set this value in the |
||
968 | * device. |
||
969 | */ |
||
970 | |||
971 | int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) |
||
972 | { |
||
973 | unsigned size = field->report_size; |
||
974 | |||
975 | hid_dump_input(field->usage + offset, value); |
||
976 | |||
977 | if (offset >= field->report_count) { |
||
978 | dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); |
||
979 | hid_dump_field(field, 8); |
||
980 | return -1; |
||
981 | } |
||
982 | if (field->logical_minimum < 0) { |
||
983 | if (value != snto32(s32ton(value, size), size)) { |
||
984 | dbg("value %d is out of range", value); |
||
985 | return -1; |
||
986 | } |
||
987 | } |
||
988 | field->value[offset] = value; |
||
989 | return 0; |
||
990 | } |
||
991 | |||
992 | int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) |
||
993 | { |
||
994 | struct hid_report_enum *report_enum = hid->report_enum + HID_OUTPUT_REPORT; |
||
995 | struct list_head *list = report_enum->report_list.next; |
||
996 | int i, j; |
||
997 | |||
998 | while (list != &report_enum->report_list) { |
||
999 | struct hid_report *report = (struct hid_report *) list; |
||
1000 | list = list->next; |
||
1001 | for (i = 0; i < report->maxfield; i++) { |
||
1002 | *field = report->field[i]; |
||
1003 | for (j = 0; j < (*field)->maxusage; j++) |
||
1004 | if ((*field)->usage[j].type == type && (*field)->usage[j].code == code) |
||
1005 | return j; |
||
1006 | } |
||
1007 | } |
||
1008 | return -1; |
||
1009 | } |
||
1010 | |||
1011 | /* |
||
1012 | * Find a report with a specified HID usage. |
||
1013 | */ |
||
1014 | |||
1015 | int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type) |
||
1016 | { |
||
1017 | struct hid_report_enum *report_enum = hid->report_enum + type; |
||
1018 | struct list_head *list = report_enum->report_list.next; |
||
1019 | int i, j; |
||
1020 | |||
1021 | while (list != &report_enum->report_list) { |
||
1022 | *report = (struct hid_report *) list; |
||
1023 | list = list->next; |
||
1024 | for (i = 0; i < (*report)->maxfield; i++) { |
||
1025 | struct hid_field *field = (*report)->field[i]; |
||
1026 | for (j = 0; j < field->maxusage; j++) |
||
1027 | if (field->logical == wanted_usage) |
||
1028 | return j; |
||
1029 | } |
||
1030 | } |
||
1031 | return -1; |
||
1032 | } |
||
1033 | |||
1034 | int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field) |
||
1035 | { |
||
1036 | int i, j; |
||
1037 | |||
1038 | for (i = 0; i < report->maxfield; i++) { |
||
1039 | *field = report->field[i]; |
||
1040 | for (j = 0; j < (*field)->maxusage; j++) |
||
1041 | if ((*field)->usage[j].hid == wanted_usage) |
||
1042 | return j; |
||
1043 | } |
||
1044 | |||
1045 | return -1; |
||
1046 | } |
||
1047 | |||
1048 | static int hid_submit_out(struct hid_device *hid) |
||
1049 | { |
||
1050 | struct hid_report *report; |
||
1051 | |||
1052 | report = hid->out[hid->outtail]; |
||
1053 | |||
1054 | hid_output_report(report, hid->outbuf); |
||
1055 | hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
||
1056 | hid->urbout->dev = hid->dev; |
||
1057 | |||
1058 | dbg("submitting out urb"); |
||
1059 | |||
1060 | if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { |
||
1061 | err("usb_submit_urb(out) failed"); |
||
1062 | return -1; |
||
1063 | } |
||
1064 | |||
1065 | return 0; |
||
1066 | } |
||
1067 | |||
1068 | static int hid_submit_ctrl(struct hid_device *hid) |
||
1069 | { |
||
1070 | struct hid_report *report; |
||
1071 | unsigned char dir; |
||
1072 | |||
1073 | report = hid->ctrl[hid->ctrltail].report; |
||
1074 | dir = hid->ctrl[hid->ctrltail].dir; |
||
1075 | |||
1076 | if (dir == USB_DIR_OUT) |
||
1077 | hid_output_report(report, hid->ctrlbuf); |
||
1078 | |||
1079 | hid->urbctrl->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
||
1080 | hid->urbctrl->pipe = (dir == USB_DIR_OUT) ? usb_sndctrlpipe(hid->dev, 0) : usb_rcvctrlpipe(hid->dev, 0); |
||
1081 | hid->urbctrl->dev = hid->dev; |
||
1082 | |||
1083 | hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; |
||
1084 | hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; |
||
1085 | hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); |
||
1086 | hid->cr->wIndex = cpu_to_le16(hid->ifnum); |
||
1087 | hid->cr->wLength = cpu_to_le16(hid->urbctrl->transfer_buffer_length); |
||
1088 | |||
1089 | dbg("submitting ctrl urb"); |
||
1090 | |||
1091 | if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { |
||
1092 | err("usb_submit_urb(ctrl) failed"); |
||
1093 | return -1; |
||
1094 | } |
||
1095 | |||
1096 | return 0; |
||
1097 | } |
||
1098 | |||
1099 | /* |
||
1100 | * Output interrupt completion handler. |
||
1101 | */ |
||
1102 | |||
1103 | static void hid_irq_out(struct urb *urb, struct pt_regs *regs) |
||
1104 | { |
||
1105 | struct hid_device *hid = urb->context; |
||
1106 | unsigned long flags; |
||
1107 | |||
1108 | if (urb->status) |
||
1109 | warn("output irq status %d received", urb->status); |
||
1110 | |||
1111 | spin_lock_irqsave(&hid->outlock, flags); |
||
1112 | |||
1113 | hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); |
||
1114 | |||
1115 | if (hid->outhead != hid->outtail) { |
||
1116 | hid_submit_out(hid); |
||
1117 | spin_unlock_irqrestore(&hid->outlock, flags); |
||
1118 | return; |
||
1119 | } |
||
1120 | |||
1121 | clear_bit(HID_OUT_RUNNING, &hid->iofl); |
||
1122 | |||
1123 | spin_unlock_irqrestore(&hid->outlock, flags); |
||
1124 | |||
1125 | wake_up(&hid->wait); |
||
1126 | } |
||
1127 | |||
1128 | /* |
||
1129 | * Control pipe completion handler. |
||
1130 | */ |
||
1131 | |||
1132 | static void hid_ctrl(struct urb *urb, struct pt_regs *regs) |
||
1133 | { |
||
1134 | struct hid_device *hid = urb->context; |
||
1135 | unsigned long flags; |
||
1136 | |||
1137 | if (urb->status) |
||
1138 | warn("ctrl urb status %d received", urb->status); |
||
1139 | |||
1140 | spin_lock_irqsave(&hid->ctrllock, flags); |
||
1141 | |||
1142 | if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) |
||
1143 | hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs); |
||
1144 | |||
1145 | hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); |
||
1146 | |||
1147 | if (hid->ctrlhead != hid->ctrltail) { |
||
1148 | hid_submit_ctrl(hid); |
||
1149 | spin_unlock_irqrestore(&hid->ctrllock, flags); |
||
1150 | return; |
||
1151 | } |
||
1152 | |||
1153 | clear_bit(HID_CTRL_RUNNING, &hid->iofl); |
||
1154 | |||
1155 | spin_unlock_irqrestore(&hid->ctrllock, flags); |
||
1156 | |||
1157 | wake_up(&hid->wait); |
||
1158 | } |
||
1159 | |||
1160 | void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) |
||
1161 | { |
||
1162 | int head; |
||
1163 | unsigned long flags; |
||
1164 | |||
1165 | if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) |
||
1166 | return; |
||
1167 | |||
1168 | if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { |
||
1169 | |||
1170 | spin_lock_irqsave(&hid->outlock, flags); |
||
1171 | |||
1172 | if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { |
||
1173 | spin_unlock_irqrestore(&hid->outlock, flags); |
||
1174 | warn("output queue full"); |
||
1175 | return; |
||
1176 | } |
||
1177 | |||
1178 | hid->out[hid->outhead] = report; |
||
1179 | hid->outhead = head; |
||
1180 | |||
1181 | if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) |
||
1182 | hid_submit_out(hid); |
||
1183 | |||
1184 | spin_unlock_irqrestore(&hid->outlock, flags); |
||
1185 | return; |
||
1186 | } |
||
1187 | |||
1188 | spin_lock_irqsave(&hid->ctrllock, flags); |
||
1189 | |||
1190 | if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { |
||
1191 | spin_unlock_irqrestore(&hid->ctrllock, flags); |
||
1192 | warn("control queue full"); |
||
1193 | return; |
||
1194 | } |
||
1195 | |||
1196 | hid->ctrl[hid->ctrlhead].report = report; |
||
1197 | hid->ctrl[hid->ctrlhead].dir = dir; |
||
1198 | hid->ctrlhead = head; |
||
1199 | |||
1200 | if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) |
||
1201 | hid_submit_ctrl(hid); |
||
1202 | |||
1203 | spin_unlock_irqrestore(&hid->ctrllock, flags); |
||
1204 | } |
||
1205 | |||
1206 | int hid_wait_io(struct hid_device *hid) |
||
1207 | { |
||
1208 | DECLARE_WAITQUEUE(wait, current); |
||
1209 | int timeout = 1*HZ; |
||
1210 | |||
1211 | set_current_state(TASK_UNINTERRUPTIBLE); |
||
1212 | add_wait_queue(&hid->wait, &wait); |
||
1213 | |||
1214 | while (timeout && (test_bit(HID_CTRL_RUNNING, &hid->iofl) || |
||
1215 | test_bit(HID_OUT_RUNNING, &hid->iofl))) |
||
1216 | timeout = schedule_timeout(timeout); |
||
1217 | |||
1218 | set_current_state(TASK_RUNNING); |
||
1219 | remove_wait_queue(&hid->wait, &wait); |
||
1220 | |||
1221 | /* if (!timeout) { |
||
1222 | dbg("timeout waiting for ctrl or out queue to clear"); |
||
1223 | return -1; |
||
1224 | } */ |
||
1225 | return 0; |
||
1226 | } |
||
1227 | |||
1228 | static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, |
||
1229 | unsigned char type, void *buf, int size) |
||
1230 | { |
||
1231 | return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
||
1232 | USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, |
||
1233 | (type << 8), ifnum, buf, size, HZ * USB_CTRL_GET_TIMEOUT); |
||
1234 | } |
||
1235 | |||
1236 | int hid_open(struct hid_device *hid) |
||
1237 | { |
||
1238 | if (hid->open++) |
||
1239 | return 0; |
||
1240 | |||
1241 | hid->urbin->dev = hid->dev; |
||
1242 | |||
1243 | if (usb_submit_urb(hid->urbin, GFP_KERNEL)) |
||
1244 | return -EIO; |
||
1245 | |||
1246 | return 0; |
||
1247 | } |
||
1248 | |||
1249 | void hid_close(struct hid_device *hid) |
||
1250 | { |
||
1251 | if (!--hid->open) |
||
1252 | usb_unlink_urb(hid->urbin); |
||
1253 | } |
||
1254 | |||
1255 | /* |
||
1256 | * Initialize all reports |
||
1257 | */ |
||
1258 | |||
1259 | void hid_init_reports(struct hid_device *hid) |
||
1260 | { |
||
1261 | struct hid_report_enum *report_enum; |
||
1262 | struct hid_report *report; |
||
1263 | struct list_head *list; |
||
1264 | int len; |
||
1265 | int err, ret; |
||
1266 | |||
1267 | report_enum = hid->report_enum + HID_INPUT_REPORT; |
||
1268 | list = report_enum->report_list.next; |
||
1269 | while (list != &report_enum->report_list) { |
||
1270 | report = (struct hid_report *) list; |
||
1271 | hid_submit_report(hid, report, USB_DIR_IN); |
||
1272 | list = list->next; |
||
1273 | } |
||
1274 | |||
1275 | report_enum = hid->report_enum + HID_FEATURE_REPORT; |
||
1276 | list = report_enum->report_list.next; |
||
1277 | while (list != &report_enum->report_list) { |
||
1278 | report = (struct hid_report *) list; |
||
1279 | hid_submit_report(hid, report, USB_DIR_IN); |
||
1280 | list = list->next; |
||
1281 | } |
||
1282 | |||
1283 | err = 0; |
||
1284 | while ((ret = hid_wait_io(hid))) { |
||
1285 | err |= ret; |
||
1286 | if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) |
||
1287 | usb_unlink_urb(hid->urbctrl); |
||
1288 | if (test_bit(HID_OUT_RUNNING, &hid->iofl)) |
||
1289 | usb_unlink_urb(hid->urbout); |
||
1290 | } |
||
1291 | |||
1292 | if (err) |
||
1293 | warn("timeout initializing reports\n"); |
||
1294 | |||
1295 | report_enum = hid->report_enum + HID_INPUT_REPORT; |
||
1296 | list = report_enum->report_list.next; |
||
1297 | while (list != &report_enum->report_list) { |
||
1298 | report = (struct hid_report *) list; |
||
1299 | len = ((report->size - 1) >> 3) + 1 + report_enum->numbered; |
||
1300 | if (len > hid->urbin->transfer_buffer_length) |
||
1301 | hid->urbin->transfer_buffer_length = len < HID_BUFFER_SIZE ? len : HID_BUFFER_SIZE; |
||
1302 | usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), |
||
1303 | 0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id, |
||
1304 | hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); |
||
1305 | list = list->next; |
||
1306 | } |
||
1307 | } |
||
1308 | |||
1309 | #define USB_VENDOR_ID_WACOM 0x056a |
||
1310 | #define USB_DEVICE_ID_WACOM_PENPARTNER 0x0000 |
||
1311 | #define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010 |
||
1312 | #define USB_DEVICE_ID_WACOM_INTUOS 0x0020 |
||
1313 | #define USB_DEVICE_ID_WACOM_PL 0x0030 |
||
1314 | #define USB_DEVICE_ID_WACOM_INTUOS2 0x0040 |
||
1315 | |||
1316 | #define USB_VENDOR_ID_KBGEAR 0x084e |
||
1317 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
||
1318 | |||
1319 | |||
1320 | #define USB_VENDOR_ID_AIPTEK 0x08ca |
||
1321 | #define USB_DEVICE_ID_AIPTEK_6000 0x0020 |
||
1322 | |||
1323 | #define USB_VENDOR_ID_GRIFFIN 0x077d |
||
1324 | #define USB_DEVICE_ID_POWERMATE 0x0410 |
||
1325 | #define USB_DEVICE_ID_SOUNDKNOB 0x04AA |
||
1326 | |||
1327 | #define USB_VENDOR_ID_ATEN 0x0557 |
||
1328 | #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 |
||
1329 | #define USB_DEVICE_ID_ATEN_CS124U 0x2202 |
||
1330 | #define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 |
||
1331 | #define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 |
||
1332 | #define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 |
||
1333 | |||
1334 | #define USB_VENDOR_ID_TOPMAX 0x0663 |
||
1335 | #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 |
||
1336 | |||
1337 | #define USB_VENDOR_ID_HAPP 0x078b |
||
1338 | #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 |
||
1339 | #define USB_DEVICE_ID_UGCI_FLYING 0x0020 |
||
1340 | #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 |
||
1341 | |||
1342 | #define USB_VENDOR_ID_MGE 0x0463 |
||
1343 | #define USB_DEVICE_ID_MGE_UPS 0xffff |
||
1344 | #define USB_DEVICE_ID_MGE_UPS1 0x0001 |
||
1345 | |||
1346 | #define USB_VENDOR_ID_ONTRAK 0x0a07 |
||
1347 | #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 |
||
1348 | |||
1349 | #define USB_VENDOR_ID_TANGTOP 0x0d3d |
||
1350 | #define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001 |
||
1351 | |||
1352 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f |
||
1353 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 |
||
1354 | |||
1355 | #define USB_VENDOR_ID_A4TECH 0x09DA |
||
1356 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 |
||
1357 | |||
1358 | struct hid_blacklist { |
||
1359 | __u16 idVendor; |
||
1360 | __u16 idProduct; |
||
1361 | unsigned quirks; |
||
1362 | } hid_blacklist[] = { |
||
1363 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE }, |
||
1364 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE }, |
||
1365 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE }, |
||
1366 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 2, HID_QUIRK_IGNORE }, |
||
1367 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS, HID_QUIRK_IGNORE }, |
||
1368 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1, HID_QUIRK_IGNORE }, |
||
1369 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2, HID_QUIRK_IGNORE }, |
||
1370 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3, HID_QUIRK_IGNORE }, |
||
1371 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4, HID_QUIRK_IGNORE }, |
||
1372 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL, HID_QUIRK_IGNORE }, |
||
1373 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 1, HID_QUIRK_IGNORE }, |
||
1374 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 2, HID_QUIRK_IGNORE }, |
||
1375 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE }, |
||
1376 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE }, |
||
1377 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE }, |
||
1378 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2, HID_QUIRK_IGNORE }, |
||
1379 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE }, |
||
1380 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE }, |
||
1381 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE }, |
||
1382 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE }, |
||
1383 | { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, |
||
1384 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_6000, HID_QUIRK_IGNORE }, |
||
1385 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, |
||
1386 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, |
||
1387 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
||
1388 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
||
1389 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, |
||
1390 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, |
||
1391 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, |
||
1392 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV }, |
||
1393 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV }, |
||
1394 | { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, |
||
1395 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD|HID_QUIRK_MULTI_INPUT }, |
||
1396 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD|HID_QUIRK_MULTI_INPUT }, |
||
1397 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD|HID_QUIRK_MULTI_INPUT }, |
||
1398 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, |
||
1399 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, |
||
1400 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, |
||
1401 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, |
||
1402 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, |
||
1403 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, |
||
1404 | { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, |
||
1405 | { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, |
||
1406 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK }, |
||
1407 | { 0, 0 } |
||
1408 | }; |
||
1409 | |||
1410 | static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) |
||
1411 | { |
||
1412 | if (!(hid->inbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->inbuf_dma))) |
||
1413 | return -1; |
||
1414 | if (!(hid->outbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->outbuf_dma))) |
||
1415 | return -1; |
||
1416 | if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) |
||
1417 | return -1; |
||
1418 | if (!(hid->ctrlbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->ctrlbuf_dma))) |
||
1419 | return -1; |
||
1420 | |||
1421 | return 0; |
||
1422 | } |
||
1423 | |||
1424 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) |
||
1425 | { |
||
1426 | if (hid->inbuf) |
||
1427 | usb_buffer_free(dev, HID_BUFFER_SIZE, hid->inbuf, hid->inbuf_dma); |
||
1428 | if (hid->outbuf) |
||
1429 | usb_buffer_free(dev, HID_BUFFER_SIZE, hid->outbuf, hid->outbuf_dma); |
||
1430 | if (hid->cr) |
||
1431 | usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); |
||
1432 | if (hid->ctrlbuf) |
||
1433 | usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma); |
||
1434 | } |
||
1435 | |||
1436 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) |
||
1437 | { |
||
1438 | struct usb_host_interface *interface = intf->altsetting + intf->act_altsetting; |
||
1439 | struct usb_device *dev = interface_to_usbdev (intf); |
||
1440 | struct hid_descriptor *hdesc; |
||
1441 | struct hid_device *hid; |
||
1442 | unsigned quirks = 0, rsize = 0; |
||
1443 | char *buf, *rdesc; |
||
1444 | int n; |
||
1445 | |||
1446 | for (n = 0; hid_blacklist[n].idVendor; n++) |
||
1447 | if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) && |
||
1448 | (hid_blacklist[n].idProduct == dev->descriptor.idProduct)) |
||
1449 | quirks = hid_blacklist[n].quirks; |
||
1450 | |||
1451 | if (quirks & HID_QUIRK_IGNORE) |
||
1452 | return NULL; |
||
1453 | |||
1454 | if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) || |
||
1455 | usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { |
||
1456 | dbg("class descriptor not present\n"); |
||
1457 | return NULL; |
||
1458 | } |
||
1459 | |||
1460 | for (n = 0; n < hdesc->bNumDescriptors; n++) |
||
1461 | if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) |
||
1462 | rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); |
||
1463 | |||
1464 | if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { |
||
1465 | dbg("weird size of report descriptor (%u)", rsize); |
||
1466 | return NULL; |
||
1467 | } |
||
1468 | |||
1469 | if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { |
||
1470 | dbg("couldn't allocate rdesc memory"); |
||
1471 | return NULL; |
||
1472 | } |
||
1473 | |||
1474 | if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { |
||
1475 | dbg("reading report descriptor failed"); |
||
1476 | kfree(rdesc); |
||
1477 | return NULL; |
||
1478 | } |
||
1479 | |||
1480 | #ifdef DEBUG_DATA |
||
1481 | printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); |
||
1482 | for (n = 0; n < rsize; n++) |
||
1483 | printk(" %02x", (unsigned char) rdesc[n]); |
||
1484 | printk("\n"); |
||
1485 | #endif |
||
1486 | |||
1487 | if (!(hid = hid_parse_report(rdesc, rsize))) { |
||
1488 | dbg("parsing report descriptor failed"); |
||
1489 | kfree(rdesc); |
||
1490 | return NULL; |
||
1491 | } |
||
1492 | |||
1493 | kfree(rdesc); |
||
1494 | hid->quirks = quirks; |
||
1495 | |||
1496 | if (hid_alloc_buffers(dev, hid)) { |
||
1497 | hid_free_buffers(dev, hid); |
||
1498 | goto fail; |
||
1499 | } |
||
1500 | |||
1501 | for (n = 0; n < interface->desc.bNumEndpoints; n++) { |
||
1502 | |||
1503 | struct usb_endpoint_descriptor *endpoint; |
||
1504 | int pipe; |
||
1505 | |||
1506 | endpoint = &interface->endpoint[n].desc; |
||
1507 | if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ |
||
1508 | continue; |
||
1509 | |||
1510 | if (endpoint->bEndpointAddress & USB_DIR_IN) { |
||
1511 | if (hid->urbin) |
||
1512 | continue; |
||
1513 | if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) |
||
1514 | goto fail; |
||
1515 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
||
1516 | usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0, |
||
1517 | hid_irq_in, hid, endpoint->bInterval); |
||
1518 | hid->urbin->transfer_dma = hid->inbuf_dma; |
||
1519 | hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
||
1520 | } else { |
||
1521 | if (hid->urbout) |
||
1522 | continue; |
||
1523 | if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) |
||
1524 | goto fail; |
||
1525 | pipe = usb_sndbulkpipe(dev, endpoint->bEndpointAddress); |
||
1526 | usb_fill_bulk_urb(hid->urbout, dev, pipe, hid->outbuf, 0, |
||
1527 | hid_irq_out, hid); |
||
1528 | hid->urbout->transfer_dma = hid->outbuf_dma; |
||
1529 | hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
||
1530 | } |
||
1531 | } |
||
1532 | |||
1533 | if (!hid->urbin) { |
||
1534 | err("couldn't find an input interrupt endpoint"); |
||
1535 | goto fail; |
||
1536 | } |
||
1537 | |||
1538 | init_waitqueue_head(&hid->wait); |
||
1539 | |||
1540 | hid->outlock = SPIN_LOCK_UNLOCKED; |
||
1541 | hid->ctrllock = SPIN_LOCK_UNLOCKED; |
||
1542 | |||
1543 | hid->version = le16_to_cpu(hdesc->bcdHID); |
||
1544 | hid->country = hdesc->bCountryCode; |
||
1545 | hid->dev = dev; |
||
1546 | hid->ifnum = interface->desc.bInterfaceNumber; |
||
1547 | |||
1548 | hid->name[0] = 0; |
||
1549 | |||
1550 | if (!(buf = kmalloc(64, GFP_KERNEL))) |
||
1551 | goto fail; |
||
1552 | |||
1553 | if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) { |
||
1554 | strcat(hid->name, buf); |
||
1555 | if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0) |
||
1556 | snprintf26(hid->name, 64, "%s %s", hid->name, buf); |
||
1557 | } else if (usb_string(dev, dev->descriptor.iProduct, buf, 128) > 0) { |
||
1558 | snprintf26(hid->name, 128, "%s", buf); |
||
1559 | } else |
||
1560 | snprintf26(hid->name, 128, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct); |
||
1561 | |||
1562 | usb_make_path(dev, buf, 64); |
||
1563 | snprintf26(hid->phys, 64, "%s/input%d", buf, |
||
1564 | intf->altsetting[0].desc.bInterfaceNumber); |
||
1565 | |||
1566 | if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) |
||
1567 | hid->uniq[0] = 0; |
||
1568 | |||
1569 | kfree(buf); |
||
1570 | |||
1571 | hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); |
||
1572 | if (!hid->urbctrl) |
||
1573 | goto fail; |
||
1574 | usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, |
||
1575 | hid->ctrlbuf, 1, hid_ctrl, hid); |
||
1576 | hid->urbctrl->setup_dma = hid->cr_dma; |
||
1577 | hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; |
||
1578 | hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP |
||
1579 | | URB_NO_SETUP_DMA_MAP); |
||
1580 | |||
1581 | return hid; |
||
1582 | |||
1583 | fail: |
||
1584 | |||
1585 | if (hid->urbin) |
||
1586 | usb_free_urb(hid->urbin); |
||
1587 | if (hid->urbout) |
||
1588 | usb_free_urb(hid->urbout); |
||
1589 | if (hid->urbctrl) |
||
1590 | usb_free_urb(hid->urbctrl); |
||
1591 | hid_free_buffers(dev, hid); |
||
1592 | hid_free_device(hid); |
||
1593 | |||
1594 | return NULL; |
||
1595 | } |
||
1596 | |||
1597 | static void hid_disconnect(struct usb_interface *intf) |
||
1598 | { |
||
1599 | struct hid_device *hid = usb_get_intfdata (intf); |
||
1600 | |||
1601 | if (!hid) |
||
1602 | return; |
||
1603 | |||
1604 | usb_set_intfdata(intf, NULL); |
||
1605 | usb_unlink_urb(hid->urbin); |
||
1606 | usb_unlink_urb(hid->urbout); |
||
1607 | usb_unlink_urb(hid->urbctrl); |
||
1608 | |||
1609 | if (hid->claimed & HID_CLAIMED_INPUT) |
||
1610 | hidinput_disconnect(hid); |
||
1611 | if (hid->claimed & HID_CLAIMED_HIDDEV) |
||
1612 | hiddev_disconnect(hid); |
||
1613 | |||
1614 | usb_free_urb(hid->urbin); |
||
1615 | usb_free_urb(hid->urbctrl); |
||
1616 | if (hid->urbout) |
||
1617 | usb_free_urb(hid->urbout); |
||
1618 | |||
1619 | hid_free_buffers(hid->dev, hid); |
||
1620 | hid_free_device(hid); |
||
1621 | } |
||
1622 | |||
1623 | static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id) |
||
1624 | { |
||
1625 | struct hid_device *hid; |
||
1626 | char path[64]; |
||
1627 | int i; |
||
1628 | char *c; |
||
1629 | |||
1630 | dbg("HID probe called for ifnum %d", |
||
1631 | intf->altsetting->desc.bInterfaceNumber); |
||
1632 | |||
1633 | if (!(hid = usb_hid_configure(intf))) |
||
1634 | return -EIO; |
||
1635 | |||
1636 | hid_init_reports(hid); |
||
1637 | hid_dump_device(hid); |
||
1638 | |||
1639 | if (!hidinput_connect(hid)) |
||
1640 | hid->claimed |= HID_CLAIMED_INPUT; |
||
1641 | if (!hiddev_connect(hid)) |
||
1642 | hid->claimed |= HID_CLAIMED_HIDDEV; |
||
1643 | |||
1644 | usb_set_intfdata(intf, hid); |
||
1645 | |||
1646 | if (!hid->claimed) { |
||
1647 | printk ("HID device not claimed by input or hiddev\n"); |
||
1648 | hid_disconnect(intf); |
||
1649 | return -EIO; |
||
1650 | } |
||
1651 | |||
1652 | printk(KERN_INFO); |
||
1653 | |||
1654 | if (hid->claimed & HID_CLAIMED_INPUT) |
||
1655 | printk("input"); |
||
1656 | if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV)) |
||
1657 | printk(","); |
||
1658 | if (hid->claimed & HID_CLAIMED_HIDDEV) |
||
1659 | printk("hiddev%d", hid->minor); |
||
1660 | |||
1661 | c = "Device"; |
||
1662 | for (i = 0; i < hid->maxcollection; i++) { |
||
1663 | if (hid->collection[i].type == HID_COLLECTION_APPLICATION && |
||
1664 | (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && |
||
1665 | (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { |
||
1666 | c = hid_types[hid->collection[i].usage & 0xffff]; |
||
1667 | break; |
||
1668 | } |
||
1669 | } |
||
1670 | |||
1671 | usb_make_path(interface_to_usbdev(intf), path, 63); |
||
1672 | |||
1673 | printk(": USB HID v%x.%02x %s [%s] on %s\n", |
||
1674 | hid->version >> 8, hid->version & 0xff, c, hid->name, path); |
||
1675 | |||
1676 | return 0; |
||
1677 | } |
||
1678 | |||
1679 | static struct usb_device_id hid_usb_ids [] = { |
||
1680 | { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, |
||
1681 | .bInterfaceClass = USB_INTERFACE_CLASS_HID }, |
||
1682 | { } /* Terminating entry */ |
||
1683 | }; |
||
1684 | |||
1685 | MODULE_DEVICE_TABLE (usb, hid_usb_ids); |
||
1686 | |||
1687 | static struct usb_driver hid_driver = { |
||
1688 | .owner = THIS_MODULE, |
||
1689 | .name = "hid", |
||
1690 | .probe = hid_probe, |
||
1691 | .disconnect = hid_disconnect, |
||
1692 | .id_table = hid_usb_ids, |
||
1693 | }; |
||
1694 | |||
1695 | /*static*/ int __init hid_init(void) |
||
1696 | { |
||
1697 | int retval; |
||
1698 | retval = hiddev_init(); |
||
1699 | if (retval) |
||
1700 | goto hiddev_init_fail; |
||
1701 | retval = usb_register(&hid_driver); |
||
1702 | if (retval) |
||
1703 | goto usb_register_fail; |
||
1704 | info(DRIVER_VERSION ":" DRIVER_DESC); |
||
1705 | |||
1706 | return 0; |
||
1707 | usb_register_fail: |
||
1708 | hiddev_exit(); |
||
1709 | hiddev_init_fail: |
||
1710 | return retval; |
||
1711 | } |
||
1712 | |||
1713 | /*static*/ void __exit hid_exit(void) |
||
1714 | { |
||
1715 | hiddev_exit(); |
||
1716 | usb_deregister(&hid_driver); |
||
1717 | } |
||
1718 | |||
1719 | module_init(hid_init); |
||
1720 | module_exit(hid_exit); |
||
1721 | |||
1722 | MODULE_AUTHOR(DRIVER_AUTHOR); |
||
1723 | MODULE_DESCRIPTION(DRIVER_DESC); |
||
1724 | MODULE_LICENSE(DRIVER_LICENSE); |