Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/usb/usb_hid.c
Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
#endif /* USB_GLOBAL_INCLUDE_FILE */ | #endif /* USB_GLOBAL_INCLUDE_FILE */ | ||||
static void hid_clear_local(struct hid_item *); | static void hid_clear_local(struct hid_item *); | ||||
static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize); | static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize); | ||||
#define MAXUSAGE 64 | #define MAXUSAGE 64 | ||||
#define MAXPUSH 4 | #define MAXPUSH 4 | ||||
#define MAXID 16 | #define MAXID 16 | ||||
#define MAXLOCCNT 1024 | |||||
struct hid_pos_data { | struct hid_pos_data { | ||||
int32_t rid; | int32_t rid; | ||||
uint32_t pos; | uint32_t pos; | ||||
}; | }; | ||||
struct hid_data { | struct hid_data { | ||||
const uint8_t *start; | const uint8_t *start; | ||||
const uint8_t *end; | const uint8_t *end; | ||||
const uint8_t *p; | const uint8_t *p; | ||||
struct hid_item cur[MAXPUSH]; | struct hid_item cur[MAXPUSH]; | ||||
struct hid_pos_data last_pos[MAXID]; | struct hid_pos_data last_pos[MAXID]; | ||||
int32_t usages_min[MAXUSAGE]; | int32_t usages_min[MAXUSAGE]; | ||||
int32_t usages_max[MAXUSAGE]; | int32_t usages_max[MAXUSAGE]; | ||||
int32_t usage_last; /* last seen usage */ | int32_t usage_last; /* last seen usage */ | ||||
uint32_t loc_size; /* last seen size */ | uint32_t loc_size; /* last seen size */ | ||||
uint32_t loc_count; /* last seen count */ | uint32_t loc_count; /* last seen count */ | ||||
uint32_t ncount; /* end usage item count */ | |||||
uint32_t icount; /* current usage item count */ | |||||
uint8_t kindset; /* we have 5 kinds so 8 bits are enough */ | uint8_t kindset; /* we have 5 kinds so 8 bits are enough */ | ||||
uint8_t pushlevel; /* current pushlevel */ | uint8_t pushlevel; /* current pushlevel */ | ||||
uint8_t ncount; /* end usage item count */ | |||||
uint8_t icount; /* current usage item count */ | |||||
uint8_t nusage; /* end "usages_min/max" index */ | uint8_t nusage; /* end "usages_min/max" index */ | ||||
uint8_t iusage; /* current "usages_min/max" index */ | uint8_t iusage; /* current "usages_min/max" index */ | ||||
uint8_t ousage; /* current "usages_min/max" offset */ | uint8_t ousage; /* current "usages_min/max" offset */ | ||||
uint8_t susage; /* usage set flags */ | uint8_t susage; /* usage set flags */ | ||||
}; | }; | ||||
/*------------------------------------------------------------------------* | /*------------------------------------------------------------------------* | ||||
* hid_clear_local | * hid_clear_local | ||||
▲ Show 20 Lines • Show All 236 Lines • ▼ Show 20 Lines | default: | ||||
continue; | continue; | ||||
} | } | ||||
switch (bType) { | switch (bType) { | ||||
case 0: /* Main */ | case 0: /* Main */ | ||||
switch (bTag) { | switch (bTag) { | ||||
case 8: /* Input */ | case 8: /* Input */ | ||||
c->kind = hid_input; | c->kind = hid_input; | ||||
c->flags = dval; | |||||
ret: | ret: | ||||
c->flags = dval; | |||||
c->loc.count = s->loc_count; | c->loc.count = s->loc_count; | ||||
c->loc.size = s->loc_size; | c->loc.size = s->loc_size; | ||||
if (c->flags & HIO_VARIABLE) { | if (c->flags & HIO_VARIABLE) { | ||||
/* range check usage count */ | /* range check usage count */ | ||||
if (c->loc.count > 255) { | if (c->loc.count > MAXLOCCNT) { | ||||
DPRINTFN(0, "Number of " | DPRINTFN(0, "Number of " | ||||
"items(%u) truncated to 255\n", | "items(%u) truncated to %u\n", | ||||
(unsigned)(c->loc.count)); | (unsigned)(c->loc.count), | ||||
s->ncount = 255; | MAXLOCCNT); | ||||
s->ncount = MAXLOCCNT; | |||||
} else | } else | ||||
s->ncount = c->loc.count; | s->ncount = c->loc.count; | ||||
/* | /* | ||||
* The "top" loop will return | * The "top" loop will return | ||||
* one and one item: | * one and one item: | ||||
*/ | */ | ||||
c->loc.count = 1; | c->loc.count = 1; | ||||
} else { | } else { | ||||
s->ncount = 1; | s->ncount = 1; | ||||
} | } | ||||
goto top; | goto top; | ||||
case 9: /* Output */ | case 9: /* Output */ | ||||
c->kind = hid_output; | c->kind = hid_output; | ||||
c->flags = dval; | |||||
goto ret; | goto ret; | ||||
case 10: /* Collection */ | case 10: /* Collection */ | ||||
c->kind = hid_collection; | c->kind = hid_collection; | ||||
c->collection = dval; | c->collection = dval; | ||||
c->collevel++; | c->collevel++; | ||||
c->usage = s->usage_last; | c->usage = s->usage_last; | ||||
*h = *c; | *h = *c; | ||||
return (1); | return (1); | ||||
case 11: /* Feature */ | case 11: /* Feature */ | ||||
c->kind = hid_feature; | c->kind = hid_feature; | ||||
c->flags = dval; | |||||
goto ret; | goto ret; | ||||
case 12: /* End collection */ | case 12: /* End collection */ | ||||
c->kind = hid_endcollection; | c->kind = hid_endcollection; | ||||
if (c->collevel == 0) { | if (c->collevel == 0) { | ||||
DPRINTFN(0, "invalid end collection\n"); | DPRINTFN(0, "invalid end collection\n"); | ||||
return (0); | return (0); | ||||
} | } | ||||
c->collevel--; | c->collevel--; | ||||
▲ Show 20 Lines • Show All 605 Lines • Show Last 20 Lines |