FreeBSD Bugzilla – Attachment 181754 Details for
Bug 218627
[PATCH] add Evdev ioctl handler to the Linux compat layer
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
add an Evdev ioctl handler to the Linux compat layer
evdev-linux-compat.patch (text/plain), 4.36 KB, created by
Jan Kokemüller
on 2017-04-13 11:21:41 UTC
(
hide
)
Description:
add an Evdev ioctl handler to the Linux compat layer
Filename:
MIME Type:
Creator:
Jan Kokemüller
Created:
2017-04-13 11:21:41 UTC
Size:
4.36 KB
patch
obsolete
>diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c >index de5ad41..0810648 100644 >--- a/sys/compat/linux/linux_ioctl.c >+++ b/sys/compat/linux/linux_ioctl.c >@@ -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_ioctl_v4l; > 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_handler = > { 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_handler); > 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 > { >@@ -3563,6 +3569,88 @@ linux_ioctl_fbsd_usb(struct thread *td, struct linux_ioctl_args *args) > } > > /* >+ * Some evdev ioctls are defined in a weird way on Linux. >+ * We need to translate them. >+ * - EVIOCGMTSLOTS is a IOC_READ ioctl on Linux although it has input data >+ * (must be IOC_INOUT on FreeBSD). >+ * - EVIOCGRAB and EVIOCREVOKE are defined as IOC_WRITE with an int argument. >+ * They don't read from an int, however, but make their decisions based on >+ * the value of the _pointer_ argument. >+ */ >+static int >+linux_ioctl_evdev(struct thread *td, struct linux_ioctl_args *args) >+{ >+ int error; >+ int clock; >+ cap_rights_t rights; >+ struct file *fp; >+ >+ args->cmd = SETDIR(args->cmd); >+ >+ switch (args->cmd) { >+ case (EVIOCGRAB & ~IOC_DIRMASK) | IOC_IN | (sizeof(int) << 16): >+ /* >+ * The length field of the new args->cmd must be zero to >+ * properly pass along the value of the data pointer for cuse >+ * based evdev devices (look at the comment in >+ * cuse_client_ioctl() from sys/fs/cuse/cuse.c). >+ */ >+ args->cmd = EVIOCGRAB; >+ break; >+ case (EVIOCREVOKE & ~IOC_DIRMASK) | IOC_IN | (sizeof(int) << 16): >+ args->cmd = EVIOCREVOKE; >+ break; >+ case EVIOCSCLOCKID: { >+ error = copyin((void *)args->arg, &clock, sizeof(clock)); >+ if (error) { >+ return (error); >+ } >+ >+ switch (clock) { >+ case LINUX_CLOCK_REALTIME: >+ clock = CLOCK_REALTIME; >+ break; >+ case LINUX_CLOCK_MONOTONIC: >+ clock = CLOCK_MONOTONIC; >+ break; >+ case LINUX_CLOCK_BOOTTIME: >+ /* >+ * TODO: FreeBSD does not have an equivalent to Linux' >+ * CLOCK_BOOTTIME. Map it to CLOCK_MONOTONIC for now. >+ */ >+ clock = CLOCK_MONOTONIC; >+ break; >+ default: >+ return (-EINVAL); >+ } >+ >+ error = fget( >+ td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); >+ if (error) { >+ return (error); >+ } >+ >+ error = fo_ioctl( >+ fp, EVIOCSCLOCKID, (caddr_t)&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; >+ } >+ >+ error = (sys_ioctl(td, (struct ioctl_args *)args)); >+ return (error); >+} >+ >+/* > * main ioctl syscall function > */ > >diff --git a/sys/compat/linux/linux_ioctl.h b/sys/compat/linux/linux_ioctl.h >index 873937d..1da0ec3 100644 >--- a/sys/compat/linux/linux_ioctl.h >+++ b/sys/compat/linux/linux_ioctl.h >@@ -749,6 +749,11 @@ > */ > #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 > > /* > * Pluggable ioctl handlers
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 218627
:
181754
|
181846