Subject: Automatically configuring mouse repeating
To: None <tech-kern@netbsd.org>
From: Julio M. Merino Vidal <jmmv84@gmail.com>
List: tech-kern
Date: 02/07/2006 11:30:19
------=_Part_196_23636548.1139308219736
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hi,

Following the addition of 'mouse button autorepeating', it'd be nice if the
driver detected affected mice and set up them so that they worked as
expected "out of the box" (i.e., as advertized by the manufacturer).

The attached patch does this (for my specific mouse model) by defining
a quirks table in ums(4) and setting the repeat rate if it finds the mouse.
I don't think this is possible to do at the wsmouse(4) level because it
cannot identify mice, can it?  I mean, each bus has its own way to
describe devices (e.g., vendor/product in usb)... unless we used a string
with the mouse's full name, in which case wsmouse(4) could do it.  Mmm.

Note that the same automatic setup can be applied to "emulate 3rd
button", when implemented.

Is this correct to do?

Thanks,

--
Julio M. Merino Vidal <jmmv84@gmail.com>
The Julipedia - http://julipedia.blogspot.com/

------=_Part_196_23636548.1139308219736
Content-Type: application/octet-stream; name=patch.diff
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="patch.diff"

Index: usb/ums.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ums.c,v
retrieving revision 1.64
diff -u -p -r1.64 ums.c
--- usb/ums.c	11 Dec 2005 12:24:01 -0000	1.64
+++ usb/ums.c	7 Feb 2006 10:21:47 -0000
@@ -92,6 +92,7 @@ int	umsdebug = 0;
 
 struct ums_softc {
 	struct uhidev sc_hdev;
+	struct usb_devno sc_devno;
 
 	struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_w;
 	struct hid_location sc_loc_btn[MAX_BUTTONS];
@@ -115,6 +116,7 @@ struct ums_softc {
 #define MOUSE_FLAGS (HIO_RELATIVE)
 
 Static void ums_intr(struct uhidev *addr, void *ibuf, u_int len);
+Static void ums_setup(struct ums_softc *);
 
 Static int	ums_enable(void *);
 Static void	ums_disable(void *);
@@ -128,6 +130,16 @@ const struct wsmouse_accessops ums_acces
 
 USB_DECLARE_DRIVER(ums);
 
+struct ums_quirk {
+	struct usb_devno	uq_dev;
+	struct wsmouse_repeat	uq_repeat;
+} ums_quirks[] = {
+	{
+		{ USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_MARBLEMOUSE },
+		{ 0x0018, 200, 25, 50 },
+	},
+};
+
 int
 ums_match(struct device *parent, struct cfdata *match, void *aux)
 {
@@ -159,6 +171,9 @@ ums_attach(struct device *parent, struct
 	sc->sc_hdev.sc_parent = uha->parent;
 	sc->sc_hdev.sc_report_id = uha->reportid;
 
+	sc->sc_devno.ud_vendor = uha->uaa->vendor;
+	sc->sc_devno.ud_product = uha->uaa->product;
+
 	quirks = usbd_get_quirks(uha->parent->sc_udev)->uq_flags;
 	if (quirks & UQ_MS_REVZ)
 		sc->flags |= UMS_REVZ;
@@ -266,10 +281,23 @@ ums_attach(struct device *parent, struct
 	a.accesscookie = sc;
 
 	sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
+	ums_setup(sc);
 
 	USB_ATTACH_SUCCESS_RETURN;
 }
 
+Static void
+ums_setup(struct ums_softc *sc)
+{
+	const struct ums_quirk *uq;
+
+	uq = (const struct ums_quirk *)usb_lookup(ums_quirks,
+	    sc->sc_devno.ud_vendor, sc->sc_devno.ud_product);
+	if (uq != NULL)
+		wsmouse_set_repeat((struct wsmouse_softc *)sc->sc_wsmousedev,
+		    &uq->uq_repeat);
+}
+
 int
 ums_activate(device_ptr_t self, enum devact act)
 {
Index: wscons/wsmouse.c
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsmouse.c,v
retrieving revision 1.40
diff -u -p -r1.40 wsmouse.c
--- wscons/wsmouse.c	7 Feb 2006 09:13:02 -0000	1.40
+++ wscons/wsmouse.c	7 Feb 2006 10:21:47 -0000
@@ -729,21 +729,8 @@ wsmouse_do_ioctl(struct wsmouse_softc *s
 		if ((flag & FWRITE) == 0)
 			return EACCES;
 
-		/* Validate input data. */
-		wr = (struct wsmouse_repeat *)data;
-		if (wr->wr_delay_first != 0 &&
-		    (wr->wr_delay_first < wr->wr_delay_decrement ||
-		     wr->wr_delay_first < wr->wr_delay_minimum ||
-		     wr->wr_delay_first < wr->wr_delay_minimum +
-		     wr->wr_delay_decrement))
-			return EINVAL;
-
-		/* Stop current repeating and set new data. */
-		sc->sc_repeat_button = -1;
-		callout_stop(&sc->sc_repeat_callout);
-		memcpy(&sc->sc_repeat, wr, sizeof(sc->sc_repeat));
-
-		return 0;
+		return wsmouse_set_repeat(sc,
+		    (const struct wsmouse_repeat *)data);
 	}
 
 	/*
@@ -813,3 +800,23 @@ wsmouse_add_mux(int unit, struct wsmux_s
 	return (wsmux_attach_sc(muxsc, &sc->sc_base));
 }
 #endif /* NWSMUX > 0 */
+
+int
+wsmouse_set_repeat(struct wsmouse_softc *sc, const struct wsmouse_repeat *wr)
+{
+
+	/* Validate input data. */
+	if (wr->wr_delay_first != 0 &&
+	    (wr->wr_delay_first < wr->wr_delay_decrement ||
+	     wr->wr_delay_first < wr->wr_delay_minimum ||
+	     wr->wr_delay_first < wr->wr_delay_minimum +
+	     wr->wr_delay_decrement))
+		return EINVAL;
+
+	/* Stop current repeating and set new data. */
+	sc->sc_repeat_button = -1;
+	callout_stop(&sc->sc_repeat_callout);
+	memcpy(&sc->sc_repeat, wr, sizeof(sc->sc_repeat));
+
+	return 0;
+}
Index: wscons/wsmousevar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/wscons/wsmousevar.h,v
retrieving revision 1.7
diff -u -p -r1.7 wsmousevar.h
--- wscons/wsmousevar.h	11 Dec 2005 12:24:12 -0000	1.7
+++ wscons/wsmousevar.h	7 Feb 2006 10:21:47 -0000
@@ -47,6 +47,10 @@ struct wsmouse_accessops {
 	void	(*disable)(void *);
 };
 
+struct wsmouse_softc;
+int	wsmouse_set_repeat(struct wsmouse_softc *,
+	    const struct wsmouse_repeat *);
+
 /*
  * Attachment information provided by wsmousedev devices when attaching
  * wsmouse units.




------=_Part_196_23636548.1139308219736--