From owner-svn-src-all@freebsd.org Sun Apr 30 06:14:59 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 734FFD56128; Sun, 30 Apr 2017 06:14:59 +0000 (UTC) (envelope-from dchagin@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::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 4035919F5; Sun, 30 Apr 2017 06:14:59 +0000 (UTC) (envelope-from dchagin@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3U6EwiO096940; Sun, 30 Apr 2017 06:14:58 GMT (envelope-from dchagin@FreeBSD.org) Received: (from dchagin@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3U6EwPT096938; Sun, 30 Apr 2017 06:14:58 GMT (envelope-from dchagin@FreeBSD.org) Message-Id: <201704300614.v3U6EwPT096938@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dchagin set sender to dchagin@FreeBSD.org using -f From: Dmitry Chagin Date: Sun, 30 Apr 2017 06:14:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r317602 - stable/11/sys/compat/linux X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Apr 2017 06:14:59 -0000 Author: dchagin Date: Sun Apr 30 06:14:57 2017 New Revision: 317602 URL: https://svnweb.freebsd.org/changeset/base/317602 Log: MFC r317323: Add Evdev ioctl handler to the Linuxulator. PR: 218627 Modified: stable/11/sys/compat/linux/linux_ioctl.c stable/11/sys/compat/linux/linux_ioctl.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/compat/linux/linux_ioctl.c ============================================================================== --- stable/11/sys/compat/linux/linux_ioctl.c Sun Apr 30 05:56:57 2017 (r317601) +++ stable/11/sys/compat/linux/linux_ioctl.c Sun Apr 30 06:14:57 2017 (r317602) @@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #ifdef COMPAT_LINUX32 @@ -83,6 +84,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -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 { @@ -3573,6 +3579,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: stable/11/sys/compat/linux/linux_ioctl.h ============================================================================== --- stable/11/sys/compat/linux/linux_ioctl.h Sun Apr 30 05:56:57 2017 (r317601) +++ stable/11/sys/compat/linux/linux_ioctl.h Sun Apr 30 06:14:57 2017 (r317602) @@ -749,7 +749,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 */