From owner-svn-src-user@FreeBSD.ORG Mon Aug 18 16:55:19 2014 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D0776F79; Mon, 18 Aug 2014 16:55:19 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BB5493C05; Mon, 18 Aug 2014 16:55:19 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s7IGtJoM077246; Mon, 18 Aug 2014 16:55:19 GMT (envelope-from jceel@FreeBSD.org) Received: (from jceel@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s7IGtIcc077238; Mon, 18 Aug 2014 16:55:18 GMT (envelope-from jceel@FreeBSD.org) Message-Id: <201408181655.s7IGtIcc077238@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: jceel set sender to jceel@FreeBSD.org using -f From: Jakub Wojciech Klama Date: Mon, 18 Aug 2014 16:55:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r270139 - in user/jceel/soc2014_evdev/head/sys: amd64/conf dev/evdev X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Aug 2014 16:55:19 -0000 Author: jceel Date: Mon Aug 18 16:55:18 2014 New Revision: 270139 URL: http://svnweb.freebsd.org/changeset/base/270139 Log: Bulk update of evdev code: * Implemented async and non-blocking I/O mode in evdev characted device driver * Fixed crash when closing not-yet-registered uinput device * Added UI_DEV_GETPATH ioctl to uinput which provides newly created evdev node path * Implemented UI_SET_PHYS ioctl in uinput * Implemented EVIOCREVOKE ioctl * Added uep(4) to EVDEV kernel config Modified: user/jceel/soc2014_evdev/head/sys/amd64/conf/EVDEV user/jceel/soc2014_evdev/head/sys/dev/evdev/cdev.c user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.h user/jceel/soc2014_evdev/head/sys/dev/evdev/input.h user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.c user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.h Modified: user/jceel/soc2014_evdev/head/sys/amd64/conf/EVDEV ============================================================================== --- user/jceel/soc2014_evdev/head/sys/amd64/conf/EVDEV Mon Aug 18 16:08:07 2014 (r270138) +++ user/jceel/soc2014_evdev/head/sys/amd64/conf/EVDEV Mon Aug 18 16:55:18 2014 (r270139) @@ -322,6 +322,7 @@ device umass # Disks/Mass storage - R device ums device uhid device utouch +device uep # Sound support device sound # Generic sound driver (required) Modified: user/jceel/soc2014_evdev/head/sys/dev/evdev/cdev.c ============================================================================== --- user/jceel/soc2014_evdev/head/sys/dev/evdev/cdev.c Mon Aug 18 16:08:07 2014 (r270138) +++ user/jceel/soc2014_evdev/head/sys/dev/evdev/cdev.c Mon Aug 18 16:55:18 2014 (r270139) @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include @@ -97,6 +99,8 @@ struct evdev_cdev_state struct evdev_client * ecs_client; struct selinfo ecs_selp; struct sigio * ecs_sigio; + bool ecs_async; + bool ecs_revoked; }; static int evdev_cdev_count = 0; @@ -141,6 +145,7 @@ evdev_dtor(void *data) struct evdev_cdev_state *state = (struct evdev_cdev_state *)data; seldrain(&state->ecs_selp); + funsetown(&state->ecs_sigio); evdev_dispose_client(state->ecs_client); free(data, M_EVDEV); } @@ -161,6 +166,9 @@ evdev_read(struct cdev *dev, struct uio if (ret != 0) return (ret); + if (state->ecs_revoked) + return (EPERM); + client = state->ecs_client; if (uio->uio_resid % sizeof(struct input_event) != 0) { @@ -172,8 +180,14 @@ evdev_read(struct cdev *dev, struct uio EVDEV_CLIENT_LOCKQ(client); - if (EVDEV_CLIENT_EMPTYQ(client)) + if (EVDEV_CLIENT_EMPTYQ(client)) { + if (ioflag & O_NONBLOCK) { + EVDEV_CLIENT_UNLOCKQ(client); + return (EWOULDBLOCK); + } + mtx_sleep(client, &client->ec_buffer_mtx, 0, "evrea", 0); + } for (;;) { if (EVDEV_CLIENT_EMPTYQ(client)) @@ -210,6 +224,9 @@ evdev_write(struct cdev *dev, struct uio if (ret != 0) return (ret); + if (state->ecs_revoked) + return (EPERM); + if (uio->uio_resid % sizeof(struct input_event) != 0) { debugf("write size not multiple of struct input_event size"); return (EINVAL); @@ -232,6 +249,9 @@ evdev_poll(struct cdev *dev, int events, if (ret != 0) return (POLLNVAL); + if (state->ecs_revoked) + return (POLLNVAL); + client = state->ecs_client; if (events & (POLLIN | POLLRDNORM)) { @@ -299,16 +319,40 @@ evdev_ioctl(struct cdev *dev, u_long cmd int rep_params[2]; int ret, len, num, limit; - len = IOCPARM_LEN(cmd); - cmd = IOCBASECMD(cmd); - num = IOCNUM(cmd); - ret = devfs_get_cdevpriv((void **)&state); if (ret != 0) return (ret); + if (state->ecs_revoked) + return (EPERM); + + /* file I/O ioctl handling */ + switch (cmd) { + case FIOSETOWN: + return (fsetown(*(int *)data, &state->ecs_sigio)); + + case FIOGETOWN: + *(int *)data = fgetown(&state->ecs_sigio); + return (0); + + case FIONBIO: + return (0); + + case FIOASYNC: + if (*(int *)data) + state->ecs_async = true; + else + state->ecs_async = false; + + return (0); + } + + len = IOCPARM_LEN(cmd); + cmd = IOCBASECMD(cmd); + num = IOCNUM(cmd); debugf("cdev: ioctl called: cmd=0x%08lx, data=%p", cmd, data); + /* evdev ioctls handling */ switch (cmd) { case IOCBASECMD(EVIOCGVERSION): data = (caddr_t)EV_VERSION; @@ -412,7 +456,12 @@ evdev_ioctl(struct cdev *dev, u_long cmd break; case IOCBASECMD(EVIOCREVOKE): + if (*(int *)data != 0) + return (EINVAL); + + state->ecs_revoked = true; break; + } if (IOCGROUP(cmd) != 'E') @@ -511,6 +560,9 @@ evdev_notify_event(struct evdev_client * struct evdev_cdev_state *state = (struct evdev_cdev_state *)data; selwakeup(&state->ecs_selp); + + if (state->ecs_async && state->ecs_sigio != NULL) + pgsigio(&state->ecs_sigio, SIGIO, 0); } int @@ -519,10 +571,13 @@ evdev_cdev_create(struct evdev_dev *evde struct evdev_cdev_softc *sc; struct cdev *cdev; + snprintf(evdev->ev_cdev_name, NAMELEN, "input/event%d", + evdev_cdev_count++); cdev = make_dev(&evdev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, - "input/event%d", evdev_cdev_count++); + evdev->ev_cdev_name, evdev_cdev_count++); - sc = malloc(sizeof(struct evdev_cdev_softc), M_EVDEV, M_WAITOK | M_ZERO); + sc = malloc(sizeof(struct evdev_cdev_softc), M_EVDEV, + M_WAITOK | M_ZERO); sc->ecs_evdev = evdev; evdev->ev_cdev = cdev; Modified: user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.h ============================================================================== --- user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.h Mon Aug 18 16:08:07 2014 (r270138) +++ user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.h Mon Aug 18 16:55:18 2014 (r270139) @@ -74,6 +74,7 @@ struct evdev_dev device_t ev_dev; void * ev_softc; struct cdev * ev_cdev; + char ev_cdev_name[NAMELEN]; struct mtx ev_mtx; struct input_id ev_id; bool ev_grabbed; Modified: user/jceel/soc2014_evdev/head/sys/dev/evdev/input.h ============================================================================== --- user/jceel/soc2014_evdev/head/sys/dev/evdev/input.h Mon Aug 18 16:08:07 2014 (r270138) +++ user/jceel/soc2014_evdev/head/sys/dev/evdev/input.h Mon Aug 18 16:55:18 2014 (r270139) @@ -150,7 +150,7 @@ struct input_keymap_entry { #define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */ #define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */ -#define EVIOCREVOKE _IOW('E', 0x91, int) /* Revoke device access */ +#define EVIOCREVOKE _IOWINT('E', 0x91) /* Revoke device access */ #define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */ Modified: user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.c ============================================================================== --- user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.c Mon Aug 18 16:08:07 2014 (r270138) +++ user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.c Mon Aug 18 16:55:18 2014 (r270139) @@ -120,8 +120,10 @@ uinput_dtor(void *data) { struct uinput_cdev_state *state = (struct uinput_cdev_state *)data; - evdev_unregister(NULL, state->ucs_evdev); - evdev_free(state->ucs_evdev); + if (state->ucs_connected) { + evdev_unregister(NULL, state->ucs_evdev); + evdev_free(state->ucs_evdev); + } free(data, M_EVDEV); } @@ -261,6 +263,11 @@ uinput_ioctl(struct cdev *dev, u_long cm state->ucs_connected = false; break; + case UI_DEV_GETPATH: + strncpy((char *)data, state->ucs_evdev->ev_cdev_name, + UINPUT_MAXLEN); + break; + case UI_SET_EVBIT: evdev_support_event(state->ucs_evdev, (uint16_t)(uintptr_t)data); break; @@ -290,6 +297,7 @@ uinput_ioctl(struct cdev *dev, u_long cm break; case UI_SET_PHYS: + evdev_set_phys(state->ucs_evdev, (char *)data); break; case UI_SET_SWBIT: Modified: user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.h ============================================================================== --- user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.h Mon Aug 18 16:08:07 2014 (r270138) +++ user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.h Mon Aug 18 16:55:18 2014 (r270139) @@ -36,7 +36,7 @@ #include #define UINPUT_VERSION 3 - +#define UINPUT_MAXLEN 80 struct uinput_ff_upload { uint32_t request_id; @@ -56,6 +56,9 @@ struct uinput_ff_erase { #define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1) #define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2) +/* FreeBSD-specific one */ +#define UI_DEV_GETPATH _IOR(UINPUT_IOCTL_BASE, 50, char[UINPUT_MAXLEN]) + #define UI_SET_EVBIT _IOWINT(UINPUT_IOCTL_BASE, 100) #define UI_SET_KEYBIT _IOWINT(UINPUT_IOCTL_BASE, 101) #define UI_SET_RELBIT _IOWINT(UINPUT_IOCTL_BASE, 102) @@ -64,7 +67,7 @@ struct uinput_ff_erase { #define UI_SET_LEDBIT _IOWINT(UINPUT_IOCTL_BASE, 105) #define UI_SET_SNDBIT _IOWINT(UINPUT_IOCTL_BASE, 106) #define UI_SET_FFBIT _IOWINT(UINPUT_IOCTL_BASE, 107) -#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*) +#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char[UINPUT_MAXLEN]) #define UI_SET_SWBIT _IOWINT(UINPUT_IOCTL_BASE, 109) #define UI_SET_PROPBIT _IOWINT(UINPUT_IOCTL_BASE, 110)