Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb Fix kern/41737 -- add quirks to make MS Wireless...



details:   https://anonhg.NetBSD.org/src/rev/e56481826ab8
branches:  trunk
changeset: 748816:e56481826ab8
user:      rafal <rafal%NetBSD.org@localhost>
date:      Fri Nov 06 04:42:27 2009 +0000

description:
Fix kern/41737 -- add quirks to make MS Wireless Laser Mouse 6000 work.

diffstat:

 sys/dev/usb/uhidev.c |  20 +++++-----
 sys/dev/usb/ums.c    |  95 ++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 77 insertions(+), 38 deletions(-)

diffs (238 lines):

diff -r 29177f796047 -r e56481826ab8 sys/dev/usb/uhidev.c
--- a/sys/dev/usb/uhidev.c      Thu Nov 05 21:26:25 2009 +0000
+++ b/sys/dev/usb/uhidev.c      Fri Nov 06 04:42:27 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uhidev.c,v 1.43 2009/09/23 19:07:19 plunky Exp $       */
+/*     $NetBSD: uhidev.c,v 1.44 2009/11/06 04:42:27 rafal Exp $        */
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.43 2009/09/23 19:07:19 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.44 2009/11/06 04:42:27 rafal Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -105,7 +105,7 @@
        struct uhidev_attach_arg uha;
        device_t dev;
        struct uhidev *csc;
-       int size, nrepid, repid, repsz;
+       int maxinpktsize, size, nrepid, repid, repsz;
        int *repsizes;
        int i;
        void *desc;
@@ -140,6 +140,7 @@
                (void)usbd_set_protocol(iface, 1);
 #endif
 
+       maxinpktsize = 0;
        sc->sc_iep_addr = sc->sc_oep_addr = -1;
        for (i = 0; i < id->bNumEndpoints; i++) {
                ed = usbd_interface2endpoint_descriptor(iface, i);
@@ -161,6 +162,7 @@
 
                if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
+                       maxinpktsize = UGETW(ed->wMaxPacketSize);
                        sc->sc_iep_addr = ed->bEndpointAddress;
                } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
                    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
@@ -265,8 +267,10 @@
                aprint_error_dev(self, "no memory\n");
                USB_ATTACH_ERROR_RETURN;
        }
+
+       /* Just request max packet size for the interrupt pipe */
+       sc->sc_isize = maxinpktsize;
        sc->sc_nrepid = nrepid;
-       sc->sc_isize = 0;
 
        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
                           USBDEV(sc->sc_dev));
@@ -275,12 +279,8 @@
                repsz = hid_report_size(desc, size, hid_input, repid);
                DPRINTF(("uhidev_match: repid=%d, repsz=%d\n", repid, repsz));
                repsizes[repid] = repsz;
-               if (repsz > 0) {
-                       if (repsz > sc->sc_isize)
-                               sc->sc_isize = repsz;
-               }
        }
-       sc->sc_isize += nrepid != 1;    /* space for report ID */
+
        DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize));
 
        uha.parent = sc;
@@ -478,7 +478,7 @@
                    rep, scd, scd ? scd->sc_state : 0));
        if (!(scd->sc_state & UHIDEV_OPEN))
                return;
-       if (scd->sc_in_rep_size != cc) {
+       if (scd->sc_in_rep_size > cc) {
                printf("%s: bad input length %d != %d\n",
                       USBDEVNAME(sc->sc_dev), scd->sc_in_rep_size, cc);
                return;
diff -r 29177f796047 -r e56481826ab8 sys/dev/usb/ums.c
--- a/sys/dev/usb/ums.c Thu Nov 05 21:26:25 2009 +0000
+++ b/sys/dev/usb/ums.c Fri Nov 06 04:42:27 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ums.c,v 1.74 2009/03/09 15:59:33 uebayasi Exp $        */
+/*     $NetBSD: ums.c,v 1.75 2009/11/06 04:42:27 rafal Exp $   */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.74 2009/03/09 15:59:33 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.75 2009/11/06 04:42:27 rafal Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -94,6 +94,7 @@
 #define UMS_Z          0x01    /* z direction available */
 #define UMS_SPUR_BUT_UP        0x02    /* spurious button up events */
 #define UMS_REVZ       0x04    /* Z-axis is reversed */
+#define UMS_W          0x08    /* w direction/tilt available */
 
        int nbuttons;
 
@@ -151,7 +152,8 @@
        int size;
        void *desc;
        u_int32_t flags, quirks;
-       int i, wheel;
+       int i, hl;
+       struct hid_location *zloc;
        struct hid_location loc_btn;
 
        aprint_naive("\n");
@@ -197,10 +199,16 @@
        }
 
        /* Try the wheel first as the Z activator since it's tradition. */
-       wheel = hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
-                                                 HUG_WHEEL),
-                          uha->reportid, hid_input, &sc->sc_loc_z, &flags);
-       if (wheel) {
+       hl = hid_locate(desc, 
+                       size, 
+                       HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), 
+                       uha->reportid, 
+                       hid_input, 
+                       &sc->sc_loc_z, 
+                       &flags);
+
+       zloc = &sc->sc_loc_z;
+       if (hl) {
                if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
                        aprint_verbose("\n%s: Wheel report 0x%04x not "
                            "supported\n", USBDEVNAME(sc->sc_hdev.sc_dev),
@@ -210,33 +218,59 @@
                        sc->flags |= UMS_Z;
                        /* Wheels need the Z axis reversed. */
                        sc->flags ^= UMS_REVZ;
+                       /* Put Z on the W coordinate */
+                       zloc = &sc->sc_loc_w;
                }
-               /*
-                * We might have both a wheel and Z direction, if so put
-                * put the Z on the W coordinate.
-                */
-               if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
-                                                     HUG_Z),
-                       uha->reportid, hid_input, &sc->sc_loc_w, &flags)) {
-                       if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
-                               aprint_verbose("\n%s: Z report 0x%04x not "
-                                   "supported\n",
-                                      USBDEVNAME(sc->sc_hdev.sc_dev), flags);
-                               sc->sc_loc_w.size = 0;  /* Bad Z, ignore */
-                       }
-               }
-        } else if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
-                                                     HUG_Z),
-                     uha->reportid, hid_input, &sc->sc_loc_z, &flags)) {
+       }
+
+       hl = hid_locate(desc, 
+                       size, 
+                       HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
+                       uha->reportid,
+                       hid_input,
+                       zloc,
+                       &flags);
+
+       /*
+        * The horizontal component of the scrollball can also be given by
+        * Application Control Pan in the Consumer page, so if we didnt see
+        * any Z then check that.
+        */
+       if (!hl) {
+               hl = hid_locate(desc, 
+                               size, 
+                               HID_USAGE2(HUP_CONSUMER, HUC_AC_PAN), 
+                               uha->reportid,
+                               hid_input,
+                               zloc,
+                               &flags);
+       }
+
+       if (hl) {
                if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
                        aprint_verbose("\n%s: Z report 0x%04x not supported\n",
                               USBDEVNAME(sc->sc_hdev.sc_dev), flags);
-                       sc->sc_loc_z.size = 0;  /* Bad Z coord, ignore it */
+                       zloc->size = 0; /* Bad Z coord, ignore it */
                } else {
-                       sc->flags |= UMS_Z;
+                       if (sc->flags & UMS_Z)
+                               sc->flags |= UMS_W;
+                       else
+                               sc->flags |= UMS_Z;
                }
        }
 
+       /*
+        * The Microsoft Wireless Laser Mouse 6000 v2.0 reports a bad
+        * position for the wheel and wheel tilt controls -- should be
+        * in bytes 3 & 4 of the report.  Fix this if necessary.
+        */
+       if (uha->uaa->vendor == USB_VENDOR_MICROSOFT &&
+           uha->uaa->product == USB_PRODUCT_MICROSOFT_24GHZ_XCVR) {
+               if ((sc->flags & UMS_Z) && sc->sc_loc_z.pos == 0)
+                       sc->sc_loc_z.pos = 24;
+               if ((sc->flags & UMS_W) && sc->sc_loc_w.pos == 0)
+                       sc->sc_loc_w.pos = sc->sc_loc_z.pos + 8;
+       }
 
        /* figure out the number of buttons */
        for (i = 1; i <= MAX_BUTTONS; i++)
@@ -245,9 +279,11 @@
                        break;
        sc->nbuttons = i - 1;
 
-       aprint_normal(": %d button%s%s\n",
+       aprint_normal(": %d button%s%s%s%s\n",
            sc->nbuttons, sc->nbuttons == 1 ? "" : "s",
-           sc->flags & UMS_Z ? " and Z dir." : "");
+           sc->flags & UMS_W ? ", W" : "",
+           sc->flags & UMS_Z ? " and Z dir" : "",
+           sc->flags & UMS_W ? "s" : "");
 
        for (i = 1; i <= sc->nbuttons; i++)
                hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
@@ -263,6 +299,9 @@
        if (sc->flags & UMS_Z)
                DPRINTF(("ums_attach: Z\t%d/%d\n",
                         sc->sc_loc_z.pos, sc->sc_loc_z.size));
+       if (sc->flags & UMS_W)
+               DPRINTF(("ums_attach: W\t%d/%d\n",
+                        sc->sc_loc_w.pos, sc->sc_loc_w.size));
        for (i = 1; i <= sc->nbuttons; i++) {
                DPRINTF(("ums_attach: B%d\t%d/%d\n",
                         i, sc->sc_loc_btn[i-1].pos,sc->sc_loc_btn[i-1].size));



Home | Main Index | Thread Index | Old Index