diff options
Diffstat (limited to 'drivers/usb/input')
-rw-r--r-- | drivers/usb/input/ati_remote.c | 173 | ||||
-rw-r--r-- | drivers/usb/input/hid-input.c | 3 | ||||
-rw-r--r-- | drivers/usb/input/hiddev.c | 72 |
3 files changed, 139 insertions, 109 deletions
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index df198cf76f52..3719fcb04b8f 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c | |||
@@ -111,14 +111,28 @@ | |||
111 | #define NAME_BUFSIZE 80 /* size of product name, path buffers */ | 111 | #define NAME_BUFSIZE 80 /* size of product name, path buffers */ |
112 | #define DATA_BUFSIZE 63 /* size of URB data buffers */ | 112 | #define DATA_BUFSIZE 63 /* size of URB data buffers */ |
113 | 113 | ||
114 | /* | ||
115 | * Duplicate event filtering time. | ||
116 | * Sequential, identical KIND_FILTERED inputs with less than | ||
117 | * FILTER_TIME milliseconds between them are considered as repeat | ||
118 | * events. The hardware generates 5 events for the first keypress | ||
119 | * and we have to take this into account for an accurate repeat | ||
120 | * behaviour. | ||
121 | */ | ||
122 | #define FILTER_TIME 60 /* msec */ | ||
123 | |||
114 | static unsigned long channel_mask; | 124 | static unsigned long channel_mask; |
115 | module_param(channel_mask, ulong, 0444); | 125 | module_param(channel_mask, ulong, 0644); |
116 | MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore"); | 126 | MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore"); |
117 | 127 | ||
118 | static int debug; | 128 | static int debug; |
119 | module_param(debug, int, 0444); | 129 | module_param(debug, int, 0644); |
120 | MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); | 130 | MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); |
121 | 131 | ||
132 | static int repeat_filter = FILTER_TIME; | ||
133 | module_param(repeat_filter, int, 0644); | ||
134 | MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec"); | ||
135 | |||
122 | #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) | 136 | #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) |
123 | #undef err | 137 | #undef err |
124 | #define err(format, arg...) printk(KERN_ERR format , ## arg) | 138 | #define err(format, arg...) printk(KERN_ERR format , ## arg) |
@@ -143,18 +157,6 @@ MODULE_DEVICE_TABLE(usb, ati_remote_table); | |||
143 | static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; | 157 | static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; |
144 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; | 158 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; |
145 | 159 | ||
146 | /* Acceleration curve for directional control pad */ | ||
147 | static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | ||
148 | |||
149 | /* Duplicate event filtering time. | ||
150 | * Sequential, identical KIND_FILTERED inputs with less than | ||
151 | * FILTER_TIME jiffies between them are considered as repeat | ||
152 | * events. The hardware generates 5 events for the first keypress | ||
153 | * and we have to take this into account for an accurate repeat | ||
154 | * behaviour. | ||
155 | */ | ||
156 | #define FILTER_TIME 60 /* msec */ | ||
157 | |||
158 | struct ati_remote { | 160 | struct ati_remote { |
159 | struct input_dev *idev; | 161 | struct input_dev *idev; |
160 | struct usb_device *udev; | 162 | struct usb_device *udev; |
@@ -412,6 +414,43 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2) | |||
412 | } | 414 | } |
413 | 415 | ||
414 | /* | 416 | /* |
417 | * ati_remote_compute_accel | ||
418 | * | ||
419 | * Implements acceleration curve for directional control pad | ||
420 | * If elapsed time since last event is > 1/4 second, user "stopped", | ||
421 | * so reset acceleration. Otherwise, user is probably holding the control | ||
422 | * pad down, so we increase acceleration, ramping up over two seconds to | ||
423 | * a maximum speed. | ||
424 | */ | ||
425 | static int ati_remote_compute_accel(struct ati_remote *ati_remote) | ||
426 | { | ||
427 | static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | ||
428 | unsigned long now = jiffies; | ||
429 | int acc; | ||
430 | |||
431 | if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) { | ||
432 | acc = 1; | ||
433 | ati_remote->acc_jiffies = now; | ||
434 | } | ||
435 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125))) | ||
436 | acc = accel[0]; | ||
437 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250))) | ||
438 | acc = accel[1]; | ||
439 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500))) | ||
440 | acc = accel[2]; | ||
441 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000))) | ||
442 | acc = accel[3]; | ||
443 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500))) | ||
444 | acc = accel[4]; | ||
445 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000))) | ||
446 | acc = accel[5]; | ||
447 | else | ||
448 | acc = accel[6]; | ||
449 | |||
450 | return acc; | ||
451 | } | ||
452 | |||
453 | /* | ||
415 | * ati_remote_report_input | 454 | * ati_remote_report_input |
416 | */ | 455 | */ |
417 | static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | 456 | static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) |
@@ -464,9 +503,9 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
464 | 503 | ||
465 | if (ati_remote_tbl[index].kind == KIND_FILTERED) { | 504 | if (ati_remote_tbl[index].kind == KIND_FILTERED) { |
466 | /* Filter duplicate events which happen "too close" together. */ | 505 | /* Filter duplicate events which happen "too close" together. */ |
467 | if ((ati_remote->old_data[0] == data[1]) && | 506 | if (ati_remote->old_data[0] == data[1] && |
468 | (ati_remote->old_data[1] == data[2]) && | 507 | ati_remote->old_data[1] == data[2] && |
469 | time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(FILTER_TIME))) { | 508 | time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(repeat_filter))) { |
470 | ati_remote->repeat_count++; | 509 | ati_remote->repeat_count++; |
471 | } else { | 510 | } else { |
472 | ati_remote->repeat_count = 0; | 511 | ati_remote->repeat_count = 0; |
@@ -476,75 +515,61 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
476 | ati_remote->old_data[1] = data[2]; | 515 | ati_remote->old_data[1] = data[2]; |
477 | ati_remote->old_jiffies = jiffies; | 516 | ati_remote->old_jiffies = jiffies; |
478 | 517 | ||
479 | if ((ati_remote->repeat_count > 0) | 518 | if (ati_remote->repeat_count > 0 && |
480 | && (ati_remote->repeat_count < 5)) | 519 | ati_remote->repeat_count < 5) |
481 | return; | 520 | return; |
482 | 521 | ||
483 | 522 | ||
484 | input_regs(dev, regs); | 523 | input_regs(dev, regs); |
485 | input_event(dev, ati_remote_tbl[index].type, | 524 | input_event(dev, ati_remote_tbl[index].type, |
486 | ati_remote_tbl[index].code, 1); | 525 | ati_remote_tbl[index].code, 1); |
526 | input_sync(dev); | ||
487 | input_event(dev, ati_remote_tbl[index].type, | 527 | input_event(dev, ati_remote_tbl[index].type, |
488 | ati_remote_tbl[index].code, 0); | 528 | ati_remote_tbl[index].code, 0); |
489 | input_sync(dev); | 529 | input_sync(dev); |
490 | 530 | ||
491 | return; | 531 | } else { |
492 | } | ||
493 | 532 | ||
494 | /* | 533 | /* |
495 | * Other event kinds are from the directional control pad, and have an | 534 | * Other event kinds are from the directional control pad, and have an |
496 | * acceleration factor applied to them. Without this acceleration, the | 535 | * acceleration factor applied to them. Without this acceleration, the |
497 | * control pad is mostly unusable. | 536 | * control pad is mostly unusable. |
498 | * | 537 | */ |
499 | * If elapsed time since last event is > 1/4 second, user "stopped", | 538 | acc = ati_remote_compute_accel(ati_remote); |
500 | * so reset acceleration. Otherwise, user is probably holding the control | 539 | |
501 | * pad down, so we increase acceleration, ramping up over two seconds to | 540 | input_regs(dev, regs); |
502 | * a maximum speed. The acceleration curve is #defined above. | 541 | switch (ati_remote_tbl[index].kind) { |
503 | */ | 542 | case KIND_ACCEL: |
504 | if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) { | 543 | input_event(dev, ati_remote_tbl[index].type, |
505 | acc = 1; | 544 | ati_remote_tbl[index].code, |
506 | ati_remote->acc_jiffies = jiffies; | 545 | ati_remote_tbl[index].value * acc); |
507 | } | 546 | break; |
508 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3))) acc = accel[0]; | 547 | case KIND_LU: |
509 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2))) acc = accel[1]; | 548 | input_report_rel(dev, REL_X, -acc); |
510 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1))) acc = accel[2]; | 549 | input_report_rel(dev, REL_Y, -acc); |
511 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ)) acc = accel[3]; | 550 | break; |
512 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4]; | 551 | case KIND_RU: |
513 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1))) acc = accel[5]; | 552 | input_report_rel(dev, REL_X, acc); |
514 | else acc = accel[6]; | 553 | input_report_rel(dev, REL_Y, -acc); |
515 | 554 | break; | |
516 | input_regs(dev, regs); | 555 | case KIND_LD: |
517 | switch (ati_remote_tbl[index].kind) { | 556 | input_report_rel(dev, REL_X, -acc); |
518 | case KIND_ACCEL: | 557 | input_report_rel(dev, REL_Y, acc); |
519 | input_event(dev, ati_remote_tbl[index].type, | 558 | break; |
520 | ati_remote_tbl[index].code, | 559 | case KIND_RD: |
521 | ati_remote_tbl[index].value * acc); | 560 | input_report_rel(dev, REL_X, acc); |
522 | break; | 561 | input_report_rel(dev, REL_Y, acc); |
523 | case KIND_LU: | 562 | break; |
524 | input_report_rel(dev, REL_X, -acc); | 563 | default: |
525 | input_report_rel(dev, REL_Y, -acc); | 564 | dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", |
526 | break; | 565 | ati_remote_tbl[index].kind); |
527 | case KIND_RU: | 566 | } |
528 | input_report_rel(dev, REL_X, acc); | 567 | input_sync(dev); |
529 | input_report_rel(dev, REL_Y, -acc); | ||
530 | break; | ||
531 | case KIND_LD: | ||
532 | input_report_rel(dev, REL_X, -acc); | ||
533 | input_report_rel(dev, REL_Y, acc); | ||
534 | break; | ||
535 | case KIND_RD: | ||
536 | input_report_rel(dev, REL_X, acc); | ||
537 | input_report_rel(dev, REL_Y, acc); | ||
538 | break; | ||
539 | default: | ||
540 | dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", | ||
541 | ati_remote_tbl[index].kind); | ||
542 | } | ||
543 | input_sync(dev); | ||
544 | 568 | ||
545 | ati_remote->old_jiffies = jiffies; | 569 | ati_remote->old_jiffies = jiffies; |
546 | ati_remote->old_data[0] = data[1]; | 570 | ati_remote->old_data[0] = data[1]; |
547 | ati_remote->old_data[1] = data[2]; | 571 | ati_remote->old_data[1] = data[2]; |
572 | } | ||
548 | } | 573 | } |
549 | 574 | ||
550 | /* | 575 | /* |
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 028e1ad89f5d..7208839f2dbf 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
@@ -607,7 +607,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
607 | 607 | ||
608 | } | 608 | } |
609 | 609 | ||
610 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 610 | if (usage->type == EV_ABS && |
611 | (usage->hat_min < usage->hat_max || usage->hat_dir)) { | ||
611 | int i; | 612 | int i; |
612 | for (i = usage->code; i < usage->code + 2 && i <= max; i++) { | 613 | for (i = usage->code; i < usage->code + 2 && i <= max; i++) { |
613 | input_set_abs_params(input, i, -1, 1, 0, 0); | 614 | input_set_abs_params(input, i, -1, 1, 0, 0); |
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 70477f02cc29..f6b839c257a7 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
@@ -49,7 +49,7 @@ struct hiddev { | |||
49 | int open; | 49 | int open; |
50 | wait_queue_head_t wait; | 50 | wait_queue_head_t wait; |
51 | struct hid_device *hid; | 51 | struct hid_device *hid; |
52 | struct hiddev_list *list; | 52 | struct list_head list; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | struct hiddev_list { | 55 | struct hiddev_list { |
@@ -59,7 +59,7 @@ struct hiddev_list { | |||
59 | unsigned flags; | 59 | unsigned flags; |
60 | struct fasync_struct *fasync; | 60 | struct fasync_struct *fasync; |
61 | struct hiddev *hiddev; | 61 | struct hiddev *hiddev; |
62 | struct hiddev_list *next; | 62 | struct list_head node; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static struct hiddev *hiddev_table[HIDDEV_MINORS]; | 65 | static struct hiddev *hiddev_table[HIDDEV_MINORS]; |
@@ -73,12 +73,15 @@ static struct hiddev *hiddev_table[HIDDEV_MINORS]; | |||
73 | static struct hid_report * | 73 | static struct hid_report * |
74 | hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) | 74 | hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) |
75 | { | 75 | { |
76 | unsigned flags = rinfo->report_id & ~HID_REPORT_ID_MASK; | 76 | unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK; |
77 | unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK; | ||
77 | struct hid_report_enum *report_enum; | 78 | struct hid_report_enum *report_enum; |
79 | struct hid_report *report; | ||
78 | struct list_head *list; | 80 | struct list_head *list; |
79 | 81 | ||
80 | if (rinfo->report_type < HID_REPORT_TYPE_MIN || | 82 | if (rinfo->report_type < HID_REPORT_TYPE_MIN || |
81 | rinfo->report_type > HID_REPORT_TYPE_MAX) return NULL; | 83 | rinfo->report_type > HID_REPORT_TYPE_MAX) |
84 | return NULL; | ||
82 | 85 | ||
83 | report_enum = hid->report_enum + | 86 | report_enum = hid->report_enum + |
84 | (rinfo->report_type - HID_REPORT_TYPE_MIN); | 87 | (rinfo->report_type - HID_REPORT_TYPE_MIN); |
@@ -88,21 +91,25 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) | |||
88 | break; | 91 | break; |
89 | 92 | ||
90 | case HID_REPORT_ID_FIRST: | 93 | case HID_REPORT_ID_FIRST: |
91 | list = report_enum->report_list.next; | 94 | if (list_empty(&report_enum->report_list)) |
92 | if (list == &report_enum->report_list) | ||
93 | return NULL; | 95 | return NULL; |
94 | rinfo->report_id = ((struct hid_report *) list)->id; | 96 | |
97 | list = report_enum->report_list.next; | ||
98 | report = list_entry(list, struct hid_report, list); | ||
99 | rinfo->report_id = report->id; | ||
95 | break; | 100 | break; |
96 | 101 | ||
97 | case HID_REPORT_ID_NEXT: | 102 | case HID_REPORT_ID_NEXT: |
98 | list = (struct list_head *) | 103 | report = report_enum->report_id_hash[rid]; |
99 | report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK]; | 104 | if (!report) |
100 | if (list == NULL) | ||
101 | return NULL; | 105 | return NULL; |
102 | list = list->next; | 106 | |
107 | list = report->list.next; | ||
103 | if (list == &report_enum->report_list) | 108 | if (list == &report_enum->report_list) |
104 | return NULL; | 109 | return NULL; |
105 | rinfo->report_id = ((struct hid_report *) list)->id; | 110 | |
111 | report = list_entry(list, struct hid_report, list); | ||
112 | rinfo->report_id = report->id; | ||
106 | break; | 113 | break; |
107 | 114 | ||
108 | default: | 115 | default: |
@@ -125,12 +132,13 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref) | |||
125 | struct hid_field *field; | 132 | struct hid_field *field; |
126 | 133 | ||
127 | if (uref->report_type < HID_REPORT_TYPE_MIN || | 134 | if (uref->report_type < HID_REPORT_TYPE_MIN || |
128 | uref->report_type > HID_REPORT_TYPE_MAX) return NULL; | 135 | uref->report_type > HID_REPORT_TYPE_MAX) |
136 | return NULL; | ||
129 | 137 | ||
130 | report_enum = hid->report_enum + | 138 | report_enum = hid->report_enum + |
131 | (uref->report_type - HID_REPORT_TYPE_MIN); | 139 | (uref->report_type - HID_REPORT_TYPE_MIN); |
132 | 140 | ||
133 | list_for_each_entry(report, &report_enum->report_list, list) | 141 | list_for_each_entry(report, &report_enum->report_list, list) { |
134 | for (i = 0; i < report->maxfield; i++) { | 142 | for (i = 0; i < report->maxfield; i++) { |
135 | field = report->field[i]; | 143 | field = report->field[i]; |
136 | for (j = 0; j < field->maxusage; j++) { | 144 | for (j = 0; j < field->maxusage; j++) { |
@@ -142,6 +150,7 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref) | |||
142 | } | 150 | } |
143 | } | 151 | } |
144 | } | 152 | } |
153 | } | ||
145 | 154 | ||
146 | return NULL; | 155 | return NULL; |
147 | } | 156 | } |
@@ -150,9 +159,9 @@ static void hiddev_send_event(struct hid_device *hid, | |||
150 | struct hiddev_usage_ref *uref) | 159 | struct hiddev_usage_ref *uref) |
151 | { | 160 | { |
152 | struct hiddev *hiddev = hid->hiddev; | 161 | struct hiddev *hiddev = hid->hiddev; |
153 | struct hiddev_list *list = hiddev->list; | 162 | struct hiddev_list *list; |
154 | 163 | ||
155 | while (list) { | 164 | list_for_each_entry(list, &hiddev->list, node) { |
156 | if (uref->field_index != HID_FIELD_INDEX_NONE || | 165 | if (uref->field_index != HID_FIELD_INDEX_NONE || |
157 | (list->flags & HIDDEV_FLAG_REPORT) != 0) { | 166 | (list->flags & HIDDEV_FLAG_REPORT) != 0) { |
158 | list->buffer[list->head] = *uref; | 167 | list->buffer[list->head] = *uref; |
@@ -160,8 +169,6 @@ static void hiddev_send_event(struct hid_device *hid, | |||
160 | (HIDDEV_BUFFER_SIZE - 1); | 169 | (HIDDEV_BUFFER_SIZE - 1); |
161 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 170 | kill_fasync(&list->fasync, SIGIO, POLL_IN); |
162 | } | 171 | } |
163 | |||
164 | list = list->next; | ||
165 | } | 172 | } |
166 | 173 | ||
167 | wake_up_interruptible(&hiddev->wait); | 174 | wake_up_interruptible(&hiddev->wait); |
@@ -180,7 +187,7 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, | |||
180 | uref.report_type = | 187 | uref.report_type = |
181 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : | 188 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : |
182 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : | 189 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : |
183 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); | 190 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0)); |
184 | uref.report_id = field->report->id; | 191 | uref.report_id = field->report->id; |
185 | uref.field_index = field->index; | 192 | uref.field_index = field->index; |
186 | uref.usage_index = (usage - field->usage); | 193 | uref.usage_index = (usage - field->usage); |
@@ -200,7 +207,7 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report) | |||
200 | uref.report_type = | 207 | uref.report_type = |
201 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : | 208 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : |
202 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : | 209 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : |
203 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); | 210 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0)); |
204 | uref.report_id = report->id; | 211 | uref.report_id = report->id; |
205 | uref.field_index = HID_FIELD_INDEX_NONE; | 212 | uref.field_index = HID_FIELD_INDEX_NONE; |
206 | 213 | ||
@@ -213,7 +220,9 @@ static int hiddev_fasync(int fd, struct file *file, int on) | |||
213 | { | 220 | { |
214 | int retval; | 221 | int retval; |
215 | struct hiddev_list *list = file->private_data; | 222 | struct hiddev_list *list = file->private_data; |
223 | |||
216 | retval = fasync_helper(fd, file, on, &list->fasync); | 224 | retval = fasync_helper(fd, file, on, &list->fasync); |
225 | |||
217 | return retval < 0 ? retval : 0; | 226 | return retval < 0 ? retval : 0; |
218 | } | 227 | } |
219 | 228 | ||
@@ -224,14 +233,9 @@ static int hiddev_fasync(int fd, struct file *file, int on) | |||
224 | static int hiddev_release(struct inode * inode, struct file * file) | 233 | static int hiddev_release(struct inode * inode, struct file * file) |
225 | { | 234 | { |
226 | struct hiddev_list *list = file->private_data; | 235 | struct hiddev_list *list = file->private_data; |
227 | struct hiddev_list **listptr; | ||
228 | 236 | ||
229 | listptr = &list->hiddev->list; | ||
230 | hiddev_fasync(-1, file, 0); | 237 | hiddev_fasync(-1, file, 0); |
231 | 238 | list_del(&list->node); | |
232 | while (*listptr && (*listptr != list)) | ||
233 | listptr = &((*listptr)->next); | ||
234 | *listptr = (*listptr)->next; | ||
235 | 239 | ||
236 | if (!--list->hiddev->open) { | 240 | if (!--list->hiddev->open) { |
237 | if (list->hiddev->exist) | 241 | if (list->hiddev->exist) |
@@ -248,7 +252,8 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
248 | /* | 252 | /* |
249 | * open file op | 253 | * open file op |
250 | */ | 254 | */ |
251 | static int hiddev_open(struct inode * inode, struct file * file) { | 255 | static int hiddev_open(struct inode *inode, struct file *file) |
256 | { | ||
252 | struct hiddev_list *list; | 257 | struct hiddev_list *list; |
253 | 258 | ||
254 | int i = iminor(inode) - HIDDEV_MINOR_BASE; | 259 | int i = iminor(inode) - HIDDEV_MINOR_BASE; |
@@ -260,9 +265,7 @@ static int hiddev_open(struct inode * inode, struct file * file) { | |||
260 | return -ENOMEM; | 265 | return -ENOMEM; |
261 | 266 | ||
262 | list->hiddev = hiddev_table[i]; | 267 | list->hiddev = hiddev_table[i]; |
263 | list->next = hiddev_table[i]->list; | 268 | list_add_tail(&list->node, &hiddev_table[i]->list); |
264 | hiddev_table[i]->list = list; | ||
265 | |||
266 | file->private_data = list; | 269 | file->private_data = list; |
267 | 270 | ||
268 | if (!list->hiddev->open++) | 271 | if (!list->hiddev->open++) |
@@ -362,6 +365,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun | |||
362 | static unsigned int hiddev_poll(struct file *file, poll_table *wait) | 365 | static unsigned int hiddev_poll(struct file *file, poll_table *wait) |
363 | { | 366 | { |
364 | struct hiddev_list *list = file->private_data; | 367 | struct hiddev_list *list = file->private_data; |
368 | |||
365 | poll_wait(file, &list->hiddev->wait, wait); | 369 | poll_wait(file, &list->hiddev->wait, wait); |
366 | if (list->head != list->tail) | 370 | if (list->head != list->tail) |
367 | return POLLIN | POLLRDNORM; | 371 | return POLLIN | POLLRDNORM; |
@@ -382,7 +386,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
382 | struct hiddev_collection_info cinfo; | 386 | struct hiddev_collection_info cinfo; |
383 | struct hiddev_report_info rinfo; | 387 | struct hiddev_report_info rinfo; |
384 | struct hiddev_field_info finfo; | 388 | struct hiddev_field_info finfo; |
385 | struct hiddev_usage_ref_multi *uref_multi=NULL; | 389 | struct hiddev_usage_ref_multi *uref_multi = NULL; |
386 | struct hiddev_usage_ref *uref; | 390 | struct hiddev_usage_ref *uref; |
387 | struct hiddev_devinfo dinfo; | 391 | struct hiddev_devinfo dinfo; |
388 | struct hid_report *report; | 392 | struct hid_report *report; |
@@ -764,15 +768,15 @@ int hiddev_connect(struct hid_device *hid) | |||
764 | } | 768 | } |
765 | 769 | ||
766 | init_waitqueue_head(&hiddev->wait); | 770 | init_waitqueue_head(&hiddev->wait); |
767 | 771 | INIT_LIST_HEAD(&hiddev->list); | |
768 | hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; | ||
769 | |||
770 | hiddev->hid = hid; | 772 | hiddev->hid = hid; |
771 | hiddev->exist = 1; | 773 | hiddev->exist = 1; |
772 | 774 | ||
773 | hid->minor = hid->intf->minor; | 775 | hid->minor = hid->intf->minor; |
774 | hid->hiddev = hiddev; | 776 | hid->hiddev = hiddev; |
775 | 777 | ||
778 | hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; | ||
779 | |||
776 | return 0; | 780 | return 0; |
777 | } | 781 | } |
778 | 782 | ||