1 /* $NetBSD: hid.c,v 1.17 2001/11/13 06:24:53 lukem Exp $ */ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause 4 * 5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Lennart Augustsson (lennart@augustsson.net) at 10 * Carlstedt Research & Technology. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "opt_hid.h" 35 36 #include <sys/param.h> 37 #include <sys/bus.h> 38 #include <sys/kdb.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/module.h> 42 #include <sys/sysctl.h> 43 44 #define HID_DEBUG_VAR hid_debug 45 #include <dev/hid/hid.h> 46 #include <dev/hid/hidquirk.h> 47 48 #include "hid_if.h" 49 50 /* 51 * Define this unconditionally in case a kernel module is loaded that 52 * has been compiled with debugging options. 53 */ 54 int hid_debug = 0; 55 56 SYSCTL_NODE(_hw, OID_AUTO, hid, CTLFLAG_RW, 0, "HID debugging"); 57 SYSCTL_INT(_hw_hid, OID_AUTO, debug, CTLFLAG_RWTUN, 58 &hid_debug, 0, "Debug level"); 59 60 static void hid_clear_local(struct hid_item *); 61 static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize); 62 63 static hid_test_quirk_t hid_test_quirk_w; 64 hid_test_quirk_t *hid_test_quirk_p = &hid_test_quirk_w; 65 66 #define MAXUSAGE 64 67 #define MAXPUSH 4 68 #define MAXID 16 69 #define MAXLOCCNT 2048 70 71 struct hid_pos_data { 72 uint32_t rid; 73 uint32_t pos; 74 }; 75 76 struct hid_data { 77 const uint8_t *start; 78 const uint8_t *end; 79 const uint8_t *p; 80 struct hid_item cur[MAXPUSH]; 81 struct hid_pos_data last_pos[MAXID]; 82 uint32_t usages_min[MAXUSAGE]; 83 uint32_t usages_max[MAXUSAGE]; 84 uint32_t usage_last; /* last seen usage */ 85 uint32_t loc_size; /* last seen size */ 86 uint32_t loc_count; /* last seen count */ 87 uint32_t ncount; /* end usage item count */ 88 uint32_t icount; /* current usage item count */ 89 uint8_t kindset; /* we have 5 kinds so 8 bits are enough */ 90 uint8_t pushlevel; /* current pushlevel */ 91 uint8_t nusage; /* end "usages_min/max" index */ 92 uint8_t iusage; /* current "usages_min/max" index */ 93 uint8_t ousage; /* current "usages_min/max" offset */ 94 uint8_t susage; /* usage set flags */ 95 }; 96 97 /*------------------------------------------------------------------------* 98 * hid_clear_local 99 *------------------------------------------------------------------------*/ 100 static void 101 hid_clear_local(struct hid_item *c) 102 { 103 104 c->loc.count = 0; 105 c->loc.size = 0; 106 c->nusages = 0; 107 memset(c->usages, 0, sizeof(c->usages)); 108 c->usage_minimum = 0; 109 c->usage_maximum = 0; 110 c->designator_index = 0; 111 c->designator_minimum = 0; 112 c->designator_maximum = 0; 113 c->string_index = 0; 114 c->string_minimum = 0; 115 c->string_maximum = 0; 116 c->set_delimiter = 0; 117 } 118 119 static void 120 hid_switch_rid(struct hid_data *s, struct hid_item *c, uint32_t next_rID) 121 { 122 uint8_t i; 123 124 /* check for same report ID - optimise */ 125 126 if (c->report_ID == next_rID) 127 return; 128 129 /* save current position for current rID */ 130 131 if (c->report_ID == 0) { 132 i = 0; 133 } else { 134 for (i = 1; i != MAXID; i++) { 135 if (s->last_pos[i].rid == c->report_ID) 136 break; 137 if (s->last_pos[i].rid == 0) 138 break; 139 } 140 } 141 if (i != MAXID) { 142 s->last_pos[i].rid = c->report_ID; 143 s->last_pos[i].pos = c->loc.pos; 144 } 145 146 /* store next report ID */ 147 148 c->report_ID = next_rID; 149 150 /* lookup last position for next rID */ 151 152 if (next_rID == 0) { 153 i = 0; 154 } else { 155 for (i = 1; i != MAXID; i++) { 156 if (s->last_pos[i].rid == next_rID) 157 break; 158 if (s->last_pos[i].rid == 0) 159 break; 160 } 161 } 162 if (i != MAXID) { 163 s->last_pos[i].rid = next_rID; 164 c->loc.pos = s->last_pos[i].pos; 165 } else { 166 DPRINTF("Out of RID entries, position is set to zero!\n"); 167 c->loc.pos = 0; 168 } 169 } 170 171 /*------------------------------------------------------------------------* 172 * hid_start_parse 173 *------------------------------------------------------------------------*/ 174 struct hid_data * 175 hid_start_parse(const void *d, hid_size_t len, int kindset) 176 { 177 struct hid_data *s; 178 179 if ((kindset-1) & kindset) { 180 DPRINTFN(0, "Only one bit can be " 181 "set in the kindset\n"); 182 return (NULL); 183 } 184 185 s = malloc(sizeof *s, M_TEMP, M_WAITOK | M_ZERO); 186 s->start = s->p = d; 187 s->end = ((const uint8_t *)d) + len; 188 s->kindset = kindset; 189 return (s); 190 } 191 192 /*------------------------------------------------------------------------* 193 * hid_end_parse 194 *------------------------------------------------------------------------*/ 195 void 196 hid_end_parse(struct hid_data *s) 197 { 198 if (s == NULL) 199 return; 200 201 free(s, M_TEMP); 202 } 203 204 /*------------------------------------------------------------------------* 205 * get byte from HID descriptor 206 *------------------------------------------------------------------------*/ 207 static uint8_t 208 hid_get_byte(struct hid_data *s, const uint16_t wSize) 209 { 210 const uint8_t *ptr; 211 uint8_t retval; 212 213 ptr = s->p; 214 215 /* check if end is reached */ 216 if (ptr == s->end) 217 return (0); 218 219 /* read out a byte */ 220 retval = *ptr; 221 222 /* check if data pointer can be advanced by "wSize" bytes */ 223 if ((s->end - ptr) < wSize) 224 ptr = s->end; 225 else 226 ptr += wSize; 227 228 /* update pointer */ 229 s->p = ptr; 230 231 return (retval); 232 } 233 234 /*------------------------------------------------------------------------* 235 * hid_get_item 236 *------------------------------------------------------------------------*/ 237 int 238 hid_get_item(struct hid_data *s, struct hid_item *h) 239 { 240 struct hid_item *c; 241 unsigned int bTag, bType, bSize; 242 uint32_t oldpos; 243 int32_t mask; 244 int32_t dval; 245 uint32_t uval; 246 247 if (s == NULL) 248 return (0); 249 250 c = &s->cur[s->pushlevel]; 251 252 top: 253 /* check if there is an array of items */ 254 if (s->icount < s->ncount) { 255 /* get current usage */ 256 if (s->iusage < s->nusage) { 257 uval = s->usages_min[s->iusage] + s->ousage; 258 c->usage = uval; 259 s->usage_last = uval; 260 if (uval == s->usages_max[s->iusage]) { 261 s->iusage ++; 262 s->ousage = 0; 263 } else { 264 s->ousage ++; 265 } 266 } else { 267 DPRINTFN(1, "Using last usage\n"); 268 uval = s->usage_last; 269 } 270 c->nusages = 1; 271 /* array type HID item may have multiple usages */ 272 while ((c->flags & HIO_VARIABLE) == 0 && s->ousage == 0 && 273 s->iusage < s->nusage && c->nusages < HID_ITEM_MAXUSAGE) 274 c->usages[c->nusages++] = s->usages_min[s->iusage++]; 275 if ((c->flags & HIO_VARIABLE) == 0 && s->ousage == 0 && 276 s->iusage < s->nusage) 277 DPRINTFN(0, "HID_ITEM_MAXUSAGE should be increased " 278 "up to %hhu to parse the HID report descriptor\n", 279 s->nusage); 280 s->icount ++; 281 /* 282 * Only copy HID item, increment position and return 283 * if correct kindset! 284 */ 285 if (s->kindset & (1 << c->kind)) { 286 *h = *c; 287 DPRINTFN(1, "%u,%u,%u\n", h->loc.pos, 288 h->loc.size, h->loc.count); 289 c->loc.pos += c->loc.size * c->loc.count; 290 return (1); 291 } 292 } 293 294 /* reset state variables */ 295 s->icount = 0; 296 s->ncount = 0; 297 s->iusage = 0; 298 s->nusage = 0; 299 s->susage = 0; 300 s->ousage = 0; 301 hid_clear_local(c); 302 303 /* get next item */ 304 while (s->p != s->end) { 305 bSize = hid_get_byte(s, 1); 306 if (bSize == 0xfe) { 307 /* long item */ 308 bSize = hid_get_byte(s, 1); 309 bSize |= hid_get_byte(s, 1) << 8; 310 bTag = hid_get_byte(s, 1); 311 bType = 0xff; /* XXX what should it be */ 312 } else { 313 /* short item */ 314 bTag = bSize >> 4; 315 bType = (bSize >> 2) & 3; 316 bSize &= 3; 317 if (bSize == 3) 318 bSize = 4; 319 } 320 switch (bSize) { 321 case 0: 322 uval = 0; 323 dval = uval; 324 mask = 0; 325 break; 326 case 1: 327 uval = hid_get_byte(s, 1); 328 dval = (int8_t)uval; 329 mask = 0xFF; 330 break; 331 case 2: 332 uval = hid_get_byte(s, 1); 333 uval |= hid_get_byte(s, 1) << 8; 334 dval = (int16_t)uval; 335 mask = 0xFFFF; 336 break; 337 case 4: 338 uval = hid_get_byte(s, 1); 339 uval |= hid_get_byte(s, 1) << 8; 340 uval |= hid_get_byte(s, 1) << 16; 341 uval |= hid_get_byte(s, 1) << 24; 342 dval = uval; 343 mask = 0xFFFFFFFF; 344 break; 345 default: 346 uval = hid_get_byte(s, bSize); 347 dval = uval; 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 = uval; 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 = uval; 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 = uval << 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 = uval; 431 break; 432 case 6: 433 c->unit = uval; 434 break; 435 case 7: 436 /* mask because value is unsigned */ 437 s->loc_size = uval & mask; 438 break; 439 case 8: 440 hid_switch_rid(s, c, uval & mask); 441 break; 442 case 9: 443 /* mask because value is unsigned */ 444 s->loc_count = uval & 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 uval = (uval & mask) | c->_usage_page; 488 489 /* set last usage, in case of a collection */ 490 s->usage_last = uval; 491 492 if (s->nusage < MAXUSAGE) { 493 s->usages_min[s->nusage] = uval; 494 s->usages_max[s->nusage] = uval; 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 uval = (uval & mask) | c->_usage_page; 508 c->usage_minimum = uval; 509 510 goto check_set; 511 case 2: 512 s->susage |= 2; 513 514 if (bSize != 4) 515 uval = (uval & mask) | c->_usage_page; 516 c->usage_maximum = uval; 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 = uval; 538 break; 539 case 4: 540 c->designator_minimum = uval; 541 break; 542 case 5: 543 c->designator_maximum = uval; 544 break; 545 case 7: 546 c->string_index = uval; 547 break; 548 case 8: 549 c->string_minimum = uval; 550 break; 551 case 9: 552 c->string_maximum = uval; 553 break; 554 case 10: 555 c->set_delimiter = uval; 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, 0); 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_intr_start(device_t dev) 1037 { 1038 return (HID_INTR_START(device_get_parent(dev), dev)); 1039 } 1040 1041 int 1042 hid_intr_stop(device_t dev) 1043 { 1044 return (HID_INTR_STOP(device_get_parent(dev), dev)); 1045 } 1046 1047 void 1048 hid_intr_poll(device_t dev) 1049 { 1050 HID_INTR_POLL(device_get_parent(dev), dev); 1051 } 1052 1053 int 1054 hid_get_rdesc(device_t dev, void *data, hid_size_t len) 1055 { 1056 return (HID_GET_RDESC(device_get_parent(dev), dev, data, len)); 1057 } 1058 1059 int 1060 hid_read(device_t dev, void *data, hid_size_t maxlen, hid_size_t *actlen) 1061 { 1062 return (HID_READ(device_get_parent(dev), dev, data, maxlen, actlen)); 1063 } 1064 1065 int 1066 hid_write(device_t dev, const void *data, hid_size_t len) 1067 { 1068 return (HID_WRITE(device_get_parent(dev), dev, data, len)); 1069 } 1070 1071 int 1072 hid_get_report(device_t dev, void *data, hid_size_t maxlen, hid_size_t *actlen, 1073 uint8_t type, uint8_t id) 1074 { 1075 return (HID_GET_REPORT(device_get_parent(dev), dev, data, maxlen, 1076 actlen, type, id)); 1077 } 1078 1079 int 1080 hid_set_report(device_t dev, const void *data, hid_size_t len, uint8_t type, 1081 uint8_t id) 1082 { 1083 return (HID_SET_REPORT(device_get_parent(dev), dev, data, len, type, 1084 id)); 1085 } 1086 1087 int 1088 hid_set_idle(device_t dev, uint16_t duration, uint8_t id) 1089 { 1090 return (HID_SET_IDLE(device_get_parent(dev), dev, duration, id)); 1091 } 1092 1093 int 1094 hid_set_protocol(device_t dev, uint16_t protocol) 1095 { 1096 return (HID_SET_PROTOCOL(device_get_parent(dev), dev, protocol)); 1097 } 1098 1099 int 1100 hid_ioctl(device_t dev, unsigned long cmd, uintptr_t data) 1101 { 1102 return (HID_IOCTL(device_get_parent(dev), dev, cmd, data)); 1103 } 1104 1105 MODULE_VERSION(hid, 1); 1106