Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Nov 2004 21:40:33 GMT
From:      Anish Mistry <mistry.7@osu.edu>
To:        freebsd-usb@FreeBSD.org
Subject:   Re: kern/70607: [patch] Add Support for USB Microsoft Intellimouse (possibly others)
Message-ID:  <200411082140.iA8LeXQs087630@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/70607; it has been noted by GNATS.

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--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411082140.iA8LeXQs087630>