usb2 moused issue (Microsoft Wireless Optical)
Giorgos Keramidas
keramida at freebsd.org
Tue Feb 17 10:55:45 PST 2009
On Tue, 17 Feb 2009 14:36:57 +0100, Hans Petter Selasky <hselasky at freebsd.org> wrote:
> Can you send me the patched file "sys/dev/usb2/core/usb2_hid.c" ? I
> cannot see that "size=2" has changed. It's wrong size information that
> causes your mouse problem.
It is usb2_hid.c from /head at svn rev 188665, plus the changes you sent
me before.
Script started on Tue Feb 17 20:25:31 2009
keramida at kobe:/home/keramida/svn/head$ svn diff sys/dev/usb2/core
Index: sys/dev/usb2/core/usb2_hid.c
===================================================================
--- sys/dev/usb2/core/usb2_hid.c (revision 188665)
+++ sys/dev/usb2/core/usb2_hid.c (working copy)
@@ -392,22 +392,38 @@
{
struct hid_data *d;
struct hid_item h;
- int hi, lo, size, id;
+ uint32_t size;
+ uint32_t hi;
+ uint32_t lo;
+ uint8_t id;
id = 0;
- hi = lo = -1;
+ hi = 0;
+ lo = (uint32_t)(0-1);
for (d = hid_start_parse(buf, len, 1 << k); hid_get_item(d, &h);)
if (h.kind == k) {
if (h.report_ID != 0 && !id)
id = h.report_ID;
if (h.report_ID == id) {
- if (lo < 0)
+ /* check if "lo" is greater than "pos" */
+ if (lo > h.loc.pos)
lo = h.loc.pos;
- hi = h.loc.pos + h.loc.size * h.loc.count;
+ /* compute end position */
+ size = h.loc.pos + (h.loc.size * h.loc.count);
+ /* check if "size" wrapped */
+ /* check if "hi" is less than "size" */
+ if (size < h.loc.pos)
+ hi = (uint32_t)(0-1);
+ else if (hi < size)
+ hi = size;
}
}
hid_end_parse(d);
- size = hi - lo;
+ if (lo > hi)
+ size = 0;
+ else
+ size = hi - lo;
+
if (id != 0) {
size += 8;
*idp = id; /* XXX wrong */
keramida at kobe:/home/keramida/svn/head$ exit
exit
Script done on Tue Feb 17 20:25:39 2009
The code of hid_report_size() is similar in old usb and the new usb
stack, but I am not sure about all the differences I see. The
calculation of `size' is done correctly with old usb code, so I am
testing the patch attached below now. It essentially pulls in the
hid_report_size() from the old usb code, with the if (h.kind == k) check
reversed to remove one spurious indentation level:
%%%
diff --git a/sys/dev/usb2/core/usb2_hid.c b/sys/dev/usb2/core/usb2_hid.c
--- a/sys/dev/usb2/core/usb2_hid.c
+++ b/sys/dev/usb2/core/usb2_hid.c
@@ -392,41 +392,26 @@
{
struct hid_data *d;
struct hid_item h;
- uint32_t size;
- uint32_t hi;
- uint32_t lo;
- uint8_t id;
+ int hi, lo, size, id;
id = 0;
- hi = 0;
- lo = (uint32_t)(0-1);
- for (d = hid_start_parse(buf, len, 1 << k); hid_get_item(d, &h);)
- if (h.kind == k) {
- if (h.report_ID != 0 && !id)
- id = h.report_ID;
- if (h.report_ID == id) {
- /* check if "lo" is greater than "pos" */
- if (lo > h.loc.pos)
- lo = h.loc.pos;
- /* compute end position */
- size = h.loc.pos + (h.loc.size * h.loc.count);
- /* check if "size" wrapped */
- /* check if "hi" is less than "size" */
- if (size < h.loc.pos)
- hi = (uint32_t)(0-1);
- else if (hi < size)
- hi = size;
- }
+ hi = lo = -1;
+ for (d = hid_start_parse(buf, len, 1<<k); hid_get_item(d, &h); ) {
+ if (h.kind != k)
+ continue;
+ if (h.report_ID != 0 && !id)
+ id = h.report_ID;
+ if (h.report_ID == id) {
+ if (lo < 0)
+ lo = h.loc.pos;
+ hi = h.loc.pos + h.loc.size * h.loc.count;
}
+ }
hid_end_parse(d);
- if (lo > hi)
- size = 0;
- else
- size = hi - lo;
-
+ size = hi - lo;
if (id != 0) {
size += 8;
- *idp = id; /* XXX wrong */
+ *idp = id; /* XXX wrong */
} else
*idp = 0;
return ((size + 7) / 8);
%%%
I'll report back later ;)
More information about the freebsd-current
mailing list