diff options
| author | John W. Linville <linville@tuxdriver.com> | 2006-08-14 15:33:54 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2006-08-14 15:33:54 -0400 |
| commit | e9ffb3d7ec94083a44a8721681391beca2ffd68c (patch) | |
| tree | 6768ab487b3f44c2a4995ee61307e47760ca9b88 /drivers/usb | |
| parent | 8b9411014e6f18a883c18b38f41338dbd53fddea (diff) | |
| parent | e9fa4f7bd291c29a785666e2fa5a9cf3241ee6c3 (diff) | |
Merge branch 'from-linus' into upstream
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/host/ohci-au1xxx.c | 1 | ||||
| -rw-r--r-- | drivers/usb/input/appletouch.c | 2 | ||||
| -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 | ||||
| -rw-r--r-- | drivers/usb/misc/usbtest.c | 5 | ||||
| -rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/ftdi_sio.h | 6 | ||||
| -rw-r--r-- | drivers/usb/serial/ipaq.c | 2 | ||||
| -rw-r--r-- | drivers/usb/storage/unusual_devs.h | 10 |
10 files changed, 163 insertions, 113 deletions
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 822914e2f43b..f7a975d5db09 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
| @@ -110,7 +110,6 @@ static void au1xxx_start_ohc(struct platform_device *dev) | |||
| 110 | 110 | ||
| 111 | printk(KERN_DEBUG __FILE__ | 111 | printk(KERN_DEBUG __FILE__ |
| 112 | ": Clock to USB host has been enabled \n"); | 112 | ": Clock to USB host has been enabled \n"); |
| 113 | #endif | ||
| 114 | } | 113 | } |
| 115 | 114 | ||
| 116 | static void au1xxx_stop_ohc(struct platform_device *dev) | 115 | static void au1xxx_stop_ohc(struct platform_device *dev) |
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index 9e3f13903371..044faa07e297 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c | |||
| @@ -597,9 +597,9 @@ static void atp_disconnect(struct usb_interface *iface) | |||
| 597 | if (dev) { | 597 | if (dev) { |
| 598 | usb_kill_urb(dev->urb); | 598 | usb_kill_urb(dev->urb); |
| 599 | input_unregister_device(dev->input); | 599 | input_unregister_device(dev->input); |
| 600 | usb_free_urb(dev->urb); | ||
| 601 | usb_buffer_free(dev->udev, dev->datalen, | 600 | usb_buffer_free(dev->udev, dev->datalen, |
| 602 | dev->data, dev->urb->transfer_dma); | 601 | dev->data, dev->urb->transfer_dma); |
| 602 | usb_free_urb(dev->urb); | ||
| 603 | kfree(dev); | 603 | kfree(dev); |
| 604 | } | 604 | } |
| 605 | printk(KERN_INFO "input: appletouch disconnected\n"); | 605 | printk(KERN_INFO "input: appletouch disconnected\n"); |
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 | ||
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 786e1dbe88ec..983e104dd452 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
| @@ -1242,11 +1242,12 @@ done: | |||
| 1242 | static int ctrl_out (struct usbtest_dev *dev, | 1242 | static int ctrl_out (struct usbtest_dev *dev, |
| 1243 | unsigned count, unsigned length, unsigned vary) | 1243 | unsigned count, unsigned length, unsigned vary) |
| 1244 | { | 1244 | { |
| 1245 | unsigned i, j, len, retval; | 1245 | unsigned i, j, len; |
| 1246 | int retval; | ||
| 1246 | u8 *buf; | 1247 | u8 *buf; |
| 1247 | char *what = "?"; | 1248 | char *what = "?"; |
| 1248 | struct usb_device *udev; | 1249 | struct usb_device *udev; |
| 1249 | 1250 | ||
| 1250 | if (length < 1 || length > 0xffff || vary >= length) | 1251 | if (length < 1 || length > 0xffff || vary >= length) |
| 1251 | return -EINVAL; | 1252 | return -EINVAL; |
| 1252 | 1253 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index a20da8528a5f..15945e806f03 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -306,6 +306,8 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { | |||
| 306 | 306 | ||
| 307 | 307 | ||
| 308 | static struct usb_device_id id_table_combined [] = { | 308 | static struct usb_device_id id_table_combined [] = { |
| 309 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, | ||
| 310 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, | ||
| 309 | { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, | 311 | { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, |
| 310 | { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, | 312 | { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, |
| 311 | { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, | 313 | { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 9f7343a45424..8888cd80a491 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
| @@ -32,6 +32,12 @@ | |||
| 32 | #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ | 32 | #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ |
| 33 | 33 | ||
| 34 | 34 | ||
| 35 | /* www.canusb.com Lawicel CANUSB device */ | ||
| 36 | #define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ | ||
| 37 | |||
| 38 | /* AlphaMicro Components AMC-232USB01 device */ | ||
| 39 | #define FTDI_AMC232_PID 0xFF00 /* Product Id */ | ||
| 40 | |||
| 35 | /* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ | 41 | /* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ |
| 36 | #define FTDI_ACTZWAVE_PID 0xF2D0 | 42 | #define FTDI_ACTZWAVE_PID 0xF2D0 |
| 37 | 43 | ||
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 7e1bd5d6dfa0..9840bade79f9 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
| @@ -251,6 +251,8 @@ static struct usb_device_id ipaq_id_table [] = { | |||
| 251 | { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ | 251 | { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ |
| 252 | { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ | 252 | { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ |
| 253 | { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */ | 253 | { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */ |
| 254 | { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */ | ||
| 255 | { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */ | ||
| 254 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ | 256 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ |
| 255 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ | 257 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ |
| 256 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ | 258 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 2793f9a912b4..fd158e063c06 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -1240,6 +1240,16 @@ UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103, | |||
| 1240 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1240 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 1241 | US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64), | 1241 | US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64), |
| 1242 | 1242 | ||
| 1243 | /* David Kuehling <dvdkhlng@gmx.de>: | ||
| 1244 | * for MP3-Player AVOX WSX-300ER (bought in Japan). Reports lots of SCSI | ||
| 1245 | * errors when trying to write. | ||
| 1246 | */ | ||
| 1247 | UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, | ||
| 1248 | "C-MEX", | ||
| 1249 | "A-VOX", | ||
| 1250 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
| 1251 | US_FL_IGNORE_RESIDUE ), | ||
| 1252 | |||
| 1243 | /* Reported by Michael Stattmann <michael@stattmann.com> */ | 1253 | /* Reported by Michael Stattmann <michael@stattmann.com> */ |
| 1244 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, | 1254 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, |
| 1245 | "Sony Ericsson", | 1255 | "Sony Ericsson", |
