2007/10/19, Vadim Jukov <[EMAIL PROTECTED]>:
> After digging in Linux HUD driver and checking again usbhidctl output, I
> realized that sometimes (and looks like in my case too) the wheel is
> represented by HID consumer "AC Pan" device. But when I just simply add
> test for this device in attach function, it doesn't work (no panic,
> just "me is not there"). I'll send extended version of your diff (which
> also tests for HUG_RZ, not only HUG_Z) later, when I'll be fully stuck
> or found solution.

Oh, how stupid I was... :(

Shortly, this modified version of your diff makes my mouse behave
absolutely correct.
I decided to not hardcode Z axis position, so it is detected as next
to sc_loc_y, same size.

(I hope that GMail will not corrupt diff, but if it'll, I'll send it
in a new thread, sorry)

--
  Best wishes,
    Vadim Jukov


Index: dev/usb/ums.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ums.c,v
retrieving revision 1.26
diff -u -u -r1.26 ums.c
--- dev/usb/ums.c       17 Sep 2007 01:40:38 -0000      1.26
+++ dev/usb/ums.c       20 Oct 2007 08:32:13 -0000
@@ -80,11 +80,6 @@

 #define UMSUNIT(s)     (minor(s))

-#define PS2LBUTMASK    x01
-#define PS2RBUTMASK    x02
-#define PS2MBUTMASK    x04
-#define PS2BUTMASK 0x0f
-
 #define MAX_BUTTONS    16      /* must not exceed size of sc_buttons */

 struct ums_softc {
@@ -96,9 +91,13 @@
        int sc_enabled;

        int flags;              /* device configuration */
-#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_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 available */
+#define UMS_REVW                       0x10    /* W-axis is reversed */
+#define UMS_LEADINGBYTE                        0x20    /* Unknown leading byte 
*/
+#define UMS_IGNORE_WHEEL_BUTTONS       0x40    /* Ignore buttons 4 and 5 */

        int nbuttons;

@@ -166,7 +165,7 @@
        int size;
        void *desc;
        u_int32_t flags, quirks;
-       int i;
+       int i, wheel, twheel;
        struct hid_location loc_btn;

        sc->sc_hdev.sc_intr = ums_intr;
@@ -178,6 +177,8 @@
                sc->flags |= UMS_REVZ;
        if (quirks & UQ_SPUR_BUT_UP)
                sc->flags |= UMS_SPUR_BUT_UP;
+       if (quirks & UQ_MS_LEADING_BYTE)
+               sc->flags |= UMS_LEADINGBYTE;

        uhidev_get_report_desc(uha->parent, &desc, &size);

@@ -205,9 +206,22 @@
                return;
        }

-       /* Try the wheel as Z activator first */
-       if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
-           uha->reportid, hid_input, &sc->sc_loc_z, &flags)) {
+       /*
+        * Try to guess the Z activator: check WHEEL, TWHEEL, and Z,
+        * in that order.
+        */
+
+       wheel = hid_locate(desc, size,
+           HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
+           uha->reportid, hid_input, &sc->sc_loc_z, &flags);
+       if (wheel == 0)
+               twheel = hid_locate(desc, size,
+                   HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
+                   uha->reportid, hid_input, &sc->sc_loc_z, &flags);
+       else
+               twheel = 0;
+
+       if (wheel || twheel) {
                if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
                        DPRINTF(("\n%s: Wheel report 0x%04x not supported\n",
                                sc->sc_hdev.sc_dev.dv_xname, flags));
@@ -230,6 +244,8 @@
                                /* Bad Z coord, ignore it */
                                sc->sc_loc_w.size = 0;
                        }
+                       else
+                               sc->flags |= UMS_W;
                }
        } else if (hid_locate(desc, size,
            HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
@@ -243,6 +259,21 @@
                }
        }

+       /*
+        * The Microsoft Wireless Intellimouse 2.0 reports its wheel
+        * using 0x0048 (I've called it HUG_TWHEEL) and seems to expect
+        * us to know that the byte after the wheel is the tilt axis.
+        * There are no other HID axis descriptors other than X, Y and
+        * TWHEEL, so we report TWHEEL on the W axis.
+        */
+       if (twheel) {
+               sc->sc_loc_w = sc->sc_loc_z;
+               sc->sc_loc_w.pos = sc->sc_loc_w.pos + 8;
+               sc->flags |= UMS_W | UMS_LEADINGBYTE;
+               /* Wheels need their axis reversed. */
+               sc->flags ^= UMS_REVW;
+       }
+
        /* figure out the number of buttons */
        for (i = 1; i <= MAX_BUTTONS; i++)
                if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
@@ -250,9 +281,50 @@
                        break;
        sc->nbuttons = i - 1;

-       printf(": %d button%s%s\n",
-           sc->nbuttons, sc->nbuttons == 1 ? "" : "s",
-           sc->flags & UMS_Z ? " and Z dir." : "");
+       /*
+        * The Microsoft Wireless Notebook Optical Mouse seems to be in worse
+        * shape than the Wireless Intellimouse 2.0, as its X, Y, wheel, and
+        * all of its other button positions are all off. It also reports that
+        * it has two addional buttons and a tilt wheel.
+        */
+       if (quirks & UQ_MS_BAD_CLASS) {
+               /* UMS_LEADINGBYTE cleared on purpose */
+               sc->flags = UMS_Z | UMS_SPUR_BUT_UP;
+               sc->nbuttons = 3;
+               /* XXX change sc_hdev isize to 5? */
+               /* 1st byte of descriptor report contains garbage */
+               sc->sc_loc_x.pos = 16;
+               sc->sc_loc_y.pos = 24;
+               sc->sc_loc_z.pos = 32;
+               sc->sc_loc_btn[0].pos = 8;
+               sc->sc_loc_btn[1].pos = 9;
+               sc->sc_loc_btn[2].pos = 10;
+       }
+
+       if (quirks & UQ_IGNORE_WHEEL_BUTTONS)
+               sc->flags |= UMS_IGNORE_WHEEL_BUTTONS;
+
+       /*
+        * Dirty hack? Maybe. But it helps at least in Microsoft Wireless
+        * Optical Desktop 1000 case.
+        */
+       if (sc->sc_loc_z.pos == 0 && sc->sc_loc_btn[0].pos == 0)
+               sc->sc_loc_z.pos = sc->sc_loc_y.pos + sc->sc_loc_y.size;
+
+       printf(": %d button%s",
+           sc->nbuttons, sc->nbuttons <= 1 ? "" : "s");
+       switch (sc->flags & (UMS_Z | UMS_W)) {
+       case UMS_Z:
+               printf(", Z dir");
+               break;
+       case UMS_W:
+               printf(", W dir");
+               break;
+       case UMS_Z | UMS_W:
+               printf(", Z and W dir");
+               break;
+       }
+       printf("\n");

        for (i = 1; i <= sc->nbuttons; i++)
                hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
@@ -315,9 +387,10 @@
 }

 void
-ums_intr(struct uhidev *addr, void *ibuf, u_int len)
+ums_intr(struct uhidev *addr, void *buf, u_int len)
 {
        struct ums_softc *sc = (struct ums_softc *)addr;
+       u_char *ibuf = (u_char *)buf;
        int dx, dy, dz, dw;
        u_int32_t buttons = 0;
        int i;
@@ -325,15 +398,47 @@

        DPRINTFN(5,("ums_intr: len=%d\n", len));

+       /*
+        * The Microsoft Wireless Intellimouse 2.0 sends one extra leading
+        * byte of data compared to most USB mice.  This byte frequently
+        * switches from 0x01 (usual state) to 0x02.  It may be used to
+        * report non-standard events (such as battery life).  However,
+        * at the same time, it generates a left click event on the
+        * button byte, where there shouldn't be any.  We simply discard
+        * the packet in this case.
+        *
+        * This problem affects the MS Wireless Notebook Optical Mouse, too.
+        * However, the leading byte for this mouse is normally 0x11, and
+        * the phantom mouse click occurs when it's 0x14.
+        */
+       if (sc->flags & UMS_LEADINGBYTE) {
+               if (*ibuf++ == 0x02)
+                       return;
+               /* else
+                       len--; */
+       } else if (sc->flags & UMS_SPUR_BUT_UP) {
+               if (*ibuf == 0x14 || *ibuf == 0x15)
+                       return;
+       }
+
+       for (i = 0; i < sc->nbuttons; i++)
+               if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
+                       buttons |= (1 << UMS_BUT(i));
        dx =  hid_get_data(ibuf, &sc->sc_loc_x);
        dy = -hid_get_data(ibuf, &sc->sc_loc_y);
        dz =  hid_get_data(ibuf, &sc->sc_loc_z);
        dw =  hid_get_data(ibuf, &sc->sc_loc_w);
+
+       if (sc->flags & UMS_IGNORE_WHEEL_BUTTONS)
+               buttons ^= ((1 << UMS_BUT(3)) | (1 << UMS_BUT(4))) & buttons;
+
        if (sc->flags & UMS_REVZ)
                dz = -dz;
-       for (i = 0; i < sc->nbuttons; i++)
-               if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
-                       buttons |= (1 << UMS_BUT(i));
+       if (sc->flags & UMS_REVW)
+               dw = -dw;
+
+       if (dz != 0)
+               DPRINTFN(3, ("ums_intr: dz=%d", dz));

        if (dx != 0 || dy != 0 || dz != 0 || dw != 0 ||
            buttons != sc->sc_buttons) {
Index: dev/usb/usb_quirks.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb_quirks.c,v
retrieving revision 1.30
diff -u -u -r1.30 usb_quirks.c
--- dev/usb/usb_quirks.c        28 Aug 2007 09:45:46 -0000      1.30
+++ dev/usb/usb_quirks.c        20 Oct 2007 08:32:13 -0000
@@ -136,6 +136,16 @@
  { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR, ANY,   { UQ_BAD_HID }},
  { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1,           ANY,   { UQ_BAD_HID }},
  { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2,           ANY,   { UQ_BAD_HID }},
+
+  /* MS mice do weird things */
+ { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK,
+       ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }},
+ { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2,
+       ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }},
+ { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE,
+       ANY, { UQ_MS_LEADING_BYTE }},
+ { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLOPTDSK1000,
+       ANY, { UQ_IGNORE_WHEEL_BUTTONS }},
  { 0, 0, 0, { 0 } }
 };

Index: dev/usb/usb_quirks.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb_quirks.h,v
retrieving revision 1.10
diff -u -u -r1.10 usb_quirks.h
--- dev/usb/usb_quirks.h        14 May 2006 12:00:04 -0000      1.10
+++ dev/usb/usb_quirks.h        20 Oct 2007 08:32:13 -0000
@@ -41,21 +41,42 @@

 struct usbd_quirks {
        u_int32_t uq_flags;     /* Device problems: */
-#define UQ_NO_SET_PROTO        0x0001  /* cannot handle SET PROTOCOL. */
-#define UQ_SWAP_UNICODE        0x0002  /* has some Unicode strings swapped. */
-#define UQ_MS_REVZ     0x0004  /* mouse has Z-axis reversed */
-#define UQ_NO_STRINGS  0x0008  /* string descriptors are broken. */
-#define UQ_BAD_ADC     0x0010  /* bad audio spec version number. */
-#define UQ_BUS_POWERED 0x0020  /* device is bus powered, despite claim */
-#define UQ_BAD_AUDIO   0x0040  /* device claims audio class, but isn't */
-#define UQ_SPUR_BUT_UP 0x0080  /* spurious mouse button up events */
-#define UQ_AU_NO_XU    0x0100  /* audio device has broken extension unit */
-#define UQ_POWER_CLAIM 0x0200  /* hub lies about power status */
-#define UQ_AU_NO_FRAC  0x0400  /* don't adjust for fractional samples */
-#define UQ_AU_INP_ASYNC        0x0800  /* input is async despite claim of 
adaptive */
-#define UQ_ASSUME_CM_OVER_DATA 0x1000 /* modem device breaks on cm over data */
-#define UQ_BROKEN_BIDIR        0x2000  /* printer has broken bidir mode */
-#define UQ_BAD_HID     0x4000  /* device claims uhid, but isn't */
+       /* cannot handle SET PROTOCOL. */
+#define UQ_NO_SET_PROTO                0x00000001
+       /* has some Unicode strings swapped. */
+#define UQ_SWAP_UNICODE                0x00000002
+       /* mouse has Z-axis reversed */
+#define UQ_MS_REVZ             0x00000004
+       /* string descriptors are broken. */
+#define UQ_NO_STRINGS          0x00000008
+       /* bad audio spec version number. */
+#define UQ_BAD_ADC             0x00000010
+       /* device is bus powered, despite claim */
+#define UQ_BUS_POWERED         0x00000020
+       /* device claims audio class, but isn't */
+#define UQ_BAD_AUDIO           0x00000040
+       /* spurious mouse button up events */
+#define UQ_SPUR_BUT_UP         0x00000080
+       /* audio device has broken extension unit */
+#define UQ_AU_NO_XU            0x00000100
+       /* hub lies about power status */
+#define UQ_POWER_CLAIM         0x00000200
+       /* don't adjust for fractional samples */
+#define UQ_AU_NO_FRAC          0x00000400
+       /* input is async despite claim of adaptive */
+#define UQ_AU_INP_ASYNC                0x00000800
+       /* modem device breaks on cm over data */
+#define UQ_ASSUME_CM_OVER_DATA 0x00001000
+       /* printer has broken bidir mode */
+#define UQ_BROKEN_BIDIR                0x00002000
+       /* device claims uhid, but isn't */
+#define UQ_BAD_HID             0x00004000
+       /* doesn't identify properly */
+#define UQ_MS_BAD_CLASS                0x00008000
+       /* mouse sends an unknown leading byte. */
+#define UQ_MS_LEADING_BYTE     0x00010000
+       /* Ignore buttons 4 and 5 */
+#define UQ_IGNORE_WHEEL_BUTTONS        0x00020000
 };

 extern const struct usbd_quirks usbd_no_quirk;
Index: dev/usb/usbdevs
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs,v
retrieving revision 1.302
diff -u -u -r1.302 usbdevs
--- dev/usb/usbdevs     14 Oct 2007 08:29:17 -0000      1.302
+++ dev/usb/usbdevs     20 Oct 2007 08:32:16 -0000
@@ -1612,11 +1612,16 @@
 product MICROSOFT NATURALKBD   0x000b  Natural
 product MICROSOFT DDS80                0x0014  Digital Sound System 80
 product MICROSOFT SIDEWINDER   0x001a  Sidewinder Precision Racing Wheel
-product MICROSOFT TBEXPLORER   0x0024  Trackball Explorer
+product MICROSOFT TBEXPLORER   0x0024  Trackball Explorer
 product MICROSOFT INTELLIEYE   0x0025  IntelliEye mouse
 product MICROSOFT INETPRO      0x002b  Internet Keyboard Pro
 product MICROSOFT MN510                0x006e  MN510 Wireless
 product MICROSOFT MN110                0x007a  10/100 Ethernet
+product MICROSOFT WLINTELLIMOUSE 0x008c        Wireless Optical IntelliMouse
+product MICROSOFT WLOPTDSK1000 0x009d  Wireless Optical Desktop 1000
+product MICROSOFT WLNOTEBOOK   0x00b9  Wireless Optical Mouse (Model 1023)
+product MICROSOFT WLNOTEBOOK2  0x00e1  Wireless Optical Mouse 3000 (Model 1056)
+product MICROSOFT WLUSBMOUSE   0x00b9  Wireless USB Mouse
 product MICROSOFT XBOX360      0x0292  XBOX 360 WLAN

 /* Microtech products */
Index: dev/usb/usbdevs.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v
retrieving revision 1.311
diff -u -u -r1.311 usbdevs.h
--- dev/usb/usbdevs.h   14 Oct 2007 08:30:49 -0000      1.311
+++ dev/usb/usbdevs.h   20 Oct 2007 08:32:18 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdevs.h,v 1.311 2007/10/14 08:30:49 fkr Exp $       */
+/*     $OpenBSD$       */

 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -1624,6 +1624,11 @@
 #define        USB_PRODUCT_MICROSOFT_INETPRO   0x002b          /* Internet 
Keyboard Pro */
 #define        USB_PRODUCT_MICROSOFT_MN510     0x006e          /* MN510 
Wireless */
 #define        USB_PRODUCT_MICROSOFT_MN110     0x007a          /* 10/100 
Ethernet */
+#define        USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE    0x008c          /* 
Wireless
Optical IntelliMouse */
+#define        USB_PRODUCT_MICROSOFT_WLOPTDSK1000      0x009d          /* 
Wireless
Optical Desktop 1000 */
+#define        USB_PRODUCT_MICROSOFT_WLNOTEBOOK        0x00b9          /* 
Wireless Optical
Mouse (Model 1023) */
+#define        USB_PRODUCT_MICROSOFT_WLNOTEBOOK2       0x00e1          /* 
Wireless Optical
Mouse 3000 (Model 1056) */
+#define        USB_PRODUCT_MICROSOFT_WLUSBMOUSE        0x00b9          /* 
Wireless USB Mouse */
 #define        USB_PRODUCT_MICROSOFT_XBOX360   0x0292          /* XBOX 360 
WLAN */

 /* Microtech products */
Index: dev/usb/usbdevs_data.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs_data.h,v
retrieving revision 1.308
diff -u -u -r1.308 usbdevs_data.h
--- dev/usb/usbdevs_data.h      14 Oct 2007 08:30:49 -0000      1.308
+++ dev/usb/usbdevs_data.h      20 Oct 2007 08:32:21 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdevs_data.h,v 1.308 2007/10/14 08:30:49 fkr Exp $  */
+/*     $OpenBSD$       */

 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -2935,6 +2935,26 @@
        {
            USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110,
            "10/100 Ethernet",
+       },
+       {
+           USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE,
+           "Wireless Optical IntelliMouse",
+       },
+       {
+           USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLOPTDSK1000,
+           "Wireless Optical Desktop 1000",
+       },
+       {
+           USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK,
+           "Wireless Optical Mouse (Model 1023)",
+       },
+       {
+           USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2,
+           "Wireless Optical Mouse 3000 (Model 1056)",
+       },
+       {
+           USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLUSBMOUSE,
+           "Wireless USB Mouse",
        },
        {
            USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_XBOX360,
Index: dev/usb/usbhid.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbhid.h,v
retrieving revision 1.10
diff -u -u -r1.10 usbhid.h
--- dev/usb/usbhid.h    1 Sep 2007 17:06:26 -0000       1.10
+++ dev/usb/usbhid.h    20 Oct 2007 08:32:21 -0000
@@ -124,6 +124,7 @@
 #define HUG_VBRY               0x0044
 #define HUG_VBRZ               0x0045
 #define HUG_VNO                        0x0046
+#define HUG_TWHEEL             0x0048
 #define HUG_SYSTEM_CONTROL     0x0080
 #define HUG_SYSTEM_POWER_DOWN  0x0081
 #define HUG_SYSTEM_SLEEP       0x0082

Reply via email to