1 /* $NetBSD: hid.c,v 1.17 2001/11/13 06:24:53 lukem Exp $ */ 2 3 4 #include <sys/cdefs.h> 5 __FBSDID("$FreeBSD$"); 6 /*- 7 * Copyright (c) 1998 The NetBSD Foundation, Inc. 8 * All rights reserved. 9 * 10 * This code is derived from software contributed to The NetBSD Foundation 11 * by Lennart Augustsson (lennart@augustsson.net) at 12 * Carlstedt Research & Technology. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by the NetBSD 25 * Foundation, Inc. and its contributors. 26 * 4. Neither the name of The NetBSD Foundation nor the names of its 27 * contributors may be used to endorse or promote products derived 28 * from this software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 31 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 32 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 33 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 34 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 35 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 36 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 37 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 38 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40 * POSSIBILITY OF SUCH DAMAGE. 41 */ 42 43 #include <sys/stdint.h> 44 #include <sys/stddef.h> 45 #include <sys/param.h> 46 #include <sys/queue.h> 47 #include <sys/types.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/bus.h> 51 #include <sys/linker_set.h> 52 #include <sys/module.h> 53 #include <sys/lock.h> 54 #include <sys/mutex.h> 55 #include <sys/condvar.h> 56 #include <sys/sysctl.h> 57 #include <sys/sx.h> 58 #include <sys/unistd.h> 59 #include <sys/callout.h> 60 #include <sys/malloc.h> 61 #include <sys/priv.h> 62 63 #include <dev/usb/usb.h> 64 #include <dev/usb/usbdi.h> 65 #include <dev/usb/usbdi_util.h> 66 #include <dev/usb/usbhid.h> 67 68 #define USB_DEBUG_VAR usb_debug 69 70 #include <dev/usb/usb_core.h> 71 #include <dev/usb/usb_debug.h> 72 #include <dev/usb/usb_process.h> 73 #include <dev/usb/usb_device.h> 74 #include <dev/usb/usb_request.h> 75 76 static void hid_clear_local(struct hid_item *); 77 static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize); 78 79 #define MAXUSAGE 64 80 #define MAXPUSH 4 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 int32_t usages_min[MAXUSAGE]; 87 int32_t usages_max[MAXUSAGE]; 88 int32_t usage_last; /* last seen usage */ 89 uint32_t loc_size; /* last seen size */ 90 uint32_t loc_count; /* last seen count */ 91 uint8_t kindset; /* we have 5 kinds so 8 bits are enough */ 92 uint8_t pushlevel; /* current pushlevel */ 93 uint8_t ncount; /* end usage item count */ 94 uint8_t icount; /* current usage item count */ 95 uint8_t nusage; /* end "usages_min/max" index */ 96 uint8_t iusage; /* current "usages_min/max" index */ 97 uint8_t ousage; /* current "usages_min/max" offset */ 98 uint8_t susage; /* usage set flags */ 99 }; 100 101 /*------------------------------------------------------------------------* 102 * hid_clear_local 103 *------------------------------------------------------------------------*/ 104 static void 105 hid_clear_local(struct hid_item *c) 106 { 107 108 c->loc.count = 0; 109 c->loc.size = 0; 110 c->usage = 0; 111 c->usage_minimum = 0; 112 c->usage_maximum = 0; 113 c->designator_index = 0; 114 c->designator_minimum = 0; 115 c->designator_maximum = 0; 116 c->string_index = 0; 117 c->string_minimum = 0; 118 c->string_maximum = 0; 119 c->set_delimiter = 0; 120 } 121 122 /*------------------------------------------------------------------------* 123 * hid_start_parse 124 *------------------------------------------------------------------------*/ 125 struct hid_data * 126 hid_start_parse(const void *d, usb_size_t len, int kindset) 127 { 128 struct hid_data *s; 129 130 if ((kindset-1) & kindset) { 131 DPRINTFN(0, "Only one bit can be " 132 "set in the kindset\n"); 133 return (NULL); 134 } 135 136 s = malloc(sizeof *s, M_TEMP, M_WAITOK | M_ZERO); 137 s->start = s->p = d; 138 s->end = ((const uint8_t *)d) + len; 139 s->kindset = kindset; 140 return (s); 141 } 142 143 /*------------------------------------------------------------------------* 144 * hid_end_parse 145 *------------------------------------------------------------------------*/ 146 void 147 hid_end_parse(struct hid_data *s) 148 { 149 if (s == NULL) 150 return; 151 152 free(s, M_TEMP); 153 } 154 155 /*------------------------------------------------------------------------* 156 * get byte from HID descriptor 157 *------------------------------------------------------------------------*/ 158 static uint8_t 159 hid_get_byte(struct hid_data *s, const uint16_t wSize) 160 { 161 const uint8_t *ptr; 162 uint8_t retval; 163 164 ptr = s->p; 165 166 /* check if end is reached */ 167 if (ptr == s->end) 168 return (0); 169 170 /* read out a byte */ 171 retval = *ptr; 172 173 /* check if data pointer can be advanced by "wSize" bytes */ 174 if ((s->end - ptr) < wSize) 175 ptr = s->end; 176 else 177 ptr += wSize; 178 179 /* update pointer */ 180 s->p = ptr; 181 182 return (retval); 183 } 184 185 /*------------------------------------------------------------------------* 186 * hid_get_item 187 *------------------------------------------------------------------------*/ 188 int 189 hid_get_item(struct hid_data *s, struct hid_item *h) 190 { 191 struct hid_item *c; 192 unsigned int bTag, bType, bSize; 193 uint32_t oldpos; 194 int32_t mask; 195 int32_t dval; 196 197 if (s == NULL) 198 return (0); 199 200 c = &s->cur[s->pushlevel]; 201 202 top: 203 /* check if there is an array of items */ 204 if (s->icount < s->ncount) { 205 /* get current usage */ 206 if (s->iusage < s->nusage) { 207 dval = s->usages_min[s->iusage] + s->ousage; 208 c->usage = dval; 209 s->usage_last = dval; 210 if (dval == s->usages_max[s->iusage]) { 211 s->iusage ++; 212 s->ousage = 0; 213 } else { 214 s->ousage ++; 215 } 216 } else { 217 DPRINTFN(1, "Using last usage\n"); 218 dval = s->usage_last; 219 } 220 s->icount ++; 221 /* 222 * Only copy HID item, increment position and return 223 * if correct kindset! 224 */ 225 if (s->kindset & (1 << c->kind)) { 226 *h = *c; 227 DPRINTFN(1, "%u,%u,%u\n", h->loc.pos, 228 h->loc.size, h->loc.count); 229 c->loc.pos += c->loc.size * c->loc.count; 230 return (1); 231 } 232 } 233 234 /* reset state variables */ 235 s->icount = 0; 236 s->ncount = 0; 237 s->iusage = 0; 238 s->nusage = 0; 239 s->susage = 0; 240 s->ousage = 0; 241 hid_clear_local(c); 242 243 /* get next item */ 244 while (s->p != s->end) { 245 246 bSize = hid_get_byte(s, 1); 247 if (bSize == 0xfe) { 248 /* long item */ 249 bSize = hid_get_byte(s, 1); 250 bSize |= hid_get_byte(s, 1) << 8; 251 bTag = hid_get_byte(s, 1); 252 bType = 0xff; /* XXX what should it be */ 253 } else { 254 /* short item */ 255 bTag = bSize >> 4; 256 bType = (bSize >> 2) & 3; 257 bSize &= 3; 258 if (bSize == 3) 259 bSize = 4; 260 } 261 switch (bSize) { 262 case 0: 263 dval = 0; 264 mask = 0; 265 break; 266 case 1: 267 dval = (int8_t)hid_get_byte(s, 1); 268 mask = 0xFF; 269 break; 270 case 2: 271 dval = hid_get_byte(s, 1); 272 dval |= hid_get_byte(s, 1) << 8; 273 dval = (int16_t)dval; 274 mask = 0xFFFF; 275 break; 276 case 4: 277 dval = hid_get_byte(s, 1); 278 dval |= hid_get_byte(s, 1) << 8; 279 dval |= hid_get_byte(s, 1) << 16; 280 dval |= hid_get_byte(s, 1) << 24; 281 mask = 0xFFFFFFFF; 282 break; 283 default: 284 dval = hid_get_byte(s, bSize); 285 DPRINTFN(0, "bad length %u (data=0x%02x)\n", 286 bSize, dval); 287 continue; 288 } 289 290 switch (bType) { 291 case 0: /* Main */ 292 switch (bTag) { 293 case 8: /* Input */ 294 c->kind = hid_input; 295 c->flags = dval; 296 ret: 297 c->loc.count = s->loc_count; 298 c->loc.size = s->loc_size; 299 300 if (c->flags & HIO_VARIABLE) { 301 /* range check usage count */ 302 if (c->loc.count > 255) { 303 DPRINTFN(0, "Number of " 304 "items truncated to 255\n"); 305 s->ncount = 255; 306 } else 307 s->ncount = c->loc.count; 308 309 /* 310 * The "top" loop will return 311 * one and one item: 312 */ 313 c->loc.count = 1; 314 } else { 315 s->ncount = 1; 316 } 317 goto top; 318 319 case 9: /* Output */ 320 c->kind = hid_output; 321 c->flags = dval; 322 goto ret; 323 case 10: /* Collection */ 324 c->kind = hid_collection; 325 c->collection = dval; 326 c->collevel++; 327 c->usage = s->usage_last; 328 *h = *c; 329 return (1); 330 case 11: /* Feature */ 331 c->kind = hid_feature; 332 c->flags = dval; 333 goto ret; 334 case 12: /* End collection */ 335 c->kind = hid_endcollection; 336 if (c->collevel == 0) { 337 DPRINTFN(0, "invalid end collection\n"); 338 return (0); 339 } 340 c->collevel--; 341 *h = *c; 342 return (1); 343 default: 344 DPRINTFN(0, "Main bTag=%d\n", bTag); 345 break; 346 } 347 break; 348 case 1: /* Global */ 349 switch (bTag) { 350 case 0: 351 c->_usage_page = dval << 16; 352 break; 353 case 1: 354 c->logical_minimum = dval; 355 break; 356 case 2: 357 c->logical_maximum = dval; 358 break; 359 case 3: 360 c->physical_minimum = dval; 361 break; 362 case 4: 363 c->physical_maximum = dval; 364 break; 365 case 5: 366 c->unit_exponent = dval; 367 break; 368 case 6: 369 c->unit = dval; 370 break; 371 case 7: 372 /* mask because value is unsigned */ 373 s->loc_size = dval & mask; 374 break; 375 case 8: 376 c->report_ID = dval; 377 /* new report - reset position */ 378 c->loc.pos = 0; 379 break; 380 case 9: 381 /* mask because value is unsigned */ 382 s->loc_count = dval & mask; 383 break; 384 case 10: /* Push */ 385 s->pushlevel ++; 386 if (s->pushlevel < MAXPUSH) { 387 s->cur[s->pushlevel] = *c; 388 /* store size and count */ 389 c->loc.size = s->loc_size; 390 c->loc.count = s->loc_count; 391 /* update current item pointer */ 392 c = &s->cur[s->pushlevel]; 393 } else { 394 DPRINTFN(0, "Cannot push " 395 "item @ %d!\n", s->pushlevel); 396 } 397 break; 398 case 11: /* Pop */ 399 s->pushlevel --; 400 if (s->pushlevel < MAXPUSH) { 401 /* preserve position */ 402 oldpos = c->loc.pos; 403 c = &s->cur[s->pushlevel]; 404 /* restore size and count */ 405 s->loc_size = c->loc.size; 406 s->loc_count = c->loc.count; 407 /* set default item location */ 408 c->loc.pos = oldpos; 409 c->loc.size = 0; 410 c->loc.count = 0; 411 } else { 412 DPRINTFN(0, "Cannot pop " 413 "item @ %d!\n", s->pushlevel); 414 } 415 break; 416 default: 417 DPRINTFN(0, "Global bTag=%d\n", bTag); 418 break; 419 } 420 break; 421 case 2: /* Local */ 422 switch (bTag) { 423 case 0: 424 if (bSize != 4) 425 dval = (dval & mask) | c->_usage_page; 426 427 /* set last usage, in case of a collection */ 428 s->usage_last = dval; 429 430 if (s->nusage < MAXUSAGE) { 431 s->usages_min[s->nusage] = dval; 432 s->usages_max[s->nusage] = dval; 433 s->nusage ++; 434 } else { 435 DPRINTFN(0, "max usage reached!\n"); 436 } 437 438 /* clear any pending usage sets */ 439 s->susage = 0; 440 break; 441 case 1: 442 s->susage |= 1; 443 444 if (bSize != 4) 445 dval = (dval & mask) | c->_usage_page; 446 c->usage_minimum = dval; 447 448 goto check_set; 449 case 2: 450 s->susage |= 2; 451 452 if (bSize != 4) 453 dval = (dval & mask) | c->_usage_page; 454 c->usage_maximum = dval; 455 456 check_set: 457 if (s->susage != 3) 458 break; 459 460 /* sanity check */ 461 if ((s->nusage < MAXUSAGE) && 462 (c->usage_minimum <= c->usage_maximum)) { 463 /* add usage range */ 464 s->usages_min[s->nusage] = 465 c->usage_minimum; 466 s->usages_max[s->nusage] = 467 c->usage_maximum; 468 s->nusage ++; 469 } else { 470 DPRINTFN(0, "Usage set dropped!\n"); 471 } 472 s->susage = 0; 473 break; 474 case 3: 475 c->designator_index = dval; 476 break; 477 case 4: 478 c->designator_minimum = dval; 479 break; 480 case 5: 481 c->designator_maximum = dval; 482 break; 483 case 7: 484 c->string_index = dval; 485 break; 486 case 8: 487 c->string_minimum = dval; 488 break; 489 case 9: 490 c->string_maximum = dval; 491 break; 492 case 10: 493 c->set_delimiter = dval; 494 break; 495 default: 496 DPRINTFN(0, "Local bTag=%d\n", bTag); 497 break; 498 } 499 break; 500 default: 501 DPRINTFN(0, "default bType=%d\n", bType); 502 break; 503 } 504 } 505 return (0); 506 } 507 508 /*------------------------------------------------------------------------* 509 * hid_report_size 510 *------------------------------------------------------------------------*/ 511 int 512 hid_report_size(const void *buf, usb_size_t len, enum hid_kind k, uint8_t *id) 513 { 514 struct hid_data *d; 515 struct hid_item h; 516 uint32_t temp; 517 uint32_t hpos; 518 uint32_t lpos; 519 uint8_t any_id; 520 521 any_id = 0; 522 hpos = 0; 523 lpos = 0xFFFFFFFF; 524 525 for (d = hid_start_parse(buf, len, 1 << k); hid_get_item(d, &h);) { 526 if (h.kind == k) { 527 /* check for ID-byte presense */ 528 if ((h.report_ID != 0) && !any_id) { 529 if (id != NULL) 530 *id = h.report_ID; 531 any_id = 1; 532 } 533 /* compute minimum */ 534 if (lpos > h.loc.pos) 535 lpos = h.loc.pos; 536 /* compute end position */ 537 temp = h.loc.pos + (h.loc.size * h.loc.count); 538 /* compute maximum */ 539 if (hpos < temp) 540 hpos = temp; 541 } 542 } 543 hid_end_parse(d); 544 545 /* safety check - can happen in case of currupt descriptors */ 546 if (lpos > hpos) 547 temp = 0; 548 else 549 temp = hpos - lpos; 550 551 /* check for ID byte */ 552 if (any_id) 553 temp += 8; 554 else if (id != NULL) 555 *id = 0; 556 557 /* return length in bytes rounded up */ 558 return ((temp + 7) / 8); 559 } 560 561 /*------------------------------------------------------------------------* 562 * hid_locate 563 *------------------------------------------------------------------------*/ 564 int 565 hid_locate(const void *desc, usb_size_t size, uint32_t u, enum hid_kind k, 566 uint8_t index, struct hid_location *loc, uint32_t *flags, uint8_t *id) 567 { 568 struct hid_data *d; 569 struct hid_item h; 570 571 for (d = hid_start_parse(desc, size, 1 << k); hid_get_item(d, &h);) { 572 if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) { 573 if (index--) 574 continue; 575 if (loc != NULL) 576 *loc = h.loc; 577 if (flags != NULL) 578 *flags = h.flags; 579 if (id != NULL) 580 *id = h.report_ID; 581 hid_end_parse(d); 582 return (1); 583 } 584 } 585 if (loc != NULL) 586 loc->size = 0; 587 if (flags != NULL) 588 *flags = 0; 589 if (id != NULL) 590 *id = 0; 591 hid_end_parse(d); 592 return (0); 593 } 594 595 /*------------------------------------------------------------------------* 596 * hid_get_data 597 *------------------------------------------------------------------------*/ 598 uint32_t 599 hid_get_data(const uint8_t *buf, usb_size_t len, struct hid_location *loc) 600 { 601 uint32_t hpos = loc->pos; 602 uint32_t hsize = loc->size; 603 uint32_t data; 604 uint32_t rpos; 605 uint8_t n; 606 607 DPRINTFN(11, "hid_get_data: loc %d/%d\n", hpos, hsize); 608 609 /* Range check and limit */ 610 if (hsize == 0) 611 return (0); 612 if (hsize > 32) 613 hsize = 32; 614 615 /* Get data in a safe way */ 616 data = 0; 617 rpos = (hpos / 8); 618 n = (hsize + 7) / 8; 619 rpos += n; 620 while (n--) { 621 rpos--; 622 if (rpos < len) 623 data |= buf[rpos] << (8 * n); 624 } 625 626 /* Correctly shift down data */ 627 data = (data >> (hpos % 8)); 628 629 /* Mask and sign extend in one */ 630 n = 32 - hsize; 631 data = ((int32_t)data << n) >> n; 632 633 DPRINTFN(11, "hid_get_data: loc %d/%d = %lu\n", 634 loc->pos, loc->size, (long)data); 635 return (data); 636 } 637 638 /*------------------------------------------------------------------------* 639 * hid_is_collection 640 *------------------------------------------------------------------------*/ 641 int 642 hid_is_collection(const void *desc, usb_size_t size, uint32_t usage) 643 { 644 struct hid_data *hd; 645 struct hid_item hi; 646 int err; 647 648 hd = hid_start_parse(desc, size, hid_input); 649 if (hd == NULL) 650 return (0); 651 652 while ((err = hid_get_item(hd, &hi))) { 653 if (hi.kind == hid_collection && 654 hi.usage == usage) 655 break; 656 } 657 hid_end_parse(hd); 658 return (err); 659 } 660 661 /*------------------------------------------------------------------------* 662 * hid_get_descriptor_from_usb 663 * 664 * This function will search for a HID descriptor between two USB 665 * interface descriptors. 666 * 667 * Return values: 668 * NULL: No more HID descriptors. 669 * Else: Pointer to HID descriptor. 670 *------------------------------------------------------------------------*/ 671 struct usb_hid_descriptor * 672 hid_get_descriptor_from_usb(struct usb_config_descriptor *cd, 673 struct usb_interface_descriptor *id) 674 { 675 struct usb_descriptor *desc = (void *)id; 676 677 if (desc == NULL) { 678 return (NULL); 679 } 680 while ((desc = usb_desc_foreach(cd, desc))) { 681 if ((desc->bDescriptorType == UDESC_HID) && 682 (desc->bLength >= USB_HID_DESCRIPTOR_SIZE(0))) { 683 return (void *)desc; 684 } 685 if (desc->bDescriptorType == UDESC_INTERFACE) { 686 break; 687 } 688 } 689 return (NULL); 690 } 691 692 /*------------------------------------------------------------------------* 693 * usbd_req_get_hid_desc 694 * 695 * This function will read out an USB report descriptor from the USB 696 * device. 697 * 698 * Return values: 699 * NULL: Failure. 700 * Else: Success. The pointer should eventually be passed to free(). 701 *------------------------------------------------------------------------*/ 702 usb_error_t 703 usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx, 704 void **descp, uint16_t *sizep, 705 struct malloc_type *mem, uint8_t iface_index) 706 { 707 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 708 struct usb_hid_descriptor *hid; 709 usb_error_t err; 710 711 if ((iface == NULL) || (iface->idesc == NULL)) { 712 return (USB_ERR_INVAL); 713 } 714 hid = hid_get_descriptor_from_usb 715 (usbd_get_config_descriptor(udev), iface->idesc); 716 717 if (hid == NULL) { 718 return (USB_ERR_IOERROR); 719 } 720 *sizep = UGETW(hid->descrs[0].wDescriptorLength); 721 if (*sizep == 0) { 722 return (USB_ERR_IOERROR); 723 } 724 if (mtx) 725 mtx_unlock(mtx); 726 727 *descp = malloc(*sizep, mem, M_ZERO | M_WAITOK); 728 729 if (mtx) 730 mtx_lock(mtx); 731 732 if (*descp == NULL) { 733 return (USB_ERR_NOMEM); 734 } 735 err = usbd_req_get_report_descriptor 736 (udev, mtx, *descp, *sizep, iface_index); 737 738 if (err) { 739 free(*descp, mem); 740 *descp = NULL; 741 return (err); 742 } 743 return (USB_ERR_NORMAL_COMPLETION); 744 } 745