Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb hid_get_data() does not work if the size of data...
details: https://anonhg.NetBSD.org/src/rev/bc9364facfc4
branches: trunk
changeset: 754793:bc9364facfc4
user: plunky <plunky%NetBSD.org@localhost>
date: Wed May 12 18:44:48 2010 +0000
description:
hid_get_data() does not work if the size of data is less than
a byte and crosses a byte boundary, and it always returns a
sign-extended value.
fix this by using the algorithm from libusbhid to read bytes,
and provide a hid_get_udata() function to return unsigned data
values.
while here, const args
diffstat:
sys/dev/usb/hid.c | 43 ++++++++++++++++++++++++++++---------------
sys/dev/usb/hid.h | 5 +++--
2 files changed, 31 insertions(+), 17 deletions(-)
diffs (92 lines):
diff -r 2953429595a5 -r bc9364facfc4 sys/dev/usb/hid.c
--- a/sys/dev/usb/hid.c Wed May 12 18:37:56 2010 +0000
+++ b/sys/dev/usb/hid.c Wed May 12 18:44:48 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hid.c,v 1.28 2008/04/28 20:23:59 martin Exp $ */
+/* $NetBSD: hid.c,v 1.29 2010/05/12 18:44:48 plunky Exp $ */
/* $FreeBSD: src/sys/dev/usb/hid.c,v 1.11 1999/11/17 22:33:39 n_hibma Exp $ */
/*
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hid.c,v 1.28 2008/04/28 20:23:59 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hid.c,v 1.29 2010/05/12 18:44:48 plunky Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -427,30 +427,43 @@
return (0);
}
+long
+hid_get_data(const u_char *buf, const struct hid_location *loc)
+{
+ u_int hsize = loc->size;
+ u_long data;
+
+ if (hsize == 0)
+ return (0);
+
+ data = hid_get_udata(buf, loc);
+ if (data < (1 << (hsize - 1)))
+ return (data);
+ return data - (1 << hsize);
+}
+
u_long
-hid_get_data(u_char *buf, struct hid_location *loc)
+hid_get_udata(const u_char *buf, const struct hid_location *loc)
{
u_int hpos = loc->pos;
u_int hsize = loc->size;
- u_int32_t data;
- int i, s;
-
- DPRINTFN(10, ("hid_get_data: loc %d/%d\n", hpos, hsize));
+ u_int i, num, off;
+ u_long data;
if (hsize == 0)
return (0);
data = 0;
- s = hpos / 8;
- for (i = hpos; i < hpos+hsize; i += 8)
- data |= buf[i / 8] << ((i / 8 - s) * 8);
+ off = hpos / 8;
+ num = (hpos + hsize + 7) / 8 - off;
+
+ for (i = 0; i < num; i++)
+ data |= buf[off + i] << (i * 8);
+
data >>= hpos % 8;
data &= (1 << hsize) - 1;
- hsize = 32 - hsize;
- /* Sign extend */
- data = ((int32_t)data << hsize) >> hsize;
- DPRINTFN(10,("hid_get_data: loc %d/%d = %lu\n",
- loc->pos, loc->size, (long)data));
+
+ DPRINTFN(10,("hid_get_data: loc %d/%d = %lu\n", hpos, hsize, data));
return (data);
}
diff -r 2953429595a5 -r bc9364facfc4 sys/dev/usb/hid.h
--- a/sys/dev/usb/hid.h Wed May 12 18:37:56 2010 +0000
+++ b/sys/dev/usb/hid.h Wed May 12 18:44:48 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hid.h,v 1.12 2008/04/28 20:23:59 martin Exp $ */
+/* $NetBSD: hid.h,v 1.13 2010/05/12 18:44:49 plunky Exp $ */
/* $FreeBSD: src/sys/dev/usb/hid.h,v 1.7 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@@ -84,5 +84,6 @@
int hid_report_size(const void *, int, enum hid_kind, u_int8_t);
int hid_locate(const void *, int, u_int32_t, u_int8_t, enum hid_kind,
struct hid_location *, u_int32_t *);
-u_long hid_get_data(u_char *, struct hid_location *);
+long hid_get_data(const u_char *, const struct hid_location *);
+u_long hid_get_udata(const u_char *, const struct hid_location *);
int hid_is_collection(const void *, int, u_int8_t, u_int32_t);
Home |
Main Index |
Thread Index |
Old Index