kern/70607: Add Support for USB Microsoft Intellimouse (possibly others)

Anish Mistry amistry at am-productions.biz
Tue Aug 17 21:30:28 PDT 2004


>Number:         70607
>Category:       kern
>Synopsis:       Add Support for USB Microsoft Intellimouse (possibly others)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 18 04:30:27 GMT 2004
>Closed-Date:
>Last-Modified:
>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 at 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:
>Unformatted:


More information about the freebsd-bugs mailing list