1 1.108 dholland /* $NetBSD: usb_quirks.c,v 1.108 2024/02/28 21:52:40 dholland 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.108 dholland __KERNEL_RCSID(0, "$NetBSD: usb_quirks.c,v 1.108 2024/02/28 21:52:40 dholland 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.88 manu #define DPRINTF(FMT,A,B,C,D) USBHIST_LOG(usbdebug,FMT,A,B,C,D) 52 1.88 manu 53 1.38 augustss #define ANY 0xffff 54 1.88 manu #define _USETW(w) { (w) & 0x00ff, ((w) & 0xff00) >> 8 } 55 1.88 manu 56 1.88 manu /* 57 1.88 manu * NXP PN533 NFC chip descriptors 58 1.88 manu */ 59 1.88 manu static const usb_endpoint_descriptor_t desc_ep_pn533_in = { 60 1.88 manu /* bLength */ sizeof(desc_ep_pn533_in), 61 1.88 manu /* bDescriptorType */ UDESC_ENDPOINT, 62 1.88 manu /* bEndpointAddress */ UE_DIR_IN | 0x04, 63 1.88 manu /* bmAttributes */ UE_BULK, 64 1.88 manu /* wMaxPacketSize */ _USETW(0x0040), 65 1.88 manu /* bInterval */ 0x04, /* 255ms */ 66 1.88 manu }; 67 1.88 manu 68 1.88 manu static const usb_endpoint_descriptor_t desc_ep_pn533_out = { 69 1.88 manu /* bLength */ sizeof(desc_ep_pn533_in), 70 1.88 manu /* bDescriptorType */ UDESC_ENDPOINT, 71 1.88 manu /* bEndpointAddress */ UE_DIR_OUT | 0x04, 72 1.88 manu /* bmAttributes */ UE_BULK, 73 1.88 manu /* wMaxPacketSize */ _USETW(0x0040), 74 1.88 manu /* bInterval */ 0x04, /* 255ms */ 75 1.88 manu }; 76 1.88 manu 77 1.88 manu static const usb_interface_descriptor_t desc_iface_pn533 = { 78 1.88 manu /* bLength */ sizeof(desc_iface_pn533), 79 1.88 manu /* bDescriptorType */ UDESC_INTERFACE, 80 1.88 manu /* bInterfaceNumber */ 0, 81 1.88 manu /* bAlternateSetting */ 0, 82 1.88 manu /* bNumEndpoints */ 2, 83 1.88 manu /* bInterfaceClass */ 0xff, 84 1.88 manu /* bInterfaceSubClass */ 0xff, 85 1.88 manu /* bInterfaceProtocol */ 0xff, 86 1.88 manu /* iInterface */ 0, 87 1.88 manu }; 88 1.88 manu 89 1.88 manu static const usb_config_descriptor_t desc_conf_pn533 = { 90 1.88 manu /* bLength */ sizeof(desc_conf_pn533), 91 1.88 manu /* bDescriptorType */ UDESC_CONFIG, 92 1.88 manu /* wTotalLength */ _USETW(sizeof(desc_conf_pn533) + 93 1.88 manu sizeof(desc_iface_pn533) + 94 1.88 manu sizeof(desc_ep_pn533_in) + 95 1.88 manu sizeof(desc_ep_pn533_out) 96 1.88 manu ), 97 1.98 andvar /* bNumInterface */ 1, 98 1.88 manu /* bConfigurationValue */1, 99 1.88 manu /* iConfiguration */ 0, 100 1.88 manu /* bmAttributes */ UC_ATTR_MBO, 101 1.88 manu /* bMaxPower */ 0x32, /* 100mA */ 102 1.88 manu }; 103 1.88 manu 104 1.88 manu static const usb_descriptor_t *desc_pn533[] = { 105 1.88 manu (const usb_descriptor_t *)&desc_conf_pn533, 106 1.88 manu (const usb_descriptor_t *)&desc_iface_pn533, 107 1.88 manu (const usb_descriptor_t *)&desc_ep_pn533_out, 108 1.88 manu (const usb_descriptor_t *)&desc_ep_pn533_in, 109 1.88 manu NULL 110 1.88 manu }; 111 1.88 manu 112 1.88 manu 113 1.88 manu usbd_status 114 1.88 manu usbd_get_desc_fake(struct usbd_device *dev, int type, int index, 115 1.88 manu int len, void *desc) 116 1.88 manu { 117 1.88 manu USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 118 1.88 manu #ifdef USB_DEBUG 119 1.88 manu const usb_device_descriptor_t *dd = usbd_get_device_descriptor(dev); 120 1.88 manu #endif 121 1.88 manu const usb_descriptor_t *ub; 122 1.88 manu int i = 0; 123 1.88 manu int j = 0; 124 1.88 manu usbd_status err = USBD_INVAL; 125 1.88 manu 126 1.88 manu if (dev->ud_quirks == NULL || dev->ud_quirks->desc == NULL) { 127 1.95 christos DPRINTF("%04jx/%04j: no fake descriptors", 128 1.88 manu UGETW(dd->idVendor), UGETW(dd->idProduct), 0, 0); 129 1.88 manu goto out; 130 1.88 manu } 131 1.88 manu 132 1.88 manu for (j = 0; dev->ud_quirks->desc[j]; j++) { 133 1.88 manu ub = dev->ud_quirks->desc[j]; 134 1.88 manu if (ub->bDescriptorType == type && i++ == index) 135 1.88 manu break; 136 1.88 manu } 137 1.88 manu 138 1.88 manu if (dev->ud_quirks->desc[j] == NULL) { 139 1.95 christos DPRINTF("%04jx/%04jx: no fake descriptor type = %jd, len = %jd", 140 1.88 manu UGETW(dd->idVendor), UGETW(dd->idProduct), type, len); 141 1.88 manu goto out; 142 1.88 manu } 143 1.88 manu 144 1.88 manu do { 145 1.88 manu ub = dev->ud_quirks->desc[j]; 146 1.88 manu 147 1.88 manu if (ub->bLength > len) { 148 1.95 christos DPRINTF("%04jx/%04jx: short buf len = %jd, bLength = %jd", 149 1.88 manu UGETW(dd->idVendor), UGETW(dd->idProduct), 150 1.88 manu type, ub->bLength); 151 1.88 manu goto out; 152 1.88 manu } 153 1.88 manu 154 1.88 manu memcpy(desc, ub, ub->bLength); 155 1.95 christos DPRINTF("%04jx/%04jx: Use fake descriptor type %jd", 156 1.88 manu UGETW(dd->idVendor), UGETW(dd->idProduct), 157 1.88 manu type, 0); 158 1.88 manu 159 1.88 manu desc = (char *)desc + ub->bLength; 160 1.88 manu len -= ub->bLength; 161 1.88 manu j++; 162 1.88 manu } while (len && dev->ud_quirks->desc[j] && 163 1.88 manu dev->ud_quirks->desc[j]->bDescriptorType != type); 164 1.88 manu 165 1.88 manu err = USBD_NORMAL_COMPLETION; 166 1.88 manu 167 1.95 christos DPRINTF("%04jx/%04jx: Using fake USB descriptors\n", 168 1.88 manu UGETW(dd->idVendor), UGETW(dd->idProduct), 0, 0); 169 1.88 manu out: 170 1.95 christos DPRINTF("return err = %jd", err, 0, 0, 0); 171 1.92 msaitoh return err; 172 1.88 manu } 173 1.37 augustss 174 1.36 jdolecek Static const struct usbd_quirk_entry { 175 1.84 skrll uint16_t idVendor; 176 1.84 skrll uint16_t idProduct; 177 1.84 skrll uint16_t bcdDevice; 178 1.1 augustss struct usbd_quirks quirks; 179 1.15 augustss } usb_quirks[] = { 180 1.57 veego /* Devices which should be ignored by uhid */ 181 1.88 manu { USB_VENDOR_APC, USB_PRODUCT_APC_UPS, ANY, 182 1.88 manu { UQ_HID_IGNORE, NULL }}, 183 1.102 martin { USB_VENDOR_APC, USB_PRODUCT_APC_UPS3, ANY, 184 1.102 martin { UQ_HID_IGNORE, NULL }}, 185 1.101 mrg { USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_UPS0, ANY, 186 1.101 mrg { 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.101 mrg { USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_UPS2, ANY, 190 1.101 mrg { UQ_HID_IGNORE, NULL }}, 191 1.91 jakllsch { USB_VENDOR_GRETAGMACBETH, ANY, ANY, 192 1.91 jakllsch { UQ_HID_IGNORE, NULL }}, 193 1.88 manu { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1, ANY, 194 1.88 manu { UQ_HID_IGNORE, NULL }}, 195 1.88 manu { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2, ANY, 196 1.88 manu { UQ_HID_IGNORE, NULL }}, 197 1.88 manu { USB_VENDOR_MICROCHIP, USB_PRODUCT_MICROCHIP_PICKIT1, ANY, 198 1.88 manu { UQ_HID_IGNORE, NULL }}, 199 1.103 bouyer { USB_VENDOR_MICROCHIP, USB_PRODUCT_MICROCHIP_PICKIT2, ANY, 200 1.103 bouyer { UQ_HID_IGNORE, NULL }}, 201 1.103 bouyer { USB_VENDOR_MICROCHIP, USB_PRODUCT_MICROCHIP_PICKIT3, ANY, 202 1.103 bouyer { UQ_HID_IGNORE, NULL }}, 203 1.88 manu { USB_VENDOR_TRIPPLITE2, ANY, ANY, 204 1.88 manu { UQ_HID_IGNORE, NULL }}, 205 1.88 manu { USB_VENDOR_MISC, USB_PRODUCT_MISC_WISPY_24X, ANY, 206 1.88 manu { UQ_HID_IGNORE, NULL }}, 207 1.88 manu { USB_VENDOR_WELTREND, USB_PRODUCT_WELTREND_HID, ANY, 208 1.88 manu { UQ_HID_IGNORE, NULL }}, 209 1.88 manu { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_EC3, ANY, 210 1.88 manu { UQ_HID_IGNORE, NULL }}, 211 1.88 manu { USB_VENDOR_TI, USB_PRODUCT_TI_MSP430, ANY, 212 1.88 manu { UQ_HID_IGNORE, NULL }}, 213 1.91 jakllsch { USB_VENDOR_XRITE, ANY, ANY, 214 1.91 jakllsch { UQ_HID_IGNORE, NULL }}, 215 1.96 jym { USB_VENDOR_WAYTECH, USB_PRODUCT_WAYTECH_USB2SERIAL, ANY, 216 1.96 jym { UQ_HID_IGNORE, NULL }}, 217 1.88 manu { USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, 0x100, 218 1.88 manu { UQ_NO_SET_PROTO, NULL }}, 219 1.88 manu { USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4, 0x094, 220 1.88 manu { UQ_SWAP_UNICODE, NULL }}, 221 1.88 manu { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, 222 1.88 manu { UQ_BAD_ADC, NULL }}, 223 1.88 manu { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, 224 1.88 manu { UQ_AU_NO_XU, NULL }}, 225 1.88 manu { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, 0x103, 226 1.88 manu { UQ_BAD_ADC, NULL }}, 227 1.88 manu { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, 0x000, 228 1.88 manu { UQ_BAD_AUDIO, NULL }}, 229 1.88 manu { USB_VENDOR_SONY, USB_PRODUCT_SONY_PS2EYETOY4, 0x000, 230 1.88 manu { UQ_BAD_AUDIO, NULL }}, 231 1.88 manu { USB_VENDOR_SONY, USB_PRODUCT_SONY_PS2EYETOY5, 0x000, 232 1.88 manu { UQ_BAD_AUDIO, NULL }}, 233 1.88 manu { USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_PCVC740K, ANY, 234 1.88 manu { UQ_BAD_AUDIO, NULL }}, 235 1.88 manu { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRONB, 0x000, 236 1.88 manu { UQ_BAD_AUDIO, NULL }}, 237 1.88 manu { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO4K, 0x000, 238 1.88 manu { UQ_BAD_AUDIO, NULL }}, 239 1.88 manu { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMMESS, 0x100, 240 1.88 manu { UQ_BAD_ADC, NULL }}, 241 1.88 manu { USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, 0x110, 242 1.88 manu { UQ_SPUR_BUT_UP, NULL }}, 243 1.88 manu { USB_VENDOR_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB, 0x001, 244 1.88 manu { UQ_SPUR_BUT_UP, NULL }}, 245 1.88 manu { USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS, 0x100, 246 1.88 manu { UQ_ASSUME_CM_OVER_DATA, NULL }}, 247 1.88 manu { USB_VENDOR_SANYO, USB_PRODUCT_SANYO_SCP4900, 0x000, 248 1.88 manu { UQ_ASSUME_CM_OVER_DATA, NULL }}, 249 1.88 manu { USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_T720C, 0x001, 250 1.88 manu { UQ_ASSUME_CM_OVER_DATA, NULL }}, 251 1.88 manu { USB_VENDOR_EICON, USB_PRODUCT_EICON_DIVA852, 0x100, 252 1.88 manu { UQ_ASSUME_CM_OVER_DATA, NULL }}, 253 1.88 manu { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_MC75, 0x000, 254 1.88 manu { UQ_ASSUME_CM_OVER_DATA, NULL }}, 255 1.88 manu { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, 256 1.88 manu { UQ_AU_NO_FRAC, NULL }}, 257 1.88 manu { USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE, 0x100, 258 1.88 manu { UQ_AU_INP_ASYNC, NULL }}, 259 1.88 manu { USB_VENDOR_AVANCELOGIC, USB_PRODUCT_AVANCELOGIC_USBAUDIO, 0x101, 260 1.88 manu { UQ_AU_INP_ASYNC, NULL }}, 261 1.88 manu { USB_VENDOR_PLANTRONICS, USB_PRODUCT_PLANTRONICS_HEADSET, 0x004, 262 1.88 manu { UQ_AU_INP_ASYNC, NULL }}, 263 1.88 manu { USB_VENDOR_CMEDIA, USB_PRODUCT_CMEDIA_USBAUDIO, ANY, 264 1.88 manu { UQ_AU_INP_ASYNC, NULL }}, 265 1.88 manu 266 1.37 augustss /* XXX These should have a revision number, but I don't know what they are. */ 267 1.88 manu { USB_VENDOR_HP, USB_PRODUCT_HP_895C, ANY, 268 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 269 1.88 manu { USB_VENDOR_HP, USB_PRODUCT_HP_880C, ANY, 270 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 271 1.88 manu { USB_VENDOR_HP, USB_PRODUCT_HP_815C, ANY, 272 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 273 1.88 manu { USB_VENDOR_HP, USB_PRODUCT_HP_810C, ANY, 274 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 275 1.92 msaitoh { USB_VENDOR_HP, USB_PRODUCT_HP_830C, ANY, 276 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 277 1.88 manu { USB_VENDOR_HP, USB_PRODUCT_HP_885C, ANY, 278 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 279 1.88 manu { USB_VENDOR_HP, USB_PRODUCT_HP_840C, ANY, 280 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 281 1.92 msaitoh { USB_VENDOR_HP, USB_PRODUCT_HP_816C, ANY, 282 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 283 1.92 msaitoh { USB_VENDOR_HP, USB_PRODUCT_HP_959C, ANY, 284 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 285 1.88 manu { USB_VENDOR_MTK, USB_PRODUCT_MTK_GPS_RECEIVER, ANY, 286 1.88 manu { UQ_NO_UNION_NRM, NULL }}, 287 1.88 manu { USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY900, ANY, 288 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 289 1.88 manu { USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY760, ANY, 290 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 291 1.88 manu { USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY920, ANY, 292 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 293 1.88 manu { USB_VENDOR_NEC, USB_PRODUCT_NEC_PICTY800, ANY, 294 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 295 1.88 manu { USB_VENDOR_HP, USB_PRODUCT_HP_1220C, ANY, 296 1.88 manu { UQ_BROKEN_BIDIR, NULL }}, 297 1.56 salo 298 1.70 phx /* Apple internal notebook ISO keyboards have swapped keys */ 299 1.88 manu { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_FOUNTAIN_ISO, ANY, 300 1.88 manu { UQ_APPLE_ISO, NULL }}, 301 1.88 manu { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_GEYSER_ISO, ANY, 302 1.88 manu { UQ_APPLE_ISO, NULL }}, 303 1.70 phx 304 1.60 jmcneill /* HID and audio are both invalid on iPhone/iPod Touch */ 305 1.88 manu { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE, ANY, 306 1.88 manu { UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }}, 307 1.88 manu { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH, ANY, 308 1.88 manu { UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }}, 309 1.88 manu { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPOD_TOUCH_4G, ANY, 310 1.88 manu { UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }}, 311 1.88 manu { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G, ANY, 312 1.88 manu { UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }}, 313 1.88 manu { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3GS, ANY, 314 1.88 manu { UQ_HID_IGNORE | UQ_BAD_AUDIO, NULL }}, 315 1.88 manu 316 1.97 martin /* 317 1.97 martin * Various devices using serial boot loader protocol, as supported 318 1.97 martin * by pkgsrc/sysutils/imx_usb_loader 319 1.97 martin */ 320 1.97 martin { 0x066f, 0x3780, /* mx23 */ ANY, 321 1.97 martin { UQ_HID_IGNORE, NULL }}, 322 1.97 martin { 0x15a2, 0x004f, /* mx28 */ ANY, 323 1.97 martin { UQ_HID_IGNORE, NULL }}, 324 1.97 martin { 0x15a2, 0x0052, /* mx50 */ ANY, 325 1.97 martin { UQ_HID_IGNORE, NULL }}, 326 1.97 martin { 0x15a2, 0x0054, /* mx6 */ ANY, 327 1.97 martin { UQ_HID_IGNORE, NULL }}, 328 1.97 martin { 0x15a2, 0x0061, /* mx6 */ ANY, 329 1.97 martin { UQ_HID_IGNORE, NULL }}, 330 1.97 martin { 0x15a2, 0x0063, /* mx6 */ ANY, 331 1.97 martin { UQ_HID_IGNORE, NULL }}, 332 1.97 martin { 0x15a2, 0x0071, /* mx6 */ ANY, 333 1.97 martin { UQ_HID_IGNORE, NULL }}, 334 1.97 martin { 0x15a2, 0x007d, /* mx6 */ ANY, 335 1.97 martin { UQ_HID_IGNORE, NULL }}, 336 1.97 martin { 0x15a2, 0x0080, /* mx6ull */ ANY, 337 1.97 martin { UQ_HID_IGNORE, NULL }}, 338 1.97 martin { 0x1fc9, 0x0128, /* mx6 */ ANY, 339 1.97 martin { UQ_HID_IGNORE, NULL }}, 340 1.97 martin { 0x15a2, 0x0076, /* mx7 */ ANY, 341 1.97 martin { UQ_HID_IGNORE, NULL }}, 342 1.97 martin { 0x1fc9, 0x0126, /* mx7ulp */ ANY, 343 1.97 martin { UQ_HID_IGNORE, NULL }}, 344 1.97 martin { 0x15a2, 0x0041, /* mx51 */ ANY, 345 1.97 martin { UQ_HID_IGNORE, NULL }}, 346 1.97 martin { 0x15a2, 0x004e, /* mx53 */ ANY, 347 1.97 martin { UQ_HID_IGNORE, NULL }}, 348 1.97 martin { 0x15a2, 0x006a, /* vybrid */ ANY, 349 1.97 martin { UQ_HID_IGNORE, NULL }}, 350 1.97 martin { 0x066f, 0x37ff, /* linux_gadget */ ANY, 351 1.97 martin { UQ_HID_IGNORE, NULL }}, 352 1.97 martin { 0x1b67, 0x4fff, /* mx6 */ ANY, 353 1.97 martin { UQ_HID_IGNORE, NULL }}, 354 1.97 martin { 0x0525, 0xb4a4, /* mx6 */ ANY, 355 1.97 martin { UQ_HID_IGNORE, NULL }}, 356 1.97 martin { 0x1fc9, 0x012b, /* mx8mq */ ANY, 357 1.97 martin { UQ_HID_IGNORE, NULL }}, 358 1.97 martin { 0x1fc9, 0x0134, /* mx8mm */ ANY, 359 1.97 martin { UQ_HID_IGNORE, NULL }}, 360 1.97 martin { 0x1fc9, 0x013e, /* mx8mn */ ANY, 361 1.97 martin { UQ_HID_IGNORE, NULL }}, 362 1.97 martin { 0x3016, 0x1001, /* mx8mn */ ANY, 363 1.97 martin { UQ_HID_IGNORE, NULL }}, 364 1.97 martin 365 1.88 manu { USB_VENDOR_LG, USB_PRODUCT_LG_CDMA_MSM, ANY, 366 1.88 manu { UQ_ASSUME_CM_OVER_DATA, NULL }}, 367 1.88 manu { USB_VENDOR_QUALCOMM2, USB_PRODUCT_QUALCOMM2_CDMA_MSM, ANY, 368 1.88 manu { UQ_ASSUME_CM_OVER_DATA, NULL }}, 369 1.88 manu { USB_VENDOR_HYUNDAI, USB_PRODUCT_HYUNDAI_UM175, ANY, 370 1.88 manu { UQ_ASSUME_CM_OVER_DATA, NULL }}, 371 1.88 manu { USB_VENDOR_ZOOM, USB_PRODUCT_ZOOM_3095, ANY, 372 1.88 manu { UQ_LOST_CS_DESC, NULL }}, 373 1.88 manu 374 1.90 manu /* 375 1.90 manu * NXP PN533 bugs 376 1.90 manu * 377 1.90 manu * 1. It corrupts its USB descriptors. The quirk is to provide hardcoded 378 1.90 manu * descriptors instead of getting them from the device. 379 1.90 manu * 2. It mishandles the USB toggle bit. This causes some replies to be 380 1.105 andvar * filtered out by the USB host controller and be reported as timed out. 381 1.90 manu * NFC tool's libnfc workaround this bug by sending a dummy frame to 382 1.90 manu * resync the toggle bit, but in order to succeed, that operation must 383 1.90 manu * not be reported as failed. The quirk is therefore to pretend to 384 1.90 manu * userland that output timeouts are successes. 385 1.90 manu */ 386 1.89 martin { USB_VENDOR_PHILIPSSEMI, USB_PRODUCT_PHILIPSSEMI_PN533, ANY, 387 1.90 manu { UQ_DESC_CORRUPT | UQ_MISS_OUT_ACK, desc_pn533 }}, 388 1.88 manu { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SCL3711, ANY, 389 1.90 manu { UQ_DESC_CORRUPT | UQ_MISS_OUT_ACK, desc_pn533 }}, 390 1.88 manu { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SCL3712, ANY, 391 1.90 manu { UQ_DESC_CORRUPT | UQ_MISS_OUT_ACK, desc_pn533 }}, 392 1.99 macallan 393 1.99 macallan /* 394 1.99 macallan * These cheap mice will disconnect after 60 seconds, 395 1.99 macallan * reconnect, and then disconnect again (ad nauseum) 396 1.99 macallan * unless it's kept open. 397 1.99 macallan */ 398 1.99 macallan { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_OPTMOUSE0939, ANY, 399 1.99 macallan { UQ_ALWAYS_ON, NULL }}, 400 1.99 macallan { USB_VENDOR_PIXART, USB_PRODUCT_PIXART_RPIMOUSE, ANY, 401 1.99 macallan { UQ_ALWAYS_ON, NULL }}, 402 1.108 dholland { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_B100_1, ANY, 403 1.108 dholland { UQ_ALWAYS_ON, NULL }}, 404 1.108 dholland { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_B100_2, ANY, 405 1.100 mrg { UQ_ALWAYS_ON, NULL }}, 406 1.107 pgoyette { USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_OPTUSBMOUSE, ANY, { UQ_ALWAYS_ON, NULL }}, 407 1.99 macallan /* 408 1.99 macallan * The HAILUCK USB Keyboard has a built-in touchpad, which 409 1.99 macallan * needs to be active for the keyboard to function properly. 410 1.99 macallan */ 411 1.99 macallan { USB_VENDOR_HAILUCK, USB_PRODUCT_HAILUCK_KEYBOARD, ANY, 412 1.99 macallan { UQ_ALWAYS_ON, NULL }}, 413 1.99 macallan 414 1.88 manu { 0, 0, 0, { 0, NULL } } 415 1.1 augustss }; 416 1.1 augustss 417 1.36 jdolecek const struct usbd_quirks usbd_no_quirk = { 0 }; 418 1.1 augustss 419 1.36 jdolecek const struct usbd_quirks * 420 1.27 augustss usbd_find_quirk(usb_device_descriptor_t *d) 421 1.1 augustss { 422 1.36 jdolecek const struct usbd_quirk_entry *t; 423 1.84 skrll uint16_t vendor = UGETW(d->idVendor); 424 1.84 skrll uint16_t product = UGETW(d->idProduct); 425 1.84 skrll uint16_t revision = UGETW(d->bcdDevice); 426 1.1 augustss 427 1.15 augustss for (t = usb_quirks; t->idVendor != 0; t++) { 428 1.88 manu if (t->idVendor == vendor && 429 1.79 garbled (t->idProduct == ANY || t->idProduct == product) && 430 1.38 augustss (t->bcdDevice == ANY || t->bcdDevice == revision)) 431 1.1 augustss break; 432 1.1 augustss } 433 1.1 augustss #ifdef USB_DEBUG 434 1.1 augustss if (usbdebug && t->quirks.uq_flags) 435 1.94 christos printf("usbd_find_quirk 0x%04x/0x%04x/%x: %d\n", 436 1.12 augustss UGETW(d->idVendor), UGETW(d->idProduct), 437 1.12 augustss UGETW(d->bcdDevice), t->quirks.uq_flags); 438 1.1 augustss #endif 439 1.84 skrll return &t->quirks; 440 1.1 augustss } 441