svn commit: r270139 - in user/jceel/soc2014_evdev/head/sys: amd64/conf dev/evdev
Jakub Wojciech Klama
jceel at FreeBSD.org
Mon Aug 18 16:55:19 UTC 2014
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 <sys/uio.h>
#include <sys/proc.h>
#include <sys/poll.h>
+#include <sys/filio.h>
+#include <sys/fcntl.h>
#include <sys/selinfo.h>
#include <sys/malloc.h>
@@ -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 <dev/evdev/input.h>
#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)
More information about the svn-src-user
mailing list