2007-04-19 19:27:04 +08:00
|
|
|
/*
|
|
|
|
* 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>
|
2011-05-27 22:25:27 +08:00
|
|
|
#include <linux/export.h>
|
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files. percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed. Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability. As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
only the necessary includes are there. ie. if only gfp is used,
gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
blocks and try to put the new include such that its order conforms
to its surrounding. It's put in the include block which contains
core kernel includes, in the same order that the rest are ordered -
alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
because the file doesn't have fitting include block), it prints out
an error message indicating which .h file needs to be added to the
file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
over 4000 files, deleting around 700 includes and adding ~480 gfp.h
and ~3000 slab.h inclusions. The script emitted errors for ~400
files.
2. Each error was manually checked. Some didn't need the inclusion,
some needed manual addition while adding it to implementation .h or
embedding .c file was more appropriate for others. This step added
inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
e.g. lib/decompress_*.c used malloc/free() wrappers around slab
APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
editing them as sprinkling gfp.h and slab.h inclusions around .h
files could easily lead to inclusion dependency hell. Most gfp.h
inclusion directives were ignored as stuff from gfp.h was usually
wildly available and often used in preprocessor macros. Each
slab.h inclusion directive was examined and added manually as
necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
distributed build env didn't work with gcov compiles) and a few
more options had to be turned off depending on archs to make things
build (like ipr on powerpc/64 which failed due to missing writeq).
* x86 and x86_64 UP and SMP allmodconfig and a custom test config.
* powerpc and powerpc64 SMP allmodconfig
* sparc and sparc64 SMP allmodconfig
* ia64 SMP allmodconfig
* s390 SMP allmodconfig
* alpha SMP allmodconfig
* um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 16:04:11 +08:00
|
|
|
#include <linux/slab.h>
|
2007-04-19 19:27:04 +08:00
|
|
|
|
2008-06-04 17:02:56 +08:00
|
|
|
#include "../hid-ids.h"
|
2008-03-10 18:08:58 +08:00
|
|
|
|
2007-04-19 19:27:04 +08:00
|
|
|
/*
|
|
|
|
* 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 },
|
2010-09-03 05:05:09 +08:00
|
|
|
{ USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
|
2010-07-12 00:45:50 +08:00
|
|
|
{ USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT },
|
2007-04-19 19:27:04 +08:00
|
|
|
{ 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 },
|
2008-03-03 17:49:59 +08:00
|
|
|
{ USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD },
|
2007-04-19 19:27:04 +08:00
|
|
|
{ USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
|
2009-12-03 13:08:10 +08:00
|
|
|
{ USB_VENDOR_ID_NEXTWINDOW, USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN, HID_QUIRK_MULTI_INPUT},
|
2007-04-19 19:27:04 +08:00
|
|
|
{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
|
|
|
|
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
|
2008-07-01 18:35:16 +08:00
|
|
|
|
2008-03-06 20:23:14 +08:00
|
|
|
{ USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
|
|
|
|
|
2011-12-17 20:16:57 +08:00
|
|
|
{ USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II, HID_QUIRK_MULTI_INPUT },
|
2010-02-03 04:09:06 +08:00
|
|
|
{ USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
|
2014-07-08 08:44:02 +08:00
|
|
|
{ USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH_2968, HID_QUIRK_MULTI_INPUT },
|
2011-08-25 21:35:14 +08:00
|
|
|
{ USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT },
|
2007-04-19 19:27:04 +08:00
|
|
|
{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
|
2010-02-04 23:36:24 +08:00
|
|
|
{ USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT },
|
2007-04-19 19:27:04 +08:00
|
|
|
|
2012-02-28 00:23:45 +08:00
|
|
|
{ USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
|
2016-01-29 21:38:07 +08:00
|
|
|
{ USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS },
|
2016-10-09 20:21:50 +08:00
|
|
|
{ USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS },
|
HID: usbhid: Quirk a AMI virtual mouse and keyboard with ALWAYS_POLL
Quirking the following AMI USB device with ALWAYS_POLL fixes an AMI
virtual keyboard and mouse from not responding and timing out when
it is attached to a ppc64el Power 8 system and when we have some
rapid open/closes on the mouse device.
usb 1-3: new high-speed USB device number 2 using xhci_hcd
usb 1-3: New USB device found, idVendor=046b, idProduct=ff01
usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-3: Product: Virtual Hub
usb 1-3: Manufacturer: American Megatrends Inc.
usb 1-3: SerialNumber: serial
usb 1-3.3: new high-speed USB device number 3 using xhci_hcd
usb 1-3.3: New USB device found, idVendor=046b, idProduct=ff31
usb 1-3.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-3.3: Product: Virtual HardDisk Device
usb 1-3.3: Manufacturer: American Megatrends Inc.
usb 1-3.4: new low-speed USB device number 4 using xhci_hcd
usb 1-3.4: New USB device found, idVendor=046b, idProduct=ff10
usb 1-3.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-3.4: Product: Virtual Keyboard and Mouse
usb 1-3.4: Manufacturer: American Megatrends Inc.
With the quirk I have not been able to trigger the issue with
half an hour of saturation soak testing.
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2017-01-27 01:34:40 +08:00
|
|
|
{ USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
2007-04-19 19:27:04 +08:00
|
|
|
{ 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 },
|
2015-05-13 01:00:00 +08:00
|
|
|
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET },
|
2016-11-03 19:31:41 +08:00
|
|
|
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692, HID_QUIRK_NOGET },
|
2017-04-25 16:26:44 +08:00
|
|
|
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS1758, HID_QUIRK_NOGET },
|
2012-02-14 23:42:20 +08:00
|
|
|
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET },
|
2009-05-07 03:48:49 +08:00
|
|
|
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
|
2010-07-03 15:59:01 +08:00
|
|
|
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET },
|
2009-05-07 03:48:49 +08:00
|
|
|
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET },
|
2011-04-06 22:12:32 +08:00
|
|
|
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE, HID_QUIRK_NOGET },
|
2009-05-07 03:48:49 +08:00
|
|
|
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET },
|
2009-10-20 04:55:55 +08:00
|
|
|
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET },
|
2010-10-01 05:24:30 +08:00
|
|
|
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
|
2015-05-22 02:04:15 +08:00
|
|
|
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
2015-07-09 13:38:50 +08:00
|
|
|
{ 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 },
|
2016-09-19 21:52:06 +08:00
|
|
|
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
2017-02-11 02:23:00 +08:00
|
|
|
{ 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 },
|
2016-04-25 22:01:56 +08:00
|
|
|
{ USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET },
|
2017-06-06 19:53:13 +08:00
|
|
|
{ USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
2008-03-20 17:14:02 +08:00
|
|
|
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
|
2015-10-04 00:20:02 +08:00
|
|
|
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT },
|
2016-11-04 02:47:26 +08:00
|
|
|
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT },
|
2016-12-21 05:08:13 +08:00
|
|
|
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR, HID_QUIRK_MULTI_INPUT },
|
2017-01-07 19:10:37 +08:00
|
|
|
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1, HID_QUIRK_MULTI_INPUT },
|
2015-12-02 02:56:48 +08:00
|
|
|
{ USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL },
|
2007-09-14 16:18:07 +08:00
|
|
|
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
|
2012-12-29 11:07:02 +08:00
|
|
|
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
|
2012-08-06 05:57:15 +08:00
|
|
|
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
|
2016-12-23 20:50:13 +08:00
|
|
|
{ USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY, HID_QUIRK_NO_INIT_REPORTS },
|
2015-03-30 18:36:36 +08:00
|
|
|
{ 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 },
|
2015-03-25 22:38:31 +08:00
|
|
|
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
2015-03-10 23:36:22 +08:00
|
|
|
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL },
|
2015-11-20 15:10:28 +08:00
|
|
|
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET },
|
2015-03-30 18:36:35 +08:00
|
|
|
{ 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 },
|
2012-08-23 22:51:55 +08:00
|
|
|
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
|
2015-06-29 08:22:37 +08:00
|
|
|
{ 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 },
|
2015-06-08 17:11:38 +08:00
|
|
|
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER, HID_QUIRK_NO_INIT_REPORTS },
|
2014-06-19 00:05:02 +08:00
|
|
|
{ USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
|
2014-01-28 07:02:46 +08:00
|
|
|
{ USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS },
|
2012-11-23 06:40:53 +08:00
|
|
|
{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
|
2014-06-27 16:22:08 +08:00
|
|
|
{ USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610, HID_QUIRK_NOGET },
|
|
|
|
{ USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640, HID_QUIRK_NOGET },
|
2014-09-08 17:21:49 +08:00
|
|
|
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
2014-09-30 18:54:56 +08:00
|
|
|
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2, HID_QUIRK_ALWAYS_POLL },
|
2011-12-15 11:09:06 +08:00
|
|
|
{ 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 },
|
2015-03-30 18:36:35 +08:00
|
|
|
{ USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22, HID_QUIRK_ALWAYS_POLL },
|
2010-02-04 23:36:24 +08:00
|
|
|
{ USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
|
2012-08-23 18:12:47 +08:00
|
|
|
{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET },
|
2016-01-04 17:08:54 +08:00
|
|
|
{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003, HID_QUIRK_NOGET },
|
2012-03-06 17:53:48 +08:00
|
|
|
{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET },
|
2013-03-18 21:45:42 +08:00
|
|
|
{ USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS },
|
2012-07-06 04:32:49 +08:00
|
|
|
{ USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET },
|
2012-11-24 13:15:57 +08:00
|
|
|
{ USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET },
|
2013-11-27 10:05:56 +08:00
|
|
|
{ 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 },
|
2013-12-13 21:51:53 +08:00
|
|
|
{ USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS1030_TOUCH, HID_QUIRK_NOGET },
|
2007-04-19 19:27:04 +08:00
|
|
|
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
|
2011-04-26 16:51:28 +08:00
|
|
|
{ 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 },
|
2015-08-21 22:18:08 +08:00
|
|
|
{ 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 },
|
2007-04-19 19:27:04 +08:00
|
|
|
{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
|
2010-08-24 23:45:49 +08:00
|
|
|
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
|
2011-05-21 05:59:19 +08:00
|
|
|
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT },
|
2010-08-20 23:21:11 +08:00
|
|
|
{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
|
2010-08-30 18:06:36 +08:00
|
|
|
{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
|
2012-03-20 22:01:33 +08:00
|
|
|
{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET, HID_QUIRK_MULTI_INPUT },
|
2007-04-19 19:27:04 +08:00
|
|
|
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
|
|
|
|
|
2008-08-27 17:21:42 +08:00
|
|
|
{ USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
|
2007-04-19 19:27:04 +08:00
|
|
|
|
2010-07-13 01:28:28 +08:00
|
|
|
{ USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE },
|
|
|
|
|
2010-08-19 15:43:56 +08:00
|
|
|
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
|
2010-11-24 04:40:09 +08:00
|
|
|
{ USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
|
2011-08-23 15:44:30 +08:00
|
|
|
{ USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
|
2012-02-28 19:01:46 +08:00
|
|
|
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
|
2016-09-15 02:38:13 +08:00
|
|
|
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2, HID_QUIRK_MULTI_INPUT },
|
2012-02-28 19:01:46 +08:00
|
|
|
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
|
2015-02-14 16:48:44 +08:00
|
|
|
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912, HID_QUIRK_MULTI_INPUT },
|
2013-08-31 06:25:04 +08:00
|
|
|
{ USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
|
2014-06-02 16:58:00 +08:00
|
|
|
{ USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },
|
2016-03-11 01:17:58 +08:00
|
|
|
{ USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2, HID_QUIRK_NO_INIT_REPORTS },
|
2013-10-02 17:35:26 +08:00
|
|
|
{ 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 },
|
2013-11-27 10:05:57 +08:00
|
|
|
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS },
|
2013-11-27 10:05:58 +08:00
|
|
|
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS },
|
2014-05-03 01:48:13 +08:00
|
|
|
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS },
|
HID: remove initial reading of reports at connect
It looks like a bunch of devices do not like to be polled
for their reports at init time. When you look into the details,
it seems that for those that are requiring the quirk
HID_QUIRK_NO_INIT_REPORTS, the driver fails to retrieve part
of the features/inputs while others (more generic) work.
IMO, it should be acceptable to remove the need for the quirk
in the general case. On the small amount of cases where
we actually need to read the current values, the driver
in charge (hid-mt or wacom) already retrieves the features
manually.
There are 2 cases where we might need to retrieve the reports at
init:
1. hiddev devices with specific use-space tool
2. a device that would require the driver to fetch a specific
feature/input at plug
For case 2, I have seen this a few time on hid-multitouch. It
is solved in hid-multitouch directly by fetching the feature.
I hope it won't be too common and this can be solved on a per-case
basis (crossing fingers).
For case 1, we moved the implementation of HID_QUIRK_NO_INIT_REPORTS
in hiddev. When somebody starts calling ioctls that needs an initial
update, the hiddev device will fetch the initial state of the reports
to mimic the current behavior. This adds a small amount of time during
the first HIDIOCGUSAGE(S), but it should be acceptable in
most cases. To keep the currently known broken devices, we have to
keep around HID_QUIRK_NO_INIT_REPORTS, but the scope will only be
for hiddev.
Note that I don't think hidraw would be affected and I checked that
the FF drivers that need to interact with the report fields are all
using output reports, which are not initialized by
usbhid_init_reports().
NO_INIT_INPUT_REPORTS is then replaced by HID_QUIRK_NO_INIT_REPORTS:
there is no point keeping it for just one device.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2017-03-08 22:11:14 +08:00
|
|
|
{ USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096, HID_QUIRK_NO_INIT_REPORTS },
|
2015-04-26 04:30:32 +08:00
|
|
|
{ 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 },
|
2017-02-15 07:14:33 +08:00
|
|
|
{ USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI, HID_QUIRK_MULTI_INPUT },
|
2013-08-31 06:25:04 +08:00
|
|
|
|
2007-06-19 20:09:14 +08:00
|
|
|
{ 0, 0 }
|
|
|
|
};
|
|
|
|
|
2007-04-19 20:37:44 +08:00
|
|
|
/* 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 */
|
|
|
|
|
2007-04-19 19:45:57 +08:00
|
|
|
/**
|
2007-04-19 20:37:44 +08:00
|
|
|
* 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)
|
2007-05-30 21:07:13 +08:00
|
|
|
dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
|
2007-04-19 20:37:44 +08:00
|
|
|
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.
|
|
|
|
*/
|
2008-03-31 07:53:56 +08:00
|
|
|
static int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
|
|
|
|
const u32 quirks)
|
2007-04-19 20:37:44 +08:00
|
|
|
{
|
|
|
|
struct quirks_list_struct *q_new, *q;
|
|
|
|
int list_edited = 0;
|
|
|
|
|
|
|
|
if (!idVendor) {
|
2007-05-30 21:07:13 +08:00
|
|
|
dbg_hid("Cannot add a quirk with idVendor = 0\n");
|
2007-04-19 20:37:44 +08:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL);
|
2017-03-02 09:35:07 +08:00
|
|
|
if (!q_new)
|
2007-04-19 20:37:44 +08:00
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-01-19 19:32:10 +08:00
|
|
|
/**
|
2007-04-19 20:56:12 +08:00
|
|
|
* 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;
|
|
|
|
|
2009-08-08 08:17:32 +08:00
|
|
|
for (; n < MAX_USBHID_BOOT_QUIRKS && quirks_param[n]; n++) {
|
2007-04-19 20:56:12 +08:00
|
|
|
|
|
|
|
m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
|
|
|
|
&idVendor, &idProduct, &quirks);
|
|
|
|
|
|
|
|
if (m != 3 ||
|
2017-03-02 09:35:07 +08:00
|
|
|
usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) {
|
|
|
|
pr_warn("Could not parse HID quirk module param %s\n",
|
|
|
|
quirks_param[n]);
|
2007-04-19 20:56:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2007-04-19 20:37:44 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2007-04-19 19:45:57 +08:00
|
|
|
static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
|
2007-04-19 20:37:44 +08:00
|
|
|
const u16 idProduct)
|
2007-04-19 19:45:57 +08:00
|
|
|
{
|
2007-04-19 20:37:44 +08:00
|
|
|
const struct hid_blacklist *bl_entry = NULL;
|
|
|
|
int n = 0;
|
2007-04-19 19:45:57 +08:00
|
|
|
|
|
|
|
for (; hid_blacklist[n].idVendor; n++)
|
|
|
|
if (hid_blacklist[n].idVendor == idVendor &&
|
2015-12-02 02:56:48 +08:00
|
|
|
(hid_blacklist[n].idProduct == (__u16) HID_ANY_ID ||
|
|
|
|
hid_blacklist[n].idProduct == idProduct))
|
2007-04-19 19:45:57 +08:00
|
|
|
bl_entry = &hid_blacklist[n];
|
|
|
|
|
|
|
|
if (bl_entry != NULL)
|
2007-05-30 21:07:13 +08:00
|
|
|
dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
|
2017-01-19 19:32:10 +08:00
|
|
|
bl_entry->quirks, bl_entry->idVendor,
|
2007-04-19 19:45:57 +08:00
|
|
|
bl_entry->idProduct);
|
|
|
|
return bl_entry;
|
|
|
|
}
|
2007-04-19 19:27:04 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
2007-04-19 19:45:57 +08:00
|
|
|
const struct hid_blacklist *bl_entry = NULL;
|
2007-04-19 19:27:04 +08:00
|
|
|
|
2007-06-18 23:41:14 +08:00
|
|
|
/* 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)
|
2009-11-05 21:08:03 +08:00
|
|
|
return HID_QUIRK_NO_INIT_REPORTS;
|
2007-06-18 23:41:14 +08:00
|
|
|
|
2007-04-19 20:37:44 +08:00
|
|
|
down_read(&dquirks_rwsem);
|
|
|
|
bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
|
|
|
|
if (!bl_entry)
|
|
|
|
bl_entry = usbhid_exists_squirk(idVendor, idProduct);
|
2007-04-19 19:45:57 +08:00
|
|
|
if (bl_entry)
|
|
|
|
quirks = bl_entry->quirks;
|
2007-04-19 20:37:44 +08:00
|
|
|
up_read(&dquirks_rwsem);
|
|
|
|
|
2007-04-19 19:27:04 +08:00
|
|
|
return quirks;
|
|
|
|
}
|
2007-04-19 19:45:57 +08:00
|
|
|
|
2007-11-26 21:03:52 +08:00
|
|
|
EXPORT_SYMBOL_GPL(usbhid_lookup_quirk);
|