aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-ids.h3
-rw-r--r--drivers/hid/hid-picolcd_cir.c2
-rw-r--r--drivers/hid/hid-sensor-hub.c8
-rw-r--r--drivers/hid/hidraw.c1
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c25
-rw-r--r--drivers/hid/uhid.c95
-rw-r--r--drivers/hid/usbhid/hid-quirks.c1
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
607static const struct hid_device_id sensor_hub_devices[] = { 607static 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};
611MODULE_DEVICE_TABLE(hid, sensor_hub_devices); 612MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
612 613
613static 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
618static struct hid_driver sensor_hub_driver = { 614static 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");
584out: 585out:
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
555static int i2c_hid_parse(struct hid_device *hid) 566static 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
737static int __devinit i2c_hid_init_irq(struct i2c_client *client) 748static 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
759static int __devinit i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) 770static 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
880static int __devinit i2c_hid_probe(struct i2c_client *client, 891static 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
979static int __devexit i2c_hid_remove(struct i2c_client *client) 990static 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. */
283struct 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
298static 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
358static 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
279static int uhid_dev_create(struct uhid_device *uhid, 368static 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 },