Date: Wed, 21 Sep 2016 18:52:03 +0000 (UTC) From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r306134 - in head/sys: dev/usb/input modules/usb/ums Message-ID: <201609211852.u8LIq38C096076@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gonzo Date: Wed Sep 21 18:52:03 2016 New Revision: 306134 URL: https://svnweb.freebsd.org/changeset/base/306134 Log: 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@cicgroup.ru> Reviewed by: hans Differential Revision: https://reviews.freebsd.org/D7863 Modified: head/sys/dev/usb/input/ums.c head/sys/modules/usb/ums/Makefile Modified: head/sys/dev/usb/input/ums.c ============================================================================== --- head/sys/dev/usb/input/ums.c Wed Sep 21 18:50:11 2016 (r306133) +++ head/sys/dev/usb/input/ums.c Wed Sep 21 18:52:03 2016 (r306134) @@ -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: head/sys/modules/usb/ums/Makefile ============================================================================== --- head/sys/modules/usb/ums/Makefile Wed Sep 21 18:50:11 2016 (r306133) +++ head/sys/modules/usb/ums/Makefile Wed Sep 21 18:52:03 2016 (r306134) @@ -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>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609211852.u8LIq38C096076>