1 /* $FreeBSD$ */ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause 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 /* Quirk for Kensington Slimblade Trackball */ 155 USB_QUIRK(KENSINGTON, SLIMBLADE, 0x0000, 0xffff, HQ_MS_VENDOR_BTN), 156 }; 157 #undef HID_QUIRK_VP 158 #undef USB_QUIRK 159 160 /* hidquirk.h exposes only HID_QUIRK_LIST macro when HQ() is defined */ 161 #define HQ(x) [HQ_##x] = "HQ_"#x 162 #include "hidquirk.h" 163 static const char *hidquirk_str[HID_QUIRK_MAX] = { HID_QUIRK_LIST() }; 164 #undef HQ 165 166 static hid_test_quirk_t hid_test_quirk_by_info; 167 168 /*------------------------------------------------------------------------* 169 * hidquirkstr 170 * 171 * This function converts an USB quirk code into a string. 172 *------------------------------------------------------------------------*/ 173 static const char * 174 hidquirkstr(uint16_t quirk) 175 { 176 return ((quirk < HID_QUIRK_MAX && hidquirk_str[quirk] != NULL) ? 177 hidquirk_str[quirk] : "HQ_UNKNOWN"); 178 } 179 180 /*------------------------------------------------------------------------* 181 * hid_strquirk 182 * 183 * This function converts a string into a HID quirk code. 184 * 185 * Returns: 186 * Less than HID_QUIRK_MAX: Quirk code 187 * Else: Quirk code not found 188 *------------------------------------------------------------------------*/ 189 static uint16_t 190 hid_strquirk(const char *str, size_t len) 191 { 192 const char *quirk; 193 uint16_t x; 194 195 for (x = 0; x != HID_QUIRK_MAX; x++) { 196 quirk = hidquirkstr(x); 197 if (strncmp(str, quirk, len) == 0 && 198 quirk[len] == 0) 199 break; 200 } 201 return (x); 202 } 203 204 /*------------------------------------------------------------------------* 205 * hid_test_quirk_by_info 206 * 207 * Returns: 208 * false: Quirk not found 209 * true: Quirk found 210 *------------------------------------------------------------------------*/ 211 bool 212 hid_test_quirk_by_info(const struct hid_device_info *info, uint16_t quirk) 213 { 214 uint16_t x; 215 uint16_t y; 216 217 if (quirk == HQ_NONE) 218 goto done; 219 220 mtx_lock(&hidquirk_mtx); 221 222 for (x = 0; x != HID_DEV_QUIRKS_MAX; x++) { 223 /* see if quirk information does not match */ 224 if ((hidquirks[x].bus != info->idBus) || 225 (hidquirks[x].vid != info->idVendor) || 226 (hidquirks[x].lo_rev > info->idVersion) || 227 (hidquirks[x].hi_rev < info->idVersion)) { 228 continue; 229 } 230 /* see if quirk only should match vendor ID */ 231 if (hidquirks[x].pid != info->idProduct) { 232 if (hidquirks[x].pid != 0) 233 continue; 234 235 for (y = 0; y != HID_SUB_QUIRKS_MAX; y++) { 236 if (hidquirks[x].quirks[y] == HQ_MATCH_VENDOR_ONLY) 237 break; 238 } 239 if (y == HID_SUB_QUIRKS_MAX) 240 continue; 241 } 242 /* lookup quirk */ 243 for (y = 0; y != HID_SUB_QUIRKS_MAX; y++) { 244 if (hidquirks[x].quirks[y] == quirk) { 245 mtx_unlock(&hidquirk_mtx); 246 DPRINTF("Found quirk '%s'.\n", hidquirkstr(quirk)); 247 return (true); 248 } 249 } 250 } 251 mtx_unlock(&hidquirk_mtx); 252 done: 253 return (false); /* no quirk match */ 254 } 255 256 static struct hidquirk_entry * 257 hidquirk_get_entry(uint16_t bus, uint16_t vid, uint16_t pid, 258 uint16_t lo_rev, uint16_t hi_rev, uint8_t do_alloc) 259 { 260 uint16_t x; 261 262 mtx_assert(&hidquirk_mtx, MA_OWNED); 263 264 if ((bus | vid | pid | lo_rev | hi_rev) == 0) { 265 /* all zero - special case */ 266 return (hidquirks + HID_DEV_QUIRKS_MAX - 1); 267 } 268 /* search for an existing entry */ 269 for (x = 0; x != HID_DEV_QUIRKS_MAX; x++) { 270 /* see if quirk information does not match */ 271 if ((hidquirks[x].bus != bus) || 272 (hidquirks[x].vid != vid) || 273 (hidquirks[x].pid != pid) || 274 (hidquirks[x].lo_rev != lo_rev) || 275 (hidquirks[x].hi_rev != hi_rev)) { 276 continue; 277 } 278 return (hidquirks + x); 279 } 280 281 if (do_alloc == 0) { 282 /* no match */ 283 return (NULL); 284 } 285 /* search for a free entry */ 286 for (x = 0; x != HID_DEV_QUIRKS_MAX; x++) { 287 /* see if quirk information does not match */ 288 if ((hidquirks[x].bus | 289 hidquirks[x].vid | 290 hidquirks[x].pid | 291 hidquirks[x].lo_rev | 292 hidquirks[x].hi_rev) != 0) { 293 continue; 294 } 295 hidquirks[x].bus = bus; 296 hidquirks[x].vid = vid; 297 hidquirks[x].pid = pid; 298 hidquirks[x].lo_rev = lo_rev; 299 hidquirks[x].hi_rev = hi_rev; 300 301 return (hidquirks + x); 302 } 303 304 /* no entry found */ 305 return (NULL); 306 } 307 308 /*------------------------------------------------------------------------* 309 * usb_quirk_strtou16 310 * 311 * Helper function to scan a 16-bit integer. 312 *------------------------------------------------------------------------*/ 313 static uint16_t 314 hidquirk_strtou16(const char **pptr, const char *name, const char *what) 315 { 316 unsigned long value; 317 char *end; 318 319 value = strtoul(*pptr, &end, 0); 320 if (value > 65535 || *pptr == end || (*end != ' ' && *end != '\t')) { 321 printf("%s: %s 16-bit %s value set to zero\n", 322 name, what, *end == 0 ? "incomplete" : "invalid"); 323 return (0); 324 } 325 *pptr = end + 1; 326 return ((uint16_t)value); 327 } 328 329 /*------------------------------------------------------------------------* 330 * usb_quirk_add_entry_from_str 331 * 332 * Add a USB quirk entry from string. 333 * "VENDOR PRODUCT LO_REV HI_REV QUIRK[,QUIRK[,...]]" 334 *------------------------------------------------------------------------*/ 335 static void 336 hidquirk_add_entry_from_str(const char *name, const char *env) 337 { 338 struct hidquirk_entry entry = { }; 339 struct hidquirk_entry *new; 340 uint16_t quirk_idx; 341 uint16_t quirk; 342 const char *end; 343 344 /* check for invalid environment variable */ 345 if (name == NULL || env == NULL) 346 return; 347 348 if (bootverbose) 349 printf("Adding HID QUIRK '%s' = '%s'\n", name, env); 350 351 /* parse device information */ 352 entry.bus = hidquirk_strtou16(&env, name, "Bus ID"); 353 entry.vid = hidquirk_strtou16(&env, name, "Vendor ID"); 354 entry.pid = hidquirk_strtou16(&env, name, "Product ID"); 355 entry.lo_rev = hidquirk_strtou16(&env, name, "Low revision"); 356 entry.hi_rev = hidquirk_strtou16(&env, name, "High revision"); 357 358 /* parse quirk information */ 359 quirk_idx = 0; 360 while (*env != 0 && quirk_idx != HID_SUB_QUIRKS_MAX) { 361 /* skip whitespace before quirks */ 362 while (*env == ' ' || *env == '\t') 363 env++; 364 365 /* look for quirk separation character */ 366 end = strchr(env, ','); 367 if (end == NULL) 368 end = env + strlen(env); 369 370 /* lookup quirk in string table */ 371 quirk = hid_strquirk(env, end - env); 372 if (quirk < HID_QUIRK_MAX) { 373 entry.quirks[quirk_idx++] = quirk; 374 } else { 375 printf("%s: unknown HID quirk '%.*s' (skipped)\n", 376 name, (int)(end - env), env); 377 } 378 env = end; 379 380 /* skip quirk delimiter, if any */ 381 if (*env != 0) 382 env++; 383 } 384 385 /* register quirk */ 386 if (quirk_idx != 0) { 387 if (*env != 0) { 388 printf("%s: Too many HID quirks, only %d allowed!\n", 389 name, HID_SUB_QUIRKS_MAX); 390 } 391 mtx_lock(&hidquirk_mtx); 392 new = hidquirk_get_entry(entry.bus, entry.vid, entry.pid, 393 entry.lo_rev, entry.hi_rev, 1); 394 if (new == NULL) 395 printf("%s: HID quirks table is full!\n", name); 396 else 397 memcpy(new->quirks, entry.quirks, sizeof(entry.quirks)); 398 mtx_unlock(&hidquirk_mtx); 399 } else { 400 printf("%s: No USB quirks found!\n", name); 401 } 402 } 403 404 static void 405 hidquirk_init(void *arg) 406 { 407 char envkey[sizeof(HID_QUIRK_ENVROOT) + 2]; /* 2 digits max, 0 to 99 */ 408 int i; 409 410 /* initialize mutex */ 411 mtx_init(&hidquirk_mtx, "HID quirk", NULL, MTX_DEF); 412 413 /* look for quirks defined by the environment variable */ 414 for (i = 0; i != 100; i++) { 415 snprintf(envkey, sizeof(envkey), HID_QUIRK_ENVROOT "%d", i); 416 417 /* Stop at first undefined var */ 418 if (!testenv(envkey)) 419 break; 420 421 /* parse environment variable */ 422 hidquirk_add_entry_from_str(envkey, kern_getenv(envkey)); 423 } 424 425 /* register our function */ 426 hid_test_quirk_p = &hid_test_quirk_by_info; 427 } 428 429 static void 430 hidquirk_uninit(void *arg) 431 { 432 hid_quirk_unload(arg); 433 434 /* destroy mutex */ 435 mtx_destroy(&hidquirk_mtx); 436 } 437 438 SYSINIT(hidquirk_init, SI_SUB_LOCK, SI_ORDER_FIRST, hidquirk_init, NULL); 439 SYSUNINIT(hidquirk_uninit, SI_SUB_LOCK, SI_ORDER_ANY, hidquirk_uninit, NULL); 440