svn commit: r195959 - head/sys/dev/usb/input

Alfred Perlstein alfred at FreeBSD.org
Thu Jul 30 00:13:10 UTC 2009


Author: alfred
Date: Thu Jul 30 00:13:09 2009
New Revision: 195959
URL: http://svn.freebsd.org/changeset/base/195959

Log:
          USB input
           - add support for setting the UMS polling rate through -F option
             passed to moused.
           - requested by Alexander Best
           - P4 ID: 166075
  
  PR:             usb/125264
  
  Submitted by:	hps
  Approved by:	re

Modified:
  head/sys/dev/usb/input/ums.c

Modified: head/sys/dev/usb/input/ums.c
==============================================================================
--- head/sys/dev/usb/input/ums.c	Thu Jul 30 00:12:47 2009	(r195958)
+++ head/sys/dev/usb/input/ums.c	Thu Jul 30 00:13:09 2009	(r195959)
@@ -140,6 +140,8 @@ struct ums_softc {
 
 	struct usb_xfer *sc_xfer[UMS_N_TRANSFER];
 
+	int sc_pollrate;
+
 	uint8_t	sc_buttons;
 	uint8_t	sc_iid;
 	uint8_t	sc_temp[64];
@@ -188,6 +190,7 @@ ums_intr_callback(struct usb_xfer *xfer,
 	struct usb_page_cache *pc;
 	uint8_t *buf = sc->sc_temp;
 	int32_t buttons = 0;
+	int32_t buttons_found = 0;
 	int32_t dw = 0;
 	int32_t dx = 0;
 	int32_t dy = 0;
@@ -263,16 +266,24 @@ ums_intr_callback(struct usb_xfer *xfer,
 			dt -= hid_get_data(buf, len, &info->sc_loc_t);
 
 		for (i = 0; i < info->sc_buttons; i++) {
+			uint32_t mask;
+			mask = 1UL << UMS_BUT(i);
+			/* check for correct button ID */
 			if (id != info->sc_iid_btn[i])
 				continue;
-			if (hid_get_data(buf, len, &info->sc_loc_btn[i])) {
-				buttons |= (1 << UMS_BUT(i));
-			}
+			/* check for button pressed */
+			if (hid_get_data(buf, len, &info->sc_loc_btn[i]))
+				buttons |= mask;
+			/* register button mask */
+			buttons_found |= mask;
 		}
 
 		if (++info != &sc->sc_info[UMS_INFO_MAX])
 			goto repeat;
 
+		/* keep old button value(s) for non-detected buttons */
+		buttons |= sc->sc_status.button & ~buttons_found;
+
 		if (dx || dy || dz || dt || dw ||
 		    (buttons != sc->sc_status.button)) {
 
@@ -514,6 +525,8 @@ ums_attach(device_t dev)
 		DPRINTF("error=%s\n", usbd_errstr(err));
 		goto detach;
 	}
+
+	/* Get HID descriptor */
 	err = usbd_req_get_hid_desc(uaa->device, NULL, &d_ptr,
 	    &d_len, M_TEMP, uaa->info.bIfaceIndex);
 
@@ -531,6 +544,9 @@ ums_attach(device_t dev)
 	 * it has two addional buttons and a tilt wheel.
 	 */
 	if (usb_test_quirk(uaa, UQ_MS_BAD_CLASS)) {
+
+		sc->sc_iid = 0;
+
 		info = &sc->sc_info[0];
 		info->sc_flags = (UMS_FLAG_X_AXIS |
 		    UMS_FLAG_Y_AXIS |
@@ -540,11 +556,17 @@ ums_attach(device_t dev)
 		isize = 5;
 		/* 1st byte of descriptor report contains garbage */
 		info->sc_loc_x.pos = 16;
+		info->sc_loc_x.size = 8;
 		info->sc_loc_y.pos = 24;
+		info->sc_loc_y.size = 8;
 		info->sc_loc_z.pos = 32;
+		info->sc_loc_z.size = 8;
 		info->sc_loc_btn[0].pos = 8;
+		info->sc_loc_btn[0].size = 1;
 		info->sc_loc_btn[1].pos = 9;
+		info->sc_loc_btn[1].size = 1;
 		info->sc_loc_btn[2].pos = 10;
+		info->sc_loc_btn[2].size = 1;
 
 		/* Announce device */
 		device_printf(dev, "3 buttons and [XYZ] "
@@ -653,6 +675,23 @@ static void
 ums_start_read(struct usb_fifo *fifo)
 {
 	struct ums_softc *sc = usb_fifo_softc(fifo);
+	int rate;
+
+	/* Check if we should override the default polling interval */
+	rate = sc->sc_pollrate;
+	/* Range check rate */
+	if (rate > 1000)
+		rate = 1000;
+	/* Check for set rate */
+	if ((rate > 0) && (sc->sc_xfer[UMS_INTR_DT] != NULL)) {
+		DPRINTF("Setting pollrate = %d\n", rate);
+		/* Stop current transfer, if any */
+		usbd_transfer_stop(sc->sc_xfer[UMS_INTR_DT]);
+		/* Set new interval */
+		usbd_xfer_set_interval(sc->sc_xfer[UMS_INTR_DT], 1000 / rate);
+		/* Only set pollrate once */
+		sc->sc_pollrate = 0;
+	}
 
 	usbd_transfer_start(sc->sc_xfer[UMS_INTR_DT]);
 }
@@ -791,6 +830,9 @@ ums_ioctl(struct usb_fifo *fifo, u_long 
 			sc->sc_mode.level = mode.level;
 		}
 
+		/* store polling rate */
+		sc->sc_pollrate = mode.rate;
+
 		if (sc->sc_mode.level == 0) {
 			if (sc->sc_buttons > MOUSE_MSC_MAXBUTTON)
 				sc->sc_hw.buttons = MOUSE_MSC_MAXBUTTON;


More information about the svn-src-all mailing list