From owner-svn-src-head@FreeBSD.ORG Thu Mar 12 02:32:54 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 98BEE106566B; Thu, 12 Mar 2009 02:32:54 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8578F8FC0C; Thu, 12 Mar 2009 02:32:54 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n2C2Wsjh013937; Thu, 12 Mar 2009 02:32:54 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n2C2WsnM013936; Thu, 12 Mar 2009 02:32:54 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200903120232.n2C2WsnM013936@svn.freebsd.org> From: Andrew Thompson Date: Thu, 12 Mar 2009 02:32:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r189718 - head/sys/dev/usb X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Mar 2009 02:32:55 -0000 Author: thompsa Date: Thu Mar 12 02:32:54 2009 New Revision: 189718 URL: http://svn.freebsd.org/changeset/base/189718 Log: MFp4 //depot/projects/usb 159004,159053,159091 More HID parsing fixes for usb mice. - be less strict on the last HID item usage. - preserve item size and count accross items - improve default HID usage selection. Tested by: ache Submitted by: Hans Petter Selasky Modified: head/sys/dev/usb/usb_hid.c Modified: head/sys/dev/usb/usb_hid.c ============================================================================== --- head/sys/dev/usb/usb_hid.c Thu Mar 12 01:27:15 2009 (r189717) +++ head/sys/dev/usb/usb_hid.c Thu Mar 12 02:32:54 2009 (r189718) @@ -68,7 +68,10 @@ struct hid_data { struct hid_item cur[MAXPUSH]; int32_t usages_min[MAXUSAGE]; int32_t usages_max[MAXUSAGE]; - int kindset; + 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 */ @@ -181,15 +184,21 @@ hid_get_item(struct hid_data *s, struct top: /* check if there is an array of items */ - if ((s->icount != s->ncount) && - (s->iusage != s->nusage)) { - dval = s->usages_min[s->iusage] + s->ousage; - c->usage = dval; - if (dval == s->usages_max[s->iusage]) { - s->iusage ++; - s->ousage = 0; + 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 { - s->ousage ++; + DPRINTFN(1, "Using last usage\n"); + dval = s->usage_last; } s->icount ++; /* @@ -268,6 +277,9 @@ hid_get_item(struct hid_data *s, struct c->kind = hid_input; c->flags = dval; ret: + c->loc.count = s->loc_count; + c->loc.size = s->loc_size; + if (c->flags & HIO_VARIABLE) { /* range check usage count */ if (c->loc.count > 255) { @@ -285,13 +297,9 @@ hid_get_item(struct hid_data *s, struct } else { s->ncount = 1; } - /* make sure we have a usage */ - if (s->nusage == 0) { - /* use the undefined HID PAGE */ - s->usages_min[s->nusage] = 0x0000; - s->usages_max[s->nusage] = 0xFFFF; - s->nusage = s->ncount; - } + /* set default usage */ + /* use the undefined HID PAGE */ + s->usage_last = 0; goto top; case 9: /* Output */ @@ -346,7 +354,8 @@ hid_get_item(struct hid_data *s, struct c->unit = dval; break; case 7: - c->loc.size = dval; + /* mask because value is unsigned */ + s->loc_size = dval & mask; break; case 8: c->report_ID = dval; @@ -354,12 +363,17 @@ hid_get_item(struct hid_data *s, struct c->loc.pos = 0; break; case 9: - c->loc.count = dval; + /* mask because value is unsigned */ + s->loc_count = dval & mask; break; case 10: /* Push */ s->pushlevel ++; if (s->pushlevel < MAXPUSH) { s->cur[s->pushlevel] = *c; + /* store size and count */ + c->loc.size = s->loc_size; + c->loc.count = s->loc_count; + /* update current item pointer */ c = &s->cur[s->pushlevel]; } else { DPRINTFN(0, "Cannot push " @@ -372,7 +386,13 @@ hid_get_item(struct hid_data *s, struct /* preserve position */ oldpos = c->loc.pos; c = &s->cur[s->pushlevel]; + /* restore size and count */ + s->loc_size = c->loc.size; + s->loc_count = c->loc.count; + /* set default item location */ c->loc.pos = oldpos; + c->loc.size = 0; + c->loc.count = 0; } else { DPRINTFN(0, "Cannot pop " "item @ %d!\n", s->pushlevel);