svn commit: r307765 - in stable/11/sys: dev/usb/input modules/usb/ums
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Sat Oct 22 02:26:34 UTC 2016
Author: gonzo
Date: Sat Oct 22 02:26:33 2016
New Revision: 307765
URL: https://svnweb.freebsd.org/changeset/base/307765
Log:
MFC r306134:
Add evdev support to ums(4)
event generation is disabled by default in favour of sysmouse. This
behavoiur is controlled by kern.evdev.rcpt_mask sysctl, bit 2 should
be set to give priority to hw over sysmouse
Submitted by: Vladimir Kondratiev <wulf at cicgroup.ru>
Reviewed by: hans
Differential Revision: https://reviews.freebsd.org/D7863
Modified:
stable/11/sys/dev/usb/input/ums.c
stable/11/sys/modules/usb/ums/Makefile
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/usb/input/ums.c
==============================================================================
--- stable/11/sys/dev/usb/input/ums.c Sat Oct 22 02:15:39 2016 (r307764)
+++ stable/11/sys/dev/usb/input/ums.c Sat Oct 22 02:26:33 2016 (r307765)
@@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$");
* HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
*/
+#include "opt_evdev.h"
+
#include <sys/stdint.h>
#include <sys/stddef.h>
#include <sys/param.h>
@@ -68,6 +70,11 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/quirk/usb_quirk.h>
+#ifdef EVDEV
+#include <dev/evdev/input.h>
+#include <dev/evdev/evdev.h>
+#endif
+
#include <sys/ioccom.h>
#include <sys/filio.h>
#include <sys/tty.h>
@@ -135,10 +142,18 @@ struct ums_softc {
int sc_pollrate;
int sc_fflags;
+#ifdef EVDEV
+ int sc_evflags;
+#define UMS_EVDEV_OPENED 1
+#endif
uint8_t sc_buttons;
uint8_t sc_iid;
uint8_t sc_temp[64];
+
+#ifdef EVDEV
+ struct evdev_dev *sc_evdev;
+#endif
};
static void ums_put_queue_timeout(void *__sc);
@@ -149,25 +164,39 @@ static device_probe_t ums_probe;
static device_attach_t ums_attach;
static device_detach_t ums_detach;
-static usb_fifo_cmd_t ums_start_read;
-static usb_fifo_cmd_t ums_stop_read;
-static usb_fifo_open_t ums_open;
-static usb_fifo_close_t ums_close;
-static usb_fifo_ioctl_t ums_ioctl;
+static usb_fifo_cmd_t ums_fifo_start_read;
+static usb_fifo_cmd_t ums_fifo_stop_read;
+static usb_fifo_open_t ums_fifo_open;
+static usb_fifo_close_t ums_fifo_close;
+static usb_fifo_ioctl_t ums_fifo_ioctl;
+
+#ifdef EVDEV
+static evdev_open_t ums_ev_open;
+static evdev_close_t ums_ev_close;
+#endif
+static void ums_start_rx(struct ums_softc *);
+static void ums_stop_rx(struct ums_softc *);
static void ums_put_queue(struct ums_softc *, int32_t, int32_t,
int32_t, int32_t, int32_t);
static int ums_sysctl_handler_parseinfo(SYSCTL_HANDLER_ARGS);
static struct usb_fifo_methods ums_fifo_methods = {
- .f_open = &ums_open,
- .f_close = &ums_close,
- .f_ioctl = &ums_ioctl,
- .f_start_read = &ums_start_read,
- .f_stop_read = &ums_stop_read,
+ .f_open = &ums_fifo_open,
+ .f_close = &ums_fifo_close,
+ .f_ioctl = &ums_fifo_ioctl,
+ .f_start_read = &ums_fifo_start_read,
+ .f_stop_read = &ums_fifo_stop_read,
.basename[0] = "ums",
};
+#ifdef EVDEV
+static struct evdev_methods ums_evdev_methods = {
+ .ev_open = &ums_ev_open,
+ .ev_close = &ums_ev_close,
+};
+#endif
+
static void
ums_put_queue_timeout(void *__sc)
{
@@ -327,11 +356,17 @@ ums_intr_callback(struct usb_xfer *xfer,
case USB_ST_SETUP:
tr_setup:
/* check if we can put more data into the FIFO */
- if (usb_fifo_put_bytes_max(
- sc->sc_fifo.fp[USB_FIFO_RX]) != 0) {
- usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
- usbd_transfer_submit(xfer);
+ if (usb_fifo_put_bytes_max(sc->sc_fifo.fp[USB_FIFO_RX]) == 0) {
+#ifdef EVDEV
+ if (sc->sc_evflags == 0)
+ break;
+#else
+ break;
+#endif
}
+
+ usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
+ usbd_transfer_submit(xfer);
break;
default: /* Error */
@@ -655,6 +690,41 @@ ums_attach(device_t dev)
if (err)
goto detach;
+#ifdef EVDEV
+ sc->sc_evdev = evdev_alloc();
+ evdev_set_name(sc->sc_evdev, device_get_desc(dev));
+ evdev_set_phys(sc->sc_evdev, device_get_nameunit(dev));
+ evdev_set_id(sc->sc_evdev, BUS_USB, uaa->info.idVendor,
+ uaa->info.idProduct, 0);
+ evdev_set_serial(sc->sc_evdev, usb_get_serial(uaa->device));
+ evdev_set_methods(sc->sc_evdev, sc, &ums_evdev_methods);
+ evdev_support_prop(sc->sc_evdev, INPUT_PROP_POINTER);
+ evdev_support_event(sc->sc_evdev, EV_SYN);
+ evdev_support_event(sc->sc_evdev, EV_REL);
+ evdev_support_event(sc->sc_evdev, EV_KEY);
+
+ info = &sc->sc_info[0];
+
+ if (info->sc_flags & UMS_FLAG_X_AXIS)
+ evdev_support_rel(sc->sc_evdev, REL_X);
+
+ if (info->sc_flags & UMS_FLAG_Y_AXIS)
+ evdev_support_rel(sc->sc_evdev, REL_Y);
+
+ if (info->sc_flags & UMS_FLAG_Z_AXIS)
+ evdev_support_rel(sc->sc_evdev, REL_WHEEL);
+
+ if (info->sc_flags & UMS_FLAG_T_AXIS)
+ evdev_support_rel(sc->sc_evdev, REL_HWHEEL);
+
+ for (i = 0; i < info->sc_buttons; i++)
+ evdev_support_key(sc->sc_evdev, BTN_MOUSE + i);
+
+ err = evdev_register(sc->sc_evdev);
+ if (err)
+ goto detach;
+#endif
+
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
OID_AUTO, "parseinfo", CTLTYPE_STRING|CTLFLAG_RD,
@@ -680,6 +750,10 @@ ums_detach(device_t self)
usb_fifo_detach(&sc->sc_fifo);
+#ifdef EVDEV
+ evdev_free(sc->sc_evdev);
+#endif
+
usbd_transfer_unsetup(sc->sc_xfer, UMS_N_TRANSFER);
usb_callout_drain(&sc->sc_callout);
@@ -690,9 +764,44 @@ ums_detach(device_t self)
}
static void
-ums_start_read(struct usb_fifo *fifo)
+ums_reset(struct ums_softc *sc)
+{
+
+ /* reset all USB mouse parameters */
+
+ if (sc->sc_buttons > MOUSE_MSC_MAXBUTTON)
+ sc->sc_hw.buttons = MOUSE_MSC_MAXBUTTON;
+ else
+ sc->sc_hw.buttons = sc->sc_buttons;
+
+ sc->sc_hw.iftype = MOUSE_IF_USB;
+ sc->sc_hw.type = MOUSE_MOUSE;
+ sc->sc_hw.model = MOUSE_MODEL_GENERIC;
+ sc->sc_hw.hwid = 0;
+
+ sc->sc_mode.protocol = MOUSE_PROTO_MSC;
+ sc->sc_mode.rate = -1;
+ sc->sc_mode.resolution = MOUSE_RES_UNKNOWN;
+ sc->sc_mode.accelfactor = 0;
+ sc->sc_mode.level = 0;
+ sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE;
+ sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
+ sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
+
+ /* reset status */
+
+ sc->sc_status.flags = 0;
+ sc->sc_status.button = 0;
+ sc->sc_status.obutton = 0;
+ sc->sc_status.dx = 0;
+ sc->sc_status.dy = 0;
+ sc->sc_status.dz = 0;
+ /* sc->sc_status.dt = 0; */
+}
+
+static void
+ums_start_rx(struct ums_softc *sc)
{
- struct ums_softc *sc = usb_fifo_softc(fifo);
int rate;
/* Check if we should override the default polling interval */
@@ -715,14 +824,28 @@ ums_start_read(struct usb_fifo *fifo)
}
static void
-ums_stop_read(struct usb_fifo *fifo)
+ums_stop_rx(struct ums_softc *sc)
{
- struct ums_softc *sc = usb_fifo_softc(fifo);
-
usbd_transfer_stop(sc->sc_xfer[UMS_INTR_DT]);
usb_callout_stop(&sc->sc_callout);
}
+static void
+ums_fifo_start_read(struct usb_fifo *fifo)
+{
+ struct ums_softc *sc = usb_fifo_softc(fifo);
+
+ ums_start_rx(sc);
+}
+
+static void
+ums_fifo_stop_read(struct usb_fifo *fifo)
+{
+ struct ums_softc *sc = usb_fifo_softc(fifo);
+
+ ums_stop_rx(sc);
+}
+
#if ((MOUSE_SYS_PACKETSIZE != 8) || \
(MOUSE_MSC_PACKETSIZE != 5))
@@ -769,6 +892,21 @@ 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
+ 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");
}
@@ -781,8 +919,44 @@ ums_reset_buf(struct ums_softc *sc)
usb_fifo_reset(sc->sc_fifo.fp[USB_FIFO_RX]);
}
+#ifdef EVDEV
+static int
+ums_ev_open(struct evdev_dev *evdev, void *ev_softc)
+{
+ struct ums_softc *sc = (struct ums_softc *)ev_softc;
+
+ mtx_lock(&sc->sc_mtx);
+
+ sc->sc_evflags = UMS_EVDEV_OPENED;
+
+ if (sc->sc_fflags == 0) {
+ ums_reset(sc);
+ ums_start_rx(sc);
+ }
+
+ mtx_unlock(&sc->sc_mtx);
+
+ return (0);
+}
+
+static void
+ums_ev_close(struct evdev_dev *evdev, void *ev_softc)
+{
+ struct ums_softc *sc = (struct ums_softc *)ev_softc;
+
+ mtx_lock(&sc->sc_mtx);
+
+ sc->sc_evflags = 0;
+
+ if (sc->sc_fflags == 0)
+ ums_stop_rx(sc);
+
+ mtx_unlock(&sc->sc_mtx);
+}
+#endif
+
static int
-ums_open(struct usb_fifo *fifo, int fflags)
+ums_fifo_open(struct usb_fifo *fifo, int fflags)
{
struct ums_softc *sc = usb_fifo_softc(fifo);
@@ -793,39 +967,13 @@ ums_open(struct usb_fifo *fifo, int ffla
return (EBUSY);
/* check for first open */
- if (sc->sc_fflags == 0) {
-
- /* reset all USB mouse parameters */
-
- if (sc->sc_buttons > MOUSE_MSC_MAXBUTTON)
- sc->sc_hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->sc_hw.buttons = sc->sc_buttons;
-
- sc->sc_hw.iftype = MOUSE_IF_USB;
- sc->sc_hw.type = MOUSE_MOUSE;
- sc->sc_hw.model = MOUSE_MODEL_GENERIC;
- sc->sc_hw.hwid = 0;
-
- sc->sc_mode.protocol = MOUSE_PROTO_MSC;
- sc->sc_mode.rate = -1;
- sc->sc_mode.resolution = MOUSE_RES_UNKNOWN;
- sc->sc_mode.accelfactor = 0;
- sc->sc_mode.level = 0;
- sc->sc_mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->sc_mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->sc_mode.syncmask[1] = MOUSE_MSC_SYNC;
-
- /* reset status */
-
- sc->sc_status.flags = 0;
- sc->sc_status.button = 0;
- sc->sc_status.obutton = 0;
- sc->sc_status.dx = 0;
- sc->sc_status.dy = 0;
- sc->sc_status.dz = 0;
- /* sc->sc_status.dt = 0; */
- }
+#ifdef EVDEV
+ if (sc->sc_fflags == 0 && sc->sc_evflags == 0)
+ ums_reset(sc);
+#else
+ if (sc->sc_fflags == 0)
+ ums_reset(sc);
+#endif
if (fflags & FREAD) {
/* allocate RX buffer */
@@ -840,7 +988,7 @@ ums_open(struct usb_fifo *fifo, int ffla
}
static void
-ums_close(struct usb_fifo *fifo, int fflags)
+ums_fifo_close(struct usb_fifo *fifo, int fflags)
{
struct ums_softc *sc = usb_fifo_softc(fifo);
@@ -853,7 +1001,7 @@ ums_close(struct usb_fifo *fifo, int ffl
}
static int
-ums_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags)
+ums_fifo_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags)
{
struct ums_softc *sc = usb_fifo_softc(fifo);
mousemode_t mode;
Modified: stable/11/sys/modules/usb/ums/Makefile
==============================================================================
--- stable/11/sys/modules/usb/ums/Makefile Sat Oct 22 02:15:39 2016 (r307764)
+++ stable/11/sys/modules/usb/ums/Makefile Sat Oct 22 02:26:33 2016 (r307765)
@@ -30,7 +30,7 @@ S= ${.CURDIR}/../../..
.PATH: $S/dev/usb/input
KMOD= ums
-SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h vnode_if.h usbdevs.h \
- ums.c
+SRCS= opt_bus.h opt_evdev.h opt_usb.h device_if.h bus_if.h usb_if.h \
+ vnode_if.h usbdevs.h ums.c
.include <bsd.kmod.mk>
More information about the svn-src-stable-11
mailing list