diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/input/hid-core.c | 76 | ||||
-rw-r--r-- | drivers/usb/input/hid-debug.h | 34 | ||||
-rw-r--r-- | drivers/usb/input/hid-input.c | 66 | ||||
-rw-r--r-- | drivers/usb/input/hid.h | 9 | ||||
-rw-r--r-- | drivers/usb/input/hiddev.c | 1 |
5 files changed, 154 insertions, 32 deletions
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 1ab95d24c5e2..e108e0a36b74 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -2,7 +2,8 @@ | |||
2 | * USB HID support for Linux | 2 | * USB HID support for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 1999 Andreas Gal | 4 | * Copyright (c) 1999 Andreas Gal |
5 | * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | ||
6 | */ | 7 | */ |
7 | 8 | ||
8 | /* | 9 | /* |
@@ -38,7 +39,7 @@ | |||
38 | * Version Information | 39 | * Version Information |
39 | */ | 40 | */ |
40 | 41 | ||
41 | #define DRIVER_VERSION "v2.01" | 42 | #define DRIVER_VERSION "v2.6" |
42 | #define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" | 43 | #define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" |
43 | #define DRIVER_DESC "USB HID core driver" | 44 | #define DRIVER_DESC "USB HID core driver" |
44 | #define DRIVER_LICENSE "GPL" | 45 | #define DRIVER_LICENSE "GPL" |
@@ -1058,8 +1059,8 @@ static int hid_submit_ctrl(struct hid_device *hid) | |||
1058 | if (maxpacket > 0) { | 1059 | if (maxpacket > 0) { |
1059 | padlen = (len + maxpacket - 1) / maxpacket; | 1060 | padlen = (len + maxpacket - 1) / maxpacket; |
1060 | padlen *= maxpacket; | 1061 | padlen *= maxpacket; |
1061 | if (padlen > HID_BUFFER_SIZE) | 1062 | if (padlen > hid->bufsize) |
1062 | padlen = HID_BUFFER_SIZE; | 1063 | padlen = hid->bufsize; |
1063 | } else | 1064 | } else |
1064 | padlen = 0; | 1065 | padlen = 0; |
1065 | hid->urbctrl->transfer_buffer_length = padlen; | 1066 | hid->urbctrl->transfer_buffer_length = padlen; |
@@ -1096,6 +1097,7 @@ static void hid_irq_out(struct urb *urb, struct pt_regs *regs) | |||
1096 | 1097 | ||
1097 | switch (urb->status) { | 1098 | switch (urb->status) { |
1098 | case 0: /* success */ | 1099 | case 0: /* success */ |
1100 | break; | ||
1099 | case -ESHUTDOWN: /* unplug */ | 1101 | case -ESHUTDOWN: /* unplug */ |
1100 | case -EILSEQ: /* unplug timeout on uhci */ | 1102 | case -EILSEQ: /* unplug timeout on uhci */ |
1101 | unplug = 1; | 1103 | unplug = 1; |
@@ -1143,6 +1145,7 @@ static void hid_ctrl(struct urb *urb, struct pt_regs *regs) | |||
1143 | case 0: /* success */ | 1145 | case 0: /* success */ |
1144 | if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) | 1146 | if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) |
1145 | hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); | 1147 | hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); |
1148 | break; | ||
1146 | case -ESHUTDOWN: /* unplug */ | 1149 | case -ESHUTDOWN: /* unplug */ |
1147 | case -EILSEQ: /* unplug timectrl on uhci */ | 1150 | case -EILSEQ: /* unplug timectrl on uhci */ |
1148 | unplug = 1; | 1151 | unplug = 1; |
@@ -1284,13 +1287,8 @@ void hid_init_reports(struct hid_device *hid) | |||
1284 | struct hid_report *report; | 1287 | struct hid_report *report; |
1285 | int err, ret; | 1288 | int err, ret; |
1286 | 1289 | ||
1287 | list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) { | 1290 | list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) |
1288 | int size = ((report->size - 1) >> 3) + 1 + hid->report_enum[HID_INPUT_REPORT].numbered; | ||
1289 | if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE; | ||
1290 | if (size > hid->urbin->transfer_buffer_length) | ||
1291 | hid->urbin->transfer_buffer_length = size; | ||
1292 | hid_submit_report(hid, report, USB_DIR_IN); | 1291 | hid_submit_report(hid, report, USB_DIR_IN); |
1293 | } | ||
1294 | 1292 | ||
1295 | list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) | 1293 | list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) |
1296 | hid_submit_report(hid, report, USB_DIR_IN); | 1294 | hid_submit_report(hid, report, USB_DIR_IN); |
@@ -1372,12 +1370,14 @@ void hid_init_reports(struct hid_device *hid) | |||
1372 | #define USB_VENDOR_ID_A4TECH 0x09da | 1370 | #define USB_VENDOR_ID_A4TECH 0x09da |
1373 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 | 1371 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 |
1374 | 1372 | ||
1375 | #define USB_VENDOR_ID_AASHIMA 0x06D6 | 1373 | #define USB_VENDOR_ID_AASHIMA 0x06d6 |
1376 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 | 1374 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 |
1375 | #define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026 | ||
1377 | 1376 | ||
1378 | #define USB_VENDOR_ID_CYPRESS 0x04b4 | 1377 | #define USB_VENDOR_ID_CYPRESS 0x04b4 |
1379 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 | 1378 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 |
1380 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 | 1379 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 |
1380 | #define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 | ||
1381 | 1381 | ||
1382 | #define USB_VENDOR_ID_BERKSHIRE 0x0c98 | 1382 | #define USB_VENDOR_ID_BERKSHIRE 0x0c98 |
1383 | #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 | 1383 | #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 |
@@ -1432,7 +1432,7 @@ void hid_init_reports(struct hid_device *hid) | |||
1432 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | 1432 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 |
1433 | 1433 | ||
1434 | #define USB_VENDOR_ID_LD 0x0f11 | 1434 | #define USB_VENDOR_ID_LD 0x0f11 |
1435 | #define USB_DEVICE_ID_CASSY 0x1000 | 1435 | #define USB_DEVICE_ID_CASSY 0x1000 |
1436 | #define USB_DEVICE_ID_POCKETCASSY 0x1010 | 1436 | #define USB_DEVICE_ID_POCKETCASSY 0x1010 |
1437 | #define USB_DEVICE_ID_MOBILECASSY 0x1020 | 1437 | #define USB_DEVICE_ID_MOBILECASSY 0x1020 |
1438 | #define USB_DEVICE_ID_JWM 0x1080 | 1438 | #define USB_DEVICE_ID_JWM 0x1080 |
@@ -1445,7 +1445,8 @@ void hid_init_reports(struct hid_device *hid) | |||
1445 | #define USB_DEVICE_ID_POWERCONTROL 0x2030 | 1445 | #define USB_DEVICE_ID_POWERCONTROL 0x2030 |
1446 | 1446 | ||
1447 | #define USB_VENDOR_ID_APPLE 0x05ac | 1447 | #define USB_VENDOR_ID_APPLE 0x05ac |
1448 | #define USB_DEVICE_ID_APPLE_BLUETOOTH 0x1000 | 1448 | #define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 |
1449 | #define USB_DEVICE_ID_APPLE_BLUETOOTH 0x1000 | ||
1449 | 1450 | ||
1450 | /* | 1451 | /* |
1451 | * Alphabetically sorted blacklist by quirk type. | 1452 | * Alphabetically sorted blacklist by quirk type. |
@@ -1471,6 +1472,7 @@ static struct hid_blacklist { | |||
1471 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, | 1472 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, |
1472 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, | 1473 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, |
1473 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, | 1474 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, |
1475 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE }, | ||
1474 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, | 1476 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, |
1475 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, | 1477 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, |
1476 | { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, | 1478 | { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, |
@@ -1551,10 +1553,12 @@ static struct hid_blacklist { | |||
1551 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, | 1553 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, |
1552 | { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, | 1554 | { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, |
1553 | 1555 | ||
1556 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, | ||
1554 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, | 1557 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, |
1555 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, | 1558 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, |
1556 | 1559 | ||
1557 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, | 1560 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, |
1561 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, | ||
1558 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, | 1562 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, |
1559 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, | 1563 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, |
1560 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 1564 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
@@ -1567,15 +1571,32 @@ static struct hid_blacklist { | |||
1567 | { 0, 0 } | 1571 | { 0, 0 } |
1568 | }; | 1572 | }; |
1569 | 1573 | ||
1574 | /* | ||
1575 | * Traverse the supplied list of reports and find the longest | ||
1576 | */ | ||
1577 | static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max) | ||
1578 | { | ||
1579 | struct hid_report *report; | ||
1580 | int size; | ||
1581 | |||
1582 | list_for_each_entry(report, &hid->report_enum[type].report_list, list) { | ||
1583 | size = ((report->size - 1) >> 3) + 1; | ||
1584 | if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered) | ||
1585 | size++; | ||
1586 | if (*max < size) | ||
1587 | *max = size; | ||
1588 | } | ||
1589 | } | ||
1590 | |||
1570 | static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) | 1591 | static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) |
1571 | { | 1592 | { |
1572 | if (!(hid->inbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->inbuf_dma))) | 1593 | if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma))) |
1573 | return -1; | 1594 | return -1; |
1574 | if (!(hid->outbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->outbuf_dma))) | 1595 | if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma))) |
1575 | return -1; | 1596 | return -1; |
1576 | if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) | 1597 | if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) |
1577 | return -1; | 1598 | return -1; |
1578 | if (!(hid->ctrlbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->ctrlbuf_dma))) | 1599 | if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma))) |
1579 | return -1; | 1600 | return -1; |
1580 | 1601 | ||
1581 | return 0; | 1602 | return 0; |
@@ -1584,13 +1605,13 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) | |||
1584 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) | 1605 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) |
1585 | { | 1606 | { |
1586 | if (hid->inbuf) | 1607 | if (hid->inbuf) |
1587 | usb_buffer_free(dev, HID_BUFFER_SIZE, hid->inbuf, hid->inbuf_dma); | 1608 | usb_buffer_free(dev, hid->bufsize, hid->inbuf, hid->inbuf_dma); |
1588 | if (hid->outbuf) | 1609 | if (hid->outbuf) |
1589 | usb_buffer_free(dev, HID_BUFFER_SIZE, hid->outbuf, hid->outbuf_dma); | 1610 | usb_buffer_free(dev, hid->bufsize, hid->outbuf, hid->outbuf_dma); |
1590 | if (hid->cr) | 1611 | if (hid->cr) |
1591 | usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); | 1612 | usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); |
1592 | if (hid->ctrlbuf) | 1613 | if (hid->ctrlbuf) |
1593 | usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma); | 1614 | usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); |
1594 | } | 1615 | } |
1595 | 1616 | ||
1596 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) | 1617 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) |
@@ -1601,7 +1622,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1601 | struct hid_device *hid; | 1622 | struct hid_device *hid; |
1602 | unsigned quirks = 0, rsize = 0; | 1623 | unsigned quirks = 0, rsize = 0; |
1603 | char *buf, *rdesc; | 1624 | char *buf, *rdesc; |
1604 | int n; | 1625 | int n, insize = 0; |
1605 | 1626 | ||
1606 | for (n = 0; hid_blacklist[n].idVendor; n++) | 1627 | for (n = 0; hid_blacklist[n].idVendor; n++) |
1607 | if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && | 1628 | if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && |
@@ -1655,6 +1676,19 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1655 | kfree(rdesc); | 1676 | kfree(rdesc); |
1656 | hid->quirks = quirks; | 1677 | hid->quirks = quirks; |
1657 | 1678 | ||
1679 | hid->bufsize = HID_MIN_BUFFER_SIZE; | ||
1680 | hid_find_max_report(hid, HID_INPUT_REPORT, &hid->bufsize); | ||
1681 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &hid->bufsize); | ||
1682 | hid_find_max_report(hid, HID_FEATURE_REPORT, &hid->bufsize); | ||
1683 | |||
1684 | if (hid->bufsize > HID_MAX_BUFFER_SIZE) | ||
1685 | hid->bufsize = HID_MAX_BUFFER_SIZE; | ||
1686 | |||
1687 | hid_find_max_report(hid, HID_INPUT_REPORT, &insize); | ||
1688 | |||
1689 | if (insize > HID_MAX_BUFFER_SIZE) | ||
1690 | insize = HID_MAX_BUFFER_SIZE; | ||
1691 | |||
1658 | if (hid_alloc_buffers(dev, hid)) { | 1692 | if (hid_alloc_buffers(dev, hid)) { |
1659 | hid_free_buffers(dev, hid); | 1693 | hid_free_buffers(dev, hid); |
1660 | goto fail; | 1694 | goto fail; |
@@ -1685,7 +1719,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1685 | if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) | 1719 | if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) |
1686 | goto fail; | 1720 | goto fail; |
1687 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 1721 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
1688 | usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0, | 1722 | usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize, |
1689 | hid_irq_in, hid, interval); | 1723 | hid_irq_in, hid, interval); |
1690 | hid->urbin->transfer_dma = hid->inbuf_dma; | 1724 | hid->urbin->transfer_dma = hid->inbuf_dma; |
1691 | hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1725 | hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h index 52437e5e2e78..ceebab99eff2 100644 --- a/drivers/usb/input/hid-debug.h +++ b/drivers/usb/input/hid-debug.h | |||
@@ -85,6 +85,23 @@ static const struct hid_usage_entry hid_usage_table[] = { | |||
85 | {0, 0x91, "D-PadDown"}, | 85 | {0, 0x91, "D-PadDown"}, |
86 | {0, 0x92, "D-PadRight"}, | 86 | {0, 0x92, "D-PadRight"}, |
87 | {0, 0x93, "D-PadLeft"}, | 87 | {0, 0x93, "D-PadLeft"}, |
88 | { 2, 0, "Simulation" }, | ||
89 | {0, 0xb0, "Aileron"}, | ||
90 | {0, 0xb1, "AileronTrim"}, | ||
91 | {0, 0xb2, "Anti-Torque"}, | ||
92 | {0, 0xb3, "Autopilot"}, | ||
93 | {0, 0xb4, "Chaff"}, | ||
94 | {0, 0xb5, "Collective"}, | ||
95 | {0, 0xb6, "DiveBrake"}, | ||
96 | {0, 0xb7, "ElectronicCountermeasures"}, | ||
97 | {0, 0xb8, "Elevator"}, | ||
98 | {0, 0xb9, "ElevatorTrim"}, | ||
99 | {0, 0xba, "Rudder"}, | ||
100 | {0, 0xbb, "Throttle"}, | ||
101 | {0, 0xbc, "FlightCommunications"}, | ||
102 | {0, 0xbd, "FlareRelease"}, | ||
103 | {0, 0xbe, "LandingGear"}, | ||
104 | {0, 0xbf, "ToeBrake"}, | ||
88 | { 7, 0, "Keyboard" }, | 105 | { 7, 0, "Keyboard" }, |
89 | { 8, 0, "LED" }, | 106 | { 8, 0, "LED" }, |
90 | {0, 0x01, "NumLock"}, | 107 | {0, 0x01, "NumLock"}, |
@@ -92,6 +109,7 @@ static const struct hid_usage_entry hid_usage_table[] = { | |||
92 | {0, 0x03, "ScrollLock"}, | 109 | {0, 0x03, "ScrollLock"}, |
93 | {0, 0x04, "Compose"}, | 110 | {0, 0x04, "Compose"}, |
94 | {0, 0x05, "Kana"}, | 111 | {0, 0x05, "Kana"}, |
112 | {0, 0x4b, "GenericIndicator"}, | ||
95 | { 9, 0, "Button" }, | 113 | { 9, 0, "Button" }, |
96 | { 10, 0, "Ordinal" }, | 114 | { 10, 0, "Ordinal" }, |
97 | { 12, 0, "Consumer" }, | 115 | { 12, 0, "Consumer" }, |
@@ -574,7 +592,8 @@ static char *keys[KEY_MAX + 1] = { | |||
574 | [KEY_EXIT] = "Exit", [KEY_MOVE] = "Move", | 592 | [KEY_EXIT] = "Exit", [KEY_MOVE] = "Move", |
575 | [KEY_EDIT] = "Edit", [KEY_SCROLLUP] = "ScrollUp", | 593 | [KEY_EDIT] = "Edit", [KEY_SCROLLUP] = "ScrollUp", |
576 | [KEY_SCROLLDOWN] = "ScrollDown", [KEY_KPLEFTPAREN] = "KPLeftParenthesis", | 594 | [KEY_SCROLLDOWN] = "ScrollDown", [KEY_KPLEFTPAREN] = "KPLeftParenthesis", |
577 | [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_F13] = "F13", | 595 | [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_NEW] = "New", |
596 | [KEY_REDO] = "Redo", [KEY_F13] = "F13", | ||
578 | [KEY_F14] = "F14", [KEY_F15] = "F15", | 597 | [KEY_F14] = "F14", [KEY_F15] = "F15", |
579 | [KEY_F16] = "F16", [KEY_F17] = "F17", | 598 | [KEY_F16] = "F16", [KEY_F17] = "F17", |
580 | [KEY_F18] = "F18", [KEY_F19] = "F19", | 599 | [KEY_F18] = "F18", [KEY_F19] = "F19", |
@@ -584,15 +603,15 @@ static char *keys[KEY_MAX + 1] = { | |||
584 | [KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3", | 603 | [KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3", |
585 | [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend", | 604 | [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend", |
586 | [KEY_CLOSE] = "Close", [KEY_PLAY] = "Play", | 605 | [KEY_CLOSE] = "Close", [KEY_PLAY] = "Play", |
587 | [KEY_FASTFORWARD] = "Fast Forward", [KEY_BASSBOOST] = "Bass Boost", | 606 | [KEY_FASTFORWARD] = "FastForward", [KEY_BASSBOOST] = "BassBoost", |
588 | [KEY_PRINT] = "Print", [KEY_HP] = "HP", | 607 | [KEY_PRINT] = "Print", [KEY_HP] = "HP", |
589 | [KEY_CAMERA] = "Camera", [KEY_SOUND] = "Sound", | 608 | [KEY_CAMERA] = "Camera", [KEY_SOUND] = "Sound", |
590 | [KEY_QUESTION] = "Question", [KEY_EMAIL] = "Email", | 609 | [KEY_QUESTION] = "Question", [KEY_EMAIL] = "Email", |
591 | [KEY_CHAT] = "Chat", [KEY_SEARCH] = "Search", | 610 | [KEY_CHAT] = "Chat", [KEY_SEARCH] = "Search", |
592 | [KEY_CONNECT] = "Connect", [KEY_FINANCE] = "Finance", | 611 | [KEY_CONNECT] = "Connect", [KEY_FINANCE] = "Finance", |
593 | [KEY_SPORT] = "Sport", [KEY_SHOP] = "Shop", | 612 | [KEY_SPORT] = "Sport", [KEY_SHOP] = "Shop", |
594 | [KEY_ALTERASE] = "Alternate Erase", [KEY_CANCEL] = "Cancel", | 613 | [KEY_ALTERASE] = "AlternateErase", [KEY_CANCEL] = "Cancel", |
595 | [KEY_BRIGHTNESSDOWN] = "Brightness down", [KEY_BRIGHTNESSUP] = "Brightness up", | 614 | [KEY_BRIGHTNESSDOWN] = "BrightnessDown", [KEY_BRIGHTNESSUP] = "BrightnessUp", |
596 | [KEY_MEDIA] = "Media", [KEY_UNKNOWN] = "Unknown", | 615 | [KEY_MEDIA] = "Media", [KEY_UNKNOWN] = "Unknown", |
597 | [BTN_0] = "Btn0", [BTN_1] = "Btn1", | 616 | [BTN_0] = "Btn0", [BTN_1] = "Btn1", |
598 | [BTN_2] = "Btn2", [BTN_3] = "Btn3", | 617 | [BTN_2] = "Btn2", [BTN_3] = "Btn3", |
@@ -622,8 +641,8 @@ static char *keys[KEY_MAX + 1] = { | |||
622 | [BTN_TOOL_AIRBRUSH] = "ToolAirbrush", [BTN_TOOL_FINGER] = "ToolFinger", | 641 | [BTN_TOOL_AIRBRUSH] = "ToolAirbrush", [BTN_TOOL_FINGER] = "ToolFinger", |
623 | [BTN_TOOL_MOUSE] = "ToolMouse", [BTN_TOOL_LENS] = "ToolLens", | 642 | [BTN_TOOL_MOUSE] = "ToolMouse", [BTN_TOOL_LENS] = "ToolLens", |
624 | [BTN_TOUCH] = "Touch", [BTN_STYLUS] = "Stylus", | 643 | [BTN_TOUCH] = "Touch", [BTN_STYLUS] = "Stylus", |
625 | [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "Tool Doubletap", | 644 | [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "ToolDoubleTap", |
626 | [BTN_TOOL_TRIPLETAP] = "Tool Tripletap", [BTN_GEAR_DOWN] = "WheelBtn", | 645 | [BTN_TOOL_TRIPLETAP] = "ToolTripleTap", [BTN_GEAR_DOWN] = "WheelBtn", |
627 | [BTN_GEAR_UP] = "Gear up", [KEY_OK] = "Ok", | 646 | [BTN_GEAR_UP] = "Gear up", [KEY_OK] = "Ok", |
628 | [KEY_SELECT] = "Select", [KEY_GOTO] = "Goto", | 647 | [KEY_SELECT] = "Select", [KEY_GOTO] = "Goto", |
629 | [KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2", | 648 | [KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2", |
@@ -659,6 +678,9 @@ static char *keys[KEY_MAX + 1] = { | |||
659 | [KEY_TWEN] = "TWEN", [KEY_DEL_EOL] = "DeleteEOL", | 678 | [KEY_TWEN] = "TWEN", [KEY_DEL_EOL] = "DeleteEOL", |
660 | [KEY_DEL_EOS] = "DeleteEOS", [KEY_INS_LINE] = "InsertLine", | 679 | [KEY_DEL_EOS] = "DeleteEOS", [KEY_INS_LINE] = "InsertLine", |
661 | [KEY_DEL_LINE] = "DeleteLine", | 680 | [KEY_DEL_LINE] = "DeleteLine", |
681 | [KEY_SEND] = "Send", [KEY_REPLY] = "Reply", | ||
682 | [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save", | ||
683 | [KEY_DOCUMENTS] = "Documents", | ||
662 | }; | 684 | }; |
663 | 685 | ||
664 | static char *relatives[REL_MAX + 1] = { | 686 | static char *relatives[REL_MAX + 1] = { |
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 63a4db721f7e..0b6452248a39 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
@@ -78,8 +78,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
78 | { | 78 | { |
79 | struct input_dev *input = &hidinput->input; | 79 | struct input_dev *input = &hidinput->input; |
80 | struct hid_device *device = hidinput->input.private; | 80 | struct hid_device *device = hidinput->input.private; |
81 | int max, code; | 81 | int max = 0, code; |
82 | unsigned long *bit; | 82 | unsigned long *bit = NULL; |
83 | 83 | ||
84 | field->hidinput = hidinput; | 84 | field->hidinput = hidinput; |
85 | 85 | ||
@@ -131,6 +131,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
131 | map_key(code); | 131 | map_key(code); |
132 | break; | 132 | break; |
133 | 133 | ||
134 | |||
135 | case HID_UP_SIMULATION: | ||
136 | |||
137 | switch (usage->hid & 0xffff) { | ||
138 | case 0xba: map_abs(ABS_RUDDER); break; | ||
139 | case 0xbb: map_abs(ABS_THROTTLE); break; | ||
140 | } | ||
141 | break; | ||
142 | |||
134 | case HID_UP_GENDESK: | 143 | case HID_UP_GENDESK: |
135 | 144 | ||
136 | if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */ | 145 | if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */ |
@@ -238,8 +247,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
238 | case 0x000: goto ignore; | 247 | case 0x000: goto ignore; |
239 | case 0x034: map_key_clear(KEY_SLEEP); break; | 248 | case 0x034: map_key_clear(KEY_SLEEP); break; |
240 | case 0x036: map_key_clear(BTN_MISC); break; | 249 | case 0x036: map_key_clear(BTN_MISC); break; |
250 | case 0x045: map_key_clear(KEY_RADIO); break; | ||
241 | case 0x08a: map_key_clear(KEY_WWW); break; | 251 | case 0x08a: map_key_clear(KEY_WWW); break; |
252 | case 0x08d: map_key_clear(KEY_PROGRAM); break; | ||
242 | case 0x095: map_key_clear(KEY_HELP); break; | 253 | case 0x095: map_key_clear(KEY_HELP); break; |
254 | case 0x09c: map_key_clear(KEY_CHANNELUP); break; | ||
255 | case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; | ||
243 | case 0x0b0: map_key_clear(KEY_PLAY); break; | 256 | case 0x0b0: map_key_clear(KEY_PLAY); break; |
244 | case 0x0b1: map_key_clear(KEY_PAUSE); break; | 257 | case 0x0b1: map_key_clear(KEY_PAUSE); break; |
245 | case 0x0b2: map_key_clear(KEY_RECORD); break; | 258 | case 0x0b2: map_key_clear(KEY_RECORD); break; |
@@ -259,6 +272,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
259 | case 0x18a: map_key_clear(KEY_MAIL); break; | 272 | case 0x18a: map_key_clear(KEY_MAIL); break; |
260 | case 0x192: map_key_clear(KEY_CALC); break; | 273 | case 0x192: map_key_clear(KEY_CALC); break; |
261 | case 0x194: map_key_clear(KEY_FILE); break; | 274 | case 0x194: map_key_clear(KEY_FILE); break; |
275 | case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; | ||
276 | case 0x201: map_key_clear(KEY_NEW); break; | ||
277 | case 0x207: map_key_clear(KEY_SAVE); break; | ||
278 | case 0x208: map_key_clear(KEY_PRINT); break; | ||
279 | case 0x209: map_key_clear(KEY_PROPS); break; | ||
262 | case 0x21a: map_key_clear(KEY_UNDO); break; | 280 | case 0x21a: map_key_clear(KEY_UNDO); break; |
263 | case 0x21b: map_key_clear(KEY_COPY); break; | 281 | case 0x21b: map_key_clear(KEY_COPY); break; |
264 | case 0x21c: map_key_clear(KEY_CUT); break; | 282 | case 0x21c: map_key_clear(KEY_CUT); break; |
@@ -271,7 +289,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
271 | case 0x227: map_key_clear(KEY_REFRESH); break; | 289 | case 0x227: map_key_clear(KEY_REFRESH); break; |
272 | case 0x22a: map_key_clear(KEY_BOOKMARKS); break; | 290 | case 0x22a: map_key_clear(KEY_BOOKMARKS); break; |
273 | case 0x238: map_rel(REL_HWHEEL); break; | 291 | case 0x238: map_rel(REL_HWHEEL); break; |
274 | default: goto unknown; | 292 | case 0x279: map_key_clear(KEY_REDO); break; |
293 | case 0x289: map_key_clear(KEY_REPLY); break; | ||
294 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; | ||
295 | case 0x28c: map_key_clear(KEY_SEND); break; | ||
296 | default: goto ignore; | ||
275 | } | 297 | } |
276 | break; | 298 | break; |
277 | 299 | ||
@@ -296,9 +318,42 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
296 | break; | 318 | break; |
297 | 319 | ||
298 | case HID_UP_MSVENDOR: | 320 | case HID_UP_MSVENDOR: |
299 | |||
300 | goto ignore; | 321 | goto ignore; |
301 | 322 | ||
323 | case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ | ||
324 | |||
325 | set_bit(EV_REP, input->evbit); | ||
326 | switch(usage->hid & HID_USAGE) { | ||
327 | case 0x003: map_key_clear(KEY_FN); break; | ||
328 | default: goto ignore; | ||
329 | } | ||
330 | break; | ||
331 | |||
332 | case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */ | ||
333 | |||
334 | set_bit(EV_REP, input->evbit); | ||
335 | switch(usage->hid & HID_USAGE) { | ||
336 | case 0x004: map_key_clear(KEY_AGAIN); break; | ||
337 | case 0x00d: map_key_clear(KEY_HOME); break; | ||
338 | case 0x024: map_key_clear(KEY_SHUFFLE); break; | ||
339 | case 0x025: map_key_clear(KEY_TV); break; | ||
340 | case 0x026: map_key_clear(KEY_MENU); break; | ||
341 | case 0x031: map_key_clear(KEY_AUDIO); break; | ||
342 | case 0x032: map_key_clear(KEY_SUBTITLE); break; | ||
343 | case 0x033: map_key_clear(KEY_LAST); break; | ||
344 | case 0x047: map_key_clear(KEY_MP3); break; | ||
345 | case 0x048: map_key_clear(KEY_DVD); break; | ||
346 | case 0x049: map_key_clear(KEY_MEDIA); break; | ||
347 | case 0x04a: map_key_clear(KEY_VIDEO); break; | ||
348 | case 0x04b: map_key_clear(KEY_ANGLE); break; | ||
349 | case 0x04c: map_key_clear(KEY_LANGUAGE); break; | ||
350 | case 0x04d: map_key_clear(KEY_SUBTITLE); break; | ||
351 | case 0x051: map_key_clear(KEY_RED); break; | ||
352 | case 0x052: map_key_clear(KEY_CLOSE); break; | ||
353 | default: goto ignore; | ||
354 | } | ||
355 | break; | ||
356 | |||
302 | case HID_UP_PID: | 357 | case HID_UP_PID: |
303 | 358 | ||
304 | set_bit(EV_FF, input->evbit); | 359 | set_bit(EV_FF, input->evbit); |
@@ -349,6 +404,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
349 | if (usage->code > max) | 404 | if (usage->code > max) |
350 | goto ignore; | 405 | goto ignore; |
351 | 406 | ||
407 | if (((device->quirks & (HID_QUIRK_2WHEEL_POWERMOUSE)) && (usage->hid == 0x00010032))) | ||
408 | map_rel(REL_HWHEEL); | ||
409 | |||
352 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && | 410 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && |
353 | (usage->type == EV_REL) && (usage->code == REL_WHEEL)) | 411 | (usage->type == EV_REL) && (usage->code == REL_WHEEL)) |
354 | set_bit(REL_HWHEEL, bit); | 412 | set_bit(REL_HWHEEL, bit); |
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index c1b6b69bc4a4..ec2412c42f1e 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h | |||
@@ -173,6 +173,7 @@ struct hid_item { | |||
173 | 173 | ||
174 | #define HID_UP_UNDEFINED 0x00000000 | 174 | #define HID_UP_UNDEFINED 0x00000000 |
175 | #define HID_UP_GENDESK 0x00010000 | 175 | #define HID_UP_GENDESK 0x00010000 |
176 | #define HID_UP_SIMULATION 0x00020000 | ||
176 | #define HID_UP_KEYBOARD 0x00070000 | 177 | #define HID_UP_KEYBOARD 0x00070000 |
177 | #define HID_UP_LED 0x00080000 | 178 | #define HID_UP_LED 0x00080000 |
178 | #define HID_UP_BUTTON 0x00090000 | 179 | #define HID_UP_BUTTON 0x00090000 |
@@ -182,6 +183,8 @@ struct hid_item { | |||
182 | #define HID_UP_PID 0x000f0000 | 183 | #define HID_UP_PID 0x000f0000 |
183 | #define HID_UP_HPVENDOR 0xff7f0000 | 184 | #define HID_UP_HPVENDOR 0xff7f0000 |
184 | #define HID_UP_MSVENDOR 0xff000000 | 185 | #define HID_UP_MSVENDOR 0xff000000 |
186 | #define HID_UP_CUSTOM 0x00ff0000 | ||
187 | #define HID_UP_LOGIVENDOR 0xffbc0000 | ||
185 | 188 | ||
186 | #define HID_USAGE 0x0000ffff | 189 | #define HID_USAGE 0x0000ffff |
187 | 190 | ||
@@ -242,6 +245,7 @@ struct hid_item { | |||
242 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080 | 245 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080 |
243 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100 | 246 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100 |
244 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200 | 247 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200 |
248 | #define HID_QUIRK_2WHEEL_POWERMOUSE 0x400 | ||
245 | 249 | ||
246 | /* | 250 | /* |
247 | * This is the global environment of the parser. This information is | 251 | * This is the global environment of the parser. This information is |
@@ -348,7 +352,8 @@ struct hid_report_enum { | |||
348 | 352 | ||
349 | #define HID_REPORT_TYPES 3 | 353 | #define HID_REPORT_TYPES 3 |
350 | 354 | ||
351 | #define HID_BUFFER_SIZE 64 /* use 64 for compatibility with all possible packetlen */ | 355 | #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ |
356 | #define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ | ||
352 | #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ | 357 | #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ |
353 | #define HID_OUTPUT_FIFO_SIZE 64 | 358 | #define HID_OUTPUT_FIFO_SIZE 64 |
354 | 359 | ||
@@ -386,6 +391,8 @@ struct hid_device { /* device report descriptor */ | |||
386 | 391 | ||
387 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ | 392 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ |
388 | 393 | ||
394 | unsigned int bufsize; /* URB buffer size */ | ||
395 | |||
389 | struct urb *urbin; /* Input URB */ | 396 | struct urb *urbin; /* Input URB */ |
390 | char *inbuf; /* Input buffer */ | 397 | char *inbuf; /* Input buffer */ |
391 | dma_addr_t inbuf_dma; /* Input buffer dma */ | 398 | dma_addr_t inbuf_dma; /* Input buffer dma */ |
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 4c13331b5f41..d32427818af7 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
@@ -507,6 +507,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
507 | return -EINVAL; | 507 | return -EINVAL; |
508 | 508 | ||
509 | hid_submit_report(hid, report, USB_DIR_OUT); | 509 | hid_submit_report(hid, report, USB_DIR_OUT); |
510 | hid_wait_io(hid); | ||
510 | 511 | ||
511 | return 0; | 512 | return 0; |
512 | 513 | ||