Merge branches 'upstream-fixes', 'bkl-removal', 'debugfs-fixes' and 'hid-suspend...
[pandora-kernel.git] / drivers / hid / hid-core.c
index 86cb2c4..33cac48 100644 (file)
@@ -653,10 +653,9 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
        if (device->driver->report_fixup)
                device->driver->report_fixup(device, start, size);
 
-       device->rdesc = kmalloc(size, GFP_KERNEL);
+       device->rdesc = kmemdup(start, size, GFP_KERNEL);
        if (device->rdesc == NULL)
                return -ENOMEM;
-       memcpy(device->rdesc, start, size);
        device->rsize = size;
 
        parser = vmalloc(sizeof(struct hid_parser));
@@ -940,13 +939,8 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
        unsigned count = field->report_count;
        unsigned offset = field->report_offset;
        unsigned size = field->report_size;
-       unsigned bitsused = offset + count * size;
        unsigned n;
 
-       /* make sure the unused bits in the last byte are zeros */
-       if (count > 0 && size > 0 && (bitsused % 8) != 0)
-               data[(bitsused-1)/8] &= (1 << (bitsused % 8)) - 1;
-
        for (n = 0; n < count; n++) {
                if (field->logical_minimum < 0) /* signed values */
                        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)
        if (report->id > 0)
                *data++ = report->id;
 
+       memset(data, 0, ((report->size - 1) >> 3) + 1);
        for (n = 0; n < report->maxfield; n++)
                hid_output_field(report->field[n], data);
 }
@@ -1043,13 +1038,8 @@ void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
 
        if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
                hid->hiddev_report_event(hid, report);
-       if (hid->claimed & HID_CLAIMED_HIDRAW) {
-               /* numbered reports need to be passed with the report num */
-               if (report_enum->numbered)
-                       hidraw_report_event(hid, data - 1, size + 1);
-               else
-                       hidraw_report_event(hid, data, size);
-       }
+       if (hid->claimed & HID_CLAIMED_HIDRAW)
+               hidraw_report_event(hid, data, size);
 
        for (a = 0; a < report->maxfield; a++)
                hid_input_field(hid, report->field[a], cdata, interrupt);
@@ -1165,6 +1155,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
        unsigned int i;
        int len;
 
+       if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
+               connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
        if (hdev->bus != BUS_USB)
                connect_mask &= ~HID_CONNECT_HIDDEV;
        if (hid_hiddev(hdev))
@@ -1244,6 +1236,7 @@ EXPORT_SYMBOL_GPL(hid_disconnect);
 /* a list of devices for which there is a specialized driver on HID bus */
 static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
@@ -1288,7 +1281,9 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
@@ -1340,6 +1335,7 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
@@ -1350,13 +1346,16 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
 
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
        { }
@@ -1753,7 +1752,7 @@ int hid_add_device(struct hid_device *hdev)
 
        /* we need to kill them here, otherwise they will stay allocated to
         * wait for coming driver */
-       if (hid_ignore(hdev))
+       if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) && hid_ignore(hdev))
                return -ENODEV;
 
        /* XXX hack, any other cleaner solution after the driver core
@@ -1761,11 +1760,12 @@ int hid_add_device(struct hid_device *hdev)
        dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
                     hdev->vendor, hdev->product, atomic_inc_return(&id));
 
+       hid_debug_register(hdev, dev_name(&hdev->dev));
        ret = device_add(&hdev->dev);
        if (!ret)
                hdev->status |= HID_STAT_ADDED;
-
-       hid_debug_register(hdev, dev_name(&hdev->dev));
+       else
+               hid_debug_unregister(hdev);
 
        return ret;
 }