View | Details | Raw Unified | Return to bug 218627 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/compat/linux/linux_ioctl.c (+85 lines)
Lines 70-75 __FBSDID("$FreeBSD$"); Link Here
70
#include <net/if_dl.h>
70
#include <net/if_dl.h>
71
#include <net/if_types.h>
71
#include <net/if_types.h>
72
72
73
#include <dev/evdev/input.h>
73
#include <dev/usb/usb_ioctl.h>
74
#include <dev/usb/usb_ioctl.h>
74
75
75
#ifdef COMPAT_LINUX32
76
#ifdef COMPAT_LINUX32
Lines 83-88 __FBSDID("$FreeBSD$"); Link Here
83
#include <compat/linux/linux_ioctl.h>
84
#include <compat/linux/linux_ioctl.h>
84
#include <compat/linux/linux_mib.h>
85
#include <compat/linux/linux_mib.h>
85
#include <compat/linux/linux_socket.h>
86
#include <compat/linux/linux_socket.h>
87
#include <compat/linux/linux_timer.h>
86
#include <compat/linux/linux_util.h>
88
#include <compat/linux/linux_util.h>
87
89
88
#include <contrib/v4l/videodev.h>
90
#include <contrib/v4l/videodev.h>
Lines 110-115 static linux_ioctl_function_t linux_ioctl_v4l; Link Here
110
static linux_ioctl_function_t linux_ioctl_v4l2;
112
static linux_ioctl_function_t linux_ioctl_v4l2;
111
static linux_ioctl_function_t linux_ioctl_special;
113
static linux_ioctl_function_t linux_ioctl_special;
112
static linux_ioctl_function_t linux_ioctl_fbsd_usb;
114
static linux_ioctl_function_t linux_ioctl_fbsd_usb;
115
static linux_ioctl_function_t linux_ioctl_evdev;
113
116
114
static struct linux_ioctl_handler cdrom_handler =
117
static struct linux_ioctl_handler cdrom_handler =
115
{ linux_ioctl_cdrom, LINUX_IOCTL_CDROM_MIN, LINUX_IOCTL_CDROM_MAX };
118
{ linux_ioctl_cdrom, LINUX_IOCTL_CDROM_MIN, LINUX_IOCTL_CDROM_MAX };
Lines 139-144 static struct linux_ioctl_handler video2_handler = Link Here
139
{ linux_ioctl_v4l2, LINUX_IOCTL_VIDEO2_MIN, LINUX_IOCTL_VIDEO2_MAX };
142
{ linux_ioctl_v4l2, LINUX_IOCTL_VIDEO2_MIN, LINUX_IOCTL_VIDEO2_MAX };
140
static struct linux_ioctl_handler fbsd_usb =
143
static struct linux_ioctl_handler fbsd_usb =
141
{ linux_ioctl_fbsd_usb, FBSD_LUSB_MIN, FBSD_LUSB_MAX };
144
{ linux_ioctl_fbsd_usb, FBSD_LUSB_MIN, FBSD_LUSB_MAX };
145
static struct linux_ioctl_handler evdev_handler =
146
{ linux_ioctl_evdev, LINUX_IOCTL_EVDEV_MIN, LINUX_IOCTL_EVDEV_MAX };
142
147
143
DATA_SET(linux_ioctl_handler_set, cdrom_handler);
148
DATA_SET(linux_ioctl_handler_set, cdrom_handler);
144
DATA_SET(linux_ioctl_handler_set, vfat_handler);
149
DATA_SET(linux_ioctl_handler_set, vfat_handler);
Lines 154-159 DATA_SET(linux_ioctl_handler_set, sg_handler); Link Here
154
DATA_SET(linux_ioctl_handler_set, video_handler);
159
DATA_SET(linux_ioctl_handler_set, video_handler);
155
DATA_SET(linux_ioctl_handler_set, video2_handler);
160
DATA_SET(linux_ioctl_handler_set, video2_handler);
156
DATA_SET(linux_ioctl_handler_set, fbsd_usb);
161
DATA_SET(linux_ioctl_handler_set, fbsd_usb);
162
DATA_SET(linux_ioctl_handler_set, evdev_handler);
157
163
158
struct handler_element
164
struct handler_element
159
{
165
{
Lines 3611-3616 linux_ioctl_fbsd_usb(struct thread *td, struct linux_ioctl_args *args) Link Here
3611
}
3617
}
3612
3618
3613
/*
3619
/*
3620
 * Some evdev ioctls must be translated.
3621
 *  - EVIOCGMTSLOTS is a IOC_READ ioctl on Linux although it has input data
3622
 *    (must be IOC_INOUT on FreeBSD).
3623
 *  - On Linux, EVIOCGRAB, EVIOCREVOKE and EVIOCRMFF are defined as _IOW with
3624
 *    an int argument. You don't pass an int pointer to the ioctl(), however,
3625
 *    but just the int directly. On FreeBSD, they are defined as _IOWINT for
3626
 *    this to work.
3627
 */
3628
static int
3629
linux_ioctl_evdev(struct thread *td, struct linux_ioctl_args *args)
3630
{
3631
	int error;
3632
	int clock;
3633
	cap_rights_t rights;
3634
	struct file *fp;
3635
3636
	args->cmd = SETDIR(args->cmd);
3637
3638
	switch (args->cmd) {
3639
	case (EVIOCGRAB & ~IOC_DIRMASK) | IOC_IN:
3640
		args->cmd = EVIOCGRAB;
3641
		break;
3642
	case (EVIOCREVOKE & ~IOC_DIRMASK) | IOC_IN:
3643
		args->cmd = EVIOCREVOKE;
3644
		break;
3645
	case (EVIOCRMFF & ~IOC_DIRMASK) | IOC_IN:
3646
		args->cmd = EVIOCRMFF;
3647
		break;
3648
	case EVIOCSCLOCKID: {
3649
		error = copyin((void *)args->arg, &clock, sizeof(clock));
3650
		if (error) {
3651
			return (error);
3652
		}
3653
3654
		switch (clock) {
3655
		case LINUX_CLOCK_REALTIME:
3656
			clock = CLOCK_REALTIME;
3657
			break;
3658
		case LINUX_CLOCK_MONOTONIC:
3659
			clock = CLOCK_MONOTONIC;
3660
			break;
3661
		case LINUX_CLOCK_BOOTTIME:
3662
			/*
3663
			 * TODO: FreeBSD does not have an equivalent to Linux'
3664
			 * CLOCK_BOOTTIME. Map it to CLOCK_MONOTONIC for now.
3665
			 */
3666
			clock = CLOCK_MONOTONIC;
3667
			break;
3668
		default:
3669
			return (-EINVAL);
3670
		}
3671
3672
		error = fget(
3673
		    td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
3674
		if (error) {
3675
			return (error);
3676
		}
3677
3678
		error = fo_ioctl(
3679
		    fp, EVIOCSCLOCKID, (caddr_t)&clock, td->td_ucred, td);
3680
3681
		fdrop(fp, td);
3682
3683
		return (error);
3684
	}
3685
	default:
3686
		break;
3687
	}
3688
3689
	if (IOCBASECMD(args->cmd) ==
3690
	    ((EVIOCGMTSLOTS(0) & ~IOC_DIRMASK) | IOC_OUT)) {
3691
		args->cmd = (args->cmd & ~IOC_DIRMASK) | IOC_INOUT;
3692
	}
3693
3694
	error = (sys_ioctl(td, (struct ioctl_args *)args));
3695
	return (error);
3696
}
3697
3698
/*
3614
 * main ioctl syscall function
3699
 * main ioctl syscall function
3615
 */
3700
 */
3616
3701
(-)b/sys/compat/linux/linux_ioctl.h (+5 lines)
Lines 750-755 Link Here
750
 */
750
 */
751
#define LINUX_BTRFS_IOC_CLONE		0x9409 /* 0x40049409 */
751
#define LINUX_BTRFS_IOC_CLONE		0x9409 /* 0x40049409 */
752
752
753
/*
754
 * Linux evdev ioctl min and max
755
 */
756
#define LINUX_IOCTL_EVDEV_MIN		0x4500
757
#define LINUX_IOCTL_EVDEV_MAX		0x45ff
753
758
754
/*
759
/*
755
 * Pluggable ioctl handlers
760
 * Pluggable ioctl handlers

Return to bug 218627