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) item.type == HID_ITEM_TYPE_MAIN && item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && - hid->bus == BUS_USB) + (hid->bus == BUS_USB || hid->bus == BUS_I2C)) hid->group = HID_GROUP_SENSOR_HUB; } 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 @@ #define USB_VENDOR_ID_EZKEY 0x0518 #define USB_DEVICE_ID_BTC_8193 0x0002 +#define USB_VENDOR_ID_FORMOSA 0x147a +#define USB_DEVICE_ID_FORMOSA_IR_RECEIVER 0xe03e + #define USB_VENDOR_ID_FREESCALE 0x15A2 #define USB_DEVICE_ID_FREESCALE_MX28 0x004F 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) rdev->priv = data; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->allowed_protos = RC_TYPE_ALL; + rdev->allowed_protos = RC_BIT_ALL; rdev->open = picolcd_cir_open; rdev->close = picolcd_cir_close; 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) } static const struct hid_device_id sensor_hub_devices[] = { - { HID_DEVICE(BUS_USB, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) }, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, + HID_ANY_ID) }, { } }; MODULE_DEVICE_TABLE(hid, sensor_hub_devices); -static const struct hid_usage_id sensor_hub_grabbed_usages[] = { - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } -}; - static struct hid_driver sensor_hub_driver = { .name = "hid-sensor-hub", .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) if (result < 0) goto error_class; + printk(KERN_INFO "hidraw: raw HID events driver (C) Jiri Kosina\n"); out: return result; 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, { struct i2c_client *client = hid->driver_data; int report_id = buf[0]; + int ret; if (report_type == HID_INPUT_REPORT) return -EINVAL; - return i2c_hid_set_report(client, + if (report_id) { + buf++; + count--; + } + + ret = i2c_hid_set_report(client, report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, report_id, buf, count); + + if (report_id && ret >= 0) + ret++; /* add report_id to the number of transfered bytes */ + + return ret; } static int i2c_hid_parse(struct hid_device *hid) @@ -734,7 +745,7 @@ static struct hid_ll_driver i2c_hid_ll_driver = { .hidinput_input_event = i2c_hid_hidinput_input_event, }; -static int __devinit i2c_hid_init_irq(struct i2c_client *client) +static int i2c_hid_init_irq(struct i2c_client *client) { struct i2c_hid *ihid = i2c_get_clientdata(client); int ret; @@ -756,7 +767,7 @@ static int __devinit i2c_hid_init_irq(struct i2c_client *client) return 0; } -static int __devinit i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) +static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) { struct i2c_client *client = ihid->client; struct i2c_hid_desc *hdesc = &ihid->hdesc; @@ -877,8 +888,8 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client, } #endif -static int __devinit i2c_hid_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) +static int i2c_hid_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) { int ret; struct i2c_hid *ihid; @@ -976,7 +987,7 @@ err: return ret; } -static int __devexit i2c_hid_remove(struct i2c_client *client) +static int i2c_hid_remove(struct i2c_client *client) { struct i2c_hid *ihid = i2c_get_clientdata(client); struct hid_device *hid; @@ -1042,7 +1053,7 @@ static struct i2c_driver i2c_hid_driver = { }, .probe = i2c_hid_probe, - .remove = __devexit_p(i2c_hid_remove), + .remove = i2c_hid_remove, .id_table = i2c_hid_id_table, }; 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 @@ */ #include <linux/atomic.h> +#include <linux/compat.h> #include <linux/device.h> #include <linux/fs.h> #include <linux/hid.h> @@ -276,6 +277,94 @@ static struct hid_ll_driver uhid_hid_driver = { .parse = uhid_hid_parse, }; +#ifdef CONFIG_COMPAT + +/* Apparently we haven't stepped on these rakes enough times yet. */ +struct uhid_create_req_compat { + __u8 name[128]; + __u8 phys[64]; + __u8 uniq[64]; + + compat_uptr_t rd_data; + __u16 rd_size; + + __u16 bus; + __u32 vendor; + __u32 product; + __u32 version; + __u32 country; +} __attribute__((__packed__)); + +static int uhid_event_from_user(const char __user *buffer, size_t len, + struct uhid_event *event) +{ + if (is_compat_task()) { + u32 type; + + if (get_user(type, buffer)) + return -EFAULT; + + if (type == UHID_CREATE) { + /* + * This is our messed up request with compat pointer. + * It is largish (more than 256 bytes) so we better + * allocate it from the heap. + */ + struct uhid_create_req_compat *compat; + + compat = kmalloc(sizeof(*compat), GFP_KERNEL); + if (!compat) + return -ENOMEM; + + buffer += sizeof(type); + len -= sizeof(type); + if (copy_from_user(compat, buffer, + min(len, sizeof(*compat)))) { + kfree(compat); + return -EFAULT; + } + + /* Shuffle the data over to proper structure */ + event->type = type; + + memcpy(event->u.create.name, compat->name, + sizeof(compat->name)); + memcpy(event->u.create.phys, compat->phys, + sizeof(compat->phys)); + memcpy(event->u.create.uniq, compat->uniq, + sizeof(compat->uniq)); + + event->u.create.rd_data = compat_ptr(compat->rd_data); + event->u.create.rd_size = compat->rd_size; + + event->u.create.bus = compat->bus; + event->u.create.vendor = compat->vendor; + event->u.create.product = compat->product; + event->u.create.version = compat->version; + event->u.create.country = compat->country; + + kfree(compat); + return 0; + } + /* All others can be copied directly */ + } + + if (copy_from_user(event, buffer, min(len, sizeof(*event)))) + return -EFAULT; + + return 0; +} +#else +static int uhid_event_from_user(const char __user *buffer, size_t len, + struct uhid_event *event) +{ + if (copy_from_user(event, buffer, min(len, sizeof(*event)))) + return -EFAULT; + + return 0; +} +#endif + static int uhid_dev_create(struct uhid_device *uhid, const struct uhid_event *ev) { @@ -498,10 +587,10 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); len = min(count, sizeof(uhid->input_buf)); - if (copy_from_user(&uhid->input_buf, buffer, len)) { - ret = -EFAULT; + + ret = uhid_event_from_user(buffer, len, &uhid->input_buf); + if (ret) goto unlock; - } switch (uhid->input_buf.type) { 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 { { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, |