summaryrefslogtreecommitdiff
path: root/sys/dev/usb/hid.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/hid.c')
-rw-r--r--sys/dev/usb/hid.c143
1 files changed, 51 insertions, 92 deletions
diff --git a/sys/dev/usb/hid.c b/sys/dev/usb/hid.c
index 2a8a91a35cb..d14721fe107 100644
--- a/sys/dev/usb/hid.c
+++ b/sys/dev/usb/hid.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: hid.c,v 1.10 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: hid.c,v 1.22 2002/01/12 17:11:03 tsutsui Exp $ */
+/* $OpenBSD: hid.c,v 1.11 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: hid.c,v 1.16 2000/06/01 14:28:57 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/hid.c,v 1.11 1999/11/17 22:33:39 n_hibma Exp $ */
/*
@@ -51,10 +51,10 @@
#include <dev/usb/hid.h>
-#ifdef UHIDEV_DEBUG
-#define DPRINTF(x) if (uhidevdebug) logprintf x
-#define DPRINTFN(n,x) if (uhidevdebug>(n)) logprintf x
-extern int uhidevdebug;
+#ifdef UHID_DEBUG
+#define DPRINTF(x) if (usbdebug) logprintf x
+#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
+extern int usbdebug;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
@@ -62,7 +62,7 @@ extern int uhidevdebug;
Static void hid_clear_local(struct hid_item *);
-#define MAXUSAGE 256
+#define MAXUSAGE 100
struct hid_data {
u_char *start;
u_char *end;
@@ -73,14 +73,13 @@ struct hid_data {
int minset;
int multi;
int multimax;
- enum hid_kind kind;
+ int kindset;
};
Static void
hid_clear_local(struct hid_item *c)
{
- DPRINTFN(5,("hid_clear_local\n"));
c->usage = 0;
c->usage_minimum = 0;
c->usage_maximum = 0;
@@ -94,18 +93,15 @@ hid_clear_local(struct hid_item *c)
}
struct hid_data *
-hid_start_parse(void *d, int len, enum hid_kind kind)
+hid_start_parse(void *d, int len, int kindset)
{
struct hid_data *s;
s = malloc(sizeof *s, M_TEMP, M_WAITOK);
- if (s == NULL)
- panic("hid_start_parse");
memset(s, 0, sizeof *s);
-
s->start = s->p = d;
s->end = (char *)d + len;
- s->kind = kind;
+ s->kindset = kindset;
return (s);
}
@@ -132,19 +128,15 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
u_char *p;
struct hid_item *hi;
int i;
- enum hid_kind retkind;
top:
- DPRINTFN(5,("hid_get_item: multi=%d multimax=%d\n",
- s->multi, s->multimax));
if (s->multimax != 0) {
if (s->multi < s->multimax) {
c->usage = s->usages[min(s->multi, s->nu-1)];
s->multi++;
*h = *c;
c->loc.pos += c->loc.size;
- h->next = NULL;
- DPRINTFN(5,("return multi\n"));
+ h->next = 0;
return (1);
} else {
c->loc.count = s->multimax;
@@ -182,12 +174,12 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
dval = 0;
break;
case 1:
- dval = /*(int8_t)*/ *data++;
+ dval = (int8_t)*data++;
break;
case 2:
dval = *data++;
dval |= *data++ << 8;
- dval = /*(int16_t)*/ dval;
+ dval = (int16_t)dval;
break;
case 4:
dval = *data++;
@@ -200,22 +192,15 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
continue;
}
- DPRINTFN(5,("hid_get_item: bType=%d bTag=%d dval=%d\n",
- bType, bTag, dval));
switch (bType) {
case 0: /* Main */
switch (bTag) {
case 8: /* Input */
- retkind = hid_input;
- ret:
- if (s->kind != retkind) {
- s->minset = 0;
- s->nu = 0;
- hid_clear_local(c);
+ if (!(s->kindset & (1 << hid_input)))
continue;
- }
- c->kind = retkind;
+ c->kind = hid_input;
c->flags = dval;
+ ret:
if (c->flags & HIO_VARIABLE) {
s->multimax = c->loc.count;
s->multi = 0;
@@ -232,18 +217,19 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
}
goto top;
} else {
- c->usage = c->_usage_page; /* XXX */
*h = *c;
- h->next = NULL;
+ h->next = 0;
c->loc.pos +=
- c->loc.size * c->loc.count;
- s->minset = 0;
- s->nu = 0;
+ c->loc.size * c->loc.count;
hid_clear_local(c);
+ s->minset = 0;
return (1);
}
case 9: /* Output */
- retkind = hid_output;
+ if (!(s->kindset & (1 << hid_output)))
+ continue;
+ c->kind = hid_output;
+ c->flags = dval;
goto ret;
case 10: /* Collection */
c->kind = hid_collection;
@@ -254,12 +240,16 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
s->nu = 0;
return (1);
case 11: /* Feature */
- retkind = hid_feature;
+ if (!(s->kindset & (1 << hid_feature)))
+ continue;
+ c->kind = hid_feature;
+ c->flags = dval;
goto ret;
case 12: /* End collection */
c->kind = hid_endcollection;
c->collevel--;
*h = *c;
+ hid_clear_local(c);
s->nu = 0;
return (1);
default:
@@ -295,7 +285,6 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
break;
case 8:
c->report_ID = dval;
- c->loc.pos = 0;
break;
case 9:
c->loc.count = dval;
@@ -378,51 +367,35 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
}
int
-hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t id)
+hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t *idp)
{
struct hid_data *d;
struct hid_item h;
- int lo, hi;
+ int size, id;
- h.report_ID = 0;
- lo = hi = -1;
- DPRINTFN(2,("hid_report_size: kind=%d id=%d\n", k, id));
- for (d = hid_start_parse(buf, len, k); hid_get_item(d, &h); ) {
- DPRINTFN(2,("hid_report_size: item kind=%d id=%d pos=%d "
- "size=%d count=%d\n",
- h.kind, h.report_ID, h.loc.pos, h.loc.size,
- h.loc.count));
- if (h.report_ID == id && h.kind == k) {
- if (lo < 0) {
- lo = h.loc.pos;
-#ifdef DIAGNOSTIC
- if (lo != 0) {
- printf("hid_report_size: lo != 0\n");
- }
-#endif
- }
- hi = h.loc.pos + h.loc.size * h.loc.count;
- DPRINTFN(2,("hid_report_size: lo=%d hi=%d\n", lo, hi));
- }
- }
+ id = 0;
+ for (d = hid_start_parse(buf, len, 1<<k); hid_get_item(d, &h); )
+ if (h.report_ID != 0)
+ id = h.report_ID;
hid_end_parse(d);
- return ((hi - lo + 7) / 8);
+ size = h.loc.pos;
+ if (id != 0) {
+ size += 8;
+ *idp = id; /* XXX wrong */
+ } else
+ *idp = 0;
+ return ((size + 7) / 8);
}
int
-hid_locate(void *desc, int size, u_int32_t u, u_int8_t id, enum hid_kind k,
+hid_locate(void *desc, int size, u_int32_t u, enum hid_kind k,
struct hid_location *loc, u_int32_t *flags)
{
struct hid_data *d;
struct hid_item h;
- h.report_ID = 0;
- DPRINTFN(5,("hid_locate: enter usage=0x%x kind=%d id=%d\n", u, k, id));
- for (d = hid_start_parse(desc, size, k); hid_get_item(d, &h); ) {
- DPRINTFN(5,("hid_locate: usage=0x%x kind=%d id=%d flags=0x%x\n",
- h.usage, h.kind, h.report_ID, h.flags));
- if (h.kind == k && !(h.flags & HIO_CONST) &&
- h.usage == u && h.report_ID == id) {
+ for (d = hid_start_parse(desc, size, 1<<k); hid_get_item(d, &h); ) {
+ if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) {
if (loc != NULL)
*loc = h.loc;
if (flags != NULL)
@@ -464,33 +437,19 @@ hid_get_data(u_char *buf, struct hid_location *loc)
}
int
-hid_is_collection(void *desc, int size, u_int8_t id, u_int32_t usage)
+hid_is_collection(void *desc, int size, u_int32_t usage)
{
struct hid_data *hd;
struct hid_item hi;
- u_int32_t coll_usage = ~0;
+ int err;
- hd = hid_start_parse(desc, size, hid_none);
+ hd = hid_start_parse(desc, size, hid_input);
if (hd == NULL)
return (0);
- DPRINTFN(2,("hid_is_collection: id=%d usage=0x%x\n", id, usage));
- while (hid_get_item(hd, &hi)) {
- DPRINTFN(2,("hid_is_collection: kind=%d id=%d usage=0x%x"
- "(0x%x)\n",
- hi.kind, hi.report_ID, hi.usage, coll_usage));
- if (hi.kind == hid_collection &&
- hi.collection == HCOLL_APPLICATION)
- coll_usage = hi.usage;
- if (hi.kind == hid_endcollection &&
- coll_usage == usage &&
- hi.report_ID == id) {
- DPRINTFN(2,("hid_is_collection: found\n"));
- hid_end_parse(hd);
- return (1);
- }
- }
- DPRINTFN(2,("hid_is_collection: not found\n"));
+ err = hid_get_item(hd, &hi) &&
+ hi.kind == hid_collection &&
+ hi.usage == usage;
hid_end_parse(hd);
- return (0);
+ return (err);
}