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 >
*
* 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 , version 2.
*
*
*/
# 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"
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
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 } ,
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 } ,
2014-03-04 22:52:39 +04:00
/* Logitech HD Pro Webcams C920 and C930e */
{ USB_DEVICE ( 0x046d , 0x082d ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
{ USB_DEVICE ( 0x046d , 0x0843 ) , . driver_info = USB_QUIRK_DELAY_INIT } ,
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 } ,
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 } ,
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 } ,
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 } ,
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
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 } ,
2008-02-27 23:43:47 +03:00
/* INTEL VALUE SSD */
{ USB_DEVICE ( 0x8086 , 0xf1a5 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2014-07-10 09:22:35 +04:00
/* USB3503 */
{ USB_DEVICE ( 0x0424 , 0x3503 ) , . driver_info = USB_QUIRK_RESET_RESUME } ,
2014-09-19 06:13:50 +04:00
/* ASUS Base Station(T100) */
{ USB_DEVICE ( 0x0b05 , 0x17e0 ) , . driver_info =
USB_QUIRK_IGNORE_REMOTE_WAKEUP } ,
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 } ,
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 } ,
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 } ,
/* 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 ;
}
2012-07-19 14:39:13 +04:00
static u32 __usb_detect_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
}
/*
* Detect any quirks the device has , and do any housekeeping for it if needed .
*/
void usb_detect_quirks ( struct usb_device * udev )
{
2012-07-19 14:39:13 +04:00
udev - > quirks = __usb_detect_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 ) )
udev - > quirks | = __usb_detect_quirks ( udev ,
usb_amd_resume_quirk_list ) ;
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 ;
quirks = __usb_detect_quirks ( udev , usb_interface_quirk_list ) ;
if ( quirks = = 0 )
return ;
dev_dbg ( & udev - > dev , " USB interface quirks for this device: %x \n " ,
quirks ) ;
udev - > quirks | = quirks ;
}