Home | History | Annotate | Line # | Download | only in usb
usb_quirks.c revision 1.94
      1  1.94  christos /*	$NetBSD: usb_quirks.c,v 1.94 2020/03/14 02:35:33 christos Exp $	*/
      2  1.42       imp /*	$FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.30 2003/01/02 04:15:55 imp Exp $	*/
      3   1.1  augustss 
      4   1.1  augustss /*
      5  1.52   mycroft  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
      6   1.1  augustss  * All rights reserved.
      7   1.1  augustss  *
      8   1.2  augustss  * This code is derived from software contributed to The NetBSD Foundation
      9  1.26  augustss  * by Lennart Augustsson (lennart (at) augustsson.net) at
     10   1.2  augustss  * Carlstedt Research & Technology.
     11   1.1  augustss  *
     12   1.1  augustss  * Redistribution and use in source and binary forms, with or without
     13   1.1  augustss  * modification, are permitted provided that the following conditions
     14   1.1  augustss  * are met:
     15   1.1  augustss  * 1. Redistributions of source code must retain the above copyright
     16   1.1  augustss  *    notice, this list of conditions and the following disclaimer.
     17   1.1  augustss  * 2. Redistributions in binary form must reproduce the above copyright
     18   1.1  augustss  *    notice, this list of conditions and the following disclaimer in the
     19   1.1  augustss  *    documentation and/or other materials provided with the distribution.
     20   1.1  augustss  *
     21   1.1  augustss  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     22   1.1  augustss  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     23   1.1  augustss  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     24   1.1  augustss  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     25   1.1  augustss  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26   1.1  augustss  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27   1.1  augustss  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28   1.1  augustss  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29   1.1  augustss  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30   1.1  augustss  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31   1.1  augustss  * POSSIBILITY OF SUCH DAMAGE.
     32   1.1  augustss  */
     33  1.39     lukem 
     34  1.39     lukem #include <sys/cdefs.h>
     35  1.94  christos __KERNEL_RCSID(0, "$NetBSD: usb_quirks.c,v 1.94 2020/03/14 02:35:33 christos Exp $");
     36  1.81     skrll 
     37  1.81     skrll #ifdef _KERNEL_OPT
     38  1.81     skrll #include "opt_usb.h"
     39  1.81     skrll #endif
     40   1.1  augustss 
     41   1.1  augustss #include <sys/param.h>
     42   1.1  augustss #include <sys/systm.h>
     43  1.40  augustss 
     44   1.1  augustss #include <dev/usb/usb.h>
     45   1.1  augustss #include <dev/usb/usbdevs.h>
     46  1.88      manu #include <dev/usb/usbdi.h>
     47  1.88      manu #include <dev/usb/usbdivar.h>
     48  1.88      manu #include <dev/usb/usbhist.h>
     49   1.1  augustss #include <dev/usb/usb_quirks.h>
     50   1.1  augustss 
     51   1.7  augustss #ifdef USB_DEBUG
     52   1.7  augustss extern int usbdebug;
     53   1.7  augustss #endif
     54   1.7  augustss 
     55  1.88      manu #define DPRINTF(FMT,A,B,C,D)    USBHIST_LOG(usbdebug,FMT,A,B,C,D)
     56  1.88      manu 
     57  1.38  augustss #define ANY 0xffff
     58  1.88      manu #define _USETW(w) { (w) & 0x00ff, ((w) & 0xff00) >> 8 }
     59  1.88      manu 
     60  1.88      manu /*
     61  1.88      manu  * NXP PN533 NFC chip descriptors
     62  1.88      manu  */
     63  1.88      manu static const usb_endpoint_descriptor_t desc_ep_pn533_in = {
     64  1.88      manu 	/* bLength */		sizeof(desc_ep_pn533_in),
     65  1.88      manu 	/* bDescriptorType */	UDESC_ENDPOINT,
     66  1.88      manu 	/* bEndpointAddress */	UE_DIR_IN | 0x04,
     67  1.88      manu 	/* bmAttributes */	UE_BULK,
     68  1.88      manu 	/* wMaxPacketSize */	_USETW(0x0040),
     69  1.88      manu 	/* bInterval */		0x04, /* 255ms */
     70  1.88      manu };
     71  1.88      manu 
     72  1.88      manu static const usb_endpoint_descriptor_t desc_ep_pn533_out = {
     73  1.88      manu 	/* bLength */		sizeof(desc_ep_pn533_in),
     74  1.88      manu 	/* bDescriptorType */	UDESC_ENDPOINT,
     75  1.88      manu 	/* bEndpointAddress */	UE_DIR_OUT | 0x04,
     76  1.88      manu 	/* bmAttributes */	UE_BULK,
     77  1.88      manu 	/* wMaxPacketSize */	_USETW(0x0040),
     78  1.88      manu 	/* bInterval */		0x04, /* 255ms */
     79  1.88      manu };
     80  1.88      manu 
     81  1.88      manu static const usb_interface_descriptor_t desc_iface_pn533 = {
     82  1.88      manu 	/* bLength */		sizeof(desc_iface_pn533),
     83  1.88      manu 	/* bDescriptorType */	 UDESC_INTERFACE,
     84  1.88      manu 	/* bInterfaceNumber */	 0,
     85  1.88      manu 	/* bAlternateSetting */	 0,
     86  1.88      manu 	/* bNumEndpoints */	 2,
     87  1.88      manu 	/* bInterfaceClass */	 0xff,
     88  1.88      manu 	/* bInterfaceSubClass */ 0xff,
     89  1.88      manu 	/* bInterfaceProtocol */ 0xff,
     90  1.88      manu 	/* iInterface */	 0,
     91  1.88      manu };
     92  1.88      manu 
     93  1.88      manu static const usb_config_descriptor_t desc_conf_pn533 = {
     94  1.88      manu 	/* bLength */		 sizeof(desc_conf_pn533),
     95  1.88      manu 	/* bDescriptorType */	 UDESC_CONFIG,
     96  1.88      manu 	/* wTotalLength	 */	 _USETW(sizeof(desc_conf_pn533) +
     97  1.88      manu 					sizeof(desc_iface_pn533) +
     98  1.88      manu 					sizeof(desc_ep_pn533_in) +
     99  1.88      manu 					sizeof(desc_ep_pn533_out)
    100  1.88      manu 				 ),
    101  1.88      manu 	/* bNumInterfac	*/	 1,
    102  1.88      manu 	/* bConfigurationValue */1,
    103  1.88      manu 	/* iConfiguration */	 0,
    104  1.88      manu 	/* bmAttributes	*/	 UC_ATTR_MBO,
    105  1.88      manu 	/* bMaxPower */		 0x32, /* 100mA */
    106  1.88      manu };
    107  1.88      manu 
    108  1.88      manu static const usb_descriptor_t *desc_pn533[] = {
    109  1.88      manu 	(const usb_descriptor_t *)&desc_conf_pn533,
    110  1.88      manu 	(const usb_descriptor_t *)&desc_iface_pn533,
    111  1.88      manu 	(const usb_descriptor_t *)&desc_ep_pn533_out,
    112  1.88      manu 	(const usb_descriptor_t *)&desc_ep_pn533_in,
    113  1.88      manu 	NULL
    114  1.88      manu };
    115  1.88      manu 
    116  1.88      manu 
    117  1.88      manu usbd_status
    118  1.88      manu usbd_get_desc_fake(struct usbd_device *dev, int type, int index,
    119  1.88      manu 		   int len, void *desc)
    120  1.88      manu {
    121  1.88      manu 	USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
    122  1.88      manu #ifdef USB_DEBUG
    123  1.88      manu 	const usb_device_descriptor_t *dd = usbd_get_device_descriptor(dev);
    124  1.88      manu #endif
    125  1.88      manu 	const usb_descriptor_t *ub;
    126  1.88      manu 	int i = 0;
    127  1.88      manu 	int j = 0;
    128  1.88      manu 	usbd_status err = USBD_INVAL;
    129  1.88      manu 
    130  1.88      manu 	if (dev->ud_quirks == NULL || dev->ud_quirks->desc == NULL) {
    131  1.88      manu 		DPRINTF("%04x/%04x: no fake descriptors",
    132  1.88      manu 		        UGETW(dd->idVendor), UGETW(dd->idProduct), 0, 0);
    133  1.88      manu 		goto out;
    134  1.88      manu 	}
    135  1.88      manu 
    136  1.88      manu 	for (j = 0; dev->ud_quirks->desc[j]; j++) {
    137  1.88      manu 		ub = dev->ud_quirks->desc[j];
    138  1.88      manu 		if (ub->bDescriptorType == type && i++ == index)
    139  1.88      manu 			break;
    140  1.88      manu 	}
    141  1.88      manu 
    142  1.88      manu 	if (dev->ud_quirks->desc[j] == NULL) {
    143  1.88      manu 		DPRINTF("%04x/%04x: no fake descriptor type = %d, len = %d",
    144  1.88      manu 		       UGETW(dd->idVendor), UGETW(dd->idProduct), type, len);
    145  1.88      manu 		goto out;
    146  1.88      manu 	}
    147  1.88      manu 
    148  1.88      manu 	do {
    149  1.88      manu 		ub = dev->ud_quirks->desc[j];
    150  1.88      manu 
    151  1.88      manu 		if (ub->bLength > len) {
    152  1.88      manu 			DPRINTF("%04x/%04x: short buf len = %d, bLength = %d",
    153  1.88      manu 			        UGETW(dd->idVendor), UGETW(dd->idProduct),
    154  1.88      manu 			        type, ub->bLength);
    155  1.88      manu 			goto out;
    156  1.88      manu 		}
    157  1.88      manu 
    158  1.88      manu 		memcpy(desc, ub, ub->bLength);
    159  1.88      manu 		DPRINTF("%04x/%04x: Use fake descriptor type %d",
    160  1.88      manu 			UGETW(dd->idVendor), UGETW(dd->idProduct),
    161  1.88      manu 			type, 0);
    162  1.88      manu 
    163  1.88      manu 		desc = (char *)desc + ub->bLength;
    164  1.88      manu 		len -= ub->bLength;
    165  1.88      manu 		j++;
    166  1.88      manu 	} while (len && dev->ud_quirks->desc[j] &&
    167  1.88      manu 		 dev->ud_quirks->desc[j]->bDescriptorType != type);
    168  1.88      manu 
    169  1.88      manu 	err = USBD_NORMAL_COMPLETION;
    170  1.88      manu 
    171  1.88      manu 	DPRINTF("%04x/%04x: Using fake USB descriptors\n",
    172  1.88      manu 	        UGETW(dd->idVendor), UGETW(dd->idProduct), 0, 0);
    173  1.88      manu out:
    174  1.88      manu 	DPRINTF("return err = %d", err, 0, 0, 0);
    175  1.92   msaitoh 	return err;
    176  1.88      manu }
    177  1.37  augustss 
    178  1.36  jdolecek Static const struct usbd_quirk_entry {
    179  1.84     skrll 	uint16_t idVendor;
    180  1.84     skrll 	uint16_t idProduct;
    181  1.84     skrll 	uint16_t bcdDevice;
    182   1.1  augustss 	struct usbd_quirks quirks;
    183  1.15  augustss } usb_quirks[] = {
    184  1.57     veego  /* Devices which should be ignored by uhid */
    185  1.88      manu  { USB_VENDOR_APC,		USB_PRODUCT_APC_UPS,			ANY,
    186  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    187  1.88      manu  { USB_VENDOR_CYBERPOWER,	USB_PRODUCT_CYBERPOWER_UPS,		ANY,
    188  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    189  1.91  jakllsch  { USB_VENDOR_GRETAGMACBETH,	ANY,					ANY,
    190  1.91  jakllsch 	{ UQ_HID_IGNORE, NULL }},
    191  1.88      manu  { USB_VENDOR_MGE,		USB_PRODUCT_MGE_UPS1,			ANY,
    192  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    193  1.88      manu  { USB_VENDOR_MGE,		USB_PRODUCT_MGE_UPS2,			ANY,
    194  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    195  1.88      manu  { USB_VENDOR_MICROCHIP,	USB_PRODUCT_MICROCHIP_PICKIT1,		ANY,
    196  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    197  1.88      manu  { USB_VENDOR_TRIPPLITE2,	ANY,					ANY,
    198  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    199  1.88      manu  { USB_VENDOR_MISC,		USB_PRODUCT_MISC_WISPY_24X,		ANY,
    200  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    201  1.88      manu  { USB_VENDOR_WELTREND,	USB_PRODUCT_WELTREND_HID,		ANY,
    202  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    203  1.88      manu  { USB_VENDOR_SILABS,		USB_PRODUCT_SILABS_EC3,			ANY,
    204  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    205  1.88      manu  { USB_VENDOR_TI,		USB_PRODUCT_TI_MSP430,			ANY,
    206  1.88      manu 	{ UQ_HID_IGNORE, NULL }},
    207  1.91  jakllsch  { USB_VENDOR_XRITE,		ANY,					ANY,
    208  1.91  jakllsch 	{ UQ_HID_IGNORE, NULL }},
    209  1.88      manu  { USB_VENDOR_KYE,		USB_PRODUCT_KYE_NICHE,			0x100,
    210  1.88      manu 	{ UQ_NO_SET_PROTO, NULL }},
    211  1.88      manu  { USB_VENDOR_INSIDEOUT,	USB_PRODUCT_INSIDEOUT_EDGEPORT4,	0x094,
    212  1.88      manu 	{ UQ_SWAP_UNICODE, NULL }},
    213  1.88      manu  { USB_VENDOR_DALLAS,		USB_PRODUCT_DALLAS_J6502,		0x0a2,
    214  1.88      manu 	{ UQ_BAD_ADC, NULL }},
    215  1.88      manu  { USB_VENDOR_DALLAS,		USB_PRODUCT_DALLAS_J6502,		0x0a2,
    216  1.88      manu 	{ UQ_AU_NO_XU, NULL }},
    217  1.88      manu  { USB_VENDOR_ALTEC,		USB_PRODUCT_ALTEC_ADA70,		0x103,
    218  1.88      manu 	{ UQ_BAD_ADC, NULL }},
    219  1.88      manu  { USB_VENDOR_ALTEC,		USB_PRODUCT_ALTEC_ASC495,		0x000,
    220  1.88      manu 	{ UQ_BAD_AUDIO, NULL }},
    221  1.88      manu  { USB_VENDOR_SONY,		USB_PRODUCT_SONY_PS2EYETOY4,		0x000,
    222  1.88      manu 	{ UQ_BAD_AUDIO, NULL }},
    223  1.88      manu  { USB_VENDOR_SONY,		USB_PRODUCT_SONY_PS2EYETOY5,		0x000,
    224  1.88      manu 	{ UQ_BAD_AUDIO, NULL }},
    225  1.88      manu  { USB_VENDOR_PHILIPS,		USB_PRODUCT_PHILIPS_PCVC740K,		ANY,
    226  1.88      manu 	{ UQ_BAD_AUDIO, NULL }},
    227  1.88      manu  { USB_VENDOR_LOGITECH,		USB_PRODUCT_LOGITECH_QUICKCAMPRONB,	0x000,
    228  1.88      manu 	{ UQ_BAD_AUDIO, NULL }},
    229  1.88      manu  { USB_VENDOR_LOGITECH,		USB_PRODUCT_LOGITECH_QUICKCAMPRO4K,	0x000,
    230  1.88      manu 	{ UQ_BAD_AUDIO, NULL }},
    231  1.88      manu  { USB_VENDOR_LOGITECH,		USB_PRODUCT_LOGITECH_QUICKCAMMESS,	0x100,
    232  1.88      manu 	{ UQ_BAD_ADC, NULL }},
    233  1.88      manu  { USB_VENDOR_QTRONIX,		USB_PRODUCT_QTRONIX_980N,		0x110,
    234  1.88      manu 	{ UQ_SPUR_BUT_UP, NULL }},
    235  1.88      manu  { USB_VENDOR_ALCOR2,		USB_PRODUCT_ALCOR2_KBD_HUB,		0x001,
    236  1.88      manu 	{ UQ_SPUR_BUT_UP, NULL }},
    237  1.88      manu  { USB_VENDOR_METRICOM,		USB_PRODUCT_METRICOM_RICOCHET_GS,	0x100,
    238  1.88      manu 	{ UQ_ASSUME_CM_OVER_DATA, NULL }},
    239  1.88      manu  { USB_VENDOR_SANYO,		USB_PRODUCT_SANYO_SCP4900,		0x000,
    240  1.88      manu 	{ UQ_ASSUME_CM_OVER_DATA, NULL }},
    241  1.88      manu  { USB_VENDOR_MOTOROLA2,	USB_PRODUCT_MOTOROLA2_T720C,		0x001,
    242  1.88      manu 	{ UQ_ASSUME_CM_OVER_DATA, NULL }},
    243  1.88      manu  { USB_VENDOR_EICON,		USB_PRODUCT_EICON_DIVA852,		0x100,
    244  1.88      manu 	{ UQ_ASSUME_CM_OVER_DATA, NULL }},
    245  1.88      manu  { USB_VENDOR_SIEMENS2,		USB_PRODUCT_SIEMENS2_MC75,		0x000,
    246  1.88      manu 	{ UQ_ASSUME_CM_OVER_DATA, NULL }},
    247  1.88      manu  { USB_VENDOR_TELEX,		USB_PRODUCT_TELEX_MIC1,			0x009,
    248  1.88      manu 	{ UQ_AU_NO_FRAC, NULL }},
    249  1.88      manu  { USB_VENDOR_SILICONPORTALS,	USB_PRODUCT_SILICONPORTALS_YAPPHONE,	0x100,
    250  1.88      manu 	{ UQ_AU_INP_ASYNC, NULL }},
    251  1.88      manu  { USB_VENDOR_AVANCELOGIC,	USB_PRODUCT_AVANCELOGIC_USBAUDIO,	0x101,
    252  1.88      manu 	{ UQ_AU_INP_ASYNC, NULL }},
    253  1.88      manu  { USB_VENDOR_PLANTRONICS,	USB_PRODUCT_PLANTRONICS_HEADSET,	0x004,
    254  1.88      manu 	{ UQ_AU_INP_ASYNC, NULL }},
    255  1.88      manu  { USB_VENDOR_CMEDIA,		USB_PRODUCT_CMEDIA_USBAUDIO,		ANY,
    256  1.88      manu 	{ UQ_AU_INP_ASYNC, NULL }},
    257  1.88      manu 
    258  1.37  augustss  /* XXX These should have a revision number, but I don't know what they are. */
    259  1.88      manu  { USB_VENDOR_HP,		USB_PRODUCT_HP_895C,			ANY,
    260  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    261  1.88      manu  { USB_VENDOR_HP,		USB_PRODUCT_HP_880C,			ANY,
    262  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    263  1.88      manu  { USB_VENDOR_HP,		USB_PRODUCT_HP_815C,			ANY,
    264  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    265  1.88      manu  { USB_VENDOR_HP,		USB_PRODUCT_HP_810C,			ANY,
    266  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    267  1.92   msaitoh  { USB_VENDOR_HP,		USB_PRODUCT_HP_830C,			ANY,
    268  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    269  1.88      manu  { USB_VENDOR_HP,		USB_PRODUCT_HP_885C,			ANY,
    270  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    271  1.88      manu  { USB_VENDOR_HP,		USB_PRODUCT_HP_840C,			ANY,
    272  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    273  1.92   msaitoh  { USB_VENDOR_HP,		USB_PRODUCT_HP_816C,			ANY,
    274  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    275  1.92   msaitoh  { USB_VENDOR_HP,		USB_PRODUCT_HP_959C,			ANY,
    276  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    277  1.88      manu  { USB_VENDOR_MTK,		USB_PRODUCT_MTK_GPS_RECEIVER,		ANY,
    278  1.88      manu 	{ UQ_NO_UNION_NRM, NULL }},
    279  1.88      manu  { USB_VENDOR_NEC,		USB_PRODUCT_NEC_PICTY900,		ANY,
    280  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    281  1.88      manu  { USB_VENDOR_NEC,		USB_PRODUCT_NEC_PICTY760,		ANY,
    282  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    283  1.88      manu  { USB_VENDOR_NEC,		USB_PRODUCT_NEC_PICTY920,		ANY,
    284  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    285  1.88      manu  { USB_VENDOR_NEC,		USB_PRODUCT_NEC_PICTY800,		ANY,
    286  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    287  1.88      manu  { USB_VENDOR_HP,		USB_PRODUCT_HP_1220C,			ANY,
    288  1.88      manu 	{ UQ_BROKEN_BIDIR, NULL }},
    289  1.56      salo 
    290  1.70       phx  /* Apple internal notebook ISO keyboards have swapped keys */
    291  1.88      manu  { USB_VENDOR_APPLE,		USB_PRODUCT_APPLE_FOUNTAIN_ISO,		ANY,
    292  1.88      manu 	{ UQ_APPLE_ISO, NULL }},
    293  1.88      manu  { USB_VENDOR_APPLE,		USB_PRODUCT_APPLE_GEYSER_ISO,		ANY,
    294  1.88      manu 	{ UQ_APPLE_ISO, NULL }},
    295  1.70       phx 
    296  1.60  jmcneill  /* HID and audio are both invalid on iPhone/iPod Touch */
    297  1.88      manu  { USB_VENDOR_APPLE,		USB_PRODUCT_APPLE_IPHONE,		ANY,
    298  1.88      manu 	{ UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }},
    299  1.88      manu  { USB_VENDOR_APPLE,		USB_PRODUCT_APPLE_IPOD_TOUCH,		ANY,
    300  1.88      manu 	{ UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }},
    301  1.88      manu  { USB_VENDOR_APPLE,		USB_PRODUCT_APPLE_IPOD_TOUCH_4G,	ANY,
    302  1.88      manu 	{ UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }},
    303  1.88      manu  { USB_VENDOR_APPLE,		USB_PRODUCT_APPLE_IPHONE_3G,		ANY,
    304  1.88      manu 	{ UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }},
    305  1.88      manu  { USB_VENDOR_APPLE,		USB_PRODUCT_APPLE_IPHONE_3GS,		ANY,
    306  1.88      manu 	{ UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }},
    307  1.88      manu 
    308  1.88      manu  { USB_VENDOR_LG,		USB_PRODUCT_LG_CDMA_MSM,		ANY,
    309  1.88      manu 	{ UQ_ASSUME_CM_OVER_DATA, NULL }},
    310  1.88      manu  { USB_VENDOR_QUALCOMM2,	USB_PRODUCT_QUALCOMM2_CDMA_MSM,		ANY,
    311  1.88      manu 	{ UQ_ASSUME_CM_OVER_DATA, NULL }},
    312  1.88      manu  { USB_VENDOR_HYUNDAI,		USB_PRODUCT_HYUNDAI_UM175,		ANY,
    313  1.88      manu 	{ UQ_ASSUME_CM_OVER_DATA, NULL }},
    314  1.88      manu  { USB_VENDOR_ZOOM,		USB_PRODUCT_ZOOM_3095,			ANY,
    315  1.88      manu 	{ UQ_LOST_CS_DESC, NULL }},
    316  1.88      manu 
    317  1.90      manu  /*
    318  1.90      manu   * NXP PN533 bugs
    319  1.90      manu   *
    320  1.90      manu   * 1. It corrupts its USB descriptors. The quirk is to provide hardcoded
    321  1.90      manu   *    descriptors instead of getting them from the device.
    322  1.90      manu   * 2. It mishandles the USB toggle bit. This causes some replies to be
    323  1.90      manu   *    filered out by the USB host controller and be reported as timed out.
    324  1.90      manu   *    NFC tool's libnfc workaround this bug by sending a dummy frame to
    325  1.90      manu   *    resync the toggle bit, but in order to succeed, that operation must
    326  1.90      manu   *    not be reported as failed. The quirk is therefore to pretend to
    327  1.90      manu   *    userland that output timeouts are successes.
    328  1.90      manu   */
    329  1.89    martin  { USB_VENDOR_PHILIPSSEMI,	USB_PRODUCT_PHILIPSSEMI_PN533,		ANY,
    330  1.90      manu 	{ UQ_DESC_CORRUPT | UQ_MISS_OUT_ACK, desc_pn533 }},
    331  1.88      manu  { USB_VENDOR_SHUTTLE,		USB_PRODUCT_SHUTTLE_SCL3711,		ANY,
    332  1.90      manu 	{ UQ_DESC_CORRUPT | UQ_MISS_OUT_ACK, desc_pn533 }},
    333  1.88      manu  { USB_VENDOR_SHUTTLE,		USB_PRODUCT_SHUTTLE_SCL3712,		ANY,
    334  1.90      manu 	{ UQ_DESC_CORRUPT | UQ_MISS_OUT_ACK, desc_pn533 }},
    335  1.88      manu  { 0, 0, 0, { 0, NULL } }
    336   1.1  augustss };
    337   1.1  augustss 
    338  1.36  jdolecek const struct usbd_quirks usbd_no_quirk = { 0 };
    339   1.1  augustss 
    340  1.36  jdolecek const struct usbd_quirks *
    341  1.27  augustss usbd_find_quirk(usb_device_descriptor_t *d)
    342   1.1  augustss {
    343  1.36  jdolecek 	const struct usbd_quirk_entry *t;
    344  1.84     skrll 	uint16_t vendor = UGETW(d->idVendor);
    345  1.84     skrll 	uint16_t product = UGETW(d->idProduct);
    346  1.84     skrll 	uint16_t revision = UGETW(d->bcdDevice);
    347   1.1  augustss 
    348  1.15  augustss 	for (t = usb_quirks; t->idVendor != 0; t++) {
    349  1.88      manu 		if (t->idVendor == vendor &&
    350  1.79   garbled 		    (t->idProduct == ANY || t->idProduct == product) &&
    351  1.38  augustss 		    (t->bcdDevice == ANY || t->bcdDevice == revision))
    352   1.1  augustss 			break;
    353   1.1  augustss 	}
    354   1.1  augustss #ifdef USB_DEBUG
    355   1.1  augustss 	if (usbdebug && t->quirks.uq_flags)
    356  1.94  christos 		printf("usbd_find_quirk 0x%04x/0x%04x/%x: %d\n",
    357  1.12  augustss 			  UGETW(d->idVendor), UGETW(d->idProduct),
    358  1.12  augustss 			  UGETW(d->bcdDevice), t->quirks.uq_flags);
    359   1.1  augustss #endif
    360  1.84     skrll 	return &t->quirks;
    361   1.1  augustss }
    362