1 /* $FreeBSD$ */ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause-NetBSD 4 * 5 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved. 6 * Copyright (c) 1998 Lennart Augustsson. All rights reserved. 7 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 8 * Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/stdint.h> 33 #include <sys/stddef.h> 34 #include <sys/param.h> 35 #include <sys/queue.h> 36 #include <sys/types.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/bus.h> 40 #include <sys/module.h> 41 #include <sys/lock.h> 42 #include <sys/mutex.h> 43 #include <sys/condvar.h> 44 #include <sys/sysctl.h> 45 #include <sys/sx.h> 46 #include <sys/unistd.h> 47 #include <sys/callout.h> 48 #include <sys/malloc.h> 49 #include <sys/priv.h> 50 51 #include <dev/evdev/input.h> 52 53 #define HID_DEBUG_VAR hid_debug 54 #include <dev/hid/hid.h> 55 #include <dev/hid/hidquirk.h> 56 #include "usbdevs.h" 57 58 59 MODULE_DEPEND(hidquirk, hid, 1, 1, 1); 60 MODULE_VERSION(hidquirk, 1); 61 62 #define HID_DEV_QUIRKS_MAX 384 63 #define HID_SUB_QUIRKS_MAX 8 64 #define HID_QUIRK_ENVROOT "hw.hid.quirk." 65 66 struct hidquirk_entry { 67 uint16_t bus; 68 uint16_t vid; 69 uint16_t pid; 70 uint16_t lo_rev; 71 uint16_t hi_rev; 72 uint16_t quirks[HID_SUB_QUIRKS_MAX]; 73 }; 74 75 static struct mtx hidquirk_mtx; 76 77 #define HID_QUIRK_VP(b,v,p,l,h,...) \ 78 { .bus = (b), .vid = (v), .pid = (p), .lo_rev = (l), .hi_rev = (h), \ 79 .quirks = { __VA_ARGS__ } } 80 #define USB_QUIRK(v,p,l,h,...) \ 81 HID_QUIRK_VP(BUS_USB, USB_VENDOR_##v, USB_PRODUCT_##v##_##p, l, h, __VA_ARGS__) 82 83 static struct hidquirk_entry hidquirks[HID_DEV_QUIRKS_MAX] = { 84 USB_QUIRK(ASUS, LCM, 0x0000, 0xffff, HQ_HID_IGNORE), 85 USB_QUIRK(QTRONIX, 980N, 0x110, 0x110, HQ_SPUR_BUT_UP), 86 USB_QUIRK(ALCOR2, KBD_HUB, 0x001, 0x001, HQ_SPUR_BUT_UP), 87 USB_QUIRK(LOGITECH, G510S, 0x0000, 0xFFFF, HQ_KBD_BOOTPROTO), 88 /* Devices which should be ignored by usbhid */ 89 USB_QUIRK(APC, UPS, 0x0000, 0xffff, HQ_HID_IGNORE), 90 USB_QUIRK(BELKIN, F6H375USB, 0x0000, 0xffff, HQ_HID_IGNORE), 91 USB_QUIRK(BELKIN, F6C550AVR, 0x0000, 0xffff, HQ_HID_IGNORE), 92 USB_QUIRK(BELKIN, F6C1250TWRK, 0x0000, 0xffff, HQ_HID_IGNORE), 93 USB_QUIRK(BELKIN, F6C1500TWRK, 0x0000, 0xffff, HQ_HID_IGNORE), 94 USB_QUIRK(BELKIN, F6C900UNV, 0x0000, 0xffff, HQ_HID_IGNORE), 95 USB_QUIRK(BELKIN, F6C100UNV, 0x0000, 0xffff, HQ_HID_IGNORE), 96 USB_QUIRK(BELKIN, F6C120UNV, 0x0000, 0xffff, HQ_HID_IGNORE), 97 USB_QUIRK(BELKIN, F6C800UNV, 0x0000, 0xffff, HQ_HID_IGNORE), 98 USB_QUIRK(BELKIN, F6C1100UNV, 0x0000, 0xffff, HQ_HID_IGNORE), 99 USB_QUIRK(CYBERPOWER, BC900D, 0x0000, 0xffff, HQ_HID_IGNORE), 100 USB_QUIRK(CYBERPOWER, 1500CAVRLCD, 0x0000, 0xffff, HQ_HID_IGNORE), 101 USB_QUIRK(CYBERPOWER, OR2200LCDRM2U, 0x0000, 0xffff, HQ_HID_IGNORE), 102 USB_QUIRK(DELL2, VARIOUS_UPS, 0x0000, 0xffff, HQ_HID_IGNORE), 103 USB_QUIRK(CYPRESS, SILVERSHIELD, 0x0000, 0xffff, HQ_HID_IGNORE), 104 USB_QUIRK(DELORME, EARTHMATE, 0x0000, 0xffff, HQ_HID_IGNORE), 105 USB_QUIRK(DREAMLINK, DL100B, 0x0000, 0xffff, HQ_HID_IGNORE), 106 USB_QUIRK(MICROCHIP, PICOLCD20X2, 0x0000, 0xffff, HQ_HID_IGNORE), 107 USB_QUIRK(MICROCHIP, PICOLCD4X20, 0x0000, 0xffff, HQ_HID_IGNORE), 108 USB_QUIRK(LIEBERT, POWERSURE_PXT, 0x0000, 0xffff, HQ_HID_IGNORE), 109 USB_QUIRK(LIEBERT2, PSI1000, 0x0000, 0xffff, HQ_HID_IGNORE), 110 USB_QUIRK(LIEBERT2, POWERSURE_PSA, 0x0000, 0xffff, HQ_HID_IGNORE), 111 USB_QUIRK(MGE, UPS1, 0x0000, 0xffff, HQ_HID_IGNORE), 112 USB_QUIRK(MGE, UPS2, 0x0000, 0xffff, HQ_HID_IGNORE), 113 USB_QUIRK(POWERCOM, IMPERIAL_SERIES, 0x0000, 0xffff, HQ_HID_IGNORE), 114 USB_QUIRK(POWERCOM, SMART_KING_PRO, 0x0000, 0xffff, HQ_HID_IGNORE), 115 USB_QUIRK(POWERCOM, WOW, 0x0000, 0xffff, HQ_HID_IGNORE), 116 USB_QUIRK(POWERCOM, VANGUARD, 0x0000, 0xffff, HQ_HID_IGNORE), 117 USB_QUIRK(POWERCOM, BLACK_KNIGHT_PRO, 0x0000, 0xffff, HQ_HID_IGNORE), 118 USB_QUIRK(TRIPPLITE2, AVR550U, 0x0000, 0xffff, HQ_HID_IGNORE), 119 USB_QUIRK(TRIPPLITE2, AVR750U, 0x0000, 0xffff, HQ_HID_IGNORE), 120 USB_QUIRK(TRIPPLITE2, ECO550UPS, 0x0000, 0xffff, HQ_HID_IGNORE), 121 USB_QUIRK(TRIPPLITE2, T750_INTL, 0x0000, 0xffff, HQ_HID_IGNORE), 122 USB_QUIRK(TRIPPLITE2, RT_2200_INTL, 0x0000, 0xffff, HQ_HID_IGNORE), 123 USB_QUIRK(TRIPPLITE2, OMNI1000LCD, 0x0000, 0xffff, HQ_HID_IGNORE), 124 USB_QUIRK(TRIPPLITE2, OMNI900LCD, 0x0000, 0xffff, HQ_HID_IGNORE), 125 USB_QUIRK(TRIPPLITE2, SMART_2200RMXL2U, 0x0000, 0xffff, HQ_HID_IGNORE), 126 USB_QUIRK(TRIPPLITE2, UPS_3014, 0x0000, 0xffff, HQ_HID_IGNORE), 127 USB_QUIRK(TRIPPLITE2, SU1500RTXL2UA, 0x0000, 0xffff, HQ_HID_IGNORE), 128 USB_QUIRK(TRIPPLITE2, SU6000RT4U, 0x0000, 0xffff, HQ_HID_IGNORE), 129 USB_QUIRK(TRIPPLITE2, SU1500RTXL2UA_2, 0x0000, 0xffff, HQ_HID_IGNORE), 130 USB_QUIRK(APPLE, IPHONE, 0x0000, 0xffff, HQ_HID_IGNORE), 131 USB_QUIRK(APPLE, IPHONE_3G, 0x0000, 0xffff, HQ_HID_IGNORE), 132 USB_QUIRK(MEGATEC, UPS, 0x0000, 0xffff, HQ_HID_IGNORE), 133 /* Devices which should be ignored by both ukbd and uhid */ 134 USB_QUIRK(CYPRESS, WISPY1A, 0x0000, 0xffff, HQ_HID_IGNORE), 135 USB_QUIRK(METAGEEK, WISPY1B, 0x0000, 0xffff, HQ_HID_IGNORE), 136 USB_QUIRK(METAGEEK, WISPY24X, 0x0000, 0xffff, HQ_HID_IGNORE), 137 USB_QUIRK(METAGEEK2, WISPYDBX, 0x0000, 0xffff, HQ_HID_IGNORE), 138 /* MS keyboards do weird things */ 139 USB_QUIRK(MICROSOFT, NATURAL4000, 0x0000, 0xFFFF, HQ_KBD_BOOTPROTO), 140 USB_QUIRK(MICROSOFT, WLINTELLIMOUSE, 0x0000, 0xffff, HQ_MS_LEADING_BYTE), 141 /* Quirk for Corsair Vengeance K60 keyboard */ 142 USB_QUIRK(CORSAIR, K60, 0x0000, 0xffff, HQ_KBD_BOOTPROTO), 143 /* Quirk for Corsair Gaming K68 keyboard */ 144 USB_QUIRK(CORSAIR, K68, 0x0000, 0xffff, HQ_KBD_BOOTPROTO), 145 /* Quirk for Corsair Vengeance K70 keyboard */ 146 USB_QUIRK(CORSAIR, K70, 0x0000, 0xffff, HQ_KBD_BOOTPROTO), 147 /* Quirk for Corsair K70 RGB keyboard */ 148 USB_QUIRK(CORSAIR, K70_RGB, 0x0000, 0xffff, HQ_KBD_BOOTPROTO), 149 /* Quirk for Corsair STRAFE Gaming keyboard */ 150 USB_QUIRK(CORSAIR, STRAFE, 0x0000, 0xffff, HQ_KBD_BOOTPROTO), 151 USB_QUIRK(CORSAIR, STRAFE2, 0x0000, 0xffff, HQ_KBD_BOOTPROTO), 152 /* Holtek USB gaming keyboard */ 153 USB_QUIRK(HOLTEK, F85, 0x0000, 0xffff, HQ_KBD_BOOTPROTO), 154 }; 155 #undef HID_QUIRK_VP 156 #undef USB_QUIRK 157 158 /* hidquirk.h exposes only HID_QUIRK_LIST macro when HQ() is defined */ 159 #define HQ(x) [HQ_##x] = "HQ_"#x 160 #include "hidquirk.h" 161 static const char *hidquirk_str[HID_QUIRK_MAX] = { HID_QUIRK_LIST() }; 162 #undef HQ 163 164 static hid_test_quirk_t hid_test_quirk_by_info; 165 166 /*------------------------------------------------------------------------* 167 * hidquirkstr 168 * 169 * This function converts an USB quirk code into a string. 170 *------------------------------------------------------------------------*/ 171 static const char * 172 hidquirkstr(uint16_t quirk) 173 { 174 return ((quirk < HID_QUIRK_MAX && hidquirk_str[quirk] != NULL) ? 175 hidquirk_str[quirk] : "HQ_UNKNOWN"); 176 } 177 178 /*------------------------------------------------------------------------* 179 * hid_strquirk 180 * 181 * This function converts a string into a HID quirk code. 182 * 183 * Returns: 184 * Less than HID_QUIRK_MAX: Quirk code 185 * Else: Quirk code not found 186 *------------------------------------------------------------------------*/ 187 static uint16_t 188 hid_strquirk(const char *str, size_t len) 189 { 190 const char *quirk; 191 uint16_t x; 192 193 for (x = 0; x != HID_QUIRK_MAX; x++) { 194 quirk = hidquirkstr(x); 195 if (strncmp(str, quirk, len) == 0 && 196 quirk[len] == 0) 197 break; 198 } 199 return (x); 200 } 201 202 /*------------------------------------------------------------------------* 203 * hid_test_quirk_by_info 204 * 205 * Returns: 206 * false: Quirk not found 207 * true: Quirk found 208 *------------------------------------------------------------------------*/ 209 bool 210 hid_test_quirk_by_info(const struct hid_device_info *info, uint16_t quirk) 211 { 212 uint16_t x; 213 uint16_t y; 214 215 if (quirk == HQ_NONE) 216 goto done; 217 218 mtx_lock(&hidquirk_mtx); 219 220 for (x = 0; x != HID_DEV_QUIRKS_MAX; x++) { 221 /* see if quirk information does not match */ 222 if ((hidquirks[x].bus != info->idBus) || 223 (hidquirks[x].vid != info->idVendor) || 224 (hidquirks[x].lo_rev > info->idVersion) || 225 (hidquirks[x].hi_rev < info->idVersion)) { 226 continue; 227 } 228 /* see if quirk only should match vendor ID */ 229 if (hidquirks[x].pid != info->idProduct) { 230 if (hidquirks[x].pid != 0) 231 continue; 232 233 for (y = 0; y != HID_SUB_QUIRKS_MAX; y++) { 234 if (hidquirks[x].quirks[y] == HQ_MATCH_VENDOR_ONLY) 235 break; 236 } 237 if (y == HID_SUB_QUIRKS_MAX) 238 continue; 239 } 240 /* lookup quirk */ 241 for (y = 0; y != HID_SUB_QUIRKS_MAX; y++) { 242 if (hidquirks[x].quirks[y] == quirk) { 243 mtx_unlock(&hidquirk_mtx); 244 DPRINTF("Found quirk '%s'.\n", hidquirkstr(quirk)); 245 return (true); 246 } 247 } 248 } 249 mtx_unlock(&hidquirk_mtx); 250 done: 251 return (false); /* no quirk match */ 252 } 253 254 static struct hidquirk_entry * 255 hidquirk_get_entry(uint16_t bus, uint16_t vid, uint16_t pid, 256 uint16_t lo_rev, uint16_t hi_rev, uint8_t do_alloc) 257 { 258 uint16_t x; 259 260 mtx_assert(&hidquirk_mtx, MA_OWNED); 261 262 if ((bus | vid | pid | lo_rev | hi_rev) == 0) { 263 /* all zero - special case */ 264 return (hidquirks + HID_DEV_QUIRKS_MAX - 1); 265 } 266 /* search for an existing entry */ 267 for (x = 0; x != HID_DEV_QUIRKS_MAX; x++) { 268 /* see if quirk information does not match */ 269 if ((hidquirks[x].bus != bus) || 270 (hidquirks[x].vid != vid) || 271 (hidquirks[x].pid != pid) || 272 (hidquirks[x].lo_rev != lo_rev) || 273 (hidquirks[x].hi_rev != hi_rev)) { 274 continue; 275 } 276 return (hidquirks + x); 277 } 278 279 if (do_alloc == 0) { 280 /* no match */ 281 return (NULL); 282 } 283 /* search for a free entry */ 284 for (x = 0; x != HID_DEV_QUIRKS_MAX; x++) { 285 /* see if quirk information does not match */ 286 if ((hidquirks[x].bus | 287 hidquirks[x].vid | 288 hidquirks[x].pid | 289 hidquirks[x].lo_rev | 290 hidquirks[x].hi_rev) != 0) { 291 continue; 292 } 293 hidquirks[x].bus = bus; 294 hidquirks[x].vid = vid; 295 hidquirks[x].pid = pid; 296 hidquirks[x].lo_rev = lo_rev; 297 hidquirks[x].hi_rev = hi_rev; 298 299 return (hidquirks + x); 300 } 301 302 /* no entry found */ 303 return (NULL); 304 } 305 306 /*------------------------------------------------------------------------* 307 * usb_quirk_strtou16 308 * 309 * Helper function to scan a 16-bit integer. 310 *------------------------------------------------------------------------*/ 311 static uint16_t 312 hidquirk_strtou16(const char **pptr, const char *name, const char *what) 313 { 314 unsigned long value; 315 char *end; 316 317 value = strtoul(*pptr, &end, 0); 318 if (value > 65535 || *pptr == end || (*end != ' ' && *end != '\t')) { 319 printf("%s: %s 16-bit %s value set to zero\n", 320 name, what, *end == 0 ? "incomplete" : "invalid"); 321 return (0); 322 } 323 *pptr = end + 1; 324 return ((uint16_t)value); 325 } 326 327 /*------------------------------------------------------------------------* 328 * usb_quirk_add_entry_from_str 329 * 330 * Add a USB quirk entry from string. 331 * "VENDOR PRODUCT LO_REV HI_REV QUIRK[,QUIRK[,...]]" 332 *------------------------------------------------------------------------*/ 333 static void 334 hidquirk_add_entry_from_str(const char *name, const char *env) 335 { 336 struct hidquirk_entry entry = { }; 337 struct hidquirk_entry *new; 338 uint16_t quirk_idx; 339 uint16_t quirk; 340 const char *end; 341 342 /* check for invalid environment variable */ 343 if (name == NULL || env == NULL) 344 return; 345 346 if (bootverbose) 347 printf("Adding HID QUIRK '%s' = '%s'\n", name, env); 348 349 /* parse device information */ 350 entry.bus = hidquirk_strtou16(&env, name, "Bus ID"); 351 entry.vid = hidquirk_strtou16(&env, name, "Vendor ID"); 352 entry.pid = hidquirk_strtou16(&env, name, "Product ID"); 353 entry.lo_rev = hidquirk_strtou16(&env, name, "Low revision"); 354 entry.hi_rev = hidquirk_strtou16(&env, name, "High revision"); 355 356 /* parse quirk information */ 357 quirk_idx = 0; 358 while (*env != 0 && quirk_idx != HID_SUB_QUIRKS_MAX) { 359 /* skip whitespace before quirks */ 360 while (*env == ' ' || *env == '\t') 361 env++; 362 363 /* look for quirk separation character */ 364 end = strchr(env, ','); 365 if (end == NULL) 366 end = env + strlen(env); 367 368 /* lookup quirk in string table */ 369 quirk = hid_strquirk(env, end - env); 370 if (quirk < HID_QUIRK_MAX) { 371 entry.quirks[quirk_idx++] = quirk; 372 } else { 373 printf("%s: unknown HID quirk '%.*s' (skipped)\n", 374 name, (int)(end - env), env); 375 } 376 env = end; 377 378 /* skip quirk delimiter, if any */ 379 if (*env != 0) 380 env++; 381 } 382 383 /* register quirk */ 384 if (quirk_idx != 0) { 385 if (*env != 0) { 386 printf("%s: Too many HID quirks, only %d allowed!\n", 387 name, HID_SUB_QUIRKS_MAX); 388 } 389 mtx_lock(&hidquirk_mtx); 390 new = hidquirk_get_entry(entry.bus, entry.vid, entry.pid, 391 entry.lo_rev, entry.hi_rev, 1); 392 if (new == NULL) 393 printf("%s: HID quirks table is full!\n", name); 394 else 395 memcpy(new->quirks, entry.quirks, sizeof(entry.quirks)); 396 mtx_unlock(&hidquirk_mtx); 397 } else { 398 printf("%s: No USB quirks found!\n", name); 399 } 400 } 401 402 static void 403 hidquirk_init(void *arg) 404 { 405 char envkey[sizeof(HID_QUIRK_ENVROOT) + 2]; /* 2 digits max, 0 to 99 */ 406 int i; 407 408 /* initialize mutex */ 409 mtx_init(&hidquirk_mtx, "HID quirk", NULL, MTX_DEF); 410 411 /* look for quirks defined by the environment variable */ 412 for (i = 0; i != 100; i++) { 413 snprintf(envkey, sizeof(envkey), HID_QUIRK_ENVROOT "%d", i); 414 415 /* Stop at first undefined var */ 416 if (!testenv(envkey)) 417 break; 418 419 /* parse environment variable */ 420 hidquirk_add_entry_from_str(envkey, kern_getenv(envkey)); 421 } 422 423 /* register our function */ 424 hid_test_quirk_p = &hid_test_quirk_by_info; 425 } 426 427 static void 428 hidquirk_uninit(void *arg) 429 { 430 hid_quirk_unload(arg); 431 432 /* destroy mutex */ 433 mtx_destroy(&hidquirk_mtx); 434 } 435 436 SYSINIT(hidquirk_init, SI_SUB_LOCK, SI_ORDER_FIRST, hidquirk_init, NULL); 437 SYSUNINIT(hidquirk_uninit, SI_SUB_LOCK, SI_ORDER_ANY, hidquirk_uninit, NULL); 438