NetBSD Problem Report #41737

From rafal@pobox.com  Thu Jul 16 02:28:05 2009
Return-Path: <rafal@pobox.com>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by www.NetBSD.org (Postfix) with ESMTP id B5C8063B883
	for <gnats-bugs@gnats.NetBSD.org>; Thu, 16 Jul 2009 02:28:05 +0000 (UTC)
Message-Id: <20090716022725.35FE943A6@blackhole-sun.waterside.net>
Date: Wed, 15 Jul 2009 22:27:25 -0400 (EDT)
From: rafal@netbsd.org
Reply-To: rafal@netbsd.org
To: gnats-bugs@gnats.NetBSD.org
Subject: ums(4) / uhidev(4) doesn't support MS Wireless Laser Mouse 6000 v2.0
X-Send-Pr-Version: 3.95

>Number:         41737
>Category:       kern
>Synopsis:       ums(4) / uhidev(4) doesn't support MS Wireless Laser Mouse 6000
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 16 02:30:00 +0000 2009
>Closed-Date:    Mon Nov 30 18:05:43 +0000 2009
>Last-Modified:  Mon Nov 30 18:05:43 +0000 2009
>Originator:     Rafal Boni
>Release:        NetBSD 5.0_STABLE
>Organization:
Wazzat?
>Environment:
System: NetBSD puck 5.0_STABLE NetBSD 5.0_STABLE (GENERIC_DRM) #21: Wed Jul 15 17:21:41 EDT 2009  rafal@puck:/extra/amd64/obj-5/sys/arch/amd64/compile/GENERIC_DRM amd64
Architecture: x86_64
Machine: amd64
>Description:
	Plugging a Microsoft Wireless Laser Mouse 6000 (v2.0) into a NetBSD
	5.0 (and I suspect -current as well, though I've not checked there),
	attaches a ums(4) device, and a wsmouse(4) instance to that, but the
	mouse doesn't generate any events, either for motion, buttons, or
	the wheel.

>How-To-Repeat:
	Plug the above mentioned device into a NetBSD 5.0 system.
	# od -c < /dev/wsmouseN

	Hit buttons, move the mouse, scroll the wheel, etc. and notice
	that no data comes out of the wsmouse device.
>Fix:

	Apply the following patch, rebuild kernel, have a working mouse.
	Thanks to plunky@ for feedback and pointer to btms(4), which I
	borrowed some of the wheel / Z axis / pan handling from.

	I don't have a -current system available to try this on right now,
	but will try to do that RSN and check it in if it works there and
	I haven't gotten other feedback...

diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
index aa0b005..4f8e7ed 100644
--- a/sys/dev/usb/uhidev.c
+++ b/sys/dev/usb/uhidev.c
@@ -105,7 +105,7 @@ USB_ATTACH(uhidev)
 	struct uhidev_attach_arg uha;
 	device_t dev;
 	struct uhidev *csc;
-	int size, nrepid, repid, repsz;
+	int maxinpktsize, size, nrepid, repid, repsz;
 	int *repsizes;
 	int i;
 	void *desc;
@@ -137,6 +137,7 @@ USB_ATTACH(uhidev)
 		(void)usbd_set_protocol(iface, 1);
 #endif

+	maxinpktsize = 0;
 	sc->sc_iep_addr = sc->sc_oep_addr = -1;
 	for (i = 0; i < id->bNumEndpoints; i++) {
 		ed = usbd_interface2endpoint_descriptor(iface, i);
@@ -158,6 +159,7 @@ USB_ATTACH(uhidev)

 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
 		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
+			maxinpktsize = UGETW(ed->wMaxPacketSize);
 			sc->sc_iep_addr = ed->bEndpointAddress;
 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
 		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
@@ -262,8 +264,10 @@ nomem:
 		aprint_error_dev(self, "no memory\n");
 		USB_ATTACH_ERROR_RETURN;
 	}
+
+	/* Just request max packet size for the interrupt pipe */
+	sc->sc_isize = maxinpktsize;
 	sc->sc_nrepid = nrepid;
-	sc->sc_isize = 0;

 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
 			   USBDEV(sc->sc_dev));
@@ -272,12 +276,8 @@ nomem:
 		repsz = hid_report_size(desc, size, hid_input, repid);
 		DPRINTF(("uhidev_match: repid=%d, repsz=%d\n", repid, repsz));
 		repsizes[repid] = repsz;
-		if (repsz > 0) {
-			if (repsz > sc->sc_isize)
-				sc->sc_isize = repsz;
-		}
 	}
-	sc->sc_isize += nrepid != 1;	/* space for report ID */
+
 	DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize));

 	uha.parent = sc;
@@ -475,7 +475,7 @@ uhidev_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
 		    rep, scd, scd ? scd->sc_state : 0));
 	if (!(scd->sc_state & UHIDEV_OPEN))
 		return;
-	if (scd->sc_in_rep_size != cc) {
+	if (scd->sc_in_rep_size > cc) {
 		printf("%s: bad input length %d != %d\n",
 		       USBDEVNAME(sc->sc_dev), scd->sc_in_rep_size, cc);
 		return;
diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c
index 88baea2..e1f7144 100644
--- a/sys/dev/usb/ums.c
+++ b/sys/dev/usb/ums.c
@@ -95,6 +95,7 @@ struct ums_softc {
 #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/tilt available */

 	int nbuttons;

@@ -152,7 +153,8 @@ ums_attach(device_t parent, device_t self, void *aux)
 	int size;
 	void *desc;
 	u_int32_t flags, quirks;
-	int i, wheel;
+	int i, hl;
+	struct hid_location *zloc;
 	struct hid_location loc_btn;

 	aprint_naive("\n");
@@ -198,10 +200,16 @@ ums_attach(device_t parent, device_t self, void *aux)
 	}

 	/* Try the wheel first as the Z activator since it's tradition. */
-	wheel = hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
-						  HUG_WHEEL),
-			   uha->reportid, hid_input, &sc->sc_loc_z, &flags);
-	if (wheel) {
+	hl = hid_locate(desc, 
+			size, 
+			HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), 
+			uha->reportid, 
+			hid_input, 
+			&sc->sc_loc_z, 
+			&flags);
+
+	zloc = &sc->sc_loc_z;
+	if (hl) {
 		if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
 			aprint_verbose("\n%s: Wheel report 0x%04x not "
 			    "supported\n", USBDEVNAME(sc->sc_hdev.sc_dev),
@@ -211,33 +219,59 @@ ums_attach(device_t parent, device_t self, void *aux)
 			sc->flags |= UMS_Z;
 			/* Wheels need the Z axis reversed. */
 			sc->flags ^= UMS_REVZ;
+			/* Put Z on the W coordinate */
+			zloc = &sc->sc_loc_w;
 		}
-		/*
-		 * We might have both a wheel and Z direction, if so put
-		 * put the Z on the W coordinate.
-		 */
-		if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
-						      HUG_Z),
-			uha->reportid, hid_input, &sc->sc_loc_w, &flags)) {
-			if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
-				aprint_verbose("\n%s: Z report 0x%04x not "
-				    "supported\n",
-				       USBDEVNAME(sc->sc_hdev.sc_dev), flags);
-				sc->sc_loc_w.size = 0;	/* Bad Z, ignore */
-			}
-		}
-	 } else if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
-						      HUG_Z),
-		      uha->reportid, hid_input, &sc->sc_loc_z, &flags)) {
+	}
+
+	hl = hid_locate(desc, 
+			size, 
+			HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
+			uha->reportid,
+			hid_input,
+			zloc,
+			&flags);
+
+	/*
+	 * The horizontal component of the scrollball can also be given by
+	 * Application Control Pan in the Consumer page, so if we didnt see
+	 * any Z then check that.
+	 */
+	if (!hl) {
+		hl = hid_locate(desc, 
+				size, 
+				HID_USAGE2(HUP_CONSUMER, HUC_AC_PAN), 
+				uha->reportid,
+				hid_input,
+				zloc,
+				&flags);
+	}
+
+	if (hl) {
 		if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
 			aprint_verbose("\n%s: Z report 0x%04x not supported\n",
 			       USBDEVNAME(sc->sc_hdev.sc_dev), flags);
-			sc->sc_loc_z.size = 0;	/* Bad Z coord, ignore it */
+			zloc->size = 0;	/* Bad Z coord, ignore it */
 		} else {
-			sc->flags |= UMS_Z;
+			if (sc->flags & UMS_Z)
+				sc->flags |= UMS_W;
+			else
+				sc->flags |= UMS_Z;
 		}
 	}

+	/*
+	 * The Microsoft Wireless Laser Mouse 6000 v2.0 reports a bad
+	 * position for the wheel and wheel tilt controls -- should be
+	 * in bytes 3 & 4 of the report.  Fix this if necessary.
+	 */
+	if (uha->uaa->vendor == USB_VENDOR_MICROSOFT &&
+	    uha->uaa->product == USB_PRODUCT_MICROSOFT_24GHZ_XCVR) {
+		if ((sc->flags & UMS_Z) && sc->sc_loc_z.pos == 0)
+			sc->sc_loc_z.pos = 24;
+		if ((sc->flags & UMS_W) && sc->sc_loc_w.pos == 0)
+			sc->sc_loc_w.pos = sc->sc_loc_z.pos + 8;
+	}

 	/* figure out the number of buttons */
 	for (i = 1; i <= MAX_BUTTONS; i++)
@@ -246,9 +280,11 @@ ums_attach(device_t parent, device_t self, void *aux)
 			break;
 	sc->nbuttons = i - 1;

-	aprint_normal(": %d button%s%s\n",
+	aprint_normal(": %d button%s%s%s%s\n",
 	    sc->nbuttons, sc->nbuttons == 1 ? "" : "s",
-	    sc->flags & UMS_Z ? " and Z dir." : "");
+	    sc->flags & UMS_W ? ", W" : "",
+	    sc->flags & UMS_Z ? " and Z dir" : "",
+	    sc->flags & UMS_W ? "s" : "");

 	for (i = 1; i <= sc->nbuttons; i++)
 		hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
@@ -264,6 +300,9 @@ ums_attach(device_t parent, device_t self, void *aux)
 	if (sc->flags & UMS_Z)
 		DPRINTF(("ums_attach: Z\t%d/%d\n",
 			 sc->sc_loc_z.pos, sc->sc_loc_z.size));
+	if (sc->flags & UMS_W)
+		DPRINTF(("ums_attach: W\t%d/%d\n",
+			 sc->sc_loc_w.pos, sc->sc_loc_w.size));
 	for (i = 1; i <= sc->nbuttons; i++) {
 		DPRINTF(("ums_attach: B%d\t%d/%d\n",
 			 i, sc->sc_loc_btn[i-1].pos,sc->sc_loc_btn[i-1].size));
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index e2b00bf..2c13c33 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1542,6 +1542,7 @@ product MICROSOFT XBOX_DVD_PLAYBACK	0x0284	Xbox DVD Movie Playback Kit
 product MICROSOFT XBOX_CONTROLLER_S10	0x0285	Xbox Controller S (1.0)
 product MICROSOFT XBOX_CONTROLLER_HUB	0x0288	Xbox Controller Hub
 product MICROSOFT XBOX_CONTROLLER_S12	0x0289	Xbox Controller S (1.2)
+product MICROSOFT 24GHZ_XCVR		0x071f  2.4GHz Transceiver V2.0

 /* Microtech products */
 product MICROTECH SCSIDB25	0x0004	USB-SCSI-DB25
diff --git a/sys/dev/usb/usbdevs.h b/sys/dev/usb/usbdevs.h
index 53372ec..6da5460 100644
--- a/sys/dev/usb/usbdevs.h
+++ b/sys/dev/usb/usbdevs.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdevs.h,v 1.515.4.1 2008/11/22 05:12:18 snj Exp $	*/
+/*	$NetBSD$	*/

 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -1549,6 +1549,7 @@
 #define	USB_PRODUCT_MICROSOFT_XBOX_CONTROLLER_S10	0x0285		/* Xbox Controller S (1.0) */
 #define	USB_PRODUCT_MICROSOFT_XBOX_CONTROLLER_HUB	0x0288		/* Xbox Controller Hub */
 #define	USB_PRODUCT_MICROSOFT_XBOX_CONTROLLER_S12	0x0289		/* Xbox Controller S (1.2) */
+#define	USB_PRODUCT_MICROSOFT_24GHZ_XCVR	0x071f		/* 2.4GHz Transceiver V2.0 */

 /* Microtech products */
 #define	USB_PRODUCT_MICROTECH_SCSIDB25	0x0004		/* USB-SCSI-DB25 */
diff --git a/sys/dev/usb/usbdevs_data.h b/sys/dev/usb/usbdevs_data.h
index 6759cdf..bb2b02b 100644
--- a/sys/dev/usb/usbdevs_data.h
+++ b/sys/dev/usb/usbdevs_data.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdevs_data.h,v 1.516.4.1 2008/11/22 05:12:18 snj Exp $	*/
+/*	$NetBSD$	*/

 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -4579,6 +4579,10 @@ const struct usb_product usb_products[] = {
 	    "Xbox Controller S (1.2)",
 	},
 	{
+	    USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_24GHZ_XCVR,
+	    "2.4GHz Transceiver V2.0",
+	},
+	{
 	    USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25,
 	    "USB-SCSI-DB25",
 	},
@@ -6823,4 +6827,4 @@ const struct usb_product usb_products[] = {
 	    "Prestige",
 	},
 };
-const int usb_nproducts = 1241;
+const int usb_nproducts = 1242;

>Release-Note:

>Audit-Trail:

State-Changed-From-To: open->pending-pullups
State-Changed-By: rafal@NetBSD.org
State-Changed-When: Fri, 06 Nov 2009 05:22:20 +0000
State-Changed-Why:
Fixed in -current; I'd like to get it pulled up to netbsd-5


State-Changed-From-To: pending-pullups->closed
State-Changed-By: rafal@NetBSD.org
State-Changed-When: Mon, 30 Nov 2009 18:05:43 +0000
State-Changed-Why:
pulled up to netbsd-5


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.