2017-11-03 13:28:30 +03:00
// SPDX-License-Identifier: GPL-2.0
2007-01-26 16:26:21 +03:00
/*
* USB device quirk handling logic and table
*
* Copyright ( c ) 2007 Oliver Neukum
* Copyright ( c ) 2007 Greg Kroah - Hartman < gregkh @ suse . de >
*/
2018-03-19 19:26:06 +03:00
# include <linux/moduleparam.h>
2007-01-26 16:26:21 +03:00
# include <linux/usb.h>
# include <linux/usb/quirks.h>
2013-09-16 19:47:28 +04:00
# include <linux/usb/hcd.h>
2007-01-26 16:26:21 +03:00
# include "usb.h"
2018-03-19 19:26:06 +03:00
struct quirk_entry {
u16 vid ;
u16 pid ;
u32 flags ;
} ;
static DEFINE_MUTEX ( quirk_mutex ) ;
static struct quirk_entry * quirk_list ;
static unsigned int quirk_count ;
static char quirks_param [ 128 ] ;
static int quirks_param_set ( const char * val , const struct kernel_param * kp )
{
char * p , * field ;
u16 vid , pid ;
u32 flags ;
size_t i ;
2018-03-23 22:26:35 +03:00
int err ;
err = param_set_copystring ( val , kp ) ;
if ( err )
return err ;
2018-03-19 19:26:06 +03:00
mutex_lock ( & quirk_mutex ) ;
2018-03-23 22:26:35 +03:00
if ( ! * val ) {
2018-03-19 19:26:06 +03:00
quirk_count = 0 ;
kfree ( quirk_list ) ;
quirk_list = NULL ;
goto unlock ;
}
for ( quirk_count = 1 , i = 0 ; val [ i ] ; i + + )
if ( val [ i ] = = ' , ' )
quirk_count + + ;
if ( quirk_list ) {
kfree ( quirk_list ) ;
quirk_list = NULL ;
}
quirk_list = kcalloc ( quirk_count , sizeof ( struct quirk_entry ) ,
GFP_KERNEL ) ;
if ( ! quirk_list ) {
mutex_unlock ( & quirk_mutex ) ;
return - ENOMEM ;
}
for ( i = 0 , p = ( char * ) val ; p & & * p ; ) {
/* Each entry consists of VID:PID:flags */
field = strsep ( & p , " : " ) ;
if ( ! field )
break ;
if ( kstrtou16 ( field , 16 , & vid ) )
break ;
field = strsep ( & p , " : " ) ;
if ( ! field )
break ;
if ( kstrtou16 ( field , 16 , & pid ) )
break ;
field = strsep ( & p , " , " ) ;
if ( ! field | | ! * field )
break ;
/* Collect the flags */
for ( flags = 0 ; * field ; field + + ) {
switch ( * field ) {
case ' a ' :
flags | = USB_QUIRK_STRING_FETCH_255 ;
break ;
case ' b ' :
flags | = USB_QUIRK_RESET_RESUME ;
break ;
case ' c ' :
flags | = USB_QUIRK_NO_SET_INTF ;
break ;
case ' d ' :
flags | = USB_QUIRK_CONFIG_INTF_STRINGS ;
break ;
case ' e ' :
flags | = USB_QUIRK_RESET ;
break ;
case ' f ' :
flags | = USB_QUIRK_HONOR_BNUMINTERFACES ;
break ;
case ' g ' :
flags | = USB_QUIRK_DELAY_INIT ;
break ;
case ' h ' :
flags | = USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL ;
break ;
case ' i ' :
flags | = USB_QUIRK_DEVICE_QUALIFIER ;
break ;
case ' j ' :
flags | = USB_QUIRK_IGNORE_REMOTE_WAKEUP ;
break ;
case ' k ' :
flags | = USB_QUIRK_NO_LPM ;
break ;
case ' l ' :
flags | = USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL ;
break ;
case ' m ' :
flags | = USB_QUIRK_DISCONNECT_SUSPEND ;
break ;
/* Ignore unrecognized flag characters */
}
}
quirk_list [ i + + ] = ( struct quirk_entry )
{ . vid = vid , . pid = pid , . flags = flags } ;
}
if ( i < quirk_count )
quirk_count = i ;
unlock :
mutex_unlock ( & quirk_mutex ) ;
2018-03-23 22:26:35 +03:00
return 0 ;
2018-03-19 19:26:06 +03:00
}
static const struct kernel_param_ops quirks_param_ops = {
. set = quirks_param_set ,
. get = param_get_string ,
} ;
static struct kparam_string quirks_param_string = {
. maxlen = sizeof ( quirks_param ) ,
. string = quirks_param ,
} ;
module_param_cb ( quirks , & quirks_param_ops , & quirks_param_string , 0644 ) ;
MODULE_PARM_DESC ( quirks , " Add/modify USB quirks by specifying quirks=vendorID:productID:quirks " ) ;
2012-07-19 14:39:13 +04:00
/* Lists of quirky USB devices, split in device quirks and interface quirks.
* Device quirks are applied at the very beginning of the enumeration process ,
* right after reading the device descriptor . They can thus only match on device
* information .
*
* Interface quirks are applied after reading all the configuration descriptors .
* They can match on both device and interface information .
*
* Note that the DELAY_INIT and HONOR_BNUMINTERFACES quirks do not make sense as
* interface quirks , as they only influence the enumeration process which is run
* before processing the interface quirks .
*
* Please keep the lists ordered by :
2007-01-26 16:26:21 +03:00
* 1 ) Vendor ID
* 2 ) Product ID
* 3 ) Class ID
*/
static const struct usb_device_id usb_quirk_list [ ] = {
2007-09-04 18:11:41 +04:00
/* CBM - Flash disk */
{ USB_DEVICE ( 0x0204 , 0x6025 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2008-02-27 23:43:47 +03:00
2017-01-20 21:46:34 +03:00
/* WORLDE easy key (easykey.25) MIDI controller */
{ USB_DEVICE ( 0x0218 , 0x0401 ) , . driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS } ,
2007-01-26 16:26:21 +03:00
/* HP 5300/5370C scanner */
2008-02-27 23:43:47 +03:00
{ USB_DEVICE ( 0x03f0 , 0x0701 ) , . driver_info =
USB_QUIRK_STRING_FETCH_255 } ,
2007-08-28 12:34:22 +04:00
2008-02-04 18:34:11 +03:00
/* Creative SB Audigy 2 NX */
{ USB_DEVICE ( 0x041e , 0x3020 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2016-05-19 18:12:19 +03:00
/* USB3503 */
{ USB_DEVICE ( 0x0424 , 0x3503 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2014-11-24 13:22:38 +03:00
/* Microsoft Wireless Laser Mouse 6000 Receiver */
{ USB_DEVICE ( 0x045e , 0x00e1 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2012-12-05 19:17:49 +04:00
/* Microsoft LifeCam-VX700 v2.0 */
{ USB_DEVICE ( 0x045e , 0x0770 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2017-12-19 07:02:04 +03:00
/* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */
2014-03-04 22:52:39 +04:00
{ USB_DEVICE ( 0x046d , 0x082d ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
2017-08-25 10:38:35 +03:00
{ USB_DEVICE ( 0x046d , 0x0841 ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
2014-03-04 22:52:39 +04:00
{ USB_DEVICE ( 0x046d , 0x0843 ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
2017-12-19 07:02:04 +03:00
{ USB_DEVICE ( 0x046d , 0x085b ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
2014-03-04 22:52:39 +04:00
2015-10-02 00:10:22 +03:00
/* Logitech ConferenceCam CC3000e */
{ USB_DEVICE ( 0x046d , 0x0847 ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
{ USB_DEVICE ( 0x046d , 0x0848 ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
/* Logitech PTZ Pro Camera */
{ USB_DEVICE ( 0x046d , 0x0853 ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
2012-07-19 14:39:14 +04:00
/* Logitech Quickcam Fusion */
{ USB_DEVICE ( 0x046d , 0x08c1 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2011-09-13 10:42:21 +04:00
2012-07-19 14:39:14 +04:00
/* Logitech Quickcam Orbit MP */
{ USB_DEVICE ( 0x046d , 0x08c2 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2011-09-13 10:42:21 +04:00
2012-07-19 14:39:14 +04:00
/* Logitech Quickcam Pro for Notebook */
{ USB_DEVICE ( 0x046d , 0x08c3 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2011-09-29 23:42:52 +04:00
2012-07-19 14:39:14 +04:00
/* Logitech Quickcam Pro 5000 */
{ USB_DEVICE ( 0x046d , 0x08c5 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2011-09-13 10:42:21 +04:00
2012-07-19 14:39:14 +04:00
/* Logitech Quickcam OEM Dell Notebook */
{ USB_DEVICE ( 0x046d , 0x08c6 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2011-10-26 21:53:17 +04:00
2012-07-19 14:39:14 +04:00
/* Logitech Quickcam OEM Cisco VT Camera II */
{ USB_DEVICE ( 0x046d , 0x08c7 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2011-10-28 08:06:26 +04:00
2010-07-22 02:05:01 +04:00
/* Logitech Harmony 700-series */
{ USB_DEVICE ( 0x046d , 0xc122 ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
2008-02-27 23:43:47 +03:00
/* Philips PSC805 audio device */
{ USB_DEVICE ( 0x0471 , 0x0155 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2015-08-31 09:24:09 +03:00
/* Plantronic Audio 655 DSP */
{ USB_DEVICE ( 0x047f , 0xc008 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
/* Plantronic Audio 648 USB */
{ USB_DEVICE ( 0x047f , 0xc013 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2010-07-09 16:18:50 +04:00
/* Artisman Watchdog Dongle */
{ USB_DEVICE ( 0x04b4 , 0x0526 ) , . driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS } ,
2012-09-04 18:41:02 +04:00
/* Microchip Joss Optical infrared touchboard device */
{ USB_DEVICE ( 0x04d8 , 0x000c ) , . driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS } ,
2013-08-14 13:01:46 +04:00
/* CarrolTouch 4000U */
{ USB_DEVICE ( 0x04e7 , 0x0009 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
/* CarrolTouch 4500U */
{ USB_DEVICE ( 0x04e7 , 0x0030 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2011-02-05 23:52:00 +03:00
/* Samsung Android phone modem - ID conflict with SPH-I500 */
{ USB_DEVICE ( 0x04e8 , 0x6601 ) , . driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS } ,
2014-08-25 19:51:27 +04:00
/* Elan Touchscreen */
{ USB_DEVICE ( 0x04f3 , 0x0089 ) , . driver_info =
USB_QUIRK_DEVICE_QUALIFIER } ,
2014-10-09 11:29:29 +04:00
{ USB_DEVICE ( 0x04f3 , 0x009b ) , . driver_info =
USB_QUIRK_DEVICE_QUALIFIER } ,
2014-11-17 19:11:42 +03:00
{ USB_DEVICE ( 0x04f3 , 0x010c ) , . driver_info =
USB_QUIRK_DEVICE_QUALIFIER } ,
2015-05-09 20:09:11 +03:00
{ USB_DEVICE ( 0x04f3 , 0x0125 ) , . driver_info =
USB_QUIRK_DEVICE_QUALIFIER } ,
2014-10-09 11:29:30 +04:00
{ USB_DEVICE ( 0x04f3 , 0x016f ) , . driver_info =
USB_QUIRK_DEVICE_QUALIFIER } ,
2016-07-07 04:18:51 +03:00
{ USB_DEVICE ( 0x04f3 , 0x0381 ) , . driver_info =
USB_QUIRK_NO_LPM } ,
2015-11-24 18:02:04 +03:00
{ USB_DEVICE ( 0x04f3 , 0x21b8 ) , . driver_info =
USB_QUIRK_DEVICE_QUALIFIER } ,
2008-02-04 18:34:11 +03:00
/* Roland SC-8820 */
{ USB_DEVICE ( 0x0582 , 0x0007 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
/* Edirol SD-20 */
{ USB_DEVICE ( 0x0582 , 0x0027 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2013-04-30 12:18:04 +04:00
/* Alcor Micro Corp. Hub */
{ USB_DEVICE ( 0x058f , 0x9254 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2008-06-17 19:56:55 +04:00
/* appletouch */
{ USB_DEVICE ( 0x05ac , 0x021a ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2017-11-14 09:31:15 +03:00
/* Genesys Logic hub, internally used by KY-688 USB 3.1 Type-C Hub */
{ USB_DEVICE ( 0x05e3 , 0x0612 ) , . driver_info = USB_QUIRK_NO_LPM } ,
2017-12-12 18:11:30 +03:00
/* ELSA MicroLink 56K */
{ USB_DEVICE ( 0x05cc , 0x2267 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2017-08-08 12:51:27 +03:00
/* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */
{ USB_DEVICE ( 0x05e3 , 0x0616 ) , . driver_info = USB_QUIRK_NO_LPM } ,
2008-05-27 11:05:46 +04:00
/* Avision AV600U */
{ USB_DEVICE ( 0x0638 , 0x0a13 ) , . driver_info =
USB_QUIRK_STRING_FETCH_255 } ,
2009-03-18 21:28:53 +03:00
/* Saitek Cyborg Gold Joystick */
{ USB_DEVICE ( 0x06a3 , 0x0006 ) , . driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS } ,
2012-01-03 12:58:54 +04:00
/* Guillemot Webcam Hercules Dualpix Exchange (2nd ID) */
2011-09-13 10:42:21 +04:00
{ USB_DEVICE ( 0x06f8 , 0x0804 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2012-01-03 12:58:54 +04:00
/* Guillemot Webcam Hercules Dualpix Exchange*/
{ USB_DEVICE ( 0x06f8 , 0x3005 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2012-04-30 15:05:34 +04:00
/* Midiman M-Audio Keystation 88es */
{ USB_DEVICE ( 0x0763 , 0x0192 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2007-09-04 19:15:08 +04:00
/* M-Systems Flash Disk Pioneers */
{ USB_DEVICE ( 0x08ec , 0x1000 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2017-03-13 22:50:08 +03:00
/* Baum Vario Ultra */
{ USB_DEVICE ( 0x0904 , 0x6101 ) , . driver_info =
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL } ,
{ USB_DEVICE ( 0x0904 , 0x6102 ) , . driver_info =
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL } ,
{ USB_DEVICE ( 0x0904 , 0x6103 ) , . driver_info =
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL } ,
2011-02-17 18:26:38 +03:00
/* Keytouch QWERTY Panel keyboard */
{ USB_DEVICE ( 0x0926 , 0x3333 ) , . driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS } ,
2008-03-11 17:20:12 +03:00
/* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */
{ USB_DEVICE ( 0x0971 , 0x2000 ) , . driver_info = USB_QUIRK_NO_SET_INTF } ,
2010-07-14 20:26:22 +04:00
/* Broadcom BCM92035DGROM BT dongle */
{ USB_DEVICE ( 0x0a5c , 0x2021 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2013-10-14 18:22:40 +04:00
/* MAYA44USB sound device */
{ USB_DEVICE ( 0x0a92 , 0x0091 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2016-05-19 18:12:19 +03:00
/* ASUS Base Station(T100) */
{ USB_DEVICE ( 0x0b05 , 0x17e0 ) , . driver_info =
USB_QUIRK_IGNORE_REMOTE_WAKEUP } ,
2008-02-27 23:43:47 +03:00
/* Action Semiconductor flash disk */
{ USB_DEVICE ( 0x10d6 , 0x2200 ) , . driver_info =
USB_QUIRK_STRING_FETCH_255 } ,
2007-06-20 01:16:10 +04:00
2017-10-18 10:15:01 +03:00
/* Huawei 4G LTE module */
{ USB_DEVICE ( 0x12d1 , 0x15bb ) , . driver_info =
USB_QUIRK_DISCONNECT_SUSPEND } ,
{ USB_DEVICE ( 0x12d1 , 0x15c3 ) , . driver_info =
USB_QUIRK_DISCONNECT_SUSPEND } ,
2007-09-04 19:15:08 +04:00
/* SKYMEDI USB_DRIVE */
{ USB_DEVICE ( 0x1516 , 0x8628 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2007-01-26 16:26:21 +03:00
2014-07-27 21:28:04 +04:00
/* Razer - Razer Blade Keyboard */
{ USB_DEVICE ( 0x1532 , 0x0116 ) , . driver_info =
USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL } ,
2010-03-29 14:03:17 +04:00
/* BUILDWIN Photo Frame */
{ USB_DEVICE ( 0x1908 , 0x1315 ) , . driver_info =
USB_QUIRK_HONOR_BNUMINTERFACES } ,
2015-01-23 09:39:02 +03:00
/* Protocol and OTG Electrical Test Device */
{ USB_DEVICE ( 0x1a0a , 0x0200 ) , . driver_info =
USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL } ,
2018-02-15 21:24:10 +03:00
/* Corsair K70 RGB */
{ USB_DEVICE ( 0x1b1c , 0x1b13 ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard
Corsair Strafe RGB keyboard has trouble to initialize:
[ 1.679455] usb 3-6: new full-speed USB device number 4 using xhci_hcd
[ 6.871136] usb 3-6: unable to read config index 0 descriptor/all
[ 6.871138] usb 3-6: can't read configurations, error -110
[ 6.991019] usb 3-6: new full-speed USB device number 5 using xhci_hcd
[ 12.246642] usb 3-6: unable to read config index 0 descriptor/all
[ 12.246644] usb 3-6: can't read configurations, error -110
[ 12.366555] usb 3-6: new full-speed USB device number 6 using xhci_hcd
[ 17.622145] usb 3-6: unable to read config index 0 descriptor/all
[ 17.622147] usb 3-6: can't read configurations, error -110
[ 17.742093] usb 3-6: new full-speed USB device number 7 using xhci_hcd
[ 22.997715] usb 3-6: unable to read config index 0 descriptor/all
[ 22.997716] usb 3-6: can't read configurations, error -110
Although it may work after several times unpluging/pluging:
[ 68.195240] usb 3-6: new full-speed USB device number 11 using xhci_hcd
[ 68.337459] usb 3-6: New USB device found, idVendor=1b1c, idProduct=1b20
[ 68.337463] usb 3-6: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 68.337466] usb 3-6: Product: Corsair STRAFE RGB Gaming Keyboard
[ 68.337468] usb 3-6: Manufacturer: Corsair
[ 68.337470] usb 3-6: SerialNumber: 0F013021AEB8046755A93ED3F5001941
Tried three quirks: USB_QUIRK_DELAY_INIT, USB_QUIRK_NO_LPM and
USB_QUIRK_DEVICE_QUALIFIER, user confirmed that USB_QUIRK_DELAY_INIT alone
can workaround this issue. Hence add the quirk for Corsair Strafe RGB.
BugLink: https://bugs.launchpad.net/bugs/1678477
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-16 05:53:20 +03:00
/* Corsair Strafe RGB */
2018-03-06 11:38:49 +03:00
{ USB_DEVICE ( 0x1b1c , 0x1b20 ) , . driver_info = USB_QUIRK_DELAY_INIT |
USB_QUIRK_DELAY_CTRL_MSG } ,
usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard
Corsair Strafe RGB keyboard has trouble to initialize:
[ 1.679455] usb 3-6: new full-speed USB device number 4 using xhci_hcd
[ 6.871136] usb 3-6: unable to read config index 0 descriptor/all
[ 6.871138] usb 3-6: can't read configurations, error -110
[ 6.991019] usb 3-6: new full-speed USB device number 5 using xhci_hcd
[ 12.246642] usb 3-6: unable to read config index 0 descriptor/all
[ 12.246644] usb 3-6: can't read configurations, error -110
[ 12.366555] usb 3-6: new full-speed USB device number 6 using xhci_hcd
[ 17.622145] usb 3-6: unable to read config index 0 descriptor/all
[ 17.622147] usb 3-6: can't read configurations, error -110
[ 17.742093] usb 3-6: new full-speed USB device number 7 using xhci_hcd
[ 22.997715] usb 3-6: unable to read config index 0 descriptor/all
[ 22.997716] usb 3-6: can't read configurations, error -110
Although it may work after several times unpluging/pluging:
[ 68.195240] usb 3-6: new full-speed USB device number 11 using xhci_hcd
[ 68.337459] usb 3-6: New USB device found, idVendor=1b1c, idProduct=1b20
[ 68.337463] usb 3-6: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 68.337466] usb 3-6: Product: Corsair STRAFE RGB Gaming Keyboard
[ 68.337468] usb 3-6: Manufacturer: Corsair
[ 68.337470] usb 3-6: SerialNumber: 0F013021AEB8046755A93ED3F5001941
Tried three quirks: USB_QUIRK_DELAY_INIT, USB_QUIRK_NO_LPM and
USB_QUIRK_DEVICE_QUALIFIER, user confirmed that USB_QUIRK_DELAY_INIT alone
can workaround this issue. Hence add the quirk for Corsair Strafe RGB.
BugLink: https://bugs.launchpad.net/bugs/1678477
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-16 05:53:20 +03:00
2017-11-03 18:46:02 +03:00
/* Corsair K70 LUX */
{ USB_DEVICE ( 0x1b1c , 0x1b36 ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
2017-10-03 11:16:43 +03:00
/* MIDI keyboard WORLDE MINI */
{ USB_DEVICE ( 0x1c75 , 0x0204 ) , . driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS } ,
2016-05-19 18:12:20 +03:00
/* Acer C120 LED Projector */
{ USB_DEVICE ( 0x1de1 , 0xc102 ) , . driver_info = USB_QUIRK_NO_LPM } ,
2015-12-10 23:27:21 +03:00
/* Blackmagic Design Intensity Shuttle */
{ USB_DEVICE ( 0x1edb , 0xbd3b ) , . driver_info = USB_QUIRK_NO_LPM } ,
/* Blackmagic Design UltraStudio SDI */
{ USB_DEVICE ( 0x1edb , 0xbd4f ) , . driver_info = USB_QUIRK_NO_LPM } ,
2017-06-27 20:08:51 +03:00
/* Hauppauge HVR-950q */
{ USB_DEVICE ( 0x2040 , 0x7200 ) , . driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS } ,
2016-05-19 18:12:19 +03:00
/* INTEL VALUE SSD */
{ USB_DEVICE ( 0x8086 , 0xf1a5 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2007-01-26 16:26:21 +03:00
{ } /* terminating entry must be last */
} ;
2012-07-19 14:39:13 +04:00
static const struct usb_device_id usb_interface_quirk_list [ ] = {
2012-07-19 14:39:14 +04:00
/* Logitech UVC Cameras */
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x046d , USB_CLASS_VIDEO , 1 , 0 ) ,
. driver_info = USB_QUIRK_RESET_RESUME } ,
2012-07-19 14:39:13 +04:00
{ } /* terminating entry must be last */
} ;
2013-09-16 19:47:28 +04:00
static const struct usb_device_id usb_amd_resume_quirk_list [ ] = {
/* Lenovo Mouse with Pixart controller */
{ USB_DEVICE ( 0x17ef , 0x602e ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
/* Pixart Mouse */
{ USB_DEVICE ( 0x093a , 0x2500 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
{ USB_DEVICE ( 0x093a , 0x2510 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
{ USB_DEVICE ( 0x093a , 0x2521 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2017-08-04 14:05:56 +03:00
{ USB_DEVICE ( 0x03f0 , 0x2b4a ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2013-09-16 19:47:28 +04:00
/* Logitech Optical Mouse M90/M100 */
{ USB_DEVICE ( 0x046d , 0xc05a ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
{ } /* terminating entry must be last */
} ;
2012-07-19 14:39:13 +04:00
static bool usb_match_any_interface ( struct usb_device * udev ,
const struct usb_device_id * id )
{
unsigned int i ;
for ( i = 0 ; i < udev - > descriptor . bNumConfigurations ; + + i ) {
struct usb_host_config * cfg = & udev - > config [ i ] ;
unsigned int j ;
for ( j = 0 ; j < cfg - > desc . bNumInterfaces ; + + j ) {
struct usb_interface_cache * cache ;
struct usb_host_interface * intf ;
cache = cfg - > intf_cache [ j ] ;
if ( cache - > num_altsetting = = 0 )
continue ;
intf = & cache - > altsetting [ 0 ] ;
if ( usb_match_one_id_intf ( udev , intf , id ) )
return true ;
}
}
return false ;
}
2013-09-26 22:56:50 +04:00
static int usb_amd_resume_quirk ( struct usb_device * udev )
2013-09-16 19:47:28 +04:00
{
struct usb_hcd * hcd ;
hcd = bus_to_hcd ( udev - > bus ) ;
/* The device should be attached directly to root hub */
if ( udev - > level = = 1 & & hcd - > amd_resume_bug = = 1 )
return 1 ;
return 0 ;
}
2018-03-19 19:26:06 +03:00
static u32 usb_detect_static_quirks ( struct usb_device * udev ,
const struct usb_device_id * id )
2007-01-26 16:26:21 +03:00
{
2012-07-19 14:39:13 +04:00
u32 quirks = 0 ;
2007-01-26 16:26:21 +03:00
2012-07-19 14:39:13 +04:00
for ( ; id - > match_flags ; id + + ) {
if ( ! usb_match_device ( udev , id ) )
continue ;
if ( ( id - > match_flags & USB_DEVICE_ID_MATCH_INT_INFO ) & &
! usb_match_any_interface ( udev , id ) )
continue ;
quirks | = ( u32 ) ( id - > driver_info ) ;
2007-01-26 16:26:21 +03:00
}
2012-07-19 14:39:13 +04:00
return quirks ;
2007-01-26 16:26:21 +03:00
}
2018-03-19 19:26:06 +03:00
static u32 usb_detect_dynamic_quirks ( struct usb_device * udev )
{
u16 vid = le16_to_cpu ( udev - > descriptor . idVendor ) ;
u16 pid = le16_to_cpu ( udev - > descriptor . idProduct ) ;
int i , flags = 0 ;
mutex_lock ( & quirk_mutex ) ;
for ( i = 0 ; i < quirk_count ; i + + ) {
if ( vid = = quirk_list [ i ] . vid & & pid = = quirk_list [ i ] . pid ) {
flags = quirk_list [ i ] . flags ;
break ;
}
}
mutex_unlock ( & quirk_mutex ) ;
return flags ;
}
2007-01-26 16:26:21 +03:00
/*
* Detect any quirks the device has , and do any housekeeping for it if needed .
*/
void usb_detect_quirks ( struct usb_device * udev )
{
2018-03-19 19:26:06 +03:00
udev - > quirks = usb_detect_static_quirks ( udev , usb_quirk_list ) ;
2013-09-16 19:47:28 +04:00
/*
* Pixart - based mice would trigger remote wakeup issue on AMD
* Yangtze chipset , so set them as RESET_RESUME flag .
*/
if ( usb_amd_resume_quirk ( udev ) )
2018-03-19 19:26:06 +03:00
udev - > quirks | = usb_detect_static_quirks ( udev ,
2013-09-16 19:47:28 +04:00
usb_amd_resume_quirk_list ) ;
2018-03-19 19:26:06 +03:00
udev - > quirks ^ = usb_detect_dynamic_quirks ( udev ) ;
2007-01-26 16:26:21 +03:00
if ( udev - > quirks )
dev_dbg ( & udev - > dev , " USB quirks for this device: %x \n " ,
2012-07-19 14:39:13 +04:00
udev - > quirks ) ;
2007-01-26 16:26:21 +03:00
2013-03-14 02:57:31 +04:00
# ifdef CONFIG_USB_DEFAULT_PERSIST
if ( ! ( udev - > quirks & USB_QUIRK_RESET ) )
2008-03-03 23:15:59 +03:00
udev - > persist_enabled = 1 ;
# else
2013-03-14 02:57:31 +04:00
/* Hubs are automatically enabled for USB-PERSIST */
if ( udev - > descriptor . bDeviceClass = = USB_CLASS_HUB )
2009-12-18 14:14:21 +03:00
udev - > persist_enabled = 1 ;
2013-03-14 02:57:31 +04:00
# endif /* CONFIG_USB_DEFAULT_PERSIST */
2007-01-26 16:26:21 +03:00
}
2012-07-19 14:39:13 +04:00
void usb_detect_interface_quirks ( struct usb_device * udev )
{
u32 quirks ;
2018-03-19 19:26:06 +03:00
quirks = usb_detect_static_quirks ( udev , usb_interface_quirk_list ) ;
2012-07-19 14:39:13 +04:00
if ( quirks = = 0 )
return ;
dev_dbg ( & udev - > dev , " USB interface quirks for this device: %x \n " ,
quirks ) ;
udev - > quirks | = quirks ;
}
2018-03-19 19:26:06 +03:00
void usb_release_quirk_list ( void )
{
mutex_lock ( & quirk_mutex ) ;
kfree ( quirk_list ) ;
quirk_list = NULL ;
mutex_unlock ( & quirk_mutex ) ;
}