usb_hid.c (188942) | usb_hid.c (188981) |
---|---|
1/* $NetBSD: hid.c,v 1.17 2001/11/13 06:24:53 lukem Exp $ */ 2 3 4#include <sys/cdefs.h> | 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: head/sys/dev/usb/usb_hid.c 188942 2009-02-23 18:31:00Z thompsa $"); | 5__FBSDID("$FreeBSD: head/sys/dev/usb/usb_hid.c 188981 2009-02-24 03:34:05Z thompsa $"); |
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 * --- 136 unchanged lines hidden (view full) --- 150 c->loc.count = s->multimax; 151 s->multimax = 0; 152 s->nu = 0; 153 hid_clear_local(c); 154 } 155 } 156 for (;;) { 157 p = s->p; | 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 * --- 136 unchanged lines hidden (view full) --- 150 c->loc.count = s->multimax; 151 s->multimax = 0; 152 s->nu = 0; 153 hid_clear_local(c); 154 } 155 } 156 for (;;) { 157 p = s->p; |
158 if (p >= s->end) | 158 if ((p >= s->end) || (p < s->start)) |
159 return (0); 160 161 bSize = *p++; 162 if (bSize == 0xfe) { 163 /* long item */ 164 bSize = *p++; 165 bSize |= *p++ << 8; 166 bTag = *p++; --- 216 unchanged lines hidden (view full) --- 383 } 384 } 385} 386 387/*------------------------------------------------------------------------* 388 * hid_report_size 389 *------------------------------------------------------------------------*/ 390int | 159 return (0); 160 161 bSize = *p++; 162 if (bSize == 0xfe) { 163 /* long item */ 164 bSize = *p++; 165 bSize |= *p++ << 8; 166 bTag = *p++; --- 216 unchanged lines hidden (view full) --- 383 } 384 } 385} 386 387/*------------------------------------------------------------------------* 388 * hid_report_size 389 *------------------------------------------------------------------------*/ 390int |
391hid_report_size(const void *buf, int len, enum hid_kind k, uint8_t *idp) | 391hid_report_size(const void *buf, int len, enum hid_kind k, uint8_t *id) |
392{ 393 struct hid_data *d; 394 struct hid_item h; | 392{ 393 struct hid_data *d; 394 struct hid_item h; |
395 int hi, lo, size, id; | 395 uint32_t temp; 396 uint32_t hpos; 397 uint32_t lpos; 398 uint8_t any_id; |
396 | 399 |
397 id = 0; 398 hi = lo = -1; 399 for (d = hid_start_parse(buf, len, 1 << k); hid_get_item(d, &h);) | 400 any_id = 0; 401 hpos = 0; 402 lpos = 0xFFFFFFFF; 403 404 for (d = hid_start_parse(buf, len, 1 << k); hid_get_item(d, &h);) { |
400 if (h.kind == k) { | 405 if (h.kind == k) { |
401 if (h.report_ID != 0 && !id) 402 id = h.report_ID; 403 if (h.report_ID == id) { 404 if (lo < 0) 405 lo = h.loc.pos; 406 hi = h.loc.pos + h.loc.size * h.loc.count; | 406 /* check for ID-byte presense */ 407 if ((h.report_ID != 0) && !any_id) { 408 if (id != NULL) 409 *id = h.report_ID; 410 any_id = 1; |
407 } | 411 } |
412 /* compute minimum */ 413 if (lpos > h.loc.pos) 414 lpos = h.loc.pos; 415 /* compute end position */ 416 temp = h.loc.pos + (h.loc.size * h.loc.count); 417 /* compute maximum */ 418 if (hpos < temp) 419 hpos = temp; |
|
408 } | 420 } |
421 } |
|
409 hid_end_parse(d); | 422 hid_end_parse(d); |
410 size = hi - lo; 411 if (id != 0) { 412 size += 8; 413 *idp = id; /* XXX wrong */ 414 } else 415 *idp = 0; 416 return ((size + 7) / 8); | 423 424 /* safety check - can happen in case of currupt descriptors */ 425 if (lpos > hpos) 426 temp = 0; 427 else 428 temp = hpos - lpos; 429 430 /* check for ID byte */ 431 if (any_id) 432 temp += 8; 433 else if (id != NULL) 434 *id = 0; 435 436 /* return length in bytes rounded up */ 437 return ((temp + 7) / 8); |
417} 418 419/*------------------------------------------------------------------------* 420 * hid_locate 421 *------------------------------------------------------------------------*/ 422int 423hid_locate(const void *desc, int size, uint32_t u, enum hid_kind k, | 438} 439 440/*------------------------------------------------------------------------* 441 * hid_locate 442 *------------------------------------------------------------------------*/ 443int 444hid_locate(const void *desc, int size, uint32_t u, enum hid_kind k, |
424 struct hid_location *loc, uint32_t *flags) | 445 struct hid_location *loc, uint32_t *flags, uint8_t *id) |
425{ 426 struct hid_data *d; 427 struct hid_item h; 428 429 for (d = hid_start_parse(desc, size, 1 << k); hid_get_item(d, &h);) { 430 if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) { 431 if (loc != NULL) 432 *loc = h.loc; 433 if (flags != NULL) 434 *flags = h.flags; | 446{ 447 struct hid_data *d; 448 struct hid_item h; 449 450 for (d = hid_start_parse(desc, size, 1 << k); hid_get_item(d, &h);) { 451 if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) { 452 if (loc != NULL) 453 *loc = h.loc; 454 if (flags != NULL) 455 *flags = h.flags; |
456 if (id != NULL) 457 *id = h.report_ID; |
|
435 hid_end_parse(d); 436 return (1); 437 } 438 } | 458 hid_end_parse(d); 459 return (1); 460 } 461 } |
462 if (loc != NULL) 463 loc->size = 0; 464 if (flags != NULL) 465 *flags = 0; 466 if (id != NULL) 467 *id = 0; |
|
439 hid_end_parse(d); | 468 hid_end_parse(d); |
440 loc->size = 0; | |
441 return (0); 442} 443 444/*------------------------------------------------------------------------* 445 * hid_get_data 446 *------------------------------------------------------------------------*/ 447uint32_t 448hid_get_data(const uint8_t *buf, uint32_t len, struct hid_location *loc) 449{ 450 uint32_t hpos = loc->pos; 451 uint32_t hsize = loc->size; 452 uint32_t data; | 469 return (0); 470} 471 472/*------------------------------------------------------------------------* 473 * hid_get_data 474 *------------------------------------------------------------------------*/ 475uint32_t 476hid_get_data(const uint8_t *buf, uint32_t len, struct hid_location *loc) 477{ 478 uint32_t hpos = loc->pos; 479 uint32_t hsize = loc->size; 480 uint32_t data; |
453 int i, s, t; | 481 uint32_t rpos; 482 uint8_t n; |
454 455 DPRINTFN(11, "hid_get_data: loc %d/%d\n", hpos, hsize); 456 | 483 484 DPRINTFN(11, "hid_get_data: loc %d/%d\n", hpos, hsize); 485 |
486 /* Range check and limit */ |
|
457 if (hsize == 0) 458 return (0); | 487 if (hsize == 0) 488 return (0); |
489 if (hsize > 32) 490 hsize = 32; |
|
459 | 491 |
492 /* Get data in a safe way */ |
|
460 data = 0; | 493 data = 0; |
461 s = hpos / 8; 462 for (i = hpos; i < (hpos + hsize); i += 8) { 463 t = (i / 8); 464 if (t < len) { 465 data |= buf[t] << ((t - s) * 8); 466 } | 494 rpos = (hpos / 8); 495 n = (hsize + 7) / 8; 496 rpos += n; 497 while (n--) { 498 rpos--; 499 if (rpos < len) 500 data |= buf[rpos] << (8 * n); |
467 } | 501 } |
468 data >>= hpos % 8; 469 data &= (1 << hsize) - 1; 470 hsize = 32 - hsize; 471 /* Sign extend */ 472 data = ((int32_t)data << hsize) >> hsize; | 502 503 /* Correctly shift down data */ 504 data = (data >> (hpos % 8)); 505 506 /* Mask and sign extend in one */ 507 n = 32 - hsize; 508 data = ((int32_t)data << n) >> n; 509 |
473 DPRINTFN(11, "hid_get_data: loc %d/%d = %lu\n", 474 loc->pos, loc->size, (long)data); 475 return (data); 476} 477 478/*------------------------------------------------------------------------* 479 * hid_is_collection 480 *------------------------------------------------------------------------*/ --- 102 unchanged lines hidden --- | 510 DPRINTFN(11, "hid_get_data: loc %d/%d = %lu\n", 511 loc->pos, loc->size, (long)data); 512 return (data); 513} 514 515/*------------------------------------------------------------------------* 516 * hid_is_collection 517 *------------------------------------------------------------------------*/ --- 102 unchanged lines hidden --- |