From amistry@united-ware.com  Wed Aug 18 04:26:17 2004
Return-Path: <amistry@united-ware.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 02DCE16A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 18 Aug 2004 04:26:17 +0000 (GMT)
Received: from smtp3.fuse.net (mail-out3.fuse.net [216.68.8.176])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 6384F43D39
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 18 Aug 2004 04:26:16 +0000 (GMT)
	(envelope-from amistry@united-ware.com)
Received: from gx4.fuse.net ([216.196.152.37]) by smtp3.fuse.net
          (InterMail vM.6.01.03.03 201-2131-111-105-20040624) with ESMTP
          id <20040818042615.LBOX19154.smtp3.fuse.net@gx4.fuse.net>
          for <FreeBSD-gnats-submit@freebsd.org>;
          Wed, 18 Aug 2004 00:26:15 -0400
Received: from www.united-ware.com ([216.196.152.37]) by gx4.fuse.net
          (InterMail vG.1.00.00.00 201-2136-104-20040331) with ESMTP
          id <20040818042614.DRTO9892.gx4.fuse.net@www.united-ware.com>;
          Wed, 18 Aug 2004 00:26:14 -0400
Received: from www.united-ware.com (localhost [127.0.0.1])
	by www.united-ware.com (8.12.9p2/8.12.9) with ESMTP id i7I4G6lK035606
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT);
	Wed, 18 Aug 2004 00:16:07 -0400 (EDT)
	(envelope-from amistry@www.united-ware.com)
Received: (from amistry@localhost)
	by www.united-ware.com (8.12.9p2/8.12.9/Submit) id i7I4G6AI035605;
	Wed, 18 Aug 2004 00:16:06 -0400 (EDT)
	(envelope-from amistry)
Message-Id: <200408180416.i7I4G6AI035605@www.united-ware.com>
Date: Wed, 18 Aug 2004 00:16:06 -0400 (EDT)
From: Anish Mistry <amistry@am-productions.biz>
Reply-To: Anish Mistry <amistry@am-productions.biz>
To: FreeBSD-gnats-submit@freebsd.org
Cc: Marc van Kempen <marc@bowtie.nl>
Subject: Add Support for USB Microsoft Intellimouse (possibly others)
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         70607
>Category:       kern
>Synopsis:       [patch] Add Support for USB Microsoft Intellimouse (possibly others)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-usb
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 18 04:30:27 GMT 2004
>Closed-Date:    Sun Dec 12 05:35:57 GMT 2004
>Last-Modified:  Sun Dec 12 05:35:57 GMT 2004
>Originator:     Anish Mistry
>Release:        FreeBSD 5.2-CURRENT i386
>Organization:
AM Productions
>Environment:
System: FreeBSD littleguy 5.2-CURRENT FreeBSD 5.2-CURRENT #56: Tue Aug 17 11:50:14 EDT 2004     amistry@littleguy:/usr/src/sys/i386/compile/LITTLEGUY  i386

	
>Description:
	The USB Microsoft Intellimouse keeps sending the ums driver the USBD_IOERROR status even though the device is working.  The result of this is that the device attaches and is identified correctly, but ums_intr bails out since it doesn't recieve a normal completion status.  It is possible that other mice suffer from this problem as well.
	
>How-To-Repeat:
	Plug in the mouse and see it attach, but not move.
	
>Fix:
	The attached fix adds tilt wheel support as well as allows it to work normally.
	

--- intellimouse-usb-support.patch begins here ---
--- /sys/sys/mouse.h.orig	Tue Aug 17 23:54:14 2004
+++ /sys/sys/mouse.h	Tue Aug 17 23:54:02 2004
@@ -58,6 +58,7 @@
     int     dx;			/* x movement */
     int     dy;			/* y movement */
     int     dz;			/* z movement */
+    int     daa;		/* left right tilt axis */
 } mousestatus_t;
 
 /* button */
--- /sys/dev/usb/ums.c.orig	Tue Aug 17 18:45:50 2004
+++ /sys/dev/usb/ums.c	Tue Aug 17 23:41:26 2004
@@ -104,7 +104,7 @@
 	u_char *sc_ibuf;
 	u_int8_t sc_iid;
 	int sc_isize;
-	struct hid_location sc_loc_x, sc_loc_y, sc_loc_z;
+	struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_aa;
 	struct hid_location *sc_loc_btn;
 
 	usb_callout_t callout_handle;	/* for spurious button ups */
@@ -114,6 +114,7 @@
 
 	int flags;		/* device configuration */
 #define UMS_Z		0x01	/* z direction available */
+#define UMS_AA		0x02	/* aa direction available (tilt) */
 #define UMS_SPUR_BUT_UP	0x02	/* spurious button up events */
 	int nbuttons;
 #define MAX_BUTTONS	7	/* chosen because sc_buttons is u_char */
@@ -140,7 +141,7 @@
 			  usbd_private_handle priv, usbd_status status);
 
 Static void ums_add_to_queue(struct ums_softc *sc,
-				int dx, int dy, int dz, int buttons);
+				int dx, int dy, int dz, int daa, int buttons);
 Static void ums_add_to_queue_timeout(void *priv);
 
 Static int  ums_enable(void *);
@@ -408,15 +409,15 @@
 {
 	struct ums_softc *sc = addr;
 	u_char *ibuf;
-	int dx, dy, dz;
+	int dx, dy, dz, daa;
 	u_char buttons = 0;
 	int i;
 
 #define UMS_BUT(i) ((i) < 3 ? (((i) + 2) % 3) : (i))
 
 	DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status));
-	DPRINTFN(5, ("ums_intr: data = %02x %02x %02x\n",
-		     sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2]));
+	DPRINTFN(5, ("ums_intr: data = %02x %02x %02x %02x %02x %02x\n",
+		     sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2], sc->sc_ibuf[3], sc->sc_ibuf[4], sc->sc_ibuf[5]));
 
 	if (status == USBD_CANCELLED)
 		return;
@@ -425,31 +426,33 @@
 		DPRINTF(("ums_intr: status=%d\n", status));
 		if (status == USBD_STALLED)
 		    usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
-		return;
+		if(status != USBD_IOERROR)
+			return;
 	}
 
 	ibuf = sc->sc_ibuf;
 	if (sc->sc_iid) {
-		if (*ibuf++ != sc->sc_iid)
-			return;
+		ibuf++;
 	}
 
 	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);
+	daa = -hid_get_data(ibuf, &sc->sc_loc_aa);
 	for (i = 0; i < sc->nbuttons; i++)
 		if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
 			buttons |= (1 << UMS_BUT(i));
 
-	if (dx || dy || dz || (sc->flags & UMS_Z)
+	if (dx || dy || dz || daa || (sc->flags & UMS_Z)
 	    || buttons != sc->status.button) {
-		DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d buttons:0x%x\n",
-			dx, dy, dz, buttons));
+		DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d aa:%d buttons:0x%x\n",
+			dx, dy, dz, daa, buttons));
 
 		sc->status.button = buttons;
 		sc->status.dx += dx;
 		sc->status.dy += dy;
 		sc->status.dz += dz;
+		sc->status.daa += daa;
 
 		/* Discard data in case of full buffer */
 		if (sc->qcount == sizeof(sc->qbuf)) {
@@ -466,13 +469,13 @@
 		 * In any other case we delete the timeout event.
 		 */
 		if (sc->flags & UMS_SPUR_BUT_UP &&
-		    dx == 0 && dy == 0 && dz == 0 && buttons == 0) {
+		    dx == 0 && dy == 0 && dz == 0 && daa == 0 && buttons == 0) {
 			usb_callout(sc->callout_handle, MS_TO_TICKS(50 /*msecs*/),
 				    ums_add_to_queue_timeout, (void *) sc);
 		} else {
 			usb_uncallout(sc->callout_handle,
 				      ums_add_to_queue_timeout, (void *) sc);
-			ums_add_to_queue(sc, dx, dy, dz, buttons);
+			ums_add_to_queue(sc, dx, dy, dz, daa, buttons);
 		}
 	}
 }
@@ -484,12 +487,12 @@
 	int s;
 
 	s = splusb();
-	ums_add_to_queue(sc, 0, 0, 0, 0);
+	ums_add_to_queue(sc, 0, 0, 0, 0, 0);
 	splx(s);
 }
 
 Static void
-ums_add_to_queue(struct ums_softc *sc, int dx, int dy, int dz, int buttons)
+ums_add_to_queue(struct ums_softc *sc, int dx, int dy, int dz, int daa, int buttons)
 {
 	/* Discard data in case of full buffer */
 	if (sc->qhead+sc->mode.packetsize > sizeof(sc->qbuf)) {
@@ -503,6 +506,8 @@
 	if (dy < -256)		dy = -256;
 	if (dz >  126)		dz =  126;
 	if (dz < -128)		dz = -128;
+	if (daa >  126)		daa =  126;
+        if (daa < -128)		daa = -128;
 
 	sc->qbuf[sc->qhead] = sc->mode.syncmask[1];
 	sc->qbuf[sc->qhead] |= ~buttons & MOUSE_MSC_BUTTONS;
@@ -550,7 +555,7 @@
 	sc->qhead = sc->qtail = 0;
 	sc->status.flags = 0;
 	sc->status.button = sc->status.obutton = 0;
-	sc->status.dx = sc->status.dy = sc->status.dz = 0;
+	sc->status.dx = sc->status.dy = sc->status.dz = sc->status.daa = 0;
 
 	callout_handle_init((struct callout_handle *)&sc->callout_handle);
 
@@ -807,10 +812,10 @@
 		*status = sc->status;
 		sc->status.obutton = sc->status.button;
 		sc->status.button = 0;
-		sc->status.dx = sc->status.dy = sc->status.dz = 0;
+		sc->status.dx = sc->status.dy = sc->status.dz = sc->status.daa = 0;
 		splx(s);
 
-		if (status->dx || status->dy || status->dz)
+		if (status->dx || status->dy || status->dz || status->daa)
 			status->flags |= MOUSE_POSCHANGED;
 		if (status->button != status->obutton)
 			status->flags |= MOUSE_BUTTONSCHANGED;
--- intellimouse-usb-support.patch ends here ---


>Release-Note:
>Audit-Trail:

From: Mark Ovens <marko@freebsd.org>
To: freebsd-gnats-submit@FreeBSD.org, amistry@am-productions.biz
Cc:  
Subject: Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse
 (possibly others)
Date: Tue, 14 Sep 2004 22:29:32 +0100

 Kudos for fixing this Anish. I applied your patch to my latest build
 
 FreeBSD redshift 5.3-BETA4 FreeBSD 5.3-BETA4 #1:
 Tue Sep 14 19:27:04 BST 2004
 mark@redshift:/usr/obj/usr/src/sys/REDSHIFT  i386
 
 and my MS Wireless Optical Mouse 2.0 worked on USB, but there are 3 
 problems:
 
 1. This error still appears:
 
     /root{101}# moused -t auto -p /dev/ums0
     moused: unable to open /dev/ums0: Device busy
 
 2. "phantom" left button down events are generated. In the console this 
 causes text to be selected randomly, and it makes X almost unusable, 
 e.g. in a web browser it randomly follows links. This is definitely not 
 a faulty button on the mouse as it works OK when connected to a PS/2 
 port with an adaptor and it works correctly in Windows XP (dual-boot 
 machine).
 
 3. The wheel has stopped working in X. When I moved the mouse back to 
 PS/2 it works again.
 
 If you would like me to do any further testing just e-mail me.
 
 
 

From: Anish Mistry <amistry@am-productions.biz>
To: Mark Ovens <marko@freebsd.org>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse (possibly others)
Date: Tue, 14 Sep 2004 17:40:14 -0400

 --Boundary-02=_FV2RBrlcwnIz4os
 Content-Type: text/plain;
   charset="iso-8859-15"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: inline
 
 On Tuesday 14 September 2004 05:29 pm, you wrote:
 > Kudos for fixing this Anish. I applied your patch to my latest build
 >
 > FreeBSD redshift 5.3-BETA4 FreeBSD 5.3-BETA4 #1:
 > Tue Sep 14 19:27:04 BST 2004
 > mark@redshift:/usr/obj/usr/src/sys/REDSHIFT  i386
 >
 > and my MS Wireless Optical Mouse 2.0 worked on USB, but there are 3
 > problems:
 >
 > 1. This error still appears:
 >
 >     /root{101}# moused -t auto -p /dev/ums0
 >     moused: unable to open /dev/ums0: Device busy
 >
 > 2. "phantom" left button down events are generated. In the console this
 > causes text to be selected randomly, and it makes X almost unusable,
 > e.g. in a web browser it randomly follows links. This is definitely not
 > a faulty button on the mouse as it works OK when connected to a PS/2
 > port with an adaptor and it works correctly in Windows XP (dual-boot
 > machine).
 >
 > 3. The wheel has stopped working in X. When I moved the mouse back to
 > PS/2 it works again.
 >
 > If you would like me to do any further testing just e-mail me.
 Thanks, I'm aware of the issues and I'm planning on importing the NetBSD US=
 D=20
 HID source (unless someone beats me to it :) ) when I get some time and if=
 =20
 that doesn't fix the problem, then I'll make the needed changes.
 =2D-=20
 Anish Mistry
 amistry@am-productions.biz
 AM Productions http://am-productions.biz/
 
 --Boundary-02=_FV2RBrlcwnIz4os
 Content-Type: application/pgp-signature
 Content-Description: signature
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.2.4 (FreeBSD)
 
 iD8DBQBBR2VFxqA5ziudZT0RAg9MAKCviJFdwEx3JekkuqrHlcp6LwwrsQCgiY3X
 ZpFvT102KZhH3YBPOWFZS1k=
 =HvAK
 -----END PGP SIGNATURE-----
 
 --Boundary-02=_FV2RBrlcwnIz4os--
Responsible-Changed-From-To: freebsd-bugs->freebsd-usb 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Nov 4 07:31:18 GMT 2004 
Responsible-Changed-Why:  
Reassign to appropriate mailing list. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=70607 

From: Matt Wright <matt@consultmatt.co.uk>
To: freebsd-gnats-submit@FreeBSD.org, amistry@am-productions.biz
Cc:  
Subject: Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse
 (possibly others)
Date: Mon, 08 Nov 2004 10:41:18 +0000

 Further to the patch that Anish posted here is a patch that removes bugs 
 2 and 3 which Mark noticed.
 
 If you need any explanation there is a fairly detailed explanation of 
 the patch, well at least the method I used to debug it, at:
 
 http://www.consultmatt.co.uk/freebsd/intellimouse.php
 
 Regards,
 
 Matt
 
 --- sys/dev/usb/usbhid.h.orig	Mon Sep 20 00:59:48 2004
 +++ sys/dev/usb/usbhid.h	Mon Sep 20 02:14:40 2004
 @@ -123,6 +123,7 @@
   #define HUG_VBRY		0x0044
   #define HUG_VBRZ		0x0045
   #define HUG_VNO			0x0046
 +#define HUG_TWHEEL		0x0048 // M$ Wireless Intellimouse Wheel
   #define HUG_SYSTEM_CONTROL	0x0080
   #define HUG_SYSTEM_POWER_DOWN	0x0081
   #define HUG_SYSTEM_SLEEP	0x0082
 --- sys/sys/mouse.h.orig	Fri Jul 30 01:59:40 2004
 +++ sys/sys/mouse.h	Tue Sep 21 00:42:37 2004
 @@ -58,6 +58,7 @@
       int     dx;			/* x movement */
       int     dy;			/* y movement */
       int     dz;			/* z movement */
 +    int     dt;			/* left right tilt axis */
   } mousestatus_t;
 
   /* button */
 --- sys/dev/usb/ums.c.orig	Mon Aug 16 00:39:18 2004
 +++ sys/dev/usb/ums.c	Tue Sep 21 00:47:52 2004
 @@ -104,7 +104,7 @@
   	u_char *sc_ibuf;
   	u_int8_t sc_iid;
   	int sc_isize;
 -	struct hid_location sc_loc_x, sc_loc_y, sc_loc_z;
 +	struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_t;
   	struct hid_location *sc_loc_btn;
 
   	usb_callout_t callout_handle;	/* for spurious button ups */
 @@ -114,6 +114,7 @@
 
   	int flags;		/* device configuration */
   #define UMS_Z		0x01	/* z direction available */
 +#define UMS_T		0x02	/* aa direction available (tilt) */
   #define UMS_SPUR_BUT_UP	0x02	/* spurious button up events */
   	int nbuttons;
   #define MAX_BUTTONS	7	/* chosen because sc_buttons is u_char */
 @@ -140,7 +141,7 @@
   			  usbd_private_handle priv, usbd_status status);
 
   Static void ums_add_to_queue(struct ums_softc *sc,
 -				int dx, int dy, int dz, int buttons);
 +				int dx, int dy, int dz, int dt, int buttons);
   Static void ums_add_to_queue_timeout(void *priv);
 
   Static int  ums_enable(void *);
 @@ -269,6 +270,8 @@
   	if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
   		       hid_input, &sc->sc_loc_z, &flags) ||
   	    hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
 +		       hid_input, &sc->sc_loc_z, &flags) ||
 +	    hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
   		       hid_input, &sc->sc_loc_z, &flags)) {
   		if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
   			sc->sc_loc_z.size = 0;	/* Bad Z coord, ignore it */
 @@ -277,6 +280,17 @@
   		}
   	}
 
 +	/* The Microsoft Wireless Intellimouse 2.0 reports it's wheel
 +	 * using 0x0048 (i've called it HUG_TWHEEL) and seems to expect
 +	 * you 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 */
 +	if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
 +			hid_input, &sc->sc_loc_t, &flags)) {
 +			sc->sc_loc_t.pos = sc->sc_loc_t.pos + 8;
 +			sc->flags |= UMS_T;
 +	}
 +
   	/* figure out the number of buttons */
   	for (i = 1; i <= MAX_BUTTONS; i++)
   		if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
 @@ -290,8 +304,9 @@
   		USB_ATTACH_ERROR_RETURN;
   	}
 
 -	printf("%s: %d buttons%s\n", USBDEVNAME(sc->sc_dev),
 -	       sc->nbuttons, sc->flags & UMS_Z? " and Z dir." : "");
 +	printf("%s: %d buttons%s%s.\n", USBDEVNAME(sc->sc_dev),
 +	       sc->nbuttons, sc->flags & UMS_Z? " and Z dir" : "",
 +	       sc->flags & UMS_T?" and a TILT dir": "");
 
   	for (i = 1; i <= sc->nbuttons; i++)
   		hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
 @@ -408,15 +423,15 @@
   {
   	struct ums_softc *sc = addr;
   	u_char *ibuf;
 -	int dx, dy, dz;
 +	int dx, dy, dz, dt;
   	u_char buttons = 0;
   	int i;
 
   #define UMS_BUT(i) ((i) < 3 ? (((i) + 2) % 3) : (i))
 
   	DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status));
 -	DPRINTFN(5, ("ums_intr: data = %02x %02x %02x\n",
 -		     sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2]));
 +	DPRINTFN(5, ("ums_intr: data = %02x %02x %02x %02x %02x %02x\n",
 +		     sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2], sc->sc_ibuf[3], 
 sc->sc_ibuf[4], sc->sc_ibuf[5]));
 
   	if (status == USBD_CANCELLED)
   		return;
 @@ -425,32 +440,44 @@
   		DPRINTF(("ums_intr: status=%d\n", status));
   		if (status == USBD_STALLED)
   		    usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
 -		return;
 +		if(status != USBD_IOERROR)
 +			return;
   	}
 
   	ibuf = sc->sc_ibuf;
   	if (sc->sc_iid) {
 -		if (*ibuf++ != sc->sc_iid)
 -			return;
 +		ibuf++;
   	}
 
 +	/* 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. */
 +	if ((sc->sc_ibuf != ibuf) && (sc->sc_ibuf[0] == 0x02))
 +		return;
 +
   	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);
 +	dt = -hid_get_data(ibuf, &sc->sc_loc_t);
   	for (i = 0; i < sc->nbuttons; i++)
   		if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
   			buttons |= (1 << UMS_BUT(i));
 
 -	if (dx || dy || dz || (sc->flags & UMS_Z)
 +	if (dx || dy || dz || dt || (sc->flags & UMS_Z)
   	    || buttons != sc->status.button) {
 -		DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d buttons:0x%x\n",
 -			dx, dy, dz, buttons));
 +		DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d aa:%d buttons:0x%x\n",
 +			dx, dy, dz, dt, buttons));
 
   		sc->status.button = buttons;
   		sc->status.dx += dx;
   		sc->status.dy += dy;
   		sc->status.dz += dz;
 -
 +		sc->status.dt += dt;
 +		
   		/* Discard data in case of full buffer */
   		if (sc->qcount == sizeof(sc->qbuf)) {
   			DPRINTF(("Buffer full, discarded packet"));
 @@ -466,13 +493,13 @@
   		 * In any other case we delete the timeout event.
   		 */
   		if (sc->flags & UMS_SPUR_BUT_UP &&
 -		    dx == 0 && dy == 0 && dz == 0 && buttons == 0) {
 +		    dx == 0 && dy == 0 && dz == 0 && dt == 0 && buttons == 0) {
   			usb_callout(sc->callout_handle, MS_TO_TICKS(50 /*msecs*/),
   				    ums_add_to_queue_timeout, (void *) sc);
   		} else {
   			usb_uncallout(sc->callout_handle,
   				      ums_add_to_queue_timeout, (void *) sc);
 -			ums_add_to_queue(sc, dx, dy, dz, buttons);
 +			ums_add_to_queue(sc, dx, dy, dz, dt, buttons);
   		}
   	}
   }
 @@ -484,12 +511,12 @@
   	int s;
 
   	s = splusb();
 -	ums_add_to_queue(sc, 0, 0, 0, 0);
 +	ums_add_to_queue(sc, 0, 0, 0, 0, 0);
   	splx(s);
   }
 
   Static void
 -ums_add_to_queue(struct ums_softc *sc, int dx, int dy, int dz, int buttons)
 +ums_add_to_queue(struct ums_softc *sc, int dx, int dy, int dz, int dt, 
 int buttons)
   {
   	/* Discard data in case of full buffer */
   	if (sc->qhead+sc->mode.packetsize > sizeof(sc->qbuf)) {
 @@ -503,6 +530,8 @@
   	if (dy < -256)		dy = -256;
   	if (dz >  126)		dz =  126;
   	if (dz < -128)		dz = -128;
 +	if (dt >  126)		dt =  126;
 +        if (dt < -128)		dt = -128;
 
   	sc->qbuf[sc->qhead] = sc->mode.syncmask[1];
   	sc->qbuf[sc->qhead] |= ~buttons & MOUSE_MSC_BUTTONS;
 @@ -550,7 +579,7 @@
   	sc->qhead = sc->qtail = 0;
   	sc->status.flags = 0;
   	sc->status.button = sc->status.obutton = 0;
 -	sc->status.dx = sc->status.dy = sc->status.dz = 0;
 +	sc->status.dx = sc->status.dy = sc->status.dz = sc->status.dt = 0;
 
   	callout_handle_init((struct callout_handle *)&sc->callout_handle);
 
 @@ -807,10 +836,10 @@
   		*status = sc->status;
   		sc->status.obutton = sc->status.button;
   		sc->status.button = 0;
 -		sc->status.dx = sc->status.dy = sc->status.dz = 0;
 +		sc->status.dx = sc->status.dy = sc->status.dz = sc->status.dt = 0;
   		splx(s);
 
 -		if (status->dx || status->dy || status->dz)
 +		if (status->dx || status->dy || status->dz || status->dt)
   			status->flags |= MOUSE_POSCHANGED;
   		if (status->button != status->obutton)
   			status->flags |= MOUSE_BUTTONSCHANGED;

From: Anish Mistry <mistry.7@osu.edu>
To: Matt Wright <matt@consultmatt.co.uk>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse (possibly others)
Date: Mon, 8 Nov 2004 16:40:11 -0500

 --Boundary-00=_Ef+jBJHUYWZ6fJL
 Content-Type: multipart/signed;
   boundary="nextPart1115225.H8LH6WHjhn";
   protocol="application/pgp-signature";
   micalg=pgp-sha1
 Content-Transfer-Encoding: 7bit
 
 --nextPart1115225.H8LH6WHjhn
 Content-Type: text/plain;
   charset="iso-8859-1"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: inline
 
 Excellent work Matt.  I've just tested it with my wired Intellimouse, and=20
 it works great on my laptop (6-CURRENT).  It didn't work on my desktop,=20
 but I think the USB controller is flaky, ums just gets 1 interrupt then=20
 gets stuck, but my other USB mice still worked fine, so no regressions. =20
 The patch does seem a bit malformed, I'm attaching a fixed up version.
 Also posted here if it gets messed up:
 http://am-productions.biz/docs/intellimouse-woks.patch
 
 Could a committer (Ian?) take a look at this a possibly merge it?
 
 =2D-=20
 Anish Mistry
 
 --nextPart1115225.H8LH6WHjhn
 Content-Type: application/pgp-signature
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.2.6 (FreeBSD)
 
 iD8DBQBBj+fExqA5ziudZT0RAknYAKCl1g+I2oS7E2eskok2N7O7qmKCEgCfazNv
 m6TFS3cp89Swzo2GTcoijaE=
 =zqx5
 -----END PGP SIGNATURE-----
 
 --nextPart1115225.H8LH6WHjhn--
 
 --Boundary-00=_Ef+jBJHUYWZ6fJL
 Content-Type: text/x-diff;
   charset="iso-8859-1";
   name="intellimouse-works.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
 	filename="intellimouse-works.patch"
 
 --- sys/dev/usb/usbhid.h.orig	Mon Sep 20 00:59:48 2004
 +++ sys/dev/usb/usbhid.h	Mon Sep 20 02:14:40 2004
 @@ -123,6 +123,7 @@
  #define HUG_VBRY		0x0044
  #define HUG_VBRZ		0x0045
  #define HUG_VNO			0x0046
 +#define HUG_TWHEEL		0x0048 // M$ Wireless Intellimouse Wheel
  #define HUG_SYSTEM_CONTROL	0x0080
  #define HUG_SYSTEM_POWER_DOWN	0x0081
  #define HUG_SYSTEM_SLEEP	0x0082
 --- sys/sys/mouse.h.orig	Fri Jul 30 01:59:40 2004
 +++ sys/sys/mouse.h	Tue Sep 21 00:42:37 2004
 @@ -58,6 +58,7 @@
      int     dx;			/* x movement */
      int     dy;			/* y movement */
      int     dz;			/* z movement */
 +    int     dt;			/* left right tilt axis */
  } mousestatus_t;
 
  /* button */
 --- sys/dev/usb/ums.c.orig	Mon Aug 16 00:39:18 2004
 +++ sys/dev/usb/ums.c	Tue Sep 21 00:47:52 2004
 @@ -104,7 +104,7 @@
  	u_char *sc_ibuf;
  	u_int8_t sc_iid;
  	int sc_isize;
 -	struct hid_location sc_loc_x, sc_loc_y, sc_loc_z;
 +	struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_t;
  	struct hid_location *sc_loc_btn;
 
  	usb_callout_t callout_handle;	/* for spurious button ups */
 @@ -114,6 +114,7 @@
 
  	int flags;		/* device configuration */
  #define UMS_Z		0x01	/* z direction available */
 +#define UMS_T		0x02	/* aa direction available (tilt) */
  #define UMS_SPUR_BUT_UP	0x02	/* spurious button up events */
  	int nbuttons;
  #define MAX_BUTTONS	7	/* chosen because sc_buttons is u_char */
 @@ -140,7 +141,7 @@
  			  usbd_private_handle priv, usbd_status status);
 
  Static void ums_add_to_queue(struct ums_softc *sc,
 -				int dx, int dy, int dz, int buttons);
 +				int dx, int dy, int dz, int dt, int buttons);
  Static void ums_add_to_queue_timeout(void *priv);
 
  Static int  ums_enable(void *);
 @@ -269,6 +270,8 @@
  	if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
  		       hid_input, &sc->sc_loc_z, &flags) ||
  	    hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
 +		       hid_input, &sc->sc_loc_z, &flags) ||
 +	    hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
  		       hid_input, &sc->sc_loc_z, &flags)) {
  		if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
  			sc->sc_loc_z.size = 0;	/* Bad Z coord, ignore it */
 @@ -277,6 +280,17 @@
  		}
  	}
  
 +	/* The Microsoft Wireless Intellimouse 2.0 reports it's wheel
 +	 * using 0x0048 (i've called it HUG_TWHEEL) and seems to expect
 +	 * you 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 */
 +	if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
 +			hid_input, &sc->sc_loc_t, &flags)) {
 +			sc->sc_loc_t.pos = sc->sc_loc_t.pos + 8;
 +			sc->flags |= UMS_T;
 +	}
 +
  	/* figure out the number of buttons */
  	for (i = 1; i <= MAX_BUTTONS; i++)
  		if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
 @@ -290,8 +304,9 @@
  		USB_ATTACH_ERROR_RETURN;
  	}
  
 -	printf("%s: %d buttons%s\n", USBDEVNAME(sc->sc_dev),
 -	       sc->nbuttons, sc->flags & UMS_Z? " and Z dir." : "");
 +	printf("%s: %d buttons%s%s.\n", USBDEVNAME(sc->sc_dev),
 +	       sc->nbuttons, sc->flags & UMS_Z? " and Z dir" : "",
 +	       sc->flags & UMS_T?" and a TILT dir": "");
  
  	for (i = 1; i <= sc->nbuttons; i++)
  		hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
 @@ -408,15 +423,15 @@
  {
  	struct ums_softc *sc = addr;
  	u_char *ibuf;
 -	int dx, dy, dz;
 +	int dx, dy, dz, dt;
  	u_char buttons = 0;
  	int i;
  
  #define UMS_BUT(i) ((i) < 3 ? (((i) + 2) % 3) : (i))
  
  	DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status));
 -	DPRINTFN(5, ("ums_intr: data = %02x %02x %02x\n",
 -		     sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2]));
 +	DPRINTFN(5, ("ums_intr: data = %02x %02x %02x %02x %02x %02x\n",
 +		     sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2], sc->sc_ibuf[3], sc->sc_ibuf[4], sc->sc_ibuf[5]));
  
  	if (status == USBD_CANCELLED)
  		return;
 @@ -425,32 +440,44 @@
  		DPRINTF(("ums_intr: status=%d\n", status));
  		if (status == USBD_STALLED)
  		    usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
 -		return;
 +		if(status != USBD_IOERROR)
 +			return;
  	}
  
  	ibuf = sc->sc_ibuf;
  	if (sc->sc_iid) {
 -		if (*ibuf++ != sc->sc_iid)
 -			return;
 +		ibuf++;
  	}
  
 +	/* 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. */
 +	if ((sc->sc_ibuf != ibuf) && (sc->sc_ibuf[0] == 0x02))
 +		return;
 +
  	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);
 +	dt = -hid_get_data(ibuf, &sc->sc_loc_t);
  	for (i = 0; i < sc->nbuttons; i++)
  		if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
  			buttons |= (1 << UMS_BUT(i));
  
 -	if (dx || dy || dz || (sc->flags & UMS_Z)
 +	if (dx || dy || dz || dt || (sc->flags & UMS_Z)
  	    || buttons != sc->status.button) {
 -		DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d buttons:0x%x\n",
 -			dx, dy, dz, buttons));
 +		DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d aa:%d buttons:0x%x\n",
 +			dx, dy, dz, dt, buttons));
  
  		sc->status.button = buttons;
  		sc->status.dx += dx;
  		sc->status.dy += dy;
  		sc->status.dz += dz;
 -
 +		sc->status.dt += dt;
 +		
  		/* Discard data in case of full buffer */
  		if (sc->qcount == sizeof(sc->qbuf)) {
  			DPRINTF(("Buffer full, discarded packet"));
 @@ -466,13 +493,13 @@
  		 * In any other case we delete the timeout event.
  		 */
  		if (sc->flags & UMS_SPUR_BUT_UP &&
 -		    dx == 0 && dy == 0 && dz == 0 && buttons == 0) {
 +		    dx == 0 && dy == 0 && dz == 0 && dt == 0 && buttons == 0) {
  			usb_callout(sc->callout_handle, MS_TO_TICKS(50 /*msecs*/),
  				    ums_add_to_queue_timeout, (void *) sc);
  		} else {
  			usb_uncallout(sc->callout_handle,
  				      ums_add_to_queue_timeout, (void *) sc);
 -			ums_add_to_queue(sc, dx, dy, dz, buttons);
 +			ums_add_to_queue(sc, dx, dy, dz, dt, buttons);
  		}
  	}
  }
 @@ -484,12 +511,12 @@
  	int s;
  
  	s = splusb();
 -	ums_add_to_queue(sc, 0, 0, 0, 0);
 +	ums_add_to_queue(sc, 0, 0, 0, 0, 0);
  	splx(s);
  }
  
  Static void
 -ums_add_to_queue(struct ums_softc *sc, int dx, int dy, int dz, int buttons)
 +ums_add_to_queue(struct ums_softc *sc, int dx, int dy, int dz, int dt, int buttons)
  {
  	/* Discard data in case of full buffer */
  	if (sc->qhead+sc->mode.packetsize > sizeof(sc->qbuf)) {
 @@ -503,6 +530,8 @@
  	if (dy < -256)		dy = -256;
  	if (dz >  126)		dz =  126;
  	if (dz < -128)		dz = -128;
 +	if (dt >  126)		dt =  126;
 +	if (dt < -128)		dt = -128;
  
  	sc->qbuf[sc->qhead] = sc->mode.syncmask[1];
  	sc->qbuf[sc->qhead] |= ~buttons & MOUSE_MSC_BUTTONS;
 @@ -550,7 +579,7 @@
  	sc->qhead = sc->qtail = 0;
  	sc->status.flags = 0;
  	sc->status.button = sc->status.obutton = 0;
 -	sc->status.dx = sc->status.dy = sc->status.dz = 0;
 +	sc->status.dx = sc->status.dy = sc->status.dz = sc->status.dt = 0;
  
  	callout_handle_init((struct callout_handle *)&sc->callout_handle);
  
 @@ -807,10 +836,10 @@
  		*status = sc->status;
  		sc->status.obutton = sc->status.button;
  		sc->status.button = 0;
 -		sc->status.dx = sc->status.dy = sc->status.dz = 0;
 +		sc->status.dx = sc->status.dy = sc->status.dz = sc->status.dt = 0;
  		splx(s);
  
 -		if (status->dx || status->dy || status->dz)
 +		if (status->dx || status->dy || status->dz || status->dt)
  			status->flags |= MOUSE_POSCHANGED;
  		if (status->button != status->obutton)
  			status->flags |= MOUSE_BUTTONSCHANGED;
 --Boundary-00=_Ef+jBJHUYWZ6fJL--

From: Ian Dowse <iedowse@maths.tcd.ie>
To: Anish Mistry <mistry.7@osu.edu>,
	Matt Wright <matt@consultmatt.co.uk>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse (possibly others) 
Date: Tue, 09 Nov 2004 01:41:26 +0000

 In message <200411082140.iA8LeXQs087630@freefall.freebsd.org>, Anish Mistry wri
 > Excellent work Matt.  I've just tested it with my wired Intellimouse, and 
 > it works great on my laptop (6-CURRENT).  It didn't work on my desktop, 
 > but I think the USB controller is flaky, ums just gets 1 interrupt then 
 > gets stuck, but my other USB mice still worked fine, so no regressions.  
 ...
 > Could a committer (Ian?) take a look at this a possibly merge it?
 
 Sure, but one question about the patch: is it necessary to add the
 new field to the mousestatus structure, i.e. is there any userland
 code that needs the new `dt' field from the MOUSE_GETSTATUS ioctl?
 If not, it would be better to avoid having to recompile any existing
 applications that may use the MOUSE_GETSTATUS ioctl. Adding the new
 field would also require modifying all the other mouse drivers
 (sysmouse, mse, psm, pc98/mse) to initialise `dt'.
 
 Ian

From: Matt Wright <matt@consultmatt.co.uk>
To: Ian Dowse <iedowse@maths.tcd.ie>
Cc: freebsd-gnats-submit@freebsd.org, Anish Mistry <mistry.7@osu.edu>
Subject: Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse (possibly others) 
Date: Tue, 9 Nov 2004 01:43:32 +0000

 Hi,
 
 Not as far as I'm aware. I carried it over from Anish's patch. If he 
 hasn't got a reason for keeping it I don't either.
 
 Matt
 
 On 9 Nov 2004, at 01:41, Ian Dowse wrote:
 
 > In message <200411082140.iA8LeXQs087630@freefall.freebsd.org>, Anish 
 > Mistry wri
 >> Excellent work Matt.  I've just tested it with my wired Intellimouse, 
 >> and
 >> it works great on my laptop (6-CURRENT).  It didn't work on my 
 >> desktop,
 >> but I think the USB controller is flaky, ums just gets 1 interrupt 
 >> then
 >> gets stuck, but my other USB mice still worked fine, so no 
 >> regressions.
 > ...
 >> Could a committer (Ian?) take a look at this a possibly merge it?
 >
 > Sure, but one question about the patch: is it necessary to add the
 > new field to the mousestatus structure, i.e. is there any userland
 > code that needs the new `dt' field from the MOUSE_GETSTATUS ioctl?
 > If not, it would be better to avoid having to recompile any existing
 > applications that may use the MOUSE_GETSTATUS ioctl. Adding the new
 > field would also require modifying all the other mouse drivers
 > (sysmouse, mse, psm, pc98/mse) to initialise `dt'.
 >
 > Ian
 >
 

From: Anish Mistry <mistry.7@osu.edu>
To: Matt Wright <matt@consultmatt.co.uk>
Cc: Ian Dowse <iedowse@maths.tcd.ie>,
	freebsd-gnats-submit@freebsd.org
Subject: Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse (possibly others)
Date: Mon, 8 Nov 2004 20:50:41 -0500

 --nextPart8529536.YA8LHhDDUc
 Content-Type: text/plain;
   charset="iso-8859-1"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: inline
 
 On Monday 08 November 2004 08:43 pm, Matt Wright wrote:
 > Hi,
 >
 > Not as far as I'm aware. I carried it over from Anish's patch. If he
 > hasn't got a reason for keeping it I don't either.
 >
 No need to keep it.
 
 =2D-=20
 Anish Mistry
 
 --nextPart8529536.YA8LHhDDUc
 Content-Type: application/pgp-signature
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.2.6 (FreeBSD)
 
 iD8DBQBBkCJ6xqA5ziudZT0RAsGuAJ9xQxKf4lmm8mkA+6wrVZFgxokGbQCgs2jn
 a/eHUzMW56cPN0pIaha1xzU=
 =RBB6
 -----END PGP SIGNATURE-----
 
 --nextPart8529536.YA8LHhDDUc--

From: Anish Mistry <mistry.7@osu.edu>
To: freebsd-gnats-submit@freebsd.org
Cc:  
Subject: Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse (possibly others)
Date: Tue, 9 Nov 2004 23:18:01 -0500

 --nextPart1195876.kBiaPRXapZ
 Content-Type: text/plain;
   charset="iso-8859-1"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: inline
 
 Related PR:
 kern/62088: [usb] Logitech Cordless/Optical Mouse not working
 
 =2D-=20
 Anish Mistry
 
 --nextPart1195876.kBiaPRXapZ
 Content-Type: application/pgp-signature
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.2.6 (FreeBSD)
 
 iD8DBQBBkZaCxqA5ziudZT0RAtgnAKDURm9+6TM83oGzEfiXcFtC0azDFQCgz4vW
 gzucE2rzinr5bXM2uX4GQQk=
 =176W
 -----END PGP SIGNATURE-----
 
 --nextPart1195876.kBiaPRXapZ--

From: Mark Ovens <marko@freebsd.org>
To: freebsd-gnats-submit@freebsd.org, amistry@am-productions.biz
Cc:  
Subject: Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse (possibly others)
Date: Sun, 28 Nov 2004 20:42:03 +0000

 I've just tried the latest patch (with the 'dt' field removed from the 
 mousestatus structure) and it works just fine :-)
 
 FreeBSD redshift 5.3-STABLE FreeBSD 5.3-STABLE #1: Sun Nov 28 20:17:32 GMT 
 2004     mark@redshift:/usr/obj/usr/src/sys/REDSHIFT  i386
 
 I haven't tested the tilt wheel because I don't use it and am not sure how to 
 set it up.
 
 Kudos to Anish and Matt for fixing this.
 
 Mark
State-Changed-From-To: open->closed 
State-Changed-By: julian 
State-Changed-When: Sun Dec 12 05:35:19 GMT 2004 
State-Changed-Why:  
Patches applied 

http://www.freebsd.org/cgi/query-pr.cgi?pr=70607 
>Unformatted:
