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 #ifdef USB_GLOBAL_INCLUDE_FILE 36 #include USB_GLOBAL_INCLUDE_FILE 37 #else 38 #include <sys/stdint.h> 39 #include <sys/stddef.h> 40 #include <sys/param.h> 41 #include <sys/queue.h> 42 #include <sys/types.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/bus.h> 46 #include <sys/module.h> 47 #include <sys/lock.h> 48 #include <sys/mutex.h> 49 #include <sys/condvar.h> 50 #include <sys/sysctl.h> 51 #include <sys/sx.h> 52 #include <sys/unistd.h> 53 #include <sys/callout.h> 54 #include <sys/malloc.h> 55 #include <sys/priv.h> 56 57 #include <dev/usb/usb.h> 58 #include <dev/usb/usbdi.h> 59 #include <dev/usb/usbdi_util.h> 60 #include <dev/usb/usbhid.h> 61 62 #define USB_DEBUG_VAR usb_debug 63 64 #include <dev/usb/usb_core.h> 65 #include <dev/usb/usb_debug.h> 66 #include <dev/usb/usb_process.h> 67 #include <dev/usb/usb_device.h> 68 #include <dev/usb/usb_request.h> 69 #endif /* USB_GLOBAL_INCLUDE_FILE */ 70 71 static void hid_clear_local(struct hid_item *); 72 static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize); 73 74 #define MAXUSAGE 64 75 #define MAXPUSH 4 76 #define MAXID 16 77 #define MAXLOCCNT 2048 78 79 struct hid_pos_data { 80 int32_t rid; 81 uint32_t pos; 82 }; 83 84 struct hid_data { 85 const uint8_t *start; 86 const uint8_t *end; 87 const uint8_t *p; 88 struct hid_item cur[MAXPUSH]; 89 struct hid_pos_data last_pos[MAXID]; 90 int32_t usages_min[MAXUSAGE]; 91 int32_t usages_max[MAXUSAGE]; 92 int32_t usage_last; /* last seen usage */ 93 uint32_t loc_size; /* last seen size */ 94 uint32_t loc_count; /* last seen count */ 95 uint32_t ncount; /* end usage item count */ 96 uint32_t icount; /* current usage item count */ 97 uint8_t kindset; /* we have 5 kinds so 8 bits are enough */ 98 uint8_t pushlevel; /* current pushlevel */ 99 uint8_t nusage; /* end "usages_min/max" index */ 100 uint8_t iusage; /* current "usages_min/max" index */ 101 uint8_t ousage; /* current "usages_min/max" offset */ 102 uint8_t susage; /* usage set flags */ 103 }; 104 105 /*------------------------------------------------------------------------* 106 * hid_clear_local 107 *------------------------------------------------------------------------*/ 108 static void 109 hid_clear_local(struct hid_item *c) 110 { 111 112 c->loc.count = 0; 113 c->loc.size = 0; 114 c->usage = 0; 115 c->usage_minimum = 0; 116 c->usage_maximum = 0; 117 c->designator_index = 0; 118 c->designator_minimum = 0; 119 c->designator_maximum = 0; 120 c->string_index = 0; 121 c->string_minimum = 0; 122 c->string_maximum = 0; 123 c->set_delimiter = 0; 124 } 125 126 static void 127 hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID) 128 { 129 uint8_t i; 130 131 /* check for same report ID - optimise */ 132 133 if (c->report_ID == next_rID) 134 return; 135 136 /* save current position for current rID */ 137 138 if (c->report_ID == 0) { 139 i = 0; 140 } else { 141 for (i = 1; i != MAXID; i++) { 142 if (s->last_pos[i].rid == c->report_ID) 143 break; 144 if (s->last_pos[i].rid == 0) 145 break; 146 } 147 } 148 if (i != MAXID) { 149 s->last_pos[i].rid = c->report_ID; 150 s->last_pos[i].pos = c->loc.pos; 151 } 152 153 /* store next report ID */ 154 155 c->report_ID = next_rID; 156 157 /* lookup last position for next rID */ 158 159 if (next_rID == 0) { 160 i = 0; 161 } else { 162 for (i = 1; i != MAXID; i++) { 163 if (s->last_pos[i].rid == next_rID) 164 break; 165 if (s->last_pos[i].rid == 0) 166 break; 167 } 168 } 169 if (i != MAXID) { 170 s->last_pos[i].rid = next_rID; 171 c->loc.pos = s->last_pos[i].pos; 172 } else { 173 DPRINTF("Out of RID entries, position is set to zero!\n"); 174 c->loc.pos = 0; 175 } 176 } 177 178 /*------------------------------------------------------------------------* 179 * hid_start_parse 180 *------------------------------------------------------------------------*/ 181 struct hid_data * 182 hid_start_parse(const void *d, usb_size_t len, int kindset) 183 { 184 struct hid_data *s; 185 186 if ((kindset-1) & kindset) { 187 DPRINTFN(0, "Only one bit can be " 188 "set in the kindset\n"); 189 return (NULL); 190 } 191 192 s = malloc(sizeof *s, M_TEMP, M_WAITOK | M_ZERO); 193 s->start = s->p = d; 194 s->end = ((const uint8_t *)d) + len; 195 s->kindset = kindset; 196 return (s); 197 } 198 199 /*------------------------------------------------------------------------* 200 * hid_end_parse 201 *------------------------------------------------------------------------*/ 202 void 203 hid_end_parse(struct hid_data *s) 204 { 205 if (s == NULL) 206 return; 207 208 free(s, M_TEMP); 209 } 210 211 /*------------------------------------------------------------------------* 212 * get byte from HID descriptor 213 *------------------------------------------------------------------------*/ 214 static uint8_t 215 hid_get_byte(struct hid_data *s, const uint16_t wSize) 216 { 217 const uint8_t *ptr; 218 uint8_t retval; 219 220 ptr = s->p; 221 222 /* check if end is reached */ 223 if (ptr == s->end) 224 return (0); 225 226 /* read out a byte */ 227 retval = *ptr; 228 229 /* check if data pointer can be advanced by "wSize" bytes */ 230 if ((s->end - ptr) < wSize) 231 ptr = s->end; 232 else 233 ptr += wSize; 234 235 /* update pointer */ 236 s->p = ptr; 237 238 return (retval); 239 } 240 241 /*------------------------------------------------------------------------* 242 * hid_get_item 243 *------------------------------------------------------------------------*/ 244 int 245 hid_get_item(struct hid_data *s, struct hid_item *h) 246 { 247 struct hid_item *c; 248 unsigned int bTag, bType, bSize; 249 uint32_t oldpos; 250 int32_t mask; 251 int32_t dval; 252 253 if (s == NULL) 254 return (0); 255 256 c = &s->cur[s->pushlevel]; 257 258 top: 259 /* check if there is an array of items */ 260 if (s->icount < s->ncount) { 261 /* get current usage */ 262 if (s->iusage < s->nusage) { 263 dval = s->usages_min[s->iusage] + s->ousage; 264 c->usage = dval; 265 s->usage_last = dval; 266 if (dval == s->usages_max[s->iusage]) { 267 s->iusage ++; 268 s->ousage = 0; 269 } else { 270 s->ousage ++; 271 } 272 } else { 273 DPRINTFN(1, "Using last usage\n"); 274 dval = s->usage_last; 275 } 276 s->icount ++; 277 /* 278 * Only copy HID item, increment position and return 279 * if correct kindset! 280 */ 281 if (s->kindset & (1 << c->kind)) { 282 *h = *c; 283 DPRINTFN(1, "%u,%u,%u\n", h->loc.pos, 284 h->loc.size, h->loc.count); 285 c->loc.pos += c->loc.size * c->loc.count; 286 return (1); 287 } 288 } 289 290 /* reset state variables */ 291 s->icount = 0; 292 s->ncount = 0; 293 s->iusage = 0; 294 s->nusage = 0; 295 s->susage = 0; 296 s->ousage = 0; 297 hid_clear_local(c); 298 299 /* get next item */ 300 while (s->p != s->end) { 301 bSize = hid_get_byte(s, 1); 302 if (bSize == 0xfe) { 303 /* long item */ 304 bSize = hid_get_byte(s, 1); 305 bSize |= hid_get_byte(s, 1) << 8; 306 bTag = hid_get_byte(s, 1); 307 bType = 0xff; /* XXX what should it be */ 308 } else { 309 /* short item */ 310 bTag = bSize >> 4; 311 bType = (bSize >> 2) & 3; 312 bSize &= 3; 313 if (bSize == 3) 314 bSize = 4; 315 } 316 switch (bSize) { 317 case 0: 318 dval = 0; 319 mask = 0; 320 break; 321 case 1: 322 dval = (int8_t)hid_get_byte(s, 1); 323 mask = 0xFF; 324 break; 325 case 2: 326 dval = hid_get_byte(s, 1); 327 dval |= hid_get_byte(s, 1) << 8; 328 dval = (int16_t)dval; 329 mask = 0xFFFF; 330 break; 331 case 4: 332 dval = hid_get_byte(s, 1); 333 dval |= hid_get_byte(s, 1) << 8; 334 dval |= hid_get_byte(s, 1) << 16; 335 dval |= hid_get_byte(s, 1) << 24; 336 mask = 0xFFFFFFFF; 337 break; 338 default: 339 dval = hid_get_byte(s, bSize); 340 DPRINTFN(0, "bad length %u (data=0x%02x)\n", 341 bSize, dval); 342 continue; 343 } 344 345 switch (bType) { 346 case 0: /* Main */ 347 switch (bTag) { 348 case 8: /* Input */ 349 c->kind = hid_input; 350 ret: 351 c->flags = dval; 352 c->loc.count = s->loc_count; 353 c->loc.size = s->loc_size; 354 355 if (c->flags & HIO_VARIABLE) { 356 /* range check usage count */ 357 if (c->loc.count > MAXLOCCNT) { 358 DPRINTFN(0, "Number of " 359 "items(%u) truncated to %u\n", 360 (unsigned)(c->loc.count), 361 MAXLOCCNT); 362 s->ncount = MAXLOCCNT; 363 } else 364 s->ncount = c->loc.count; 365 366 /* 367 * The "top" loop will return 368 * one and one item: 369 */ 370 c->loc.count = 1; 371 } else { 372 s->ncount = 1; 373 } 374 goto top; 375 376 case 9: /* Output */ 377 c->kind = hid_output; 378 goto ret; 379 case 10: /* Collection */ 380 c->kind = hid_collection; 381 c->collection = dval; 382 c->collevel++; 383 c->usage = s->usage_last; 384 *h = *c; 385 return (1); 386 case 11: /* Feature */ 387 c->kind = hid_feature; 388 goto ret; 389 case 12: /* End collection */ 390 c->kind = hid_endcollection; 391 if (c->collevel == 0) { 392 DPRINTFN(0, "invalid end collection\n"); 393 return (0); 394 } 395 c->collevel--; 396 *h = *c; 397 return (1); 398 default: 399 DPRINTFN(0, "Main bTag=%d\n", bTag); 400 break; 401 } 402 break; 403 case 1: /* Global */ 404 switch (bTag) { 405 case 0: 406 c->_usage_page = dval << 16; 407 break; 408 case 1: 409 c->logical_minimum = dval; 410 break; 411 case 2: 412 c->logical_maximum = dval; 413 break; 414 case 3: 415 c->physical_minimum = dval; 416 break; 417 case 4: 418 c->physical_maximum = dval; 419 break; 420 case 5: 421 c->unit_exponent = dval; 422 break; 423 case 6: 424 c->unit = dval; 425 break; 426 case 7: 427 /* mask because value is unsigned */ 428 s->loc_size = dval & mask; 429 break; 430 case 8: 431 hid_switch_rid(s, c, dval & mask); 432 break; 433 case 9: 434 /* mask because value is unsigned */ 435 s->loc_count = dval & mask; 436 break; 437 case 10: /* Push */ 438 /* stop parsing, if invalid push level */ 439 if ((s->pushlevel + 1) >= MAXPUSH) { 440 DPRINTFN(0, "Cannot push item @ %d\n", s->pushlevel); 441 return (0); 442 } 443 s->pushlevel ++; 444 s->cur[s->pushlevel] = *c; 445 /* store size and count */ 446 c->loc.size = s->loc_size; 447 c->loc.count = s->loc_count; 448 /* update current item pointer */ 449 c = &s->cur[s->pushlevel]; 450 break; 451 case 11: /* Pop */ 452 /* stop parsing, if invalid push level */ 453 if (s->pushlevel == 0) { 454 DPRINTFN(0, "Cannot pop item @ 0\n"); 455 return (0); 456 } 457 s->pushlevel --; 458 /* preserve position */ 459 oldpos = c->loc.pos; 460 c = &s->cur[s->pushlevel]; 461 /* restore size and count */ 462 s->loc_size = c->loc.size; 463 s->loc_count = c->loc.count; 464 /* set default item location */ 465 c->loc.pos = oldpos; 466 c->loc.size = 0; 467 c->loc.count = 0; 468 break; 469 default: 470 DPRINTFN(0, "Global bTag=%d\n", bTag); 471 break; 472 } 473 break; 474 case 2: /* Local */ 475 switch (bTag) { 476 case 0: 477 if (bSize != 4) 478 dval = (dval & mask) | c->_usage_page; 479 480 /* set last usage, in case of a collection */ 481 s->usage_last = dval; 482 483 if (s->nusage < MAXUSAGE) { 484 s->usages_min[s->nusage] = dval; 485 s->usages_max[s->nusage] = dval; 486 s->nusage ++; 487 } else { 488 DPRINTFN(0, "max usage reached\n"); 489 } 490 491 /* clear any pending usage sets */ 492 s->susage = 0; 493 break; 494 case 1: 495 s->susage |= 1; 496 497 if (bSize != 4) 498 dval = (dval & mask) | c->_usage_page; 499 c->usage_minimum = dval; 500 501 goto check_set; 502 case 2: 503 s->susage |= 2; 504 505 if (bSize != 4) 506 dval = (dval & mask) | c->_usage_page; 507 c->usage_maximum = dval; 508 509 check_set: 510 if (s->susage != 3) 511 break; 512 513 /* sanity check */ 514 if ((s->nusage < MAXUSAGE) && 515 (c->usage_minimum <= c->usage_maximum)) { 516 /* add usage range */ 517 s->usages_min[s->nusage] = 518 c->usage_minimum; 519 s->usages_max[s->nusage] = 520 c->usage_maximum; 521 s->nusage ++; 522 } else { 523 DPRINTFN(0, "Usage set dropped\n"); 524 } 525 s->susage = 0; 526 break; 527 case 3: 528 c->designator_index = dval; 529 break; 530 case 4: 531 c->designator_minimum = dval; 532 break; 533 case 5: 534 c->designator_maximum = dval; 535 break; 536 case 7: 537 c->string_index = dval; 538 break; 539 case 8: 540 c->string_minimum = dval; 541 break; 542 case 9: 543 c->string_maximum = dval; 544 break; 545 case 10: 546 c->set_delimiter = dval; 547 break; 548 default: 549 DPRINTFN(0, "Local bTag=%d\n", bTag); 550 break; 551 } 552 break; 553 default: 554 DPRINTFN(0, "default bType=%d\n", bType); 555 break; 556 } 557 } 558 return (0); 559 } 560 561 /*------------------------------------------------------------------------* 562 * hid_report_size 563 *------------------------------------------------------------------------*/ 564 int 565 hid_report_size(const void *buf, usb_size_t len, enum hid_kind k, uint8_t *id) 566 { 567 struct hid_data *d; 568 struct hid_item h; 569 uint32_t temp; 570 uint32_t hpos; 571 uint32_t lpos; 572 uint8_t any_id; 573 574 any_id = 0; 575 hpos = 0; 576 lpos = 0xFFFFFFFF; 577 578 for (d = hid_start_parse(buf, len, 1 << k); hid_get_item(d, &h);) { 579 if (h.kind == k) { 580 /* check for ID-byte presence */ 581 if ((h.report_ID != 0) && !any_id) { 582 if (id != NULL) 583 *id = h.report_ID; 584 any_id = 1; 585 } 586 /* compute minimum */ 587 if (lpos > h.loc.pos) 588 lpos = h.loc.pos; 589 /* compute end position */ 590 temp = h.loc.pos + (h.loc.size * h.loc.count); 591 /* compute maximum */ 592 if (hpos < temp) 593 hpos = temp; 594 } 595 } 596 hid_end_parse(d); 597 598 /* safety check - can happen in case of currupt descriptors */ 599 if (lpos > hpos) 600 temp = 0; 601 else 602 temp = hpos - lpos; 603 604 /* check for ID byte */ 605 if (any_id) 606 temp += 8; 607 else if (id != NULL) 608 *id = 0; 609 610 /* return length in bytes rounded up */ 611 return ((temp + 7) / 8); 612 } 613 614 /*------------------------------------------------------------------------* 615 * hid_locate 616 *------------------------------------------------------------------------*/ 617 int 618 hid_locate(const void *desc, usb_size_t size, int32_t u, enum hid_kind k, 619 uint8_t index, struct hid_location *loc, uint32_t *flags, uint8_t *id) 620 { 621 struct hid_data *d; 622 struct hid_item h; 623 624 for (d = hid_start_parse(desc, size, 1 << k); hid_get_item(d, &h);) { 625 if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) { 626 if (index--) 627 continue; 628 if (loc != NULL) 629 *loc = h.loc; 630 if (flags != NULL) 631 *flags = h.flags; 632 if (id != NULL) 633 *id = h.report_ID; 634 hid_end_parse(d); 635 return (1); 636 } 637 } 638 if (loc != NULL) 639 loc->size = 0; 640 if (flags != NULL) 641 *flags = 0; 642 if (id != NULL) 643 *id = 0; 644 hid_end_parse(d); 645 return (0); 646 } 647 648 /*------------------------------------------------------------------------* 649 * hid_get_data 650 *------------------------------------------------------------------------*/ 651 static uint32_t 652 hid_get_data_sub(const uint8_t *buf, usb_size_t len, struct hid_location *loc, 653 int is_signed) 654 { 655 uint32_t hpos = loc->pos; 656 uint32_t hsize = loc->size; 657 uint32_t data; 658 uint32_t rpos; 659 uint8_t n; 660 661 DPRINTFN(11, "hid_get_data: loc %d/%d\n", hpos, hsize); 662 663 /* Range check and limit */ 664 if (hsize == 0) 665 return (0); 666 if (hsize > 32) 667 hsize = 32; 668 669 /* Get data in a safe way */ 670 data = 0; 671 rpos = (hpos / 8); 672 n = (hsize + 7) / 8; 673 rpos += n; 674 while (n--) { 675 rpos--; 676 if (rpos < len) 677 data |= buf[rpos] << (8 * n); 678 } 679 680 /* Correctly shift down data */ 681 data = (data >> (hpos % 8)); 682 n = 32 - hsize; 683 684 /* Mask and sign extend in one */ 685 if (is_signed != 0) 686 data = (int32_t)((int32_t)data << n) >> n; 687 else 688 data = (uint32_t)((uint32_t)data << n) >> n; 689 690 DPRINTFN(11, "hid_get_data: loc %d/%d = %lu\n", 691 loc->pos, loc->size, (long)data); 692 return (data); 693 } 694 695 int32_t 696 hid_get_data(const uint8_t *buf, usb_size_t len, struct hid_location *loc) 697 { 698 return (hid_get_data_sub(buf, len, loc, 1)); 699 } 700 701 uint32_t 702 hid_get_data_unsigned(const uint8_t *buf, usb_size_t len, struct hid_location *loc) 703 { 704 return (hid_get_data_sub(buf, len, loc, 0)); 705 } 706 707 /*------------------------------------------------------------------------* 708 * hid_put_data 709 *------------------------------------------------------------------------*/ 710 void 711 hid_put_data_unsigned(uint8_t *buf, usb_size_t len, 712 struct hid_location *loc, unsigned int value) 713 { 714 uint32_t hpos = loc->pos; 715 uint32_t hsize = loc->size; 716 uint64_t data; 717 uint64_t mask; 718 uint32_t rpos; 719 uint8_t n; 720 721 DPRINTFN(11, "hid_put_data: loc %d/%d = %u\n", hpos, hsize, value); 722 723 /* Range check and limit */ 724 if (hsize == 0) 725 return; 726 if (hsize > 32) 727 hsize = 32; 728 729 /* Put data in a safe way */ 730 rpos = (hpos / 8); 731 n = (hsize + 7) / 8; 732 data = ((uint64_t)value) << (hpos % 8); 733 mask = ((1ULL << hsize) - 1ULL) << (hpos % 8); 734 rpos += n; 735 while (n--) { 736 rpos--; 737 if (rpos < len) { 738 buf[rpos] &= ~(mask >> (8 * n)); 739 buf[rpos] |= (data >> (8 * n)); 740 } 741 } 742 } 743 744 /*------------------------------------------------------------------------* 745 * hid_is_collection 746 *------------------------------------------------------------------------*/ 747 int 748 hid_is_collection(const void *desc, usb_size_t size, int32_t usage) 749 { 750 struct hid_data *hd; 751 struct hid_item hi; 752 int err; 753 754 hd = hid_start_parse(desc, size, hid_input); 755 if (hd == NULL) 756 return (0); 757 758 while ((err = hid_get_item(hd, &hi))) { 759 if (hi.kind == hid_collection && 760 hi.usage == usage) 761 break; 762 } 763 hid_end_parse(hd); 764 return (err); 765 } 766 767 /*------------------------------------------------------------------------* 768 * hid_get_descriptor_from_usb 769 * 770 * This function will search for a HID descriptor between two USB 771 * interface descriptors. 772 * 773 * Return values: 774 * NULL: No more HID descriptors. 775 * Else: Pointer to HID descriptor. 776 *------------------------------------------------------------------------*/ 777 struct usb_hid_descriptor * 778 hid_get_descriptor_from_usb(struct usb_config_descriptor *cd, 779 struct usb_interface_descriptor *id) 780 { 781 struct usb_descriptor *desc = (void *)id; 782 783 if (desc == NULL) { 784 return (NULL); 785 } 786 while ((desc = usb_desc_foreach(cd, desc))) { 787 if ((desc->bDescriptorType == UDESC_HID) && 788 (desc->bLength >= USB_HID_DESCRIPTOR_SIZE(0))) { 789 return (void *)desc; 790 } 791 if (desc->bDescriptorType == UDESC_INTERFACE) { 792 break; 793 } 794 } 795 return (NULL); 796 } 797 798 /*------------------------------------------------------------------------* 799 * usbd_req_get_hid_desc 800 * 801 * This function will read out an USB report descriptor from the USB 802 * device. 803 * 804 * Return values: 805 * NULL: Failure. 806 * Else: Success. The pointer should eventually be passed to free(). 807 *------------------------------------------------------------------------*/ 808 usb_error_t 809 usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx, 810 void **descp, uint16_t *sizep, 811 struct malloc_type *mem, uint8_t iface_index) 812 { 813 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 814 struct usb_hid_descriptor *hid; 815 usb_error_t err; 816 817 if ((iface == NULL) || (iface->idesc == NULL)) { 818 return (USB_ERR_INVAL); 819 } 820 hid = hid_get_descriptor_from_usb 821 (usbd_get_config_descriptor(udev), iface->idesc); 822 823 if (hid == NULL) { 824 return (USB_ERR_IOERROR); 825 } 826 *sizep = UGETW(hid->descrs[0].wDescriptorLength); 827 if (*sizep == 0) { 828 return (USB_ERR_IOERROR); 829 } 830 if (mtx) 831 mtx_unlock(mtx); 832 833 *descp = malloc(*sizep, mem, M_ZERO | M_WAITOK); 834 835 if (mtx) 836 mtx_lock(mtx); 837 838 if (*descp == NULL) { 839 return (USB_ERR_NOMEM); 840 } 841 err = usbd_req_get_report_descriptor 842 (udev, mtx, *descp, *sizep, iface_index); 843 844 if (err) { 845 free(*descp, mem); 846 *descp = NULL; 847 return (err); 848 } 849 return (USB_ERR_NORMAL_COMPLETION); 850 } 851 852 /*------------------------------------------------------------------------* 853 * calculate HID item resolution. unit/mm for distances, unit/rad for angles 854 *------------------------------------------------------------------------*/ 855 int32_t 856 hid_item_resolution(struct hid_item *hi) 857 { 858 /* 859 * hid unit scaling table according to HID Usage Table Review 860 * Request 39 Tbl 17 http://www.usb.org/developers/hidpage/HUTRR39b.pdf 861 */ 862 static const int64_t scale[0x10][2] = { 863 [0x00] = { 1, 1 }, 864 [0x01] = { 1, 10 }, 865 [0x02] = { 1, 100 }, 866 [0x03] = { 1, 1000 }, 867 [0x04] = { 1, 10000 }, 868 [0x05] = { 1, 100000 }, 869 [0x06] = { 1, 1000000 }, 870 [0x07] = { 1, 10000000 }, 871 [0x08] = { 100000000, 1 }, 872 [0x09] = { 10000000, 1 }, 873 [0x0A] = { 1000000, 1 }, 874 [0x0B] = { 100000, 1 }, 875 [0x0C] = { 10000, 1 }, 876 [0x0D] = { 1000, 1 }, 877 [0x0E] = { 100, 1 }, 878 [0x0F] = { 10, 1 }, 879 }; 880 int64_t logical_size; 881 int64_t physical_size; 882 int64_t multiplier; 883 int64_t divisor; 884 int64_t resolution; 885 886 switch (hi->unit) { 887 case HUM_CENTIMETER: 888 multiplier = 1; 889 divisor = 10; 890 break; 891 case HUM_INCH: 892 multiplier = 10; 893 divisor = 254; 894 break; 895 case HUM_RADIAN: 896 multiplier = 1; 897 divisor = 1; 898 break; 899 case HUM_DEGREE: 900 multiplier = 573; 901 divisor = 10; 902 break; 903 default: 904 return (0); 905 } 906 907 if ((hi->logical_maximum <= hi->logical_minimum) || 908 (hi->physical_maximum <= hi->physical_minimum) || 909 (hi->unit_exponent < 0) || (hi->unit_exponent >= nitems(scale))) 910 return (0); 911 912 logical_size = (int64_t)hi->logical_maximum - 913 (int64_t)hi->logical_minimum; 914 physical_size = (int64_t)hi->physical_maximum - 915 (int64_t)hi->physical_minimum; 916 /* Round to ceiling */ 917 resolution = logical_size * multiplier * scale[hi->unit_exponent][0] / 918 (physical_size * divisor * scale[hi->unit_exponent][1]); 919 920 if (resolution > INT32_MAX) 921 return (0); 922 923 return (resolution); 924 } 925 926 /*------------------------------------------------------------------------* 927 * hid_is_mouse 928 * 929 * This function will decide if a USB descriptor belongs to a USB mouse. 930 * 931 * Return values: 932 * Zero: Not a USB mouse. 933 * Else: Is a USB mouse. 934 *------------------------------------------------------------------------*/ 935 int 936 hid_is_mouse(const void *d_ptr, uint16_t d_len) 937 { 938 struct hid_data *hd; 939 struct hid_item hi; 940 int mdepth; 941 int found; 942 943 hd = hid_start_parse(d_ptr, d_len, 1 << hid_input); 944 if (hd == NULL) 945 return (0); 946 947 mdepth = 0; 948 found = 0; 949 950 while (hid_get_item(hd, &hi)) { 951 switch (hi.kind) { 952 case hid_collection: 953 if (mdepth != 0) 954 mdepth++; 955 else if (hi.collection == 1 && 956 hi.usage == 957 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)) 958 mdepth++; 959 break; 960 case hid_endcollection: 961 if (mdepth != 0) 962 mdepth--; 963 break; 964 case hid_input: 965 if (mdepth == 0) 966 break; 967 if (hi.usage == 968 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X) && 969 (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE) 970 found++; 971 if (hi.usage == 972 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y) && 973 (hi.flags & (HIO_CONST|HIO_RELATIVE)) == HIO_RELATIVE) 974 found++; 975 break; 976 default: 977 break; 978 } 979 } 980 hid_end_parse(hd); 981 return (found); 982 } 983 984 /*------------------------------------------------------------------------* 985 * hid_is_keyboard 986 * 987 * This function will decide if a USB descriptor belongs to a USB keyboard. 988 * 989 * Return values: 990 * Zero: Not a USB keyboard. 991 * Else: Is a USB keyboard. 992 *------------------------------------------------------------------------*/ 993 int 994 hid_is_keyboard(const void *d_ptr, uint16_t d_len) 995 { 996 if (hid_is_collection(d_ptr, d_len, 997 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD))) 998 return (1); 999 return (0); 1000 } 1001