From owner-svn-src-all@FreeBSD.ORG Mon Mar 9 15:25:47 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 404421065675; Mon, 9 Mar 2009 15:25:47 +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 2C45D8FC26; Mon, 9 Mar 2009 15:25:47 +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 n29FPl0v030220; Mon, 9 Mar 2009 15:25:47 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n29FPlVv030219; Mon, 9 Mar 2009 15:25:47 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200903091525.n29FPlVv030219@svn.freebsd.org> From: Andrew Thompson Date: Mon, 9 Mar 2009 15:25:47 +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: r189583 - head/sys/dev/usb/input X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Mar 2009 15:25:47 -0000 Author: thompsa Date: Mon Mar 9 15:25:46 2009 New Revision: 189583 URL: http://svn.freebsd.org/changeset/base/189583 Log: MFp4 //depot/projects/usb@158916 USB mouse patch to address complicated data reporting descriptors. Reported by: Boris Kotzev Submitted by: Hans Petter Selasky Modified: head/sys/dev/usb/input/ums.c Modified: head/sys/dev/usb/input/ums.c ============================================================================== --- head/sys/dev/usb/input/ums.c Mon Mar 9 14:04:18 2009 (r189582) +++ head/sys/dev/usb/input/ums.c Mon Mar 9 15:25:46 2009 (r189583) @@ -117,6 +117,12 @@ struct ums_softc { 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 @@ ums_intr_callback(struct usb2_xfer *xfer 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 @@ ums_intr_callback(struct usb2_xfer *xfer (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 @@ ums_intr_callback(struct usb2_xfer *xfer } } - dw = (sc->sc_flags & UMS_FLAG_W_AXIS) ? - hid_get_data(buf, len, &sc->sc_loc_w) : 0; - - dx = (sc->sc_flags & UMS_FLAG_X_AXIS) ? - hid_get_data(buf, len, &sc->sc_loc_x) : 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_W_AXIS) && (id == sc->sc_iid_w)) + dw = hid_get_data(buf, len, &sc->sc_loc_w); + else + dw = 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; + + 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; + + 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; - dz = (sc->sc_flags & UMS_FLAG_Z_AXIS) ? - -hid_get_data(buf, len, &sc->sc_loc_z) : 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 @@ ums_attach(device_t dev) 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 @@ ums_attach(device_t dev) } /* 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 @@ ums_attach(device_t dev) * 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 @@ ums_attach(device_t dev) * 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 @@ ums_attach(device_t dev) 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 @@ ums_attach(device_t dev) 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 @@ ums_attach(device_t dev) #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