usb/137188: commit references a PR
dfilter service
dfilter at FreeBSD.ORG
Thu Jul 30 00:20:12 UTC 2009
The following reply was made to PR usb/137188; it has been noted by GNATS.
From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:
Subject: Re: usb/137188: commit references a PR
Date: Thu, 30 Jul 2009 00:17:20 +0000 (UTC)
Author: alfred
Date: Thu Jul 30 00:17:08 2009
New Revision: 195967
URL: http://svn.freebsd.org/changeset/base/195967
Log:
USB CORE - Improve HID parsing
See PR description for more info. Patch is
implemented differently than suggested, but
having the same result.
PR: usb/137188
Submitted by: hps
Approved by: re
Modified:
head/sys/dev/usb/usb_hid.c
Modified: head/sys/dev/usb/usb_hid.c
==============================================================================
--- head/sys/dev/usb/usb_hid.c Thu Jul 30 00:16:50 2009 (r195966)
+++ head/sys/dev/usb/usb_hid.c Thu Jul 30 00:17:08 2009 (r195967)
@@ -78,11 +78,19 @@ static uint8_t hid_get_byte(struct hid_d
#define MAXUSAGE 64
#define MAXPUSH 4
+#define MAXID 16
+
+struct hid_pos_data {
+ int32_t rid;
+ uint32_t pos;
+};
+
struct hid_data {
const uint8_t *start;
const uint8_t *end;
const uint8_t *p;
struct hid_item cur[MAXPUSH];
+ struct hid_pos_data last_pos[MAXID];
int32_t usages_min[MAXUSAGE];
int32_t usages_max[MAXUSAGE];
int32_t usage_last; /* last seen usage */
@@ -119,6 +127,58 @@ hid_clear_local(struct hid_item *c)
c->set_delimiter = 0;
}
+static void
+hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID)
+{
+ uint8_t i;
+
+ /* check for same report ID - optimise */
+
+ if (c->report_ID == next_rID)
+ return;
+
+ /* save current position for current rID */
+
+ if (c->report_ID == 0) {
+ i = 0;
+ } else {
+ for (i = 1; i != MAXID; i++) {
+ if (s->last_pos[i].rid == c->report_ID)
+ break;
+ if (s->last_pos[i].rid == 0)
+ break;
+ }
+ }
+ if (i != MAXID) {
+ s->last_pos[i].rid = c->report_ID;
+ s->last_pos[i].pos = c->loc.pos;
+ }
+
+ /* store next report ID */
+
+ c->report_ID = next_rID;
+
+ /* lookup last position for next rID */
+
+ if (next_rID == 0) {
+ i = 0;
+ } else {
+ for (i = 1; i != MAXID; i++) {
+ if (s->last_pos[i].rid == next_rID)
+ break;
+ if (s->last_pos[i].rid == 0)
+ break;
+ }
+ }
+ if (i != MAXID) {
+ s->last_pos[i].rid = next_rID;
+ c->loc.pos = s->last_pos[i].pos;
+ } else {
+ DPRINTF("Out of RID entries, position is set to zero!\n");
+ c->loc.pos = 0;
+ }
+}
+
/*------------------------------------------------------------------------*
* hid_start_parse
*------------------------------------------------------------------------*/
@@ -373,9 +433,7 @@ hid_get_item(struct hid_data *s, struct
s->loc_size = dval & mask;
break;
case 8:
- c->report_ID = dval;
- /* new report - reset position */
- c->loc.pos = 0;
+ hid_switch_rid(s, c, dval);
break;
case 9:
/* mask because value is unsigned */
_______________________________________________
svn-src-all at freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
More information about the freebsd-usb
mailing list