svn commit: r317323 - head/sys/compat/linux
Dmitry Chagin
dchagin at FreeBSD.org
Sun Apr 23 07:43:52 UTC 2017
Author: dchagin
Date: Sun Apr 23 07:43:50 2017
New Revision: 317323
URL: https://svnweb.freebsd.org/changeset/base/317323
Log:
Add Evdev ioctl handler to the Linuxulator.
PR: 218627
Submitted by: Jan Kokemüller
Reported by: Jan Kokemüller
MFC after: 1 week
Modified:
head/sys/compat/linux/linux_ioctl.c
head/sys/compat/linux/linux_ioctl.h
Modified: head/sys/compat/linux/linux_ioctl.c
==============================================================================
--- head/sys/compat/linux/linux_ioctl.c Sun Apr 23 07:37:14 2017 (r317322)
+++ head/sys/compat/linux/linux_ioctl.c Sun Apr 23 07:43:50 2017 (r317323)
@@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$");
#include <net/if_dl.h>
#include <net/if_types.h>
+#include <dev/evdev/input.h>
#include <dev/usb/usb_ioctl.h>
#ifdef COMPAT_LINUX32
@@ -83,6 +84,7 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_socket.h>
+#include <compat/linux/linux_timer.h>
#include <compat/linux/linux_util.h>
#include <contrib/v4l/videodev.h>
@@ -110,6 +112,7 @@ static linux_ioctl_function_t linux_ioct
static linux_ioctl_function_t linux_ioctl_v4l2;
static linux_ioctl_function_t linux_ioctl_special;
static linux_ioctl_function_t linux_ioctl_fbsd_usb;
+static linux_ioctl_function_t linux_ioctl_evdev;
static struct linux_ioctl_handler cdrom_handler =
{ linux_ioctl_cdrom, LINUX_IOCTL_CDROM_MIN, LINUX_IOCTL_CDROM_MAX };
@@ -139,6 +142,8 @@ static struct linux_ioctl_handler video2
{ linux_ioctl_v4l2, LINUX_IOCTL_VIDEO2_MIN, LINUX_IOCTL_VIDEO2_MAX };
static struct linux_ioctl_handler fbsd_usb =
{ linux_ioctl_fbsd_usb, FBSD_LUSB_MIN, FBSD_LUSB_MAX };
+static struct linux_ioctl_handler evdev_handler =
+{ linux_ioctl_evdev, LINUX_IOCTL_EVDEV_MIN, LINUX_IOCTL_EVDEV_MAX };
DATA_SET(linux_ioctl_handler_set, cdrom_handler);
DATA_SET(linux_ioctl_handler_set, vfat_handler);
@@ -154,6 +159,7 @@ DATA_SET(linux_ioctl_handler_set, sg_han
DATA_SET(linux_ioctl_handler_set, video_handler);
DATA_SET(linux_ioctl_handler_set, video2_handler);
DATA_SET(linux_ioctl_handler_set, fbsd_usb);
+DATA_SET(linux_ioctl_handler_set, evdev_handler);
struct handler_element
{
@@ -3621,6 +3627,65 @@ linux_ioctl_fbsd_usb(struct thread *td,
}
/*
+ * Some evdev ioctls must be translated.
+ * - EVIOCGMTSLOTS is a IOC_READ ioctl on Linux although it has input data
+ * (must be IOC_INOUT on FreeBSD).
+ * - On Linux, EVIOCGRAB, EVIOCREVOKE and EVIOCRMFF are defined as _IOW with
+ * an int argument. You don't pass an int pointer to the ioctl(), however,
+ * but just the int directly. On FreeBSD, they are defined as _IOWINT for
+ * this to work.
+ */
+static int
+linux_ioctl_evdev(struct thread *td, struct linux_ioctl_args *args)
+{
+ cap_rights_t rights;
+ struct file *fp;
+ clockid_t clock;
+ int error;
+
+ args->cmd = SETDIR(args->cmd);
+
+ switch (args->cmd) {
+ case (EVIOCGRAB & ~IOC_DIRMASK) | IOC_IN:
+ args->cmd = EVIOCGRAB;
+ break;
+ case (EVIOCREVOKE & ~IOC_DIRMASK) | IOC_IN:
+ args->cmd = EVIOCREVOKE;
+ break;
+ case (EVIOCRMFF & ~IOC_DIRMASK) | IOC_IN:
+ args->cmd = EVIOCRMFF;
+ break;
+ case EVIOCSCLOCKID: {
+ error = copyin(PTRIN(args->arg), &clock, sizeof(clock));
+ if (error != 0)
+ return (error);
+ if (clock & ~(LINUX_IOCTL_EVDEV_CLK))
+ return (EINVAL);
+ error = linux_to_native_clockid(&clock, clock);
+ if (error != 0)
+ return (error);
+
+ error = fget(td, args->fd,
+ cap_rights_init(&rights, CAP_IOCTL), &fp);
+ if (error != 0)
+ return (error);
+
+ error = fo_ioctl(fp, EVIOCSCLOCKID, &clock, td->td_ucred, td);
+ fdrop(fp, td);
+ return (error);
+ }
+ default:
+ break;
+ }
+
+ if (IOCBASECMD(args->cmd) ==
+ ((EVIOCGMTSLOTS(0) & ~IOC_DIRMASK) | IOC_OUT))
+ args->cmd = (args->cmd & ~IOC_DIRMASK) | IOC_INOUT;
+
+ return (sys_ioctl(td, (struct ioctl_args *)args));
+}
+
+/*
* main ioctl syscall function
*/
Modified: head/sys/compat/linux/linux_ioctl.h
==============================================================================
--- head/sys/compat/linux/linux_ioctl.h Sun Apr 23 07:37:14 2017 (r317322)
+++ head/sys/compat/linux/linux_ioctl.h Sun Apr 23 07:43:50 2017 (r317323)
@@ -750,7 +750,13 @@
*/
#define LINUX_BTRFS_IOC_CLONE 0x9409 /* 0x40049409 */
-
+/*
+ * Linux evdev ioctl min and max
+ */
+#define LINUX_IOCTL_EVDEV_MIN 0x4500
+#define LINUX_IOCTL_EVDEV_MAX 0x45ff
+#define LINUX_IOCTL_EVDEV_CLK LINUX_CLOCK_REALTIME | \
+ LINUX_CLOCK_MONOTONIC |LINUX_CLOCK_BOOTTIME
/*
* Pluggable ioctl handlers
*/
More information about the svn-src-all
mailing list