From owner-p4-projects@FreeBSD.ORG Mon Mar 9 12:53:46 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 177FB1065670; Mon, 9 Mar 2009 12:53:46 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CAFE91065673 for ; Mon, 9 Mar 2009 12:53:45 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id B73748FC1A for ; Mon, 9 Mar 2009 12:53:45 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n29Crjsg076262 for ; Mon, 9 Mar 2009 12:53:45 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n29Crjeo076260 for perforce@freebsd.org; Mon, 9 Mar 2009 12:53:45 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 9 Mar 2009 12:53:45 GMT Message-Id: <200903091253.n29Crjeo076260@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 158916 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Mar 2009 12:53:47 -0000 http://perforce.freebsd.org/chv.cgi?CH=158916 Change 158916 by hselasky@hselasky_laptop001 on 2009/03/09 12:53:04 USB input: USB mouse patch to address complicated data reporting descriptors. Reported by: Boris Kotzev Affected files ... .. //depot/projects/usb/src/sys/dev/usb/input/ums.c#4 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/input/ums.c#4 (text+ko) ==== @@ -117,6 +117,12 @@ uint8_t sc_buttons; uint8_t sc_iid; + uint8_t sc_iid_w; + uint8_t sc_iid_x; + uint8_t sc_iid_y; + uint8_t sc_iid_z; + uint8_t sc_iid_t; + uint8_t sc_iid_btn[UMS_BUTTON_MAX]; uint8_t sc_temp[64]; }; @@ -168,6 +174,7 @@ int32_t dz; int32_t dt; uint8_t i; + uint8_t id; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: @@ -190,42 +197,14 @@ (len > 4) ? buf[4] : 0, (len > 5) ? buf[5] : 0, (len > 6) ? buf[6] : 0, (len > 7) ? buf[7] : 0); - /* - * The M$ Wireless Intellimouse 2.0 sends 1 extra - * leading byte of data compared to most USB - * mice. This byte frequently switches from 0x01 - * (usual state) to 0x02. I assume it is to allow - * extra, non-standard, reporting (say battery-life). - * - * However at the same time it generates a left-click - * message on the button byte which causes spurious - * left-click's where there shouldn't be. This should - * sort that. Currently it's the only user of - * UMS_FLAG_T_AXIS so use it as an identifier. - * - * - * UPDATE: This problem affects the M$ Wireless - * Notebook Optical Mouse, too. However, the leading - * byte for this mouse is normally 0x11, and the - * phantom mouse click occurs when its 0x14. - * - * We probably should switch to some more official quirk. - */ if (sc->sc_iid) { - if (sc->sc_flags & UMS_FLAG_T_AXIS) { - if (*buf == 0x02) { - goto tr_setup; - } - } else { - if (*buf != sc->sc_iid) { - goto tr_setup; - } - } + id = *buf; len--; buf++; } else { + id = 0; if (sc->sc_flags & UMS_FLAG_SBU) { if ((*buf == 0x14) || (*buf == 0x15)) { goto tr_setup; @@ -233,25 +212,37 @@ } } - dw = (sc->sc_flags & UMS_FLAG_W_AXIS) ? - hid_get_data(buf, len, &sc->sc_loc_w) : 0; + if ((sc->sc_flags & UMS_FLAG_W_AXIS) && (id == sc->sc_iid_w)) + dw = hid_get_data(buf, len, &sc->sc_loc_w); + else + dw = 0; - dx = (sc->sc_flags & UMS_FLAG_X_AXIS) ? - hid_get_data(buf, len, &sc->sc_loc_x) : 0; + if ((sc->sc_flags & UMS_FLAG_X_AXIS) && (id == sc->sc_iid_x)) + dx = hid_get_data(buf, len, &sc->sc_loc_x); + else + dx = 0; - dy = (sc->sc_flags & UMS_FLAG_Y_AXIS) ? - -hid_get_data(buf, len, &sc->sc_loc_y) : 0; + if ((sc->sc_flags & UMS_FLAG_Y_AXIS) && (id == sc->sc_iid_y)) + dy = -hid_get_data(buf, len, &sc->sc_loc_y); + else + dy = 0; - dz = (sc->sc_flags & UMS_FLAG_Z_AXIS) ? - -hid_get_data(buf, len, &sc->sc_loc_z) : 0; + if ((sc->sc_flags & UMS_FLAG_Z_AXIS) && (id == sc->sc_iid_z)) + dz = -hid_get_data(buf, len, &sc->sc_loc_z); + else + dz = 0; - if (sc->sc_flags & UMS_FLAG_REVZ) { + if (sc->sc_flags & UMS_FLAG_REVZ) dz = -dz; - } - dt = (sc->sc_flags & UMS_FLAG_T_AXIS) ? - -hid_get_data(buf, len, &sc->sc_loc_t): 0; + + if ((sc->sc_flags & UMS_FLAG_T_AXIS) && (id == sc->sc_iid_t)) + dt = -hid_get_data(buf, len, &sc->sc_loc_t); + else + dt = 0; for (i = 0; i < sc->sc_buttons; i++) { + if (id != sc->sc_iid_btn[i]) + continue; if (hid_get_data(buf, len, &sc->sc_loc_btn[i])) { buttons |= (1 << UMS_BUT(i)); } @@ -413,14 +404,14 @@ goto detach; } if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), - hid_input, &sc->sc_loc_x, &flags, &sc->sc_iid)) { + hid_input, &sc->sc_loc_x, &flags, &sc->sc_iid_x)) { if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { sc->sc_flags |= UMS_FLAG_X_AXIS; } } if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), - hid_input, &sc->sc_loc_y, &flags, &sc->sc_iid)) { + hid_input, &sc->sc_loc_y, &flags, &sc->sc_iid_y)) { if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { sc->sc_flags |= UMS_FLAG_Y_AXIS; @@ -428,9 +419,9 @@ } /* Try the wheel first as the Z activator since it's tradition. */ if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, - HUG_WHEEL), hid_input, &sc->sc_loc_z, &flags, &sc->sc_iid) || + HUG_WHEEL), hid_input, &sc->sc_loc_z, &flags, &sc->sc_iid_z) || hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, - HUG_TWHEEL), hid_input, &sc->sc_loc_z, &flags, &sc->sc_iid)) { + HUG_TWHEEL), hid_input, &sc->sc_loc_z, &flags, &sc->sc_iid_z)) { if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { sc->sc_flags |= UMS_FLAG_Z_AXIS; } @@ -439,14 +430,14 @@ * put the Z on the W coordinate. */ if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, - HUG_Z), hid_input, &sc->sc_loc_w, &flags, &sc->sc_iid)) { + HUG_Z), hid_input, &sc->sc_loc_w, &flags, &sc->sc_iid_w)) { if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { sc->sc_flags |= UMS_FLAG_W_AXIS; } } } else if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, - HUG_Z), hid_input, &sc->sc_loc_z, &flags, &sc->sc_iid)) { + HUG_Z), hid_input, &sc->sc_loc_z, &flags, &sc->sc_iid_z)) { if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { sc->sc_flags |= UMS_FLAG_Z_AXIS; @@ -460,7 +451,7 @@ * TWHEEL */ if (hid_locate(d_ptr, d_len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL), - hid_input, &sc->sc_loc_t, &flags, &sc->sc_iid)) { + hid_input, &sc->sc_loc_t, &flags, &sc->sc_iid_t)) { sc->sc_loc_t.pos += 8; @@ -472,14 +463,14 @@ for (i = 0; i < UMS_BUTTON_MAX; i++) { if (!hid_locate(d_ptr, d_len, HID_USAGE2(HUP_BUTTON, (i + 1)), - hid_input, &sc->sc_loc_btn[i], NULL, &sc->sc_iid)) { + hid_input, &sc->sc_loc_btn[i], NULL, &sc->sc_iid_btn[i])) { break; } } sc->sc_buttons = i; - isize = hid_report_size(d_ptr, d_len, hid_input, NULL); + isize = hid_report_size(d_ptr, d_len, hid_input, &sc->sc_iid); /* * The Microsoft Wireless Notebook Optical Mouse seems to be in worse @@ -495,6 +486,12 @@ sc->sc_buttons = 3; isize = 5; sc->sc_iid = 0; + sc->sc_iid_x = 0; + sc->sc_iid_y = 0; + sc->sc_iid_z = 0; + sc->sc_iid_btn[0] = 0; + sc->sc_iid_btn[1] = 0; + sc->sc_iid_btn[2] = 0; /* 1st byte of descriptor report contains garbage */ sc->sc_loc_x.pos = 16; sc->sc_loc_y.pos = 24; @@ -544,15 +541,21 @@ #if USB_DEBUG DPRINTF("sc=%p\n", sc); - DPRINTF("X\t%d/%d\n", sc->sc_loc_x.pos, sc->sc_loc_x.size); - DPRINTF("Y\t%d/%d\n", sc->sc_loc_y.pos, sc->sc_loc_y.size); - DPRINTF("Z\t%d/%d\n", sc->sc_loc_z.pos, sc->sc_loc_z.size); - DPRINTF("T\t%d/%d\n", sc->sc_loc_t.pos, sc->sc_loc_t.size); - DPRINTF("W\t%d/%d\n", sc->sc_loc_w.pos, sc->sc_loc_w.size); + DPRINTF("X\t%d/%d id=%d\n", sc->sc_loc_x.pos, + sc->sc_loc_x.size, sc->sc_iid_x); + DPRINTF("Y\t%d/%d id=%d\n", sc->sc_loc_y.pos, + sc->sc_loc_y.size, sc->sc_iid_y); + DPRINTF("Z\t%d/%d id=%d\n", sc->sc_loc_z.pos, + sc->sc_loc_z.size, sc->sc_iid_z); + DPRINTF("T\t%d/%d id=%d\n", sc->sc_loc_t.pos, + sc->sc_loc_t.size, sc->sc_iid_t); + DPRINTF("W\t%d/%d id=%d\n", sc->sc_loc_w.pos, + sc->sc_loc_w.size, sc->sc_iid_w); for (i = 0; i < sc->sc_buttons; i++) { - DPRINTF("B%d\t%d/%d\n", - i + 1, sc->sc_loc_btn[i].pos, sc->sc_loc_btn[i].size); + DPRINTF("B%d\t%d/%d id=%d\n", + i + 1, sc->sc_loc_btn[i].pos, + sc->sc_loc_btn[i].size, sc->sc_iid_btn[i]); } DPRINTF("size=%d, id=%d\n", isize, sc->sc_iid); #endif