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
This commit is contained in:
parent
bf3254f22e
commit
65c7bc9cbf
@ -78,11 +78,19 @@ static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize);
|
||||
|
||||
#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 hid_item *h)
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user