diff options
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-core.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 3 | ||||
-rw-r--r-- | drivers/hid/hid-picolcd_cir.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 8 | ||||
-rw-r--r-- | drivers/hid/hidraw.c | 1 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 25 | ||||
-rw-r--r-- | drivers/hid/uhid.c | 95 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 1 |
8 files changed, 119 insertions, 18 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index eb2ee11b6412..fe3a59e2a5ba 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -729,7 +729,7 @@ static int hid_scan_report(struct hid_device *hid) | |||
729 | item.type == HID_ITEM_TYPE_MAIN && | 729 | item.type == HID_ITEM_TYPE_MAIN && |
730 | item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && | 730 | item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && |
731 | (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && | 731 | (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && |
732 | hid->bus == BUS_USB) | 732 | (hid->bus == BUS_USB || hid->bus == BUS_I2C)) |
733 | hid->group = HID_GROUP_SENSOR_HUB; | 733 | hid->group = HID_GROUP_SENSOR_HUB; |
734 | } | 734 | } |
735 | 735 | ||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 4dfa605e2d14..34e25471aeaa 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -306,6 +306,9 @@ | |||
306 | #define USB_VENDOR_ID_EZKEY 0x0518 | 306 | #define USB_VENDOR_ID_EZKEY 0x0518 |
307 | #define USB_DEVICE_ID_BTC_8193 0x0002 | 307 | #define USB_DEVICE_ID_BTC_8193 0x0002 |
308 | 308 | ||
309 | #define USB_VENDOR_ID_FORMOSA 0x147a | ||
310 | #define USB_DEVICE_ID_FORMOSA_IR_RECEIVER 0xe03e | ||
311 | |||
309 | #define USB_VENDOR_ID_FREESCALE 0x15A2 | 312 | #define USB_VENDOR_ID_FREESCALE 0x15A2 |
310 | #define USB_DEVICE_ID_FREESCALE_MX28 0x004F | 313 | #define USB_DEVICE_ID_FREESCALE_MX28 0x004F |
311 | 314 | ||
diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 13ca9191b630..a79e95bb9fb6 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c | |||
@@ -116,7 +116,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) | |||
116 | 116 | ||
117 | rdev->priv = data; | 117 | rdev->priv = data; |
118 | rdev->driver_type = RC_DRIVER_IR_RAW; | 118 | rdev->driver_type = RC_DRIVER_IR_RAW; |
119 | rdev->allowed_protos = RC_TYPE_ALL; | 119 | rdev->allowed_protos = RC_BIT_ALL; |
120 | rdev->open = picolcd_cir_open; | 120 | rdev->open = picolcd_cir_open; |
121 | rdev->close = picolcd_cir_close; | 121 | rdev->close = picolcd_cir_close; |
122 | rdev->input_name = data->hdev->name; | 122 | rdev->input_name = data->hdev->name; |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 0bc58bd8d4f5..7d96db367477 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -605,16 +605,12 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
605 | } | 605 | } |
606 | 606 | ||
607 | static const struct hid_device_id sensor_hub_devices[] = { | 607 | static const struct hid_device_id sensor_hub_devices[] = { |
608 | { HID_DEVICE(BUS_USB, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) }, | 608 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, |
609 | HID_ANY_ID) }, | ||
609 | { } | 610 | { } |
610 | }; | 611 | }; |
611 | MODULE_DEVICE_TABLE(hid, sensor_hub_devices); | 612 | MODULE_DEVICE_TABLE(hid, sensor_hub_devices); |
612 | 613 | ||
613 | static const struct hid_usage_id sensor_hub_grabbed_usages[] = { | ||
614 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | ||
615 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } | ||
616 | }; | ||
617 | |||
618 | static struct hid_driver sensor_hub_driver = { | 614 | static struct hid_driver sensor_hub_driver = { |
619 | .name = "hid-sensor-hub", | 615 | .name = "hid-sensor-hub", |
620 | .id_table = sensor_hub_devices, | 616 | .id_table = sensor_hub_devices, |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 413a73187d33..f3bbbce8353b 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -581,6 +581,7 @@ int __init hidraw_init(void) | |||
581 | if (result < 0) | 581 | if (result < 0) |
582 | goto error_class; | 582 | goto error_class; |
583 | 583 | ||
584 | printk(KERN_INFO "hidraw: raw HID events driver (C) Jiri Kosina\n"); | ||
584 | out: | 585 | out: |
585 | return result; | 586 | return result; |
586 | 587 | ||
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 9e46e4295bd9..ec7930217a6d 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -543,13 +543,24 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, | |||
543 | { | 543 | { |
544 | struct i2c_client *client = hid->driver_data; | 544 | struct i2c_client *client = hid->driver_data; |
545 | int report_id = buf[0]; | 545 | int report_id = buf[0]; |
546 | int ret; | ||
546 | 547 | ||
547 | if (report_type == HID_INPUT_REPORT) | 548 | if (report_type == HID_INPUT_REPORT) |
548 | return -EINVAL; | 549 | return -EINVAL; |
549 | 550 | ||
550 | return i2c_hid_set_report(client, | 551 | if (report_id) { |
552 | buf++; | ||
553 | count--; | ||
554 | } | ||
555 | |||
556 | ret = i2c_hid_set_report(client, | ||
551 | report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, | 557 | report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, |
552 | report_id, buf, count); | 558 | report_id, buf, count); |
559 | |||
560 | if (report_id && ret >= 0) | ||
561 | ret++; /* add report_id to the number of transfered bytes */ | ||
562 | |||
563 | return ret; | ||
553 | } | 564 | } |
554 | 565 | ||
555 | static int i2c_hid_parse(struct hid_device *hid) | 566 | static int i2c_hid_parse(struct hid_device *hid) |
@@ -734,7 +745,7 @@ static struct hid_ll_driver i2c_hid_ll_driver = { | |||
734 | .hidinput_input_event = i2c_hid_hidinput_input_event, | 745 | .hidinput_input_event = i2c_hid_hidinput_input_event, |
735 | }; | 746 | }; |
736 | 747 | ||
737 | static int __devinit i2c_hid_init_irq(struct i2c_client *client) | 748 | static int i2c_hid_init_irq(struct i2c_client *client) |
738 | { | 749 | { |
739 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 750 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
740 | int ret; | 751 | int ret; |
@@ -756,7 +767,7 @@ static int __devinit i2c_hid_init_irq(struct i2c_client *client) | |||
756 | return 0; | 767 | return 0; |
757 | } | 768 | } |
758 | 769 | ||
759 | static int __devinit i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) | 770 | static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) |
760 | { | 771 | { |
761 | struct i2c_client *client = ihid->client; | 772 | struct i2c_client *client = ihid->client; |
762 | struct i2c_hid_desc *hdesc = &ihid->hdesc; | 773 | struct i2c_hid_desc *hdesc = &ihid->hdesc; |
@@ -877,8 +888,8 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client, | |||
877 | } | 888 | } |
878 | #endif | 889 | #endif |
879 | 890 | ||
880 | static int __devinit i2c_hid_probe(struct i2c_client *client, | 891 | static int i2c_hid_probe(struct i2c_client *client, |
881 | const struct i2c_device_id *dev_id) | 892 | const struct i2c_device_id *dev_id) |
882 | { | 893 | { |
883 | int ret; | 894 | int ret; |
884 | struct i2c_hid *ihid; | 895 | struct i2c_hid *ihid; |
@@ -976,7 +987,7 @@ err: | |||
976 | return ret; | 987 | return ret; |
977 | } | 988 | } |
978 | 989 | ||
979 | static int __devexit i2c_hid_remove(struct i2c_client *client) | 990 | static int i2c_hid_remove(struct i2c_client *client) |
980 | { | 991 | { |
981 | struct i2c_hid *ihid = i2c_get_clientdata(client); | 992 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
982 | struct hid_device *hid; | 993 | struct hid_device *hid; |
@@ -1042,7 +1053,7 @@ static struct i2c_driver i2c_hid_driver = { | |||
1042 | }, | 1053 | }, |
1043 | 1054 | ||
1044 | .probe = i2c_hid_probe, | 1055 | .probe = i2c_hid_probe, |
1045 | .remove = __devexit_p(i2c_hid_remove), | 1056 | .remove = i2c_hid_remove, |
1046 | 1057 | ||
1047 | .id_table = i2c_hid_id_table, | 1058 | .id_table = i2c_hid_id_table, |
1048 | }; | 1059 | }; |
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 714cd8cc9579..fc307e0422af 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/atomic.h> | 13 | #include <linux/atomic.h> |
14 | #include <linux/compat.h> | ||
14 | #include <linux/device.h> | 15 | #include <linux/device.h> |
15 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
16 | #include <linux/hid.h> | 17 | #include <linux/hid.h> |
@@ -276,6 +277,94 @@ static struct hid_ll_driver uhid_hid_driver = { | |||
276 | .parse = uhid_hid_parse, | 277 | .parse = uhid_hid_parse, |
277 | }; | 278 | }; |
278 | 279 | ||
280 | #ifdef CONFIG_COMPAT | ||
281 | |||
282 | /* Apparently we haven't stepped on these rakes enough times yet. */ | ||
283 | struct uhid_create_req_compat { | ||
284 | __u8 name[128]; | ||
285 | __u8 phys[64]; | ||
286 | __u8 uniq[64]; | ||
287 | |||
288 | compat_uptr_t rd_data; | ||
289 | __u16 rd_size; | ||
290 | |||
291 | __u16 bus; | ||
292 | __u32 vendor; | ||
293 | __u32 product; | ||
294 | __u32 version; | ||
295 | __u32 country; | ||
296 | } __attribute__((__packed__)); | ||
297 | |||
298 | static int uhid_event_from_user(const char __user *buffer, size_t len, | ||
299 | struct uhid_event *event) | ||
300 | { | ||
301 | if (is_compat_task()) { | ||
302 | u32 type; | ||
303 | |||
304 | if (get_user(type, buffer)) | ||
305 | return -EFAULT; | ||
306 | |||
307 | if (type == UHID_CREATE) { | ||
308 | /* | ||
309 | * This is our messed up request with compat pointer. | ||
310 | * It is largish (more than 256 bytes) so we better | ||
311 | * allocate it from the heap. | ||
312 | */ | ||
313 | struct uhid_create_req_compat *compat; | ||
314 | |||
315 | compat = kmalloc(sizeof(*compat), GFP_KERNEL); | ||
316 | if (!compat) | ||
317 | return -ENOMEM; | ||
318 | |||
319 | buffer += sizeof(type); | ||
320 | len -= sizeof(type); | ||
321 | if (copy_from_user(compat, buffer, | ||
322 | min(len, sizeof(*compat)))) { | ||
323 | kfree(compat); | ||
324 | return -EFAULT; | ||
325 | } | ||
326 | |||
327 | /* Shuffle the data over to proper structure */ | ||
328 | event->type = type; | ||
329 | |||
330 | memcpy(event->u.create.name, compat->name, | ||
331 | sizeof(compat->name)); | ||
332 | memcpy(event->u.create.phys, compat->phys, | ||
333 | sizeof(compat->phys)); | ||
334 | memcpy(event->u.create.uniq, compat->uniq, | ||
335 | sizeof(compat->uniq)); | ||
336 | |||
337 | event->u.create.rd_data = compat_ptr(compat->rd_data); | ||
338 | event->u.create.rd_size = compat->rd_size; | ||
339 | |||
340 | event->u.create.bus = compat->bus; | ||
341 | event->u.create.vendor = compat->vendor; | ||
342 | event->u.create.product = compat->product; | ||
343 | event->u.create.version = compat->version; | ||
344 | event->u.create.country = compat->country; | ||
345 | |||
346 | kfree(compat); | ||
347 | return 0; | ||
348 | } | ||
349 | /* All others can be copied directly */ | ||
350 | } | ||
351 | |||
352 | if (copy_from_user(event, buffer, min(len, sizeof(*event)))) | ||
353 | return -EFAULT; | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | #else | ||
358 | static int uhid_event_from_user(const char __user *buffer, size_t len, | ||
359 | struct uhid_event *event) | ||
360 | { | ||
361 | if (copy_from_user(event, buffer, min(len, sizeof(*event)))) | ||
362 | return -EFAULT; | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | #endif | ||
367 | |||
279 | static int uhid_dev_create(struct uhid_device *uhid, | 368 | static int uhid_dev_create(struct uhid_device *uhid, |
280 | const struct uhid_event *ev) | 369 | const struct uhid_event *ev) |
281 | { | 370 | { |
@@ -498,10 +587,10 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, | |||
498 | 587 | ||
499 | memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); | 588 | memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); |
500 | len = min(count, sizeof(uhid->input_buf)); | 589 | len = min(count, sizeof(uhid->input_buf)); |
501 | if (copy_from_user(&uhid->input_buf, buffer, len)) { | 590 | |
502 | ret = -EFAULT; | 591 | ret = uhid_event_from_user(buffer, len, &uhid->input_buf); |
592 | if (ret) | ||
503 | goto unlock; | 593 | goto unlock; |
504 | } | ||
505 | 594 | ||
506 | switch (uhid->input_buf.type) { | 595 | switch (uhid->input_buf.type) { |
507 | case UHID_CREATE: | 596 | case UHID_CREATE: |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index ac9e35228254..e0e6abf1cd3b 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -70,6 +70,7 @@ static const struct hid_blacklist { | |||
70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, | 70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, |
71 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, | 71 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, |
72 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 72 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
73 | { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, | ||
73 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, | 74 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, |
74 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, | 75 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, |
75 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, | 76 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, |