Author: gonzo
Date: Sat Oct 22 22:55:10 2016
New Revision: 307805
URL: https://svnweb.freebsd.org/changeset/base/307805

Log:
  EVDEV: ums evdev support improvements: locking and event reporting
  
  - Use ums lock as evdev lock
  - Do not cap axes values to sysmouse limits for evdev reports
  - Do not map T-axis events to buttons for evdev reports
  - Use shortcuts for event reporting
  
  Submitted by: Vladimir Kondratiev <w...@cicgroup.ru>
  MFC after:    1 week

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

Modified: head/sys/dev/usb/input/ums.c
==============================================================================
--- head/sys/dev/usb/input/ums.c        Sat Oct 22 22:52:50 2016        
(r307804)
+++ head/sys/dev/usb/input/ums.c        Sat Oct 22 22:55:10 2016        
(r307805)
@@ -173,6 +173,8 @@ static usb_fifo_ioctl_t ums_fifo_ioctl;
 #ifdef EVDEV_SUPPORT
 static evdev_open_t ums_ev_open;
 static evdev_close_t ums_ev_close;
+static void ums_evdev_push(struct ums_softc *, int32_t, int32_t,
+    int32_t, int32_t, int32_t);
 #endif
 
 static void    ums_start_rx(struct ums_softc *);
@@ -205,6 +207,9 @@ ums_put_queue_timeout(void *__sc)
        mtx_assert(&sc->sc_mtx, MA_OWNED);
 
        ums_put_queue(sc, 0, 0, 0, 0, 0);
+#ifdef EVDEV_SUPPORT
+       ums_evdev_push(sc, 0, 0, 0, 0, 0);
+#endif
 }
 
 static void
@@ -216,6 +221,9 @@ ums_intr_callback(struct usb_xfer *xfer,
        uint8_t *buf = sc->sc_temp;
        int32_t buttons = 0;
        int32_t buttons_found = 0;
+#ifdef EVDEV_SUPPORT
+       int32_t buttons_reported = 0;
+#endif
        int32_t dw = 0;
        int32_t dx = 0;
        int32_t dy = 0;
@@ -306,6 +314,9 @@ ums_intr_callback(struct usb_xfer *xfer,
                if (++info != &sc->sc_info[UMS_INFO_MAX])
                        goto repeat;
 
+#ifdef EVDEV_SUPPORT
+               buttons_reported = buttons;
+#endif
                /* keep old button value(s) for non-detected buttons */
                buttons |= sc->sc_status.button & ~buttons_found;
 
@@ -351,6 +362,11 @@ ums_intr_callback(struct usb_xfer *xfer,
                                usb_callout_stop(&sc->sc_callout);
 
                                ums_put_queue(sc, dx, dy, dz, dt, buttons);
+#ifdef EVDEV_SUPPORT
+                               ums_evdev_push(sc, dx, dy, dz, dt,
+                                   buttons_reported);
+#endif
+
                        }
                }
        case USB_ST_SETUP:
@@ -720,7 +736,7 @@ ums_attach(device_t dev)
        for (i = 0; i < info->sc_buttons; i++)
                evdev_support_key(sc->sc_evdev, BTN_MOUSE + i);
 
-       err = evdev_register(sc->sc_evdev);
+       err = evdev_register_mtx(sc->sc_evdev, &sc->sc_mtx);
        if (err)
                goto detach;
 #endif
@@ -891,27 +907,32 @@ ums_put_queue(struct ums_softc *sc, int3
                }
                usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf,
                    sc->sc_mode.packetsize, 1);
-
-#ifdef EVDEV_SUPPORT
-               if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
-                       /* Push evdev event */
-                       evdev_push_event(sc->sc_evdev, EV_REL, REL_X, dx);
-                       evdev_push_event(sc->sc_evdev, EV_REL, REL_Y, -dy);
-                       evdev_push_event(sc->sc_evdev, EV_REL, REL_WHEEL, -dz);
-                       evdev_push_event(sc->sc_evdev, EV_REL, REL_HWHEEL, dt);
-                       evdev_push_mouse_btn(sc->sc_evdev,
-                           (buttons & ~MOUSE_STDBUTTONS) |
-                           (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) |
-                           (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) |
-                           (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0));
-                       evdev_sync(sc->sc_evdev);
-               }
-#endif
        } else {
                DPRINTF("Buffer full, discarded packet\n");
        }
 }
 
+#ifdef EVDEV_SUPPORT
+static void
+ums_evdev_push(struct ums_softc *sc, int32_t dx, int32_t dy,
+    int32_t dz, int32_t dt, int32_t buttons)
+{
+       if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
+               /* Push evdev event */
+               evdev_push_rel(sc->sc_evdev, REL_X, dx);
+               evdev_push_rel(sc->sc_evdev, REL_Y, -dy);
+               evdev_push_rel(sc->sc_evdev, REL_WHEEL, -dz);
+               evdev_push_rel(sc->sc_evdev, REL_HWHEEL, dt);
+               evdev_push_mouse_btn(sc->sc_evdev,
+                   (buttons & ~MOUSE_STDBUTTONS) |
+                   (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) |
+                   (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) |
+                   (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0));
+               evdev_sync(sc->sc_evdev);
+       }
+}
+#endif
+
 static void
 ums_reset_buf(struct ums_softc *sc)
 {
@@ -925,7 +946,7 @@ ums_ev_open(struct evdev_dev *evdev, voi
 {
        struct ums_softc *sc = (struct ums_softc *)ev_softc;
 
-       mtx_lock(&sc->sc_mtx);
+       mtx_assert(&sc->sc_mtx, MA_OWNED);
 
        sc->sc_evflags = UMS_EVDEV_OPENED;
 
@@ -934,8 +955,6 @@ ums_ev_open(struct evdev_dev *evdev, voi
                ums_start_rx(sc);
        }
 
-       mtx_unlock(&sc->sc_mtx);
-
        return (0);
 }
 
@@ -944,14 +963,12 @@ ums_ev_close(struct evdev_dev *evdev, vo
 {
        struct ums_softc *sc = (struct ums_softc *)ev_softc;
 
-       mtx_lock(&sc->sc_mtx);
+       mtx_assert(&sc->sc_mtx, MA_OWNED);
 
        sc->sc_evflags = 0;
 
        if (sc->sc_fflags == 0)
                ums_stop_rx(sc);
-
-       mtx_unlock(&sc->sc_mtx);
 }
 #endif
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to