Summary: | [usb8][patch] correctly handle USB report descriptors with interleaved report IDs | ||||||
---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | Eygene Ryabinkin <rea-fbsd> | ||||
Component: | usb | Assignee: | freebsd-usb (Nobody) <usb> | ||||
Status: | Closed FIXED | ||||||
Severity: | Affects Only Me | CC: | hselasky | ||||
Priority: | Normal | ||||||
Version: | 8.0-BETA2 | ||||||
Hardware: | Any | ||||||
OS: | Any | ||||||
Attachments: |
|
Description
Eygene Ryabinkin
2009-07-27 20:40:01 UTC
On Monday 27 July 2009 21:36:29 Eygene Ryabinkin wrote: > usb/137188 Hi, Kernel part committed. I removed the malloc() part from the initial patch, because it is simpler to not use malloc in this case. Is the following working for you: http://perforce.freebsd.org/chv.cgi?CH=166650 Second, can you port the kernel HID parser into libusbhid, because the kernel one is more advanced and handles more HID features than the userland one. When you are done, send a new patch. Thanks, --HPS 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@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" State Changed From-To: open->patched Mark as patched. It's fixed in HEAD but I have no idea if it is applicable or even a problem in 7.x. Hopefully the submitter or somebody more involved with USB knows. Either way, "patched" is more appropriate. This patch is MFC'ed to FreeBSD 8/9 and 10. --HPS |