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