aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 13:51:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 13:51:03 -0400
commit8b108c609adefd98577c35f0a41497a610041a6c (patch)
treef1552fdc5bf0ebcc484a88f01cd3864113adf25c /drivers/hid/hid-core.c
parent7ce1418f95e918cfc5ad36e3ec3431145c768cd0 (diff)
parent73d5e8f77e88a4d3a154dfdbb4ed2cf461b7bf21 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (59 commits) HID: fix up 'EMBEDDED' mess in Kconfig HID: roccat: cleanup preprocessor macros HID: roccat: refactor special event handling HID: roccat: fix special button support HID: roccat: Correctly mark init and exit functions HID: hidraw: Use Interrupt Endpoint for OUT Transfers if Available HID: hid-samsung: remove redundant key mappings HID: add omitted hid-zydacron.c file HID: hid-samsung: add support for Creative Desktop Wireless 6000 HID: picolcd: Eliminate use after free HID: Zydacron Remote Control driver HID: Use kmemdup HID: magicmouse: fix input registration HID: make Prodikeys driver standalone config option HID: Prodikeys PC-MIDI HID Driver HID: hidraw: fix indentation HID: ntrig: add filtering module parameters HID: ntrig: add sysfs access to filter parameters HID: ntrig: add sensitivity and responsiveness support HID: add multi-input quirk for eGalax Touchcontroller ...
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r--drivers/hid/hid-core.c53
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 143e788b729b..e10e314d38cc 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -653,10 +653,9 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
653 if (device->driver->report_fixup) 653 if (device->driver->report_fixup)
654 device->driver->report_fixup(device, start, size); 654 device->driver->report_fixup(device, start, size);
655 655
656 device->rdesc = kmalloc(size, GFP_KERNEL); 656 device->rdesc = kmemdup(start, size, GFP_KERNEL);
657 if (device->rdesc == NULL) 657 if (device->rdesc == NULL)
658 return -ENOMEM; 658 return -ENOMEM;
659 memcpy(device->rdesc, start, size);
660 device->rsize = size; 659 device->rsize = size;
661 660
662 parser = vmalloc(sizeof(struct hid_parser)); 661 parser = vmalloc(sizeof(struct hid_parser));
@@ -940,13 +939,8 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
940 unsigned count = field->report_count; 939 unsigned count = field->report_count;
941 unsigned offset = field->report_offset; 940 unsigned offset = field->report_offset;
942 unsigned size = field->report_size; 941 unsigned size = field->report_size;
943 unsigned bitsused = offset + count * size;
944 unsigned n; 942 unsigned n;
945 943
946 /* make sure the unused bits in the last byte are zeros */
947 if (count > 0 && size > 0 && (bitsused % 8) != 0)
948 data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1;
949
950 for (n = 0; n < count; n++) { 944 for (n = 0; n < count; n++) {
951 if (field->logical_minimum < 0) /* signed values */ 945 if (field->logical_minimum < 0) /* signed values */
952 implement(data, offset + n * size, size, s32ton(field->value[n], size)); 946 implement(data, offset + n * size, size, s32ton(field->value[n], size));
@@ -966,6 +960,7 @@ void hid_output_report(struct hid_report *report, __u8 *data)
966 if (report->id > 0) 960 if (report->id > 0)
967 *data++ = report->id; 961 *data++ = report->id;
968 962
963 memset(data, 0, ((report->size - 1) >> 3) + 1);
969 for (n = 0; n < report->maxfield; n++) 964 for (n = 0; n < report->maxfield; n++)
970 hid_output_field(report->field[n], data); 965 hid_output_field(report->field[n], data);
971} 966}
@@ -1086,35 +1081,28 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
1086 1081
1087 buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); 1082 buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
1088 1083
1089 if (!buf) { 1084 if (!buf)
1090 report = hid_get_report(report_enum, data);
1091 goto nomem; 1085 goto nomem;
1092 }
1093
1094 snprintf(buf, HID_DEBUG_BUFSIZE - 1,
1095 "\nreport (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
1096 hid_debug_event(hid, buf);
1097
1098 report = hid_get_report(report_enum, data);
1099 if (!report) {
1100 kfree(buf);
1101 return -1;
1102 }
1103 1086
1104 /* dump the report */ 1087 /* dump the report */
1105 snprintf(buf, HID_DEBUG_BUFSIZE - 1, 1088 snprintf(buf, HID_DEBUG_BUFSIZE - 1,
1106 "report %d (size %u) = ", report->id, size); 1089 "\nreport (size %u) (%snumbered) = ", size, report_enum->numbered ? "" : "un");
1107 hid_debug_event(hid, buf); 1090 hid_debug_event(hid, buf);
1091
1108 for (i = 0; i < size; i++) { 1092 for (i = 0; i < size; i++) {
1109 snprintf(buf, HID_DEBUG_BUFSIZE - 1, 1093 snprintf(buf, HID_DEBUG_BUFSIZE - 1,
1110 " %02x", data[i]); 1094 " %02x", data[i]);
1111 hid_debug_event(hid, buf); 1095 hid_debug_event(hid, buf);
1112 } 1096 }
1113 hid_debug_event(hid, "\n"); 1097 hid_debug_event(hid, "\n");
1114
1115 kfree(buf); 1098 kfree(buf);
1116 1099
1117nomem: 1100nomem:
1101 report = hid_get_report(report_enum, data);
1102
1103 if (!report)
1104 return -1;
1105
1118 if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { 1106 if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
1119 ret = hdrv->raw_event(hid, report, data, size); 1107 ret = hdrv->raw_event(hid, report, data, size);
1120 if (ret != 0) 1108 if (ret != 0)
@@ -1167,6 +1155,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1167 unsigned int i; 1155 unsigned int i;
1168 int len; 1156 int len;
1169 1157
1158 if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
1159 connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
1170 if (hdev->bus != BUS_USB) 1160 if (hdev->bus != BUS_USB)
1171 connect_mask &= ~HID_CONNECT_HIDDEV; 1161 connect_mask &= ~HID_CONNECT_HIDDEV;
1172 if (hid_hiddev(hdev)) 1162 if (hid_hiddev(hdev))
@@ -1246,6 +1236,7 @@ EXPORT_SYMBOL_GPL(hid_disconnect);
1246/* a list of devices for which there is a specialized driver on HID bus */ 1236/* a list of devices for which there is a specialized driver on HID bus */
1247static const struct hid_device_id hid_blacklist[] = { 1237static const struct hid_device_id hid_blacklist[] = {
1248 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, 1238 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
1239 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
1249 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, 1240 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
1250 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, 1241 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
1251 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, 1242 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
@@ -1290,14 +1281,19 @@ static const struct hid_device_id hid_blacklist[] = {
1290 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1281 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1291 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1282 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1292 { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, 1283 { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
1284 { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
1285 { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
1286 { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
1293 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, 1287 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
1294 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, 1288 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
1295 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, 1289 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
1290 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
1296 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, 1291 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
1297 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, 1292 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
1298 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, 1293 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
1299 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, 1294 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
1300 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, 1295 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
1296 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
1301 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, 1297 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
1302 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, 1298 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
1303 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, 1299 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
@@ -1331,6 +1327,8 @@ static const struct hid_device_id hid_blacklist[] = {
1331 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, 1327 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
1332 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, 1328 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
1333 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, 1329 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
1330 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
1331 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
1334 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, 1332 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
1335 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, 1333 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
1336 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, 1334 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
@@ -1342,7 +1340,9 @@ static const struct hid_device_id hid_blacklist[] = {
1342 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, 1340 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
1343 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 1341 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
1344 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, 1342 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
1343 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
1345 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1344 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1345 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
1346 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1346 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1347 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1347 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1348 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, 1348 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
@@ -1359,8 +1359,10 @@ static const struct hid_device_id hid_blacklist[] = {
1359 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, 1359 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
1360 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, 1360 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
1361 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 1361 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
1362 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
1362 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, 1363 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1363 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, 1364 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1365 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
1364 1366
1365 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, 1367 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
1366 { } 1368 { }
@@ -1757,7 +1759,7 @@ int hid_add_device(struct hid_device *hdev)
1757 1759
1758 /* we need to kill them here, otherwise they will stay allocated to 1760 /* we need to kill them here, otherwise they will stay allocated to
1759 * wait for coming driver */ 1761 * wait for coming driver */
1760 if (hid_ignore(hdev)) 1762 if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) && hid_ignore(hdev))
1761 return -ENODEV; 1763 return -ENODEV;
1762 1764
1763 /* XXX hack, any other cleaner solution after the driver core 1765 /* XXX hack, any other cleaner solution after the driver core
@@ -1765,11 +1767,12 @@ int hid_add_device(struct hid_device *hdev)
1765 dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, 1767 dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
1766 hdev->vendor, hdev->product, atomic_inc_return(&id)); 1768 hdev->vendor, hdev->product, atomic_inc_return(&id));
1767 1769
1770 hid_debug_register(hdev, dev_name(&hdev->dev));
1768 ret = device_add(&hdev->dev); 1771 ret = device_add(&hdev->dev);
1769 if (!ret) 1772 if (!ret)
1770 hdev->status |= HID_STAT_ADDED; 1773 hdev->status |= HID_STAT_ADDED;
1771 1774 else
1772 hid_debug_register(hdev, dev_name(&hdev->dev)); 1775 hid_debug_unregister(hdev);
1773 1776
1774 return ret; 1777 return ret;
1775} 1778}