static int hid_ignore_special_drivers = 0;
module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600);
------- -MODULE_PARM_DESC(debug, "Ignore any special drivers and handle all devices by generic driver");
+++++++ +MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle all devices by generic driver");
/*
* Register a new report for a device.
/* hid-rmi should take care of them, not hid-generic */
hid->group = HID_GROUP_RMI;
+ /*
+ * Vendor specific handlings
+ */
+ switch (hid->vendor) {
+ case USB_VENDOR_ID_WACOM:
+ hid->group = HID_GROUP_WACOM;
+ break;
+ }
+
vfree(parser);
return 0;
}
if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev))
hdev->claimed |= HID_CLAIMED_HIDRAW;
++++++++ if (connect_mask & HID_CONNECT_DRIVER)
++++++++ hdev->claimed |= HID_CLAIMED_DRIVER;
++++++++
/* Drivers with the ->raw_event callback set are not required to connect
* to any other listener. */
if (!hdev->claimed && !hdev->driver->raw_event) {
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
+++++++ + { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
+++++++ + { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_6000) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
#if IS_ENABLED(CONFIG_HID_ROCCAT)
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
- { 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_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WACOM, HID_ANY_ID) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) },
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001
+ +++++++#define USB_VENDOR_ID_ELAN 0x04f3
+ +++++++#define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089
+ +++++++
#define USB_VENDOR_ID_ELECOM 0x056e
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070 0xa070
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 0xa072
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081
+++++++ +#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2 0xa0c2
#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096 0xa096
#define USB_VENDOR_ID_IMATION 0x0718
#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
#define USB_VENDOR_ID_MSI 0x1770
- #define USB_DEVICE_ID_MSI_GX680R_LED_PANEL 0xff00
+ #define USB_DEVICE_ID_MSI_GT683R_LED_PANEL 0xff00
#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
#define USB_DEVICE_ID_N_S_HARMONY 0xc359
#define USB_DEVICE_ID_PENMOUNT_PCI 0x3500
#define USB_DEVICE_ID_PENMOUNT_1610 0x1610
#define USB_DEVICE_ID_PENMOUNT_1640 0x1640
+++++++ +#define USB_DEVICE_ID_PENMOUNT_6000 0x6000
#define USB_VENDOR_ID_PETALYNX 0x18b1
#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
#define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff
#define USB_VENDOR_ID_PIXART 0x093a
+ +++++++#define USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2 0x0137
+ +++++++#define USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE 0x2510
#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN 0x8001
#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1 0x8002
#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2 0x8003
static void thingm_remove_rgb(struct thingm_rgb *rgb)
{
------- - flush_work(&rgb->work);
led_classdev_unregister(&rgb->red.ldev);
led_classdev_unregister(&rgb->green.ldev);
led_classdev_unregister(&rgb->blue.ldev);
+++++++ + flush_work(&rgb->work);
}
static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (!tdev->fwinfo) {
hid_err(hdev, "unsupported firmware %c\n", tdev->version.major);
++++++++ err = -ENODEV;
goto stop;
}
struct thingm_device *tdev = hid_get_drvdata(hdev);
int i;
+++++++ + hid_hw_stop(hdev);
+++++++ +
for (i = 0; i < tdev->fwinfo->numrgb; ++i)
thingm_remove_rgb(tdev->rgb + i);
------- -
------- - hid_hw_stop(hdev);
}
static const struct hid_device_id thingm_table[] = {
struct usbhid_device *usbhid = hid->driver_data;
spin_lock_irqsave(&usbhid->lock, flags);
- ------- if (hid->open > 0 &&
+ +++++++ if ((hid->open > 0 || hid->quirks & HID_QUIRK_ALWAYS_POLL) &&
!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
!test_bit(HID_SUSPENDED, &usbhid->iofl) &&
!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
struct usbhid_device *usbhid =
container_of(work, struct usbhid_device, reset_work);
struct hid_device *hid = usbhid->hid;
------- - int rc = 0;
+++++++ + int rc;
if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) {
dev_dbg(&usbhid->intf->dev, "clear halt\n");
rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe);
clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
------- - hid_start_in(hid);
------- - }
------- -
------- - else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) {
------- - dev_dbg(&usbhid->intf->dev, "resetting device\n");
------- - rc = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf);
if (rc == 0) {
------- - rc = usb_reset_device(hid_to_usb_dev(hid));
------- - usb_unlock_device(hid_to_usb_dev(hid));
+++++++ + hid_start_in(hid);
+++++++ + } else {
+++++++ + dev_dbg(&usbhid->intf->dev,
+++++++ + "clear-halt failed: %d\n", rc);
+++++++ + set_bit(HID_RESET_PENDING, &usbhid->iofl);
}
------- - clear_bit(HID_RESET_PENDING, &usbhid->iofl);
}
------- - switch (rc) {
------- - case 0:
------- - if (!test_bit(HID_IN_RUNNING, &usbhid->iofl))
------- - hid_io_error(hid);
------- - break;
------- - default:
------- - hid_err(hid, "can't reset device, %s-%s/input%d, status %d\n",
------- - hid_to_usb_dev(hid)->bus->bus_name,
------- - hid_to_usb_dev(hid)->devpath,
------- - usbhid->ifnum, rc);
------- - /* FALLTHROUGH */
------- - case -EHOSTUNREACH:
------- - case -ENODEV:
------- - case -EINTR:
------- - break;
+++++++ + if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) {
+++++++ + dev_dbg(&usbhid->intf->dev, "resetting device\n");
+++++++ + usb_queue_reset_device(usbhid->intf);
}
}
case 0: /* success */
usbhid_mark_busy(usbhid);
usbhid->retry_delay = 0;
+ +++++++ if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open)
+ +++++++ break;
hid_input_report(urb->context, HID_INPUT_REPORT,
urb->transfer_buffer,
urb->actual_length, 1);
if (!--hid->open) {
spin_unlock_irq(&usbhid->lock);
hid_cancel_delayed_stuff(usbhid);
- ------- usb_kill_urb(usbhid->urbin);
- ------- usbhid->intf->needs_remote_wakeup = 0;
+ +++++++ if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) {
+ +++++++ usb_kill_urb(usbhid->urbin);
+ +++++++ usbhid->intf->needs_remote_wakeup = 0;
+ +++++++ }
} else {
spin_unlock_irq(&usbhid->lock);
}
set_bit(HID_STARTED, &usbhid->iofl);
+ +++++++ if (hid->quirks & HID_QUIRK_ALWAYS_POLL) {
+ +++++++ ret = usb_autopm_get_interface(usbhid->intf);
+ +++++++ if (ret)
+ +++++++ goto fail;
+ +++++++ usbhid->intf->needs_remote_wakeup = 1;
+ +++++++ ret = hid_start_in(hid);
+ +++++++ if (ret) {
+ +++++++ dev_err(&hid->dev,
+ +++++++ "failed to start in urb: %d\n", ret);
+ +++++++ }
+ +++++++ usb_autopm_put_interface(usbhid->intf);
+ +++++++ }
+ +++++++
/* Some keyboards don't work until their LEDs have been set.
* Since BIOSes do set the LEDs, it must be safe for any device
* that supports the keyboard boot protocol.
if (WARN_ON(!usbhid))
return;
+ +++++++ if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
+ +++++++ usbhid->intf->needs_remote_wakeup = 0;
+ +++++++
clear_bit(HID_STARTED, &usbhid->iofl);
spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
set_bit(HID_DISCONNECTED, &usbhid->iofl);
#define HID_CONNECT_HIDDEV 0x08
#define HID_CONNECT_HIDDEV_FORCE 0x10
#define HID_CONNECT_FF 0x20
++++++++ #define HID_CONNECT_DRIVER 0x40
#define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \
HID_CONNECT_HIDDEV|HID_CONNECT_FF)
#define HID_QUIRK_HIDINPUT_FORCE 0x00000080
#define HID_QUIRK_NO_EMPTY_INPUT 0x00000100
#define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200
+ +++++++#define HID_QUIRK_ALWAYS_POLL 0x00000400
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000
#define HID_GROUP_RMI 0x0100
/*
+ * Vendor specific HID device groups
+ */
+ #define HID_GROUP_WACOM 0x0101
+
+ /*
* This is the global environment of the parser. This information is
* persistent for main-items. The global environment can be saved and
* restored with PUSH/POP statements.
#define HID_CLAIMED_INPUT 1
#define HID_CLAIMED_HIDDEV 2
#define HID_CLAIMED_HIDRAW 4
++++++++ #define HID_CLAIMED_DRIVER 8
#define HID_STAT_ADDED 1
#define HID_STAT_PARSED 2