FreeBSD Bugzilla – Attachment 181846 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 - v2
evdev-linux-compat-2.patch (text/plain), 4.17 KB, created by
Jan Kokemüller
on 2017-04-17 15:32:12 UTC
(
hide
)
Description:
add an Evdev ioctl handler to the Linux compat layer - v2
Filename:
MIME Type:
Creator:
Jan Kokemüller
Created:
2017-04-17 15:32:12 UTC
Size:
4.17 KB
patch
obsolete
>diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c >index e4e18f7..8a79c79 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 > { >@@ -3611,6 +3617,85 @@ linux_ioctl_fbsd_usb(struct thread *td, struct linux_ioctl_args *args) > } > > /* >+ * 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) >+{ >+ 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: >+ 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((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 fe017c7..58e1087 100644 >--- a/sys/compat/linux/linux_ioctl.h >+++ b/sys/compat/linux/linux_ioctl.h >@@ -750,6 +750,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