svn commit: r205728 - head/lib/libusbhid

Kai Wang kaiw at FreeBSD.org
Sat Mar 27 08:00:17 UTC 2010


Author: kaiw
Date: Sat Mar 27 08:00:16 2010
New Revision: 205728
URL: http://svn.freebsd.org/changeset/base/205728

Log:
  Merge improvements from kernel HID parser to the userland usbhid(3)
  parser.  This merge does not change any API and should not break any
  native or thirdparty applications.
  
  Changes include:
  
  * Merge multiple report ID support and other improvements from kernel
    HID parser.
  * Ignore rid argument in hid_start_parser, parse all the report items since
    we now support multiple report ID.
  * Skip report ID byte in hid_get_data() and set report ID byte in
    hid_set_data(), if report ID is non-zero.
  * Reimplement hid_get_report_id: instead get report id from uhid device
    (which is always 0), try parsing the report descriptor and return the
    first report ID encountered.
  
  Reviewed by:	hps
  Silent on:	-usb mailing list

Modified:
  head/lib/libusbhid/data.c
  head/lib/libusbhid/descr.c
  head/lib/libusbhid/parse.c
  head/lib/libusbhid/usage.c
  head/lib/libusbhid/usbhid.h
  head/lib/libusbhid/usbvar.h

Modified: head/lib/libusbhid/data.c
==============================================================================
--- head/lib/libusbhid/data.c	Sat Mar 27 06:53:11 2010	(r205727)
+++ head/lib/libusbhid/data.c	Sat Mar 27 08:00:16 2010	(r205728)
@@ -29,6 +29,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/param.h>
 #include <assert.h>
 #include <stdlib.h>
 #include "usbhid.h"
@@ -36,18 +37,27 @@ __FBSDID("$FreeBSD$");
 int
 hid_get_data(const void *p, const hid_item_t *h)
 {
-	const unsigned char *buf;
-	unsigned int hpos;
-	unsigned int hsize;
-	int data;
+	const uint8_t *buf;
+	uint32_t hpos;
+	uint32_t hsize;
+	uint32_t data;
 	int i, end, offs;
 
 	buf = p;
+
+	/* Skip report ID byte. */
+	if (h->report_ID > 0)
+		buf++;
+
 	hpos = h->pos;			/* bit position of data */
 	hsize = h->report_size;		/* bit length of data */
 
+	/* Range check and limit */
 	if (hsize == 0)
 		return (0);
+	if (hsize > 32)
+		hsize = 32;
+
 	offs = hpos / 8;
 	end = (hpos + hsize) / 8 - offs;
 	data = 0;
@@ -66,12 +76,17 @@ hid_get_data(const void *p, const hid_it
 void
 hid_set_data(void *p, const hid_item_t *h, int data)
 {
-	unsigned char *buf;
-	unsigned int hpos;
-	unsigned int hsize;
+	uint8_t *buf;
+	uint32_t hpos;
+	uint32_t hsize;
 	int i, end, offs, mask;
 
 	buf = p;
+
+	/* Set report ID byte. */
+	if (h->report_ID > 0)
+		*buf++ = h->report_ID & 0xff;
+
 	hpos = h->pos;			/* bit position of data */
 	hsize = h->report_size;		/* bit length of data */
 
@@ -90,5 +105,5 @@ hid_set_data(void *p, const hid_item_t *
 
 	for (i = 0; i <= end; i++)
 		buf[offs + i] = (buf[offs + i] & (mask >> (i*8))) |
-			((data >> (i*8)) & 0xff);
+		    ((data >> (i*8)) & 0xff);
 }

Modified: head/lib/libusbhid/descr.c
==============================================================================
--- head/lib/libusbhid/descr.c	Sat Mar 27 06:53:11 2010	(r205727)
+++ head/lib/libusbhid/descr.c	Sat Mar 27 08:00:16 2010	(r205728)
@@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$");
 #include <unistd.h>
 #include <sys/time.h>
 #include <sys/ioctl.h>
-
 #include <dev/usb/usb_ioctl.h>
 
 #include "usbhid.h"
@@ -59,9 +58,30 @@ hid_set_immed(int fd, int enable)
 int
 hid_get_report_id(int fd)
 {
+	report_desc_t rep;
+	hid_data_t d;
+	hid_item_t h;
+	int kindset;
 	int temp = -1;
 	int ret;
 
+	if ((rep = hid_get_report_desc(fd)) == NULL)
+		goto use_ioctl;
+	kindset = 1 << hid_input | 1 << hid_output | 1 << hid_feature;
+	for (d = hid_start_parse(rep, kindset, 0); hid_get_item(d, &h); ) {
+		/* Return the first report ID we met. */
+		if (h.report_ID != 0) {
+			temp = h.report_ID;
+			break;
+		}
+	}
+	hid_end_parse(d);
+	hid_dispose_report_desc(rep);
+
+	if (temp > 0)
+		return (temp);
+
+use_ioctl:
 	ret = ioctl(fd, USB_GET_REPORT_ID, &temp);
 #ifdef HID_COMPAT7
 	if (ret < 0)

Modified: head/lib/libusbhid/parse.c
==============================================================================
--- head/lib/libusbhid/parse.c	Sat Mar 27 06:53:11 2010	(r205727)
+++ head/lib/libusbhid/parse.c	Sat Mar 27 08:00:16 2010	(r205728)
@@ -40,42 +40,43 @@ __FBSDID("$FreeBSD$");
 #include "usbhid.h"
 #include "usbvar.h"
 
-#define MAXUSAGE 100
-struct hid_data {
-	u_char *start;
-	u_char *end;
-	u_char *p;
-	hid_item_t cur;
-	unsigned int usages[MAXUSAGE];
-	int nusage;
-	int minset;
-	int logminsize;
-	int multi;
-	int multimax;
-	int kindset;
-	int reportid;
-
-	/*
-	 * The start of collection item has no report ID set, so save
-	 * it until we know the ID.
-	 */
-	hid_item_t savedcoll;
-	u_char hassavedcoll;
-	/*
-	 * Absolute data position (bits) for input/output/feature.
-	 *  Assumes that hid_input, hid_output and hid_feature have
-	 *  values 0, 1 and 2.
-	 */
-	unsigned int kindpos[3];
+#define	MAXUSAGE 100
+#define	MAXPUSH 4
+#define	MAXID 64
+
+struct hid_pos_data {
+	int32_t rid;
+	uint32_t pos;
 };
 
-static int min(int x, int y) { return x < y ? x : y; }
-
-static int hid_get_item_raw(hid_data_t s, hid_item_t *h);
+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 */
+	uint32_t loc_size;	/* last seen size */
+	uint32_t loc_count;	/* last seen count */
+	uint8_t	kindset;	/* we have 5 kinds so 8 bits are enough */
+	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	iusage;		/* current "usages_min/max" index */
+	uint8_t ousage;		/* current "usages_min/max" offset */
+	uint8_t	susage;		/* usage set flags */
+};
 
+/*------------------------------------------------------------------------*
+ *	hid_clear_local
+ *------------------------------------------------------------------------*/
 static void
 hid_clear_local(hid_item_t *c)
 {
+
 	c->usage = 0;
 	c->usage_minimum = 0;
 	c->usage_maximum = 0;
@@ -88,8 +89,61 @@ hid_clear_local(hid_item_t *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->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->pos = s->last_pos[i].pos;
+	} else
+		c->pos = 0;	/* Out of RID entries. */
+}
+
+/*------------------------------------------------------------------------*
+ *	hid_start_parse
+ *------------------------------------------------------------------------*/
 hid_data_t
-hid_start_parse(report_desc_t d, int kindset, int id)
+hid_start_parse(report_desc_t d, int kindset, int id __unused)
 {
 	struct hid_data *s;
 
@@ -98,213 +152,207 @@ hid_start_parse(report_desc_t d, int kin
 	s->start = s->p = d->data;
 	s->end = d->data + d->size;
 	s->kindset = kindset;
-	s->reportid = id;
-	s->hassavedcoll = 0;
 	return (s);
 }
 
+/*------------------------------------------------------------------------*
+ *	hid_end_parse
+ *------------------------------------------------------------------------*/
 void
 hid_end_parse(hid_data_t s)
 {
-	while (s->cur.next) {
-		hid_item_t *hi = s->cur.next->next;
-		free(s->cur.next);
-		s->cur.next = hi;
-	}
+
+	if (s == NULL)
+		return;
+
 	free(s);
 }
 
-int
-hid_get_item(hid_data_t s, hid_item_t *h)
+/*------------------------------------------------------------------------*
+ *	get byte from HID descriptor
+ *------------------------------------------------------------------------*/
+static uint8_t
+hid_get_byte(struct hid_data *s, const uint16_t wSize)
 {
-	int r;
+	const uint8_t *ptr;
+	uint8_t retval;
 
-	for (;;) {
-		r = hid_get_item_raw(s, h);
-		if (r <= 0)
-			break;
-		if (h->report_ID == s->reportid || s->reportid == -1)
-			break;
-	}
-	return (r);
-}
+	ptr = s->p;
+
+	/* check if end is reached */
+	if (ptr == s->end)
+		return (0);
 
-#define REPORT_SAVED_COLL \
-	do { \
-		if (s->hassavedcoll) { \
-			*h = s->savedcoll; \
-			h->report_ID = c->report_ID; \
-			s->hassavedcoll = 0; \
-			return (1); \
-		} \
-	} while(/*LINTED*/ 0)
+	/* read out a byte */
+	retval = *ptr;
 
-static int
-hid_get_item_raw(hid_data_t s, hid_item_t *h)
+	/* check if data pointer can be advanced by "wSize" bytes */
+	if ((s->end - ptr) < wSize)
+		ptr = s->end;
+	else
+		ptr += wSize;
+
+	/* update pointer */
+	s->p = ptr;
+
+	return (retval);
+}
+
+/*------------------------------------------------------------------------*
+ *	hid_get_item
+ *------------------------------------------------------------------------*/
+int
+hid_get_item(hid_data_t s, hid_item_t *h)
 {
 	hid_item_t *c;
-	unsigned int bTag = 0, bType = 0, bSize;
-	unsigned char *data;
-	int dval;
-	unsigned char *p;
-	hid_item_t *hi;
-	hid_item_t nc;
-	int i;
-	hid_kind_t retkind;
+	unsigned int bTag, bType, bSize;
+	uint32_t oldpos;
+	int32_t mask;
+	int32_t dval;
 
-	c = &s->cur;
+	if (s == NULL)
+		return (0);
+
+	c = &s->cur[s->pushlevel];
 
  top:
-	if (s->multimax) {
-		REPORT_SAVED_COLL;
-		if (c->logical_minimum >= c->logical_maximum) {
-			if (s->logminsize == 1)
-				c->logical_minimum =(int8_t)c->logical_minimum;
-			else if (s->logminsize == 2)
-				c->logical_minimum =(int16_t)c->logical_minimum;
+	/* check if there is an array of items */
+	if (s->icount < s->ncount) {
+		/* get current usage */
+		if (s->iusage < s->nusage) {
+			dval = s->usages_min[s->iusage] + s->ousage;
+			c->usage = dval;
+			s->usage_last = dval;
+			if (dval == s->usages_max[s->iusage]) {
+				s->iusage ++;
+				s->ousage = 0;
+			} else {
+				s->ousage ++;
+			}
+		} else {
+			/* Using last usage */
+			dval = s->usage_last;
 		}
-		if (s->multi < s->multimax) {
-			c->usage = s->usages[min(s->multi, s->nusage-1)];
-			s->multi++;
+		s->icount ++;
+		/* 
+		 * Only copy HID item, increment position and return
+		 * if correct kindset!
+		 */
+		if (s->kindset & (1 << c->kind)) {
 			*h = *c;
-			/*
-			 * 'multimax' is only non-zero if the current
-                         *  item kind is input/output/feature
-			 */
-			h->pos = s->kindpos[c->kind];
-			s->kindpos[c->kind] += c->report_size;
-			h->next = 0;
+			c->pos += c->report_size * c->report_count;
 			return (1);
-		} else {
-			c->report_count = s->multimax;
-			s->multimax = 0;
-			s->nusage = 0;
-			hid_clear_local(c);
 		}
 	}
-	for (;;) {
-		p = s->p;
-		if (p >= s->end)
-			return (0);
 
-		bSize = *p++;
+	/* reset state variables */
+	s->icount = 0;
+	s->ncount = 0;
+	s->iusage = 0;
+	s->nusage = 0;
+	s->susage = 0;
+	s->ousage = 0;
+	hid_clear_local(c);
+
+	/* get next item */
+	while (s->p != s->end) {
+
+		bSize = hid_get_byte(s, 1);
 		if (bSize == 0xfe) {
 			/* long item */
-			bSize = *p++;
-			bSize |= *p++ << 8;
-			bTag = *p++;
-			data = p;
-			p += bSize;
+			bSize = hid_get_byte(s, 1);
+			bSize |= hid_get_byte(s, 1) << 8;
+			bTag = hid_get_byte(s, 1);
+			bType = 0xff;	/* XXX what should it be */
 		} else {
 			/* short item */
 			bTag = bSize >> 4;
 			bType = (bSize >> 2) & 3;
 			bSize &= 3;
-			if (bSize == 3) bSize = 4;
-			data = p;
-			p += bSize;
+			if (bSize == 3)
+				bSize = 4;
 		}
-		s->p = p;
-		/*
-		 * The spec is unclear if the data is signed or unsigned.
-		 */
+
 		switch(bSize) {
 		case 0:
 			dval = 0;
+			mask = 0;
 			break;
 		case 1:
-			dval = *data++;
+			dval = (int8_t)hid_get_byte(s, 1);
+			mask = 0xFF;
 			break;
 		case 2:
-			dval = *data++;
-			dval |= *data++ << 8;
+			dval = hid_get_byte(s, 1);
+			dval |= hid_get_byte(s, 1) << 8;
+			dval = (int16_t)dval;
+			mask = 0xFFFF;
 			break;
 		case 4:
-			dval = *data++;
-			dval |= *data++ << 8;
-			dval |= *data++ << 16;
-			dval |= *data++ << 24;
+			dval = hid_get_byte(s, 1);
+			dval |= hid_get_byte(s, 1) << 8;
+			dval |= hid_get_byte(s, 1) << 16;
+			dval |= hid_get_byte(s, 1) << 24;
+			mask = 0xFFFFFFFF;
 			break;
 		default:
-			return (-1);
+			dval = hid_get_byte(s, bSize);
+			continue;
 		}
 
 		switch (bType) {
-		case 0:			/* Main */
+		case 0:		/* Main */
 			switch (bTag) {
-			case 8:		/* Input */
-				retkind = hid_input;
-			ret:
-				if (!(s->kindset & (1 << retkind))) {
-					/* Drop the items of this kind */
-					s->nusage = 0;
-					continue;
-				}
-				c->kind = retkind;
+			case 8:	/* Input */
+				c->kind = hid_input;
 				c->flags = dval;
+		ret:
+				c->report_count = s->loc_count;
+				c->report_size = s->loc_size;
+
 				if (c->flags & HIO_VARIABLE) {
-					s->multimax = c->report_count;
-					s->multi = 0;
+					/* range check usage count */
+					if (c->report_count > 255) {
+						s->ncount = 255;
+					} else
+						s->ncount = c->report_count;
+
+					/* 
+					 * The "top" loop will return
+					 * one and one item:
+					 */
 					c->report_count = 1;
-					if (s->minset) {
-						for (i = c->usage_minimum;
-						     i <= c->usage_maximum;
-						     i++) {
-							s->usages[s->nusage] = i;
-							if (s->nusage < MAXUSAGE-1)
-								s->nusage++;
-						}
-						c->usage_minimum = 0;
-						c->usage_maximum = 0;
-						s->minset = 0;
-					}
-					goto top;
 				} else {
-					if (s->minset)
-						c->usage = c->usage_minimum;
-					*h = *c;
-					h->next = 0;
-					h->pos = s->kindpos[c->kind];
-					s->kindpos[c->kind] +=
-					    c->report_size * c->report_count;
-					hid_clear_local(c);
-					s->minset = 0;
-					return (1);
+					s->ncount = 1;
 				}
-			case 9:		/* Output */
-				retkind = hid_output;
+				goto top;
+
+			case 9:	/* Output */
+				c->kind = hid_output;
+				c->flags = dval;
 				goto ret;
 			case 10:	/* Collection */
 				c->kind = hid_collection;
 				c->collection = dval;
 				c->collevel++;
-				nc = *c;
-				hid_clear_local(c);
-				/*c->report_ID = NO_REPORT_ID;*/
-				s->nusage = 0;
-				if (s->hassavedcoll) {
-					*h = s->savedcoll;
-					h->report_ID = nc.report_ID;
-					s->savedcoll = nc;
-					return (1);
-				} else {
-					s->hassavedcoll = 1;
-					s->savedcoll = nc;
-				}
-				break;
+				c->usage = s->usage_last;
+				*h = *c;
+				return (1);
 			case 11:	/* Feature */
-				retkind = hid_feature;
+				c->kind = hid_feature;
+				c->flags = dval;
 				goto ret;
 			case 12:	/* End collection */
-				REPORT_SAVED_COLL;
 				c->kind = hid_endcollection;
+				if (c->collevel == 0) {
+					/* Invalid end collection. */
+					return (0);
+				}
 				c->collevel--;
 				*h = *c;
-				/*hid_clear_local(c);*/
-				s->nusage = 0;
 				return (1);
 			default:
-				return (-2);
+				break;
 			}
 			break;
 
@@ -315,13 +363,12 @@ hid_get_item_raw(hid_data_t s, hid_item_
 				break;
 			case 1:
 				c->logical_minimum = dval;
-				s->logminsize = bSize;
 				break;
 			case 2:
 				c->logical_maximum = dval;
 				break;
 			case 3:
-				c->physical_maximum = dval;
+				c->physical_minimum = dval;
 				break;
 			case 4:
 				c->physical_maximum = dval;
@@ -333,45 +380,97 @@ hid_get_item_raw(hid_data_t s, hid_item_
 				c->unit = dval;
 				break;
 			case 7:
-				c->report_size = dval;
+				/* mask because value is unsigned */
+				s->loc_size = dval & mask;
 				break;
 			case 8:
-				c->report_ID = dval;
-				s->kindpos[hid_input] =
-				    s->kindpos[hid_output] =
-				    s->kindpos[hid_feature] = 0;
+				hid_switch_rid(s, c, dval);
 				break;
 			case 9:
-				c->report_count = dval;
+				/* mask because value is unsigned */
+				s->loc_count = dval & mask;
 				break;
-			case 10: /* Push */
-				hi = malloc(sizeof *hi);
-				*hi = s->cur;
-				c->next = hi;
-				break;
-			case 11: /* Pop */
-				hi = c->next;
-				s->cur = *hi;
-				free(hi);
+			case 10:	/* Push */
+				s->pushlevel ++;
+				if (s->pushlevel < MAXPUSH) {
+					s->cur[s->pushlevel] = *c;
+					/* store size and count */
+					c->report_size = s->loc_size;
+					c->report_count = s->loc_count;
+					/* update current item pointer */
+					c = &s->cur[s->pushlevel];
+				}
+				break;
+			case 11:	/* Pop */
+				s->pushlevel --;
+				if (s->pushlevel < MAXPUSH) {
+					/* preserve position */
+					oldpos = c->pos;
+					c = &s->cur[s->pushlevel];
+					/* restore size and count */
+					s->loc_size = c->report_size;
+					s->loc_count = c->report_count;
+					/* set default item location */
+					c->pos = oldpos;
+					c->report_size = 0;
+					c->report_count = 0;
+				}
 				break;
 			default:
-				return (-3);
+				break;
 			}
 			break;
 		case 2:		/* Local */
 			switch (bTag) {
 			case 0:
-				c->usage = c->_usage_page | dval;
-				if (s->nusage < MAXUSAGE)
-					s->usages[s->nusage++] = c->usage;
+				if (bSize != 4)
+					dval = (dval & mask) | c->_usage_page;
+
+				/* set last usage, in case of a collection */
+				s->usage_last = dval;
+
+				if (s->nusage < MAXUSAGE) {
+					s->usages_min[s->nusage] = dval;
+					s->usages_max[s->nusage] = dval;
+					s->nusage ++;
+				}
 				/* else XXX */
+
+				/* clear any pending usage sets */
+				s->susage = 0;
 				break;
 			case 1:
-				s->minset = 1;
-				c->usage_minimum = c->_usage_page | dval;
-				break;
+				s->susage |= 1;
+
+				if (bSize != 4)
+					dval = (dval & mask) | c->_usage_page;
+				c->usage_minimum = dval;
+
+				goto check_set;
 			case 2:
-				c->usage_maximum = c->_usage_page | dval;
+				s->susage |= 2;
+
+				if (bSize != 4)
+					dval = (dval & mask) | c->_usage_page;
+				c->usage_maximum = dval;
+
+			check_set:
+				if (s->susage != 3)
+					break;
+
+				/* sanity check */
+				if ((s->nusage < MAXUSAGE) &&
+				    (c->usage_minimum <= c->usage_maximum)) {
+					/* add usage range */
+					s->usages_min[s->nusage] = 
+					    c->usage_minimum;
+					s->usages_max[s->nusage] = 
+					    c->usage_maximum;
+					s->nusage ++;
+				}
+				/* else XXX */
+
+				s->susage = 0;
 				break;
 			case 3:
 				c->designator_index = dval;
@@ -395,40 +494,63 @@ hid_get_item_raw(hid_data_t s, hid_item_
 				c->set_delimiter = dval;
 				break;
 			default:
-				return (-4);
+				break;
 			}
 			break;
 		default:
-			return (-5);
+			break;
 		}
 	}
+	return (0);
 }
 
 int
 hid_report_size(report_desc_t r, enum hid_kind k, int id)
 {
 	struct hid_data *d;
-	hid_item_t h;
-	int size;
+	struct hid_item h;
+	uint32_t temp;
+	uint32_t hpos;
+	uint32_t lpos;
+
+	hpos = 0;
+	lpos = 0xFFFFFFFF;
 
 	memset(&h, 0, sizeof h);
-	size = 0;
-	for (d = hid_start_parse(r, 1<<k, id); hid_get_item(d, &h); ) {
+	for (d = hid_start_parse(r, 1 << k, id); hid_get_item(d, &h); ) {
 		if (h.report_ID == id && h.kind == k) {
-			size = d->kindpos[k];
+			/* compute minimum */
+			if (lpos > h.pos)
+				lpos = h.pos;
+			/* compute end position */
+			temp = h.pos + (h.report_size * h.report_count);
+			/* compute maximum */
+			if (hpos < temp)
+				hpos = temp;
 		}
 	}
 	hid_end_parse(d);
-	return ((size + 7) / 8);
+
+	/* safety check - can happen in case of currupt descriptors */
+	if (lpos > hpos)
+		temp = 0;
+	else
+		temp = hpos - lpos;
+
+	if (id)
+		temp += 8;
+
+	/* return length in bytes rounded up */
+	return ((temp + 7) / 8);
 }
 
 int
 hid_locate(report_desc_t desc, unsigned int u, enum hid_kind k,
 	   hid_item_t *h, int id)
 {
-	hid_data_t d;
+	struct hid_data *d;
 
-	for (d = hid_start_parse(desc, 1<<k, id); hid_get_item(d, h); ) {
+	for (d = hid_start_parse(desc, 1 << k, id); hid_get_item(d, h); ) {
 		if (h->kind == k && !(h->flags & HIO_CONST) && h->usage == u) {
 			hid_end_parse(d);
 			return (1);

Modified: head/lib/libusbhid/usage.c
==============================================================================
--- head/lib/libusbhid/usage.c	Sat Mar 27 06:53:11 2010	(r205727)
+++ head/lib/libusbhid/usage.c	Sat Mar 27 08:00:16 2010	(r205728)
@@ -29,6 +29,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/param.h>
 #include <assert.h>
 #include <ctype.h>
 #include <err.h>

Modified: head/lib/libusbhid/usbhid.h
==============================================================================
--- head/lib/libusbhid/usbhid.h	Sat Mar 27 06:53:11 2010	(r205727)
+++ head/lib/libusbhid/usbhid.h	Sat Mar 27 08:00:16 2010	(r205728)
@@ -29,52 +29,48 @@
  *
  */
 
-#include <sys/cdefs.h>
+#include <sys/types.h>
 
 typedef struct report_desc *report_desc_t;
 
 typedef struct hid_data *hid_data_t;
 
 typedef enum hid_kind {
-	hid_input = 0,
-	hid_output = 1,
-	hid_feature = 2,
-	hid_collection,
-	hid_endcollection
+	hid_input, hid_output, hid_feature, hid_collection, hid_endcollection
 } hid_kind_t;
 
 typedef struct hid_item {
 	/* Global */
-	unsigned int _usage_page;
-	int logical_minimum;
-	int logical_maximum;
-	int physical_minimum;
-	int physical_maximum;
-	int unit_exponent;
-	int unit;
-	int report_size;
-	int report_ID;
+	uint32_t _usage_page;
+	int32_t logical_minimum;
+	int32_t logical_maximum;
+	int32_t physical_minimum;
+	int32_t physical_maximum;
+	int32_t unit_exponent;
+	int32_t unit;
+	int32_t report_size;
+	int32_t report_ID;
 #define NO_REPORT_ID 0
-	int report_count;
+	int32_t report_count;
 	/* Local */
-	unsigned int usage;
-	int usage_minimum;
-	int usage_maximum;
-	int designator_index;
-	int designator_minimum;
-	int designator_maximum;
-	int string_index;
-	int string_minimum;
-	int string_maximum;
-	int set_delimiter;
+	uint32_t usage;
+	int32_t usage_minimum;
+	int32_t usage_maximum;
+	int32_t designator_index;
+	int32_t designator_minimum;
+	int32_t designator_maximum;
+	int32_t string_index;
+	int32_t string_minimum;
+	int32_t string_maximum;
+	int32_t set_delimiter;
 	/* Misc */
-	int collection;
-	int collevel;
+	int32_t collection;
+	int	collevel;
 	enum hid_kind kind;
-	unsigned int flags;
-	/* Absolute data position (bits) */
-	unsigned int pos;
-	/* */
+	uint32_t flags;
+	/* Location */
+	uint32_t pos;
+	/* unused */
 	struct hid_item *next;
 } hid_item_t;
 
@@ -95,7 +91,8 @@ hid_data_t hid_start_parse(report_desc_t
 void hid_end_parse(hid_data_t s);
 int hid_get_item(hid_data_t s, hid_item_t *h);
 int hid_report_size(report_desc_t d, enum hid_kind k, int id);
-int hid_locate(report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h, int id);
+int hid_locate(report_desc_t d, unsigned int usage, enum hid_kind k,
+    hid_item_t *h, int id);
 
 /* Conversion to/from usage names, usage.c: */
 const char *hid_usage_page(int i);

Modified: head/lib/libusbhid/usbvar.h
==============================================================================
--- head/lib/libusbhid/usbvar.h	Sat Mar 27 06:53:11 2010	(r205727)
+++ head/lib/libusbhid/usbvar.h	Sat Mar 27 08:00:16 2010	(r205728)
@@ -30,8 +30,8 @@
  */
 
 struct report_desc {
-	unsigned int size;
-	unsigned char data[1];
+	uint32_t size;
+	uint8_t data[1];
 };
 
 /* internal backwards compatibility functions */


More information about the svn-src-head mailing list