1 /* $FreeBSD$ */ 2 /* $NetBSD: hid.c,v 1.17 2001/11/13 06:24:53 lukem Exp $ */ 3 /*- 4 * SPDX-License-Identifier: BSD-2-Clause-NetBSD 5 * 6 * Copyright (c) 1998 The NetBSD Foundation, Inc. 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to The NetBSD Foundation 10 * by Lennart Augustsson (lennart@augustsson.net) at 11 * Carlstedt Research & Technology. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "opt_hid.h" 36 37 #include <sys/param.h> 38 #include <sys/bus.h> 39 #include <sys/kdb.h> 40 #include <sys/kernel.h> 41 #include <sys/malloc.h> 42 #include <sys/module.h> 43 #include <sys/sysctl.h> 44 45 #define HID_DEBUG_VAR hid_debug 46 #include <dev/hid/hid.h> 47 #include <dev/hid/hidquirk.h> 48 49 #include "hid_if.h" 50 51 /* 52 * Define this unconditionally in case a kernel module is loaded that 53 * has been compiled with debugging options. 54 */ 55 int hid_debug = 0; 56 57 SYSCTL_NODE(_hw, OID_AUTO, hid, CTLFLAG_RW, 0, "HID debugging"); 58 SYSCTL_INT(_hw_hid, OID_AUTO, debug, CTLFLAG_RWTUN, 59 &hid_debug, 0, "Debug level"); 60 61 #ifdef HIDRAW_MAKE_UHID_ALIAS 62 devclass_t hidraw_devclass; 63 #endif 64 65 static void hid_clear_local(struct hid_item *); 66 static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize); 67 68 static hid_test_quirk_t hid_test_quirk_w; 69 hid_test_quirk_t *hid_test_quirk_p = &hid_test_quirk_w; 70 71 #define MAXUSAGE 64 72 #define MAXPUSH 4 73 #define MAXID 16 74 #define MAXLOCCNT 2048 75 76 struct hid_pos_data { 77 int32_t rid; 78 uint32_t pos; 79 }; 80 81 struct hid_data { 82 const uint8_t *start; 83 const uint8_t *end; 84 const uint8_t *p; 85 struct hid_item cur[MAXPUSH]; 86 struct hid_pos_data last_pos[MAXID]; 87 int32_t usages_min[MAXUSAGE]; 88 int32_t usages_max[MAXUSAGE]; 89 int32_t usage_last; /* last seen usage */ 90 uint32_t loc_size; /* last seen size */ 91 uint32_t loc_count; /* last seen count */ 92 uint32_t ncount; /* end usage item count */ 93 uint32_t icount; /* current usage item count */ 94 uint8_t kindset; /* we have 5 kinds so 8 bits are enough */ 95 uint8_t pushlevel; /* current pushlevel */ 96 uint8_t nusage; /* end "usages_min/max" index */ 97 uint8_t iusage; /* current "usages_min/max" index */ 98 uint8_t ousage; /* current "usages_min/max" offset */ 99 uint8_t susage; /* usage set flags */ 100 }; 101 102 /*------------------------------------------------------------------------* 103 * hid_clear_local 104 *------------------------------------------------------------------------*/ 105 static void 106 hid_clear_local(struct hid_item *c) 107 { 108 109 c->loc.count = 0; 110 c->loc.size = 0; 111 c->nusages = 0; 112 memset(c->usages, 0, sizeof(c->usages)); 113 c->usage_minimum = 0; 114 c->usage_maximum = 0; 115 c->designator_index = 0; 116 c->designator_minimum = 0; 117 c->designator_maximum = 0; 118 c->string_index = 0; 119 c->string_minimum = 0; 120 c->string_maximum = 0; 121 c->set_delimiter = 0; 122 } 123 124 static void 125 hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID) 126 { 127 uint8_t i; 128 129 /* check for same report ID - optimise */ 130 131 if (c->report_ID == next_rID) 132 return; 133 134 /* save current position for current rID */ 135 136 if (c->report_ID == 0) { 137 i = 0; 138 } else { 139 for (i = 1; i != MAXID; i++) { 140 if (s->last_pos[i].rid == c->report_ID) 141 break; 142 if (s->last_pos[i].rid == 0) 143 break; 144 } 145 } 146 if (i != MAXID) { 147 s->last_pos[i].rid = c->report_ID; 148 s->last_pos[i].pos = c->loc.pos; 149 } 150 151 /* store next report ID */ 152 153 c->report_ID = next_rID; 154 155 /* lookup last position for next rID */ 156 157 if (next_rID == 0) { 158 i = 0; 159 } else { 160 for (i = 1; i != MAXID; i++) { 161 if (s->last_pos[i].rid == next_rID) 162 break; 163 if (s->last_pos[i].rid == 0) 164 break; 165 } 166 } 167 if (i != MAXID) { 168 s->last_pos[i].rid = next_rID; 169 c->loc.pos = s->last_pos[i].pos; 170 } else { 171 DPRINTF("Out of RID entries, position is set to zero!\n"); 172 c->loc.pos = 0; 173 } 174 } 175 176 /*------------------------------------------------------------------------* 177 * hid_start_parse 178 *------------------------------------------------------------------------*/ 179 struct hid_data * 180 hid_start_parse(const void *d, hid_size_t len, int kindset) 181 { 182 struct hid_data *s; 183 184 if ((kindset-1) & kindset) { 185 DPRINTFN(0, "Only one bit can be " 186 "set in the kindset\n"); 187 return (NULL); 188 } 189 190 s = malloc(sizeof *s, M_TEMP, M_WAITOK | M_ZERO); 191 s->start = s->p = d; 192 s->end = ((const uint8_t *)d) + len; 193 s->kindset = kindset; 194 return (s); 195 } 196 197 /*------------------------------------------------------------------------* 198 * hid_end_parse 199 *------------------------------------------------------------------------*/ 200 void 201 hid_end_parse(struct hid_data *s) 202 { 203 if (s == NULL) 204 return; 205 206 free(s, M_TEMP); 207 } 208 209 /*------------------------------------------------------------------------* 210 * get byte from HID descriptor 211 *------------------------------------------------------------------------*/ 212 static uint8_t 213 hid_get_byte(struct hid_data *s, const uint16_t wSize) 214 { 215 const uint8_t *ptr; 216 uint8_t retval; 217 218 ptr = s->p; 219 220 /* check if end is reached */ 221 if (ptr == s->end) 222 return (0); 223 224 /* read out a byte */ 225 retval = *ptr; 226 227 /* check if data pointer can be advanced by "wSize" bytes */ 228 if ((s->end - ptr) < wSize) 229 ptr = s->end; 230 else 231 ptr += wSize; 232 233 /* update pointer */ 234 s->p = ptr; 235 236 return (retval); 237 } 238 239 /*------------------------------------------------------------------------* 240 * hid_get_item 241 *------------------------------------------------------------------------*/ 242 int 243 hid_get_item(struct hid_data *s, struct hid_item *h) 244 { 245 struct hid_item *c; 246 unsigned int bTag, bType, bSize; 247 uint32_t oldpos; 248 int32_t mask; 249 int32_t dval; 250 251 if (s == NULL) 252 return (0); 253 254 c = &s->cur[s->pushlevel]; 255 256 top: 257 /* check if there is an array of items */ 258 if (s->icount < s->ncount) { 259 /* get current usage */ 260 if (s->iusage < s->nusage) { 261 dval = s->usages_min[s->iusage] + s->ousage; 262 c->usage = dval; 263 s->usage_last = dval; 264 if (dval == s->usages_max[s->iusage]) { 265 s->iusage ++; 266 s->ousage = 0; 267 } else { 268 s->ousage ++; 269 } 270 } else { 271 DPRINTFN(1, "Using last usage\n"); 272 dval = s->usage_last; 273 } 274 c->nusages = 1; 275 /* array type HID item may have multiple usages */ 276 while ((c->flags & HIO_VARIABLE) == 0 && s->ousage == 0 && 277 s->iusage < s->nusage && c->nusages < HID_ITEM_MAXUSAGE) 278 c->usages[c->nusages++] = s->usages_min[s->iusage++]; 279 if ((c->flags & HIO_VARIABLE) == 0 && s->ousage == 0 && 280 s->iusage < s->nusage) 281 DPRINTFN(0, "HID_ITEM_MAXUSAGE should be increased " 282 "up to %hhu to parse the HID report descriptor\n", 283 s->nusage); 284 s->icount ++; 285 /* 286 * Only copy HID item, increment position and return 287 * if correct kindset! 288 */ 289 if (s->kindset & (1 << c->kind)) { 290 *h = *c; 291 DPRINTFN(1, "%u,%u,%u\n", h->loc.pos, 292 h->loc.size, h->loc.count); 293 c->loc.pos += c->loc.size * c->loc.count; 294 return (1); 295 } 296 } 297 298 /* reset state variables */ 299 s->icount = 0; 300 s->ncount = 0; 301 s->iusage = 0; 302 s->nusage = 0; 303 s->susage = 0; 304 s->ousage = 0; 305 hid_clear_local(c); 306 307 /* get next item */ 308 while (s->p != s->end) { 309 bSize = hid_get_byte(s, 1); 310 if (bSize == 0xfe) { 311 /* long item */ 312 bSize = hid_get_byte(s, 1); 313 bSize |= hid_get_byte(s, 1) << 8; 314 bTag = hid_get_byte(s, 1); 315 bType = 0xff; /* XXX what should it be */ 316 } else { 317 /* short item */ 318 bTag = bSize >> 4; 319 bType = (bSize >> 2) & 3; 320 bSize &= 3; 321 if (bSize == 3) 322 bSize = 4; 323 } 324 switch (bSize) { 325 case 0: 326 dval = 0; 327 mask = 0; 328 break; 329 case 1: 330 dval = (int8_t)hid_get_byte(s, 1); 331 mask = 0xFF; 332 break; 333 case 2: 334 dval = hid_get_byte(s, 1); 335 dval |= hid_get_byte(s, 1) << 8; 336 dval = (int16_t)dval; 337 mask = 0xFFFF; 338 break; 339 case 4: 340 dval = hid_get_byte(s, 1); 341 dval |= hid_get_byte(s, 1) << 8; 342 dval |= hid_get_byte(s, 1) << 16; 343 dval |= hid_get_byte(s, 1) << 24; 344 mask = 0xFFFFFFFF; 345 break; 346 default: 347 dval = hid_get_byte(s, bSize); 348 DPRINTFN(0, "bad length %u (data=0x%02x)\n", 349 bSize, dval); 350 continue; 351 } 352 353 switch (bType) { 354 case 0: /* Main */ 355 switch (bTag) { 356 case 8: /* Input */ 357 c->kind = hid_input; 358 ret: 359 c->flags = dval; 360 c->loc.count = s->loc_count; 361 c->loc.size = s->loc_size; 362 363 if (c->flags & HIO_VARIABLE) { 364 /* range check usage count */ 365 if (c->loc.count > MAXLOCCNT) { 366 DPRINTFN(0, "Number of " 367 "items(%u) truncated to %u\n", 368 (unsigned)(c->loc.count), 369 MAXLOCCNT); 370 s->ncount = MAXLOCCNT; 371 } else 372 s->ncount = c->loc.count; 373 374 /* 375 * The "top" loop will return 376 * one and one item: 377 */ 378 c->loc.count = 1; 379 } else { 380 s->ncount = 1; 381 } 382 goto top; 383 384 case 9: /* Output */ 385 c->kind = hid_output; 386 goto ret; 387 case 10: /* Collection */ 388 c->kind = hid_collection; 389 c->collection = dval; 390 c->collevel++; 391 c->usage = s->usage_last; 392 c->nusages = 1; 393 *h = *c; 394 return (1); 395 case 11: /* Feature */ 396 c->kind = hid_feature; 397 goto ret; 398 case 12: /* End collection */ 399 c->kind = hid_endcollection; 400 if (c->collevel == 0) { 401 DPRINTFN(0, "invalid end collection\n"); 402 return (0); 403 } 404 c->collevel--; 405 *h = *c; 406 return (1); 407 default: 408 DPRINTFN(0, "Main bTag=%d\n", bTag); 409 break; 410 } 411 break; 412 case 1: /* Global */ 413 switch (bTag) { 414 case 0: 415 c->_usage_page = dval << 16; 416 break; 417 case 1: 418 c->logical_minimum = dval; 419 break; 420 case 2: 421 c->logical_maximum = dval; 422 break; 423 case 3: 424 c->physical_minimum = dval; 425 break; 426 case 4: 427 c->physical_maximum = dval; 428 break; 429 case 5: 430 c->unit_exponent = dval; 431 break; 432 case 6: 433 c->unit = dval; 434 break; 435 case 7: 436 /* mask because value is unsigned */ 437 s->loc_size = dval & mask; 438 break; 439 case 8: 440 hid_switch_rid(s, c, dval & mask); 441 break; 442 case 9: 443 /* mask because value is unsigned */ 444 s->loc_count = dval & mask; 445 break; 446 case 10: /* Push */ 447 /* stop parsing, if invalid push level */ 448 if ((s->pushlevel + 1) >= MAXPUSH) { 449 DPRINTFN(0, "Cannot push item @ %d\n", s->pushlevel); 450 return (0); 451 } 452 s->pushlevel ++; 453 s->cur[s->pushlevel] = *c; 454 /* store size and count */ 455 c->loc.size = s->loc_size; 456 c->loc.count = s->loc_count; 457 /* update current item pointer */ 458 c = &s->cur[s->pushlevel]; 459 break; 460 case 11: /* Pop */ 461 /* stop parsing, if invalid push level */ 462 if (s->pushlevel == 0) { 463 DPRINTFN(0, "Cannot pop item @ 0\n"); 464 return (0); 465 } 466 s->pushlevel --; 467 /* preserve position */ 468 oldpos = c->loc.pos; 469 c = &s->cur[s->pushlevel]; 470 /* restore size and count */ 471 s->loc_size = c->loc.size; 472 s->loc_count = c->loc.count; 473 /* set default item location */ 474 c->loc.pos = oldpos; 475 c->loc.size = 0; 476 c->loc.count = 0; 477 break; 478 default: 479 DPRINTFN(0, "Global bTag=%d\n", bTag); 480 break; 481 } 482 break; 483 case 2: /* Local */ 484 switch (bTag) { 485 case 0: 486 if (bSize != 4) 487 dval = (dval & mask) | c->_usage_page; 488 489 /* set last usage, in case of a collection */ 490 s->usage_last = dval; 491 492 if (s->nusage < MAXUSAGE) { 493 s->usages_min[s->nusage] = dval; 494 s->usages_max[s->nusage] = dval; 495 s->nusage ++; 496 } else { 497 DPRINTFN(0, "max usage reached\n"); 498 } 499 500 /* clear any pending usage sets */ 501 s->susage = 0; 502 break; 503 case 1: 504 s->susage |= 1; 505 506 if (bSize != 4) 507 dval = (dval & mask) | c->_usage_page; 508 c->usage_minimum = dval; 509 510 goto check_set; 511 case 2: 512 s->susage |= 2; 513 514 if (bSize != 4) 515 dval = (dval & mask) | c->_usage_page; 516 c->usage_maximum = dval; 517 518 check_set: 519 if (s->susage != 3) 520 break; 521 522 /* sanity check */ 523 if ((s->nusage < MAXUSAGE) && 524 (c->usage_minimum <= c->usage_maximum)) { 525 /* add usage range */ 526 s->usages_min[s->nusage] = 527 c->usage_minimum; 528 s->usages_max[s->nusage] = 529 c->usage_maximum; 530 s->nusage ++; 531 } else { 532 DPRINTFN(0, "Usage set dropped\n"); 533 } 534 s->susage = 0; 535 break; 536 case 3: 537 c->designator_index = dval; 538 break; 539 case 4: 540 c->designator_minimum = dval; 541 break; 542 case 5: 543 c->designator_maximum = dval; 544 break; 545 case 7: 546 c->string_index = dval; 547 break; 548 case 8: 549 c->string_minimum = dval; 550 break; 551 case 9: 552 c->string_maximum = dval; 553 break; 554 case 10: 555 c->set_delimiter = dval; 556 break; 557 default: 558 DPRINTFN(0, "Local bTag=%d\n", bTag); 559 break; 560 } 561 break; 562 default: 563 DPRINTFN(0, "default bType=%d\n", bType); 564 break; 565 } 566 } 567 return (0); 568 } 569 570 /*------------------------------------------------------------------------* 571 * hid_report_size 572 *------------------------------------------------------------------------*/ 573 int 574 hid_report_size(const void *buf, hid_size_t len, enum hid_kind k, uint8_t id) 575 { 576 struct hid_data *d; 577 struct hid_item h; 578 uint32_t temp; 579 uint32_t hpos; 580 uint32_t lpos; 581 int report_id = 0; 582 583 hpos = 0; 584 lpos = 0xFFFFFFFF; 585 586 for (d = hid_start_parse(buf, len, 1 << k); hid_get_item(d, &h);) { 587 if (h.kind == k && h.report_ID == id) { 588 /* compute minimum */ 589 if (lpos > h.loc.pos) 590 lpos = h.loc.pos; 591 /* compute end position */ 592 temp = h.loc.pos + (h.loc.size * h.loc.count); 593 /* compute maximum */ 594 if (hpos < temp) 595 hpos = temp; 596 if (h.report_ID != 0) 597 report_id = 1; 598 } 599 } 600 hid_end_parse(d); 601 602 /* safety check - can happen in case of currupt descriptors */ 603 if (lpos > hpos) 604 temp = 0; 605 else 606 temp = hpos - lpos; 607 608 /* return length in bytes rounded up */ 609 return ((temp + 7) / 8 + report_id); 610 } 611 612 int 613 hid_report_size_max(const void *buf, hid_size_t len, enum hid_kind k, 614 uint8_t *id) 615 { 616 struct hid_data *d; 617 struct hid_item h; 618 uint32_t temp; 619 uint32_t hpos; 620 uint32_t lpos; 621 uint8_t any_id; 622 623 any_id = 0; 624 hpos = 0; 625 lpos = 0xFFFFFFFF; 626 627 for (d = hid_start_parse(buf, len, 1 << k); hid_get_item(d, &h);) { 628 if (h.kind == k) { 629 /* check for ID-byte presence */ 630 if ((h.report_ID != 0) && !any_id) { 631 if (id != NULL) 632 *id = h.report_ID; 633 any_id = 1; 634 } 635 /* compute minimum */ 636 if (lpos > h.loc.pos) 637 lpos = h.loc.pos; 638 /* compute end position */ 639 temp = h.loc.pos + (h.loc.size * h.loc.count); 640 /* compute maximum */ 641 if (hpos < temp) 642 hpos = temp; 643 } 644 } 645 hid_end_parse(d); 646 647 /* safety check - can happen in case of currupt descriptors */ 648 if (lpos > hpos) 649 temp = 0; 650 else 651 temp = hpos - lpos; 652 653 /* check for ID byte */ 654 if (any_id) 655 temp += 8; 656 else if (id != NULL) 657 *id = 0; 658 659 /* return length in bytes rounded up */ 660 return ((temp + 7) / 8); 661 } 662 663 /*------------------------------------------------------------------------* 664 * hid_locate 665 *------------------------------------------------------------------------*/ 666 int 667 hid_locate(const void *desc, hid_size_t size, int32_t u, enum hid_kind k, 668 uint8_t index, struct hid_location *loc, uint32_t *flags, uint8_t *id) 669 { 670 struct hid_data *d; 671 struct hid_item h; 672 int i; 673 674 for (d = hid_start_parse(desc, size, 1 << k); hid_get_item(d, &h);) { 675 for (i = 0; i < h.nusages; i++) { 676 if (h.kind == k && h.usages[i] == u) { 677 if (index--) 678 break; 679 if (loc != NULL) 680 *loc = h.loc; 681 if (flags != NULL) 682 *flags = h.flags; 683 if (id != NULL) 684 *id = h.report_ID; 685 hid_end_parse(d); 686 return (1); 687 } 688 } 689 } 690 if (loc != NULL) 691 loc->size = 0; 692 if (flags != NULL) 693 *flags = 0; 694 if (id != NULL) 695 *id = 0; 696 hid_end_parse(d); 697 return (0); 698 } 699 700 /*------------------------------------------------------------------------* 701 * hid_get_data 702 *------------------------------------------------------------------------*/ 703 static uint32_t 704 hid_get_data_sub(const uint8_t *buf, hid_size_t len, struct hid_location *loc, 705 int is_signed) 706 { 707 uint32_t hpos = loc->pos; 708 uint32_t hsize = loc->size; 709 uint32_t data; 710 uint32_t rpos; 711 uint8_t n; 712 713 DPRINTFN(11, "hid_get_data: loc %d/%d\n", hpos, hsize); 714 715 /* Range check and limit */ 716 if (hsize == 0) 717 return (0); 718 if (hsize > 32) 719 hsize = 32; 720 721 /* Get data in a safe way */ 722 data = 0; 723 rpos = (hpos / 8); 724 n = (hsize + 7) / 8; 725 rpos += n; 726 while (n--) { 727 rpos--; 728 if (rpos < len) 729 data |= buf[rpos] << (8 * n); 730 } 731 732 /* Correctly shift down data */ 733 data = (data >> (hpos % 8)); 734 n = 32 - hsize; 735 736 /* Mask and sign extend in one */ 737 if (is_signed != 0) 738 data = (int32_t)((int32_t)data << n) >> n; 739 else 740 data = (uint32_t)((uint32_t)data << n) >> n; 741 742 DPRINTFN(11, "hid_get_data: loc %d/%d = %lu\n", 743 loc->pos, loc->size, (long)data); 744 return (data); 745 } 746 747 int32_t 748 hid_get_data(const uint8_t *buf, hid_size_t len, struct hid_location *loc) 749 { 750 return (hid_get_data_sub(buf, len, loc, 1)); 751 } 752 753 uint32_t 754 hid_get_udata(const uint8_t *buf, hid_size_t len, struct hid_location *loc) 755 { 756 return (hid_get_data_sub(buf, len, loc, 0)); 757 } 758 759 /*------------------------------------------------------------------------* 760 * hid_put_data 761 *------------------------------------------------------------------------*/ 762 void 763 hid_put_udata(uint8_t *buf, hid_size_t len, 764 struct hid_location *loc, unsigned int value) 765 { 766 uint32_t hpos = loc->pos; 767 uint32_t hsize = loc->size; 768 uint64_t data; 769 uint64_t mask; 770 uint32_t rpos; 771 uint8_t n; 772 773 DPRINTFN(11, "hid_put_data: loc %d/%d = %u\n", hpos, hsize, value); 774 775 /* Range check and limit */ 776 if (hsize == 0) 777 return; 778 if (hsize > 32) 779 hsize = 32; 780 781 /* Put data in a safe way */ 782 rpos = (hpos / 8); 783 n = (hsize + 7) / 8; 784 data = ((uint64_t)value) << (hpos % 8); 785 mask = ((1ULL << hsize) - 1ULL) << (hpos % 8); 786 rpos += n; 787 while (n--) { 788 rpos--; 789 if (rpos < len) { 790 buf[rpos] &= ~(mask >> (8 * n)); 791 buf[rpos] |= (data >> (8 * n)); 792 } 793 } 794 } 795 796 /*------------------------------------------------------------------------* 797 * hid_is_collection 798 *------------------------------------------------------------------------*/ 799 int 800 hid_is_collection(const void *desc, hid_size_t size, int32_t usage) 801 { 802 struct hid_data *hd; 803 struct hid_item hi; 804 int err; 805 806 hd = hid_start_parse(desc, size, hid_input); 807 if (hd == NULL) 808 return (0); 809 810 while ((err = hid_get_item(hd, &hi))) { 811 if (hi.kind == hid_collection && 812 hi.usage == usage) 813 break; 814 } 815 hid_end_parse(hd); 816 return (err); 817 } 818 819 /*------------------------------------------------------------------------* 820 * calculate HID item resolution. unit/mm for distances, unit/rad for angles 821 *------------------------------------------------------------------------*/ 822 int32_t 823 hid_item_resolution(struct hid_item *hi) 824 { 825 /* 826 * hid unit scaling table according to HID Usage Table Review 827 * Request 39 Tbl 17 http://www.usb.org/developers/hidpage/HUTRR39b.pdf 828 */ 829 static const int64_t scale[0x10][2] = { 830 [0x00] = { 1, 1 }, 831 [0x01] = { 1, 10 }, 832 [0x02] = { 1, 100 }, 833 [0x03] = { 1, 1000 }, 834 [0x04] = { 1, 10000 }, 835 [0x05] = { 1, 100000 }, 836 [0x06] = { 1, 1000000 }, 837 [0x07] = { 1, 10000000 }, 838 [0x08] = { 100000000, 1 }, 839 [0x09] = { 10000000, 1 }, 840 [0x0A] = { 1000000, 1 }, 841 [0x0B] = { 100000, 1 }, 842 [0x0C] = { 10000, 1 }, 843 [0x0D] = { 1000, 1 }, 844 [0x0E] = { 100, 1 }, 845 [0x0F] = { 10, 1 }, 846 }; 847 int64_t logical_size; 848 int64_t physical_size; 849 int64_t multiplier; 850 int64_t divisor; 851 int64_t resolution; 852 853 switch (hi->unit) { 854 case HUM_CENTIMETER: 855 multiplier = 1; 856 divisor = 10; 857 break; 858 case HUM_INCH: 859 case HUM_INCH_EGALAX: 860 multiplier = 10; 861 divisor = 254; 862 break; 863 case HUM_RADIAN: 864 multiplier = 1; 865 divisor = 1; 866 break; 867 case HUM_DEGREE: 868 multiplier = 573; 869 divisor = 10; 870 break; 871 default: 872 return (0); 873 } 874 875 if ((hi->logical_maximum <= hi->logical_minimum) || 876 (hi->physical_maximum <= hi->physical_minimum) || 877 (hi->unit_exponent < 0) || (hi->unit_exponent >= nitems(scale))) 878 return (0); 879 880 logical_size = (int64_t)hi->logical_maximum - 881 (int64_t)hi->logical_minimum; 882 physical_size = (int64_t)hi->physical_maximum - 883 (int64_t)hi->physical_minimum; 884 /* Round to ceiling */ 885 resolution = logical_size * multiplier * scale[hi->unit_exponent][0] / 886 (physical_size * divisor * scale[hi->unit_exponent][1]); 887 888 if (resolution > INT32_MAX) 889 return (0); 890 891 return (resolution); 892 } 893 894 /*------------------------------------------------------------------------* 895 * hid_is_mouse 896 * 897 * This function will decide if a USB descriptor belongs to a USB mouse. 898 * 899 * Return values: 900 * Zero: Not a USB mouse. 901 * Else: Is a USB mouse. 902 *------------------------------------------------------------------------*/ 903 int 904 hid_is_mouse(const void *d_ptr, uint16_t d_len) 905 { 906 struct hid_data *hd; 907 struct hid_item hi; 908 int mdepth; 909 int found; 910 911 hd = hid_start_parse(d_ptr, d_len, 1 << hid_input); 912 if (hd == NULL) 913 return (0); 914 915 mdepth = 0; 916 found = 0; 917 918 while (hid_get_item(hd, &hi)) { 919 switch (hi.kind) { 920 case hid_collection: 921 if (mdepth != 0) 922 mdepth++; 923 else if (hi.collection == 1 && 924 hi.usage == 925 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)) 926 mdepth++; 927 break; 928 case hid_endcollection: 929 if (mdepth != 0) 930 mdepth--; 931 break; 932 case hid_input: 933 if (mdepth == 0) 934 break; 935 if (hi.usage == 936 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X) && 937 (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE) 938 found++; 939 if (hi.usage == 940 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y) && 941 (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE) 942 found++; 943 break; 944 default: 945 break; 946 } 947 } 948 hid_end_parse(hd); 949 return (found); 950 } 951 952 /*------------------------------------------------------------------------* 953 * hid_is_keyboard 954 * 955 * This function will decide if a USB descriptor belongs to a USB keyboard. 956 * 957 * Return values: 958 * Zero: Not a USB keyboard. 959 * Else: Is a USB keyboard. 960 *------------------------------------------------------------------------*/ 961 int 962 hid_is_keyboard(const void *d_ptr, uint16_t d_len) 963 { 964 if (hid_is_collection(d_ptr, d_len, 965 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD))) 966 return (1); 967 return (0); 968 } 969 970 /*------------------------------------------------------------------------* 971 * hid_test_quirk - test a device for a given quirk 972 * 973 * Return values: 974 * false: The HID device does not have the given quirk. 975 * true: The HID device has the given quirk. 976 *------------------------------------------------------------------------*/ 977 bool 978 hid_test_quirk(const struct hid_device_info *dev_info, uint16_t quirk) 979 { 980 bool found; 981 uint8_t x; 982 983 if (quirk == HQ_NONE) 984 return (false); 985 986 /* search the automatic per device quirks first */ 987 for (x = 0; x != HID_MAX_AUTO_QUIRK; x++) { 988 if (dev_info->autoQuirk[x] == quirk) 989 return (true); 990 } 991 992 /* search global quirk table, if any */ 993 found = (hid_test_quirk_p) (dev_info, quirk); 994 995 return (found); 996 } 997 998 static bool 999 hid_test_quirk_w(const struct hid_device_info *dev_info, uint16_t quirk) 1000 { 1001 return (false); /* no match */ 1002 } 1003 1004 int 1005 hid_add_dynamic_quirk(struct hid_device_info *dev_info, uint16_t quirk) 1006 { 1007 uint8_t x; 1008 1009 for (x = 0; x != HID_MAX_AUTO_QUIRK; x++) { 1010 if (dev_info->autoQuirk[x] == 0 || 1011 dev_info->autoQuirk[x] == quirk) { 1012 dev_info->autoQuirk[x] = quirk; 1013 return (0); /* success */ 1014 } 1015 } 1016 return (ENOSPC); 1017 } 1018 1019 void 1020 hid_quirk_unload(void *arg) 1021 { 1022 /* reset function pointer */ 1023 hid_test_quirk_p = &hid_test_quirk_w; 1024 #ifdef NOT_YET 1025 hidquirk_ioctl_p = &hidquirk_ioctl_w; 1026 #endif 1027 1028 /* wait for CPU to exit the loaded functions, if any */ 1029 1030 /* XXX this is a tradeoff */ 1031 1032 pause("WAIT", hz); 1033 } 1034 1035 int 1036 hid_get_rdesc(device_t dev, void *data, hid_size_t len) 1037 { 1038 return (HID_GET_RDESC(device_get_parent(dev), data, len)); 1039 } 1040 1041 int 1042 hid_read(device_t dev, void *data, hid_size_t maxlen, hid_size_t *actlen) 1043 { 1044 return (HID_READ(device_get_parent(dev), data, maxlen, actlen)); 1045 } 1046 1047 int 1048 hid_write(device_t dev, const void *data, hid_size_t len) 1049 { 1050 return (HID_WRITE(device_get_parent(dev), data, len)); 1051 } 1052 1053 int 1054 hid_get_report(device_t dev, void *data, hid_size_t maxlen, hid_size_t *actlen, 1055 uint8_t type, uint8_t id) 1056 { 1057 return (HID_GET_REPORT(device_get_parent(dev), data, maxlen, actlen, 1058 type, id)); 1059 } 1060 1061 int 1062 hid_set_report(device_t dev, const void *data, hid_size_t len, uint8_t type, 1063 uint8_t id) 1064 { 1065 return (HID_SET_REPORT(device_get_parent(dev), data, len, type, id)); 1066 } 1067 1068 int 1069 hid_set_idle(device_t dev, uint16_t duration, uint8_t id) 1070 { 1071 return (HID_SET_IDLE(device_get_parent(dev), duration, id)); 1072 } 1073 1074 int 1075 hid_set_protocol(device_t dev, uint16_t protocol) 1076 { 1077 return (HID_SET_PROTOCOL(device_get_parent(dev), protocol)); 1078 } 1079 1080 int 1081 hid_ioctl(device_t dev, unsigned long cmd, uintptr_t data) 1082 { 1083 return (HID_IOCTL(device_get_parent(dev), cmd, data)); 1084 } 1085 1086 MODULE_VERSION(hid, 1); 1087