NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/41737: ums(4) / uhidev(4) doesn't support MS Wireless Laser Mouse 6000 v2.0
>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: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jul 16 02:30:00 +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;
Home |
Main Index |
Thread Index |
Old Index