|
@@ -653,10 +653,9 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
|
|
if (device->driver->report_fixup)
|
|
if (device->driver->report_fixup)
|
|
device->driver->report_fixup(device, start, size);
|
|
device->driver->report_fixup(device, start, size);
|
|
|
|
|
|
- device->rdesc = kmalloc(size, GFP_KERNEL);
|
|
|
|
|
|
+ device->rdesc = kmemdup(start, size, GFP_KERNEL);
|
|
if (device->rdesc == NULL)
|
|
if (device->rdesc == NULL)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
- memcpy(device->rdesc, start, size);
|
|
|
|
device->rsize = size;
|
|
device->rsize = size;
|
|
|
|
|
|
parser = vmalloc(sizeof(struct hid_parser));
|
|
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 count = field->report_count;
|
|
unsigned offset = field->report_offset;
|
|
unsigned offset = field->report_offset;
|
|
unsigned size = field->report_size;
|
|
unsigned size = field->report_size;
|
|
- unsigned bitsused = offset + count * size;
|
|
|
|
unsigned n;
|
|
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++) {
|
|
for (n = 0; n < count; n++) {
|
|
if (field->logical_minimum < 0) /* signed values */
|
|
if (field->logical_minimum < 0) /* signed values */
|
|
implement(data, offset + n * size, size, s32ton(field->value[n], size));
|
|
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)
|
|
if (report->id > 0)
|
|
*data++ = report->id;
|
|
*data++ = report->id;
|
|
|
|
|
|
|
|
+ memset(data, 0, ((report->size - 1) >> 3) + 1);
|
|
for (n = 0; n < report->maxfield; n++)
|
|
for (n = 0; n < report->maxfield; n++)
|
|
hid_output_field(report->field[n], data);
|
|
hid_output_field(report->field[n], data);
|
|
}
|
|
}
|
|
@@ -1167,6 +1162,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
|
|
unsigned int i;
|
|
unsigned int i;
|
|
int len;
|
|
int len;
|
|
|
|
|
|
|
|
+ if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
|
|
|
|
+ connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
|
|
if (hdev->bus != BUS_USB)
|
|
if (hdev->bus != BUS_USB)
|
|
connect_mask &= ~HID_CONNECT_HIDDEV;
|
|
connect_mask &= ~HID_CONNECT_HIDDEV;
|
|
if (hid_hiddev(hdev))
|
|
if (hid_hiddev(hdev))
|
|
@@ -1246,6 +1243,7 @@ EXPORT_SYMBOL_GPL(hid_disconnect);
|
|
/* a list of devices for which there is a specialized driver on HID bus */
|
|
/* a list of devices for which there is a specialized driver on HID bus */
|
|
static const struct hid_device_id hid_blacklist[] = {
|
|
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_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_WCP32PU) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
|
|
{ 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) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
|
|
@@ -1290,6 +1288,7 @@ 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_FOUNTAIN_TP_ONLY) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_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_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) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
|
|
{ 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_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
|
|
@@ -1343,6 +1342,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_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_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_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_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_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) },
|
|
{ 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[] = {
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
|
|
{ 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_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_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, 0x0005) },
|
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
|
|
{ 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) },
|
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
|
|
{ }
|
|
{ }
|
|
@@ -1757,7 +1759,7 @@ int hid_add_device(struct hid_device *hdev)
|
|
|
|
|
|
/* we need to kill them here, otherwise they will stay allocated to
|
|
/* we need to kill them here, otherwise they will stay allocated to
|
|
* wait for coming driver */
|
|
* wait for coming driver */
|
|
- if (hid_ignore(hdev))
|
|
|
|
|
|
+ if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) && hid_ignore(hdev))
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
|
|
|
/* XXX hack, any other cleaner solution after the driver core
|
|
/* XXX hack, any other cleaner solution after the driver core
|
|
@@ -1765,11 +1767,12 @@ int hid_add_device(struct hid_device *hdev)
|
|
dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
|
|
dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
|
|
hdev->vendor, hdev->product, atomic_inc_return(&id));
|
|
hdev->vendor, hdev->product, atomic_inc_return(&id));
|
|
|
|
|
|
|
|
+ hid_debug_register(hdev, dev_name(&hdev->dev));
|
|
ret = device_add(&hdev->dev);
|
|
ret = device_add(&hdev->dev);
|
|
if (!ret)
|
|
if (!ret)
|
|
hdev->status |= HID_STAT_ADDED;
|
|
hdev->status |= HID_STAT_ADDED;
|
|
-
|
|
|
|
- hid_debug_register(hdev, dev_name(&hdev->dev));
|
|
|
|
|
|
+ else
|
|
|
|
+ hid_debug_unregister(hdev);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|