mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 06:12:08 +00:00
Merge branch 'for-4.16/hid-quirks-cleanup/_base' into for-linus
This series from Benjamin Tissoires finally removes one of the big PITAs in the hid-core, which is the absolute need of having added all the new device IDs into the horrid hid_have_special_driver[]
This commit is contained in:
commit
a7acb31d6c
@ -396,6 +396,17 @@ config HID_ITE
|
||||
---help---
|
||||
Support for ITE devices not fully compliant with HID standard.
|
||||
|
||||
config HID_JABRA
|
||||
tristate "Jabra USB HID Driver"
|
||||
depends on HID
|
||||
---help---
|
||||
Support for Jabra USB HID devices.
|
||||
|
||||
Prevents mapping of vendor defined HID usages to input events. Without
|
||||
this driver HID reports from Jabra devices may incorrectly be seen as
|
||||
mouse button events.
|
||||
Say M here if you may ever plug in a Jabra USB device.
|
||||
|
||||
config HID_TWINHAN
|
||||
tristate "Twinhan IR remote control"
|
||||
depends on HID
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# Makefile for the HID driver
|
||||
#
|
||||
hid-y := hid-core.o hid-input.o
|
||||
hid-y := hid-core.o hid-input.o hid-quirks.o
|
||||
hid-$(CONFIG_DEBUG_FS) += hid-debug.o
|
||||
|
||||
obj-$(CONFIG_HID) += hid.o
|
||||
@ -52,6 +52,7 @@ obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
|
||||
obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o
|
||||
obj-$(CONFIG_HID_ICADE) += hid-icade.o
|
||||
obj-$(CONFIG_HID_ITE) += hid-ite.o
|
||||
obj-$(CONFIG_HID_JABRA) += hid-jabra.o
|
||||
obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
|
||||
obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
|
||||
obj-$(CONFIG_HID_KYE) += hid-kye.o
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,8 +24,71 @@
|
||||
|
||||
#include <linux/hid.h>
|
||||
|
||||
static struct hid_driver hid_generic;
|
||||
|
||||
static int __unmap_hid_generic(struct device *dev, void *data)
|
||||
{
|
||||
struct hid_driver *hdrv = data;
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
|
||||
/* only unbind matching devices already bound to hid-generic */
|
||||
if (hdev->driver != &hid_generic ||
|
||||
hid_match_device(hdev, hdrv) == NULL)
|
||||
return 0;
|
||||
|
||||
if (dev->parent) /* Needed for USB */
|
||||
device_lock(dev->parent);
|
||||
device_release_driver(dev);
|
||||
if (dev->parent)
|
||||
device_unlock(dev->parent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hid_generic_add_driver(struct hid_driver *hdrv)
|
||||
{
|
||||
bus_for_each_dev(&hid_bus_type, NULL, hdrv, __unmap_hid_generic);
|
||||
}
|
||||
|
||||
static void hid_generic_removed_driver(struct hid_driver *hdrv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = driver_attach(&hid_generic.driver);
|
||||
}
|
||||
|
||||
static int __check_hid_generic(struct device_driver *drv, void *data)
|
||||
{
|
||||
struct hid_driver *hdrv = to_hid_driver(drv);
|
||||
struct hid_device *hdev = data;
|
||||
|
||||
if (hdrv == &hid_generic)
|
||||
return 0;
|
||||
|
||||
return hid_match_device(hdev, hdrv) != NULL;
|
||||
}
|
||||
|
||||
static bool hid_generic_match(struct hid_device *hdev,
|
||||
bool ignore_special_driver)
|
||||
{
|
||||
if (ignore_special_driver)
|
||||
return true;
|
||||
|
||||
if (hdev->quirks & HID_QUIRK_HAVE_SPECIAL_DRIVER)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If any other driver wants the device, leave the device to this other
|
||||
* driver.
|
||||
*/
|
||||
if (bus_for_each_drv(&hid_bus_type, NULL, hdev, __check_hid_generic))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct hid_device_id hid_table[] = {
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_GENERIC, HID_ANY_ID, HID_ANY_ID) },
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, hid_table);
|
||||
@ -33,6 +96,9 @@ MODULE_DEVICE_TABLE(hid, hid_table);
|
||||
static struct hid_driver hid_generic = {
|
||||
.name = "hid-generic",
|
||||
.id_table = hid_table,
|
||||
.match = hid_generic_match,
|
||||
.bus_add_driver = hid_generic_add_driver,
|
||||
.bus_removed_driver = hid_generic_removed_driver,
|
||||
};
|
||||
module_hid_driver(hid_generic);
|
||||
|
||||
|
58
drivers/hid/hid-jabra.c
Normal file
58
drivers/hid/hid-jabra.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Jabra USB HID Driver
|
||||
*
|
||||
* Copyright (c) 2017 Niels Skou Olsen <nolsen@jabra.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define HID_UP_VENDOR_DEFINED_MIN 0xff000000
|
||||
#define HID_UP_VENDOR_DEFINED_MAX 0xffff0000
|
||||
|
||||
static int jabra_input_mapping(struct hid_device *hdev,
|
||||
struct hid_input *hi,
|
||||
struct hid_field *field,
|
||||
struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
int is_vendor_defined =
|
||||
((usage->hid & HID_USAGE_PAGE) >= HID_UP_VENDOR_DEFINED_MIN &&
|
||||
(usage->hid & HID_USAGE_PAGE) <= HID_UP_VENDOR_DEFINED_MAX);
|
||||
|
||||
dbg_hid("hid=0x%08x appl=0x%08x coll_idx=0x%02x usage_idx=0x%02x: %s\n",
|
||||
usage->hid,
|
||||
field->application,
|
||||
usage->collection_index,
|
||||
usage->usage_index,
|
||||
is_vendor_defined ? "ignored" : "defaulted");
|
||||
|
||||
/* Ignore vendor defined usages, default map standard usages */
|
||||
return is_vendor_defined ? -1 : 0;
|
||||
}
|
||||
|
||||
static const struct hid_device_id jabra_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, HID_ANY_ID) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, jabra_devices);
|
||||
|
||||
static struct hid_driver jabra_driver = {
|
||||
.name = "jabra",
|
||||
.id_table = jabra_devices,
|
||||
.input_mapping = jabra_input_mapping,
|
||||
};
|
||||
module_hid_driver(jabra_driver);
|
||||
|
||||
MODULE_AUTHOR("Niels Skou Olsen <nolsen@jabra.com>");
|
||||
MODULE_DESCRIPTION("Jabra USB HID Driver");
|
||||
MODULE_LICENSE("GPL");
|
1263
drivers/hid/hid-quirks.c
Normal file
1263
drivers/hid/hid-quirks.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
# Makefile for the USB input drivers
|
||||
#
|
||||
|
||||
usbhid-y := hid-core.o hid-quirks.o
|
||||
usbhid-y := hid-core.o
|
||||
usbhid-$(CONFIG_USB_HIDDEV) += hiddev.o
|
||||
usbhid-$(CONFIG_HID_PID) += hid-pidff.o
|
||||
|
||||
|
@ -978,8 +978,7 @@ static int usbhid_parse(struct hid_device *hid)
|
||||
int num_descriptors;
|
||||
size_t offset = offsetof(struct hid_descriptor, desc);
|
||||
|
||||
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
|
||||
le16_to_cpu(dev->descriptor.idProduct));
|
||||
quirks = hid_lookup_quirk(hid);
|
||||
|
||||
if (quirks & HID_QUIRK_IGNORE)
|
||||
return -ENODEV;
|
||||
@ -1328,8 +1327,8 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
|
||||
hid->bus = BUS_USB;
|
||||
hid->vendor = le16_to_cpu(dev->descriptor.idVendor);
|
||||
hid->product = le16_to_cpu(dev->descriptor.idProduct);
|
||||
hid->version = le16_to_cpu(dev->descriptor.bcdDevice);
|
||||
hid->name[0] = 0;
|
||||
hid->quirks = usbhid_lookup_quirk(hid->vendor, hid->product);
|
||||
if (intf->cur_altsetting->desc.bInterfaceProtocol ==
|
||||
USB_INTERFACE_PROTOCOL_MOUSE)
|
||||
hid->type = HID_TYPE_USBMOUSE;
|
||||
@ -1641,7 +1640,7 @@ static int __init hid_init(void)
|
||||
{
|
||||
int retval = -ENOMEM;
|
||||
|
||||
retval = usbhid_quirks_init(quirks_param);
|
||||
retval = hid_quirks_init(quirks_param, BUS_USB, MAX_USBHID_BOOT_QUIRKS);
|
||||
if (retval)
|
||||
goto usbhid_quirks_init_fail;
|
||||
retval = usb_register(&hid_driver);
|
||||
@ -1651,7 +1650,7 @@ static int __init hid_init(void)
|
||||
|
||||
return 0;
|
||||
usb_register_fail:
|
||||
usbhid_quirks_exit();
|
||||
hid_quirks_exit(BUS_USB);
|
||||
usbhid_quirks_init_fail:
|
||||
return retval;
|
||||
}
|
||||
@ -1659,7 +1658,7 @@ usbhid_quirks_init_fail:
|
||||
static void __exit hid_exit(void)
|
||||
{
|
||||
usb_deregister(&hid_driver);
|
||||
usbhid_quirks_exit();
|
||||
hid_quirks_exit(BUS_USB);
|
||||
}
|
||||
|
||||
module_init(hid_init);
|
||||
|
@ -1,402 +0,0 @@
|
||||
/*
|
||||
* USB HID quirks support for Linux
|
||||
*
|
||||
* Copyright (c) 1999 Andreas Gal
|
||||
* Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
|
||||
* Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
|
||||
* Copyright (c) 2006-2007 Jiri Kosina
|
||||
* Copyright (c) 2007 Paul Walmsley
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#include <linux/hid.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "../hid-ids.h"
|
||||
|
||||
/*
|
||||
* Alphabetically sorted blacklist by quirk type.
|
||||
*/
|
||||
|
||||
static const struct hid_blacklist {
|
||||
__u16 idVendor;
|
||||
__u16 idProduct;
|
||||
__u32 quirks;
|
||||
} hid_blacklist[] = {
|
||||
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN, HID_QUIRK_MULTI_INPUT},
|
||||
{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
|
||||
|
||||
{ USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
|
||||
|
||||
{ USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH_2968, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
|
||||
{ USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT },
|
||||
|
||||
{ USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS1758, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70R, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_M65RGB, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K95RGB, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL },
|
||||
{ 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_FUTABA, USB_DEVICE_ID_LED_DISPLAY, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS817_TOUCH, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS_TS, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS1030_TOUCH, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
|
||||
|
||||
{ USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
|
||||
|
||||
{ USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE },
|
||||
|
||||
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS1, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK, HID_QUIRK_MULTI_INPUT },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
/* Dynamic HID quirks list - specified at runtime */
|
||||
struct quirks_list_struct {
|
||||
struct hid_blacklist hid_bl_item;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
static LIST_HEAD(dquirks_list);
|
||||
static DECLARE_RWSEM(dquirks_rwsem);
|
||||
|
||||
/* Runtime ("dynamic") quirks manipulation functions */
|
||||
|
||||
/**
|
||||
* usbhid_exists_dquirk: find any dynamic quirks for a USB HID device
|
||||
* @idVendor: the 16-bit USB vendor ID, in native byteorder
|
||||
* @idProduct: the 16-bit USB product ID, in native byteorder
|
||||
*
|
||||
* Description:
|
||||
* Scans dquirks_list for a matching dynamic quirk and returns
|
||||
* the pointer to the relevant struct hid_blacklist if found.
|
||||
* Must be called with a read lock held on dquirks_rwsem.
|
||||
*
|
||||
* Returns: NULL if no quirk found, struct hid_blacklist * if found.
|
||||
*/
|
||||
static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor,
|
||||
const u16 idProduct)
|
||||
{
|
||||
struct quirks_list_struct *q;
|
||||
struct hid_blacklist *bl_entry = NULL;
|
||||
|
||||
list_for_each_entry(q, &dquirks_list, node) {
|
||||
if (q->hid_bl_item.idVendor == idVendor &&
|
||||
q->hid_bl_item.idProduct == idProduct) {
|
||||
bl_entry = &q->hid_bl_item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bl_entry != NULL)
|
||||
dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
|
||||
bl_entry->quirks, bl_entry->idVendor,
|
||||
bl_entry->idProduct);
|
||||
|
||||
return bl_entry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* usbhid_modify_dquirk: add/replace a HID quirk
|
||||
* @idVendor: the 16-bit USB vendor ID, in native byteorder
|
||||
* @idProduct: the 16-bit USB product ID, in native byteorder
|
||||
* @quirks: the u32 quirks value to add/replace
|
||||
*
|
||||
* Description:
|
||||
* If an dynamic quirk exists in memory for this (idVendor,
|
||||
* idProduct) pair, replace its quirks value with what was
|
||||
* provided. Otherwise, add the quirk to the dynamic quirks list.
|
||||
*
|
||||
* Returns: 0 OK, -error on failure.
|
||||
*/
|
||||
static int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
|
||||
const u32 quirks)
|
||||
{
|
||||
struct quirks_list_struct *q_new, *q;
|
||||
int list_edited = 0;
|
||||
|
||||
if (!idVendor) {
|
||||
dbg_hid("Cannot add a quirk with idVendor = 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL);
|
||||
if (!q_new)
|
||||
return -ENOMEM;
|
||||
|
||||
q_new->hid_bl_item.idVendor = idVendor;
|
||||
q_new->hid_bl_item.idProduct = idProduct;
|
||||
q_new->hid_bl_item.quirks = quirks;
|
||||
|
||||
down_write(&dquirks_rwsem);
|
||||
|
||||
list_for_each_entry(q, &dquirks_list, node) {
|
||||
|
||||
if (q->hid_bl_item.idVendor == idVendor &&
|
||||
q->hid_bl_item.idProduct == idProduct) {
|
||||
|
||||
list_replace(&q->node, &q_new->node);
|
||||
kfree(q);
|
||||
list_edited = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!list_edited)
|
||||
list_add_tail(&q_new->node, &dquirks_list);
|
||||
|
||||
up_write(&dquirks_rwsem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* usbhid_remove_all_dquirks: remove all runtime HID quirks from memory
|
||||
*
|
||||
* Description:
|
||||
* Free all memory associated with dynamic quirks - called before
|
||||
* module unload.
|
||||
*
|
||||
*/
|
||||
static void usbhid_remove_all_dquirks(void)
|
||||
{
|
||||
struct quirks_list_struct *q, *temp;
|
||||
|
||||
down_write(&dquirks_rwsem);
|
||||
list_for_each_entry_safe(q, temp, &dquirks_list, node) {
|
||||
list_del(&q->node);
|
||||
kfree(q);
|
||||
}
|
||||
up_write(&dquirks_rwsem);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* usbhid_quirks_init: apply USB HID quirks specified at module load time
|
||||
*/
|
||||
int usbhid_quirks_init(char **quirks_param)
|
||||
{
|
||||
u16 idVendor, idProduct;
|
||||
u32 quirks;
|
||||
int n = 0, m;
|
||||
|
||||
for (; n < MAX_USBHID_BOOT_QUIRKS && quirks_param[n]; n++) {
|
||||
|
||||
m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
|
||||
&idVendor, &idProduct, &quirks);
|
||||
|
||||
if (m != 3 ||
|
||||
usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) {
|
||||
pr_warn("Could not parse HID quirk module param %s\n",
|
||||
quirks_param[n]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* usbhid_quirks_exit: release memory associated with dynamic_quirks
|
||||
*
|
||||
* Description:
|
||||
* Release all memory associated with dynamic quirks. Called upon
|
||||
* module unload.
|
||||
*
|
||||
* Returns: nothing
|
||||
*/
|
||||
void usbhid_quirks_exit(void)
|
||||
{
|
||||
usbhid_remove_all_dquirks();
|
||||
}
|
||||
|
||||
/**
|
||||
* usbhid_exists_squirk: return any static quirks for a USB HID device
|
||||
* @idVendor: the 16-bit USB vendor ID, in native byteorder
|
||||
* @idProduct: the 16-bit USB product ID, in native byteorder
|
||||
*
|
||||
* Description:
|
||||
* Given a USB vendor ID and product ID, return a pointer to
|
||||
* the hid_blacklist entry associated with that device.
|
||||
*
|
||||
* Returns: pointer if quirk found, or NULL if no quirks found.
|
||||
*/
|
||||
static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
|
||||
const u16 idProduct)
|
||||
{
|
||||
const struct hid_blacklist *bl_entry = NULL;
|
||||
int n = 0;
|
||||
|
||||
for (; hid_blacklist[n].idVendor; n++)
|
||||
if (hid_blacklist[n].idVendor == idVendor &&
|
||||
(hid_blacklist[n].idProduct == (__u16) HID_ANY_ID ||
|
||||
hid_blacklist[n].idProduct == idProduct))
|
||||
bl_entry = &hid_blacklist[n];
|
||||
|
||||
if (bl_entry != NULL)
|
||||
dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
|
||||
bl_entry->quirks, bl_entry->idVendor,
|
||||
bl_entry->idProduct);
|
||||
return bl_entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* usbhid_lookup_quirk: return any quirks associated with a USB HID device
|
||||
* @idVendor: the 16-bit USB vendor ID, in native byteorder
|
||||
* @idProduct: the 16-bit USB product ID, in native byteorder
|
||||
*
|
||||
* Description:
|
||||
* Given a USB vendor ID and product ID, return any quirks associated
|
||||
* with that device.
|
||||
*
|
||||
* Returns: a u32 quirks value.
|
||||
*/
|
||||
u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
|
||||
{
|
||||
u32 quirks = 0;
|
||||
const struct hid_blacklist *bl_entry = NULL;
|
||||
|
||||
/* NCR devices must not be queried for reports */
|
||||
if (idVendor == USB_VENDOR_ID_NCR &&
|
||||
idProduct >= USB_DEVICE_ID_NCR_FIRST &&
|
||||
idProduct <= USB_DEVICE_ID_NCR_LAST)
|
||||
return HID_QUIRK_NO_INIT_REPORTS;
|
||||
|
||||
down_read(&dquirks_rwsem);
|
||||
bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
|
||||
if (!bl_entry)
|
||||
bl_entry = usbhid_exists_squirk(idVendor, idProduct);
|
||||
if (bl_entry)
|
||||
quirks = bl_entry->quirks;
|
||||
up_read(&dquirks_rwsem);
|
||||
|
||||
return quirks;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(usbhid_lookup_quirk);
|
@ -342,6 +342,7 @@ struct hid_item {
|
||||
#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_QUIRK_HAVE_SPECIAL_DRIVER 0x00080000
|
||||
#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
|
||||
#define HID_QUIRK_NO_INIT_REPORTS 0x20000000
|
||||
#define HID_QUIRK_NO_IGNORE 0x40000000
|
||||
@ -671,6 +672,7 @@ struct hid_usage_id {
|
||||
* to be called)
|
||||
* @dyn_list: list of dynamically added device ids
|
||||
* @dyn_lock: lock protecting @dyn_list
|
||||
* @match: check if the given device is handled by this driver
|
||||
* @probe: new device inserted
|
||||
* @remove: device removed (NULL if not a hot-plug capable driver)
|
||||
* @report_table: on which reports to call raw_event (NULL means all)
|
||||
@ -683,6 +685,8 @@ struct hid_usage_id {
|
||||
* @input_mapped: invoked on input registering after mapping an usage
|
||||
* @input_configured: invoked just before the device is registered
|
||||
* @feature_mapping: invoked on feature registering
|
||||
* @bus_add_driver: invoked when a HID driver is about to be added
|
||||
* @bus_removed_driver: invoked when a HID driver has been removed
|
||||
* @suspend: invoked on suspend (NULL means nop)
|
||||
* @resume: invoked on resume if device was not reset (NULL means nop)
|
||||
* @reset_resume: invoked on resume if device was reset (NULL means nop)
|
||||
@ -711,6 +715,7 @@ struct hid_driver {
|
||||
struct list_head dyn_list;
|
||||
spinlock_t dyn_lock;
|
||||
|
||||
bool (*match)(struct hid_device *dev, bool ignore_special_driver);
|
||||
int (*probe)(struct hid_device *dev, const struct hid_device_id *id);
|
||||
void (*remove)(struct hid_device *dev);
|
||||
|
||||
@ -736,6 +741,8 @@ struct hid_driver {
|
||||
void (*feature_mapping)(struct hid_device *hdev,
|
||||
struct hid_field *field,
|
||||
struct hid_usage *usage);
|
||||
void (*bus_add_driver)(struct hid_driver *driver);
|
||||
void (*bus_removed_driver)(struct hid_driver *driver);
|
||||
#ifdef CONFIG_PM
|
||||
int (*suspend)(struct hid_device *hdev, pm_message_t message);
|
||||
int (*resume)(struct hid_device *hdev);
|
||||
@ -814,6 +821,8 @@ extern bool hid_ignore(struct hid_device *);
|
||||
extern int hid_add_device(struct hid_device *);
|
||||
extern void hid_destroy_device(struct hid_device *);
|
||||
|
||||
extern struct bus_type hid_bus_type;
|
||||
|
||||
extern int __must_check __hid_register_driver(struct hid_driver *,
|
||||
struct module *, const char *mod_name);
|
||||
|
||||
@ -860,8 +869,12 @@ int hid_open_report(struct hid_device *device);
|
||||
int hid_check_keys_pressed(struct hid_device *hid);
|
||||
int hid_connect(struct hid_device *hid, unsigned int connect_mask);
|
||||
void hid_disconnect(struct hid_device *hid);
|
||||
const struct hid_device_id *hid_match_id(struct hid_device *hdev,
|
||||
bool hid_match_one_id(const struct hid_device *hdev,
|
||||
const struct hid_device_id *id);
|
||||
const struct hid_device_id *hid_match_id(const struct hid_device *hdev,
|
||||
const struct hid_device_id *id);
|
||||
const struct hid_device_id *hid_match_device(struct hid_device *hdev,
|
||||
struct hid_driver *hdrv);
|
||||
s32 hid_snto32(__u32 value, unsigned n);
|
||||
__u32 hid_field_extract(const struct hid_device *hid, __u8 *report,
|
||||
unsigned offset, unsigned n);
|
||||
@ -1098,9 +1111,9 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
|
||||
int interrupt);
|
||||
|
||||
/* HID quirks API */
|
||||
u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct);
|
||||
int usbhid_quirks_init(char **quirks_param);
|
||||
void usbhid_quirks_exit(void);
|
||||
unsigned long hid_lookup_quirk(const struct hid_device *hdev);
|
||||
int hid_quirks_init(char **quirks_param, __u16 bus, int count);
|
||||
void hid_quirks_exit(__u16 bus);
|
||||
|
||||
#ifdef CONFIG_HID_PID
|
||||
int hid_pidff_init(struct hid_device *hid);
|
||||
|
@ -789,7 +789,7 @@ static int hidp_setup_hid(struct hidp_session *session,
|
||||
hid->dev.parent = &session->conn->hcon->dev;
|
||||
hid->ll_driver = &hidp_hid_driver;
|
||||
|
||||
/* True if device is blacklisted in drivers/hid/hid-core.c */
|
||||
/* True if device is blacklisted in drivers/hid/hid-quirks.c */
|
||||
if (hid_ignore(hid)) {
|
||||
hid_destroy_device(session->hid);
|
||||
session->hid = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user