Fix kern/41737 -- add quirks to make MS Wireless Laser Mouse 6000 work.
This commit is contained in:
parent
a8036503d8
commit
4e042dc0d8
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: uhidev.c,v 1.43 2009/09/23 19:07:19 plunky Exp $ */
|
||||
/* $NetBSD: uhidev.c,v 1.44 2009/11/06 04:42:27 rafal Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.43 2009/09/23 19:07:19 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.44 2009/11/06 04:42:27 rafal Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -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;
|
||||
@ -140,6 +140,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);
|
||||
@ -161,6 +162,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) {
|
||||
@ -265,8 +267,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));
|
||||
@ -275,12 +279,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;
|
||||
@ -478,7 +478,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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ums.c,v 1.74 2009/03/09 15:59:33 uebayasi Exp $ */
|
||||
/* $NetBSD: ums.c,v 1.75 2009/11/06 04:42:27 rafal Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.74 2009/03/09 15:59:33 uebayasi Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.75 2009/11/06 04:42:27 rafal Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -94,6 +94,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;
|
||||
|
||||
@ -151,7 +152,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");
|
||||
@ -197,10 +199,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),
|
||||
@ -210,33 +218,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;
|
||||
}
|
||||
/*
|
||||
* 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)) {
|
||||
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 */
|
||||
} else {
|
||||
sc->flags |= UMS_Z;
|
||||
/* Put Z on the W coordinate */
|
||||
zloc = &sc->sc_loc_w;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
zloc->size = 0; /* Bad Z coord, ignore it */
|
||||
} else {
|
||||
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++)
|
||||
@ -245,9 +279,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),
|
||||
@ -263,6 +299,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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user