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

Collapse All | Expand All

(-)b/sys/compat/linux/linux_ioctl.c (+88 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 3563-3568 linux_ioctl_fbsd_usb(struct thread *td, struct linux_ioctl_args *args) Link Here
3563
}
3569
}
3564
3570
3565
/*
3571
/*
3572
 * Some evdev ioctls are defined in a weird way on Linux.
3573
 * We need to translate them.
3574
 *  - EVIOCGMTSLOTS is a IOC_READ ioctl on Linux although it has input data
3575
 *    (must be IOC_INOUT on FreeBSD).
3576
 *  - EVIOCGRAB and EVIOCREVOKE are defined as IOC_WRITE with an int argument.
3577
 *    They don't read from an int, however, but make their decisions based on
3578
 *    the value of the _pointer_ argument.
3579
 */
3580
static int
3581
linux_ioctl_evdev(struct thread *td, struct linux_ioctl_args *args)
3582
{
3583
	int error;
3584
	int clock;
3585
	cap_rights_t rights;
3586
	struct file *fp;
3587
3588
	args->cmd = SETDIR(args->cmd);
3589
3590
	switch (args->cmd) {
3591
	case (EVIOCGRAB & ~IOC_DIRMASK) | IOC_IN | (sizeof(int) << 16):
3592
		/*
3593
		 * The length field of the new args->cmd must be zero to
3594
		 * properly pass along the value of the data pointer for cuse
3595
		 * based evdev devices (look at the comment in
3596
		 * cuse_client_ioctl() from sys/fs/cuse/cuse.c).
3597
		 */
3598
		args->cmd = EVIOCGRAB;
3599
		break;
3600
	case (EVIOCREVOKE & ~IOC_DIRMASK) | IOC_IN | (sizeof(int) << 16):
3601
		args->cmd = EVIOCREVOKE;
3602
		break;
3603
	case EVIOCSCLOCKID: {
3604
		error = copyin((void *)args->arg, &clock, sizeof(clock));
3605
		if (error) {
3606
			return (error);
3607
		}
3608
3609
		switch (clock) {
3610
		case LINUX_CLOCK_REALTIME:
3611
			clock = CLOCK_REALTIME;
3612
			break;
3613
		case LINUX_CLOCK_MONOTONIC:
3614
			clock = CLOCK_MONOTONIC;
3615
			break;
3616
		case LINUX_CLOCK_BOOTTIME:
3617
			/*
3618
			 * TODO: FreeBSD does not have an equivalent to Linux'
3619
			 * CLOCK_BOOTTIME. Map it to CLOCK_MONOTONIC for now.
3620
			 */
3621
			clock = CLOCK_MONOTONIC;
3622
			break;
3623
		default:
3624
			return (-EINVAL);
3625
		}
3626
3627
		error = fget(
3628
		    td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
3629
		if (error) {
3630
			return (error);
3631
		}
3632
3633
		error = fo_ioctl(
3634
		    fp, EVIOCSCLOCKID, (caddr_t)&clock, td->td_ucred, td);
3635
3636
		fdrop(fp, td);
3637
3638
		return (error);
3639
	}
3640
	default:
3641
		break;
3642
	}
3643
3644
	if (IOCBASECMD(args->cmd) ==
3645
	    ((EVIOCGMTSLOTS(0) & ~IOC_DIRMASK) | IOC_OUT)) {
3646
		args->cmd = (args->cmd & ~IOC_DIRMASK) | IOC_INOUT;
3647
	}
3648
3649
	error = (sys_ioctl(td, (struct ioctl_args *)args));
3650
	return (error);
3651
}
3652
3653
/*
3566
 * main ioctl syscall function
3654
 * main ioctl syscall function
3567
 */
3655
 */
3568
3656
(-)b/sys/compat/linux/linux_ioctl.h (+5 lines)
Lines 749-754 Link Here
749
 */
749
 */
750
#define LINUX_BTRFS_IOC_CLONE		0x9409 /* 0x40049409 */
750
#define LINUX_BTRFS_IOC_CLONE		0x9409 /* 0x40049409 */
751
751
752
/*
753
 * Linux evdev ioctl min and max
754
 */
755
#define LINUX_IOCTL_EVDEV_MIN		0x4500
756
#define LINUX_IOCTL_EVDEV_MAX		0x45ff
752
757
753
/*
758
/*
754
 * Pluggable ioctl handlers
759
 * Pluggable ioctl handlers

Return to bug 218627