Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec3cad96 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Linus Torvalds
Browse files

[PATCH] move rtc compat ioctl handling to fs/compat_ioctl.c



This patch implements generic handling of RTC_IRQP_READ32, RTC_IRQP_SET32,
RTC_EPOCH_READ32 and RTC_EPOCH_SET32 in fs/compat_ioctl.c.  It's based on the
x86_64 code which needed a little massaging to be endian-clean.

parisc used COMPAT_IOCTL or generic w_long handlers for these whichce is wrong
and can't work because the ioctls encode sizeof(unsigned long) in their ioctl
number.  parisc also duplicated COMPAT_IOCTL entries for other rtc ioctls
which I remove in this patch, too.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarMatthew Wilcox <matthew@wil.cx>
Acked-by: default avatar"David S. Miller" <davem@davemloft.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 3a0f69d5
Loading
Loading
Loading
Loading
+0 −19
Original line number Diff line number Diff line
@@ -36,25 +36,6 @@ HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)

#if defined(CONFIG_GEN_RTC)
COMPATIBLE_IOCTL(RTC_AIE_ON)
COMPATIBLE_IOCTL(RTC_AIE_OFF)
COMPATIBLE_IOCTL(RTC_UIE_ON)
COMPATIBLE_IOCTL(RTC_UIE_OFF)
COMPATIBLE_IOCTL(RTC_PIE_ON)
COMPATIBLE_IOCTL(RTC_PIE_OFF)
COMPATIBLE_IOCTL(RTC_WIE_ON)
COMPATIBLE_IOCTL(RTC_WIE_OFF)
COMPATIBLE_IOCTL(RTC_ALM_SET)   /* struct rtc_time only has ints */
COMPATIBLE_IOCTL(RTC_ALM_READ)  /* struct rtc_time only has ints */
COMPATIBLE_IOCTL(RTC_RD_TIME)   /* struct rtc_time only has ints */
COMPATIBLE_IOCTL(RTC_SET_TIME)  /* struct rtc_time only has ints */
HANDLE_IOCTL(RTC_IRQP_READ, w_long)
COMPATIBLE_IOCTL(RTC_IRQP_SET)
HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
COMPATIBLE_IOCTL(RTC_EPOCH_SET)
#endif

IOCTL_TABLE_END

int ioctl_table_size = ARRAY_SIZE(ioctl_start);
+0 −47
Original line number Diff line number Diff line
@@ -17,45 +17,6 @@
#define CODE
#include "compat_ioctl.c"

#define RTC_IRQP_READ32	_IOR('p', 0x0b, unsigned int)	 /* Read IRQ rate   */
#define RTC_IRQP_SET32	_IOW('p', 0x0c, unsigned int)	 /* Set IRQ rate    */
#define RTC_EPOCH_READ32	_IOR('p', 0x0d, unsigned)	 /* Read epoch      */
#define RTC_EPOCH_SET32		_IOW('p', 0x0e, unsigned)	 /* Set epoch       */

static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg) 
{ 
	unsigned long val;
	mm_segment_t oldfs = get_fs(); 
	int ret; 
	
	switch (cmd) { 
	case RTC_IRQP_READ32: 
		set_fs(KERNEL_DS); 
		ret = sys_ioctl(fd, RTC_IRQP_READ, (unsigned long)&val); 
		set_fs(oldfs); 
		if (!ret)
			ret = put_user(val, (unsigned int __user *) arg); 
		return ret; 

	case RTC_IRQP_SET32: 
		cmd = RTC_IRQP_SET; 
		break; 

	case RTC_EPOCH_READ32:
		set_fs(KERNEL_DS); 
		ret = sys_ioctl(fd, RTC_EPOCH_READ, (unsigned long) &val); 
		set_fs(oldfs); 
		if (!ret)
			ret = put_user(val, (unsigned int __user *) arg); 
		return ret; 

	case RTC_EPOCH_SET32:
		cmd = RTC_EPOCH_SET; 
		break; 
	} 
	return sys_ioctl(fd,cmd,arg); 
} 


#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) }, 
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
@@ -64,14 +25,6 @@ struct ioctl_trans ioctl_start[] = {
#include <linux/compat_ioctl.h>
#define DECLARES
#include "compat_ioctl.c"

/* And these ioctls need translation */
/* realtime device */
HANDLE_IOCTL(RTC_IRQP_READ,  rtc32_ioctl)
HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
/* take care of sizeof(sizeof()) breakage */
}; 

+47 −0
Original line number Diff line number Diff line
@@ -2475,6 +2475,49 @@ static int old_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg
	return -EINVAL;
}

#define RTC_IRQP_READ32		_IOR('p', 0x0b, compat_ulong_t)
#define RTC_IRQP_SET32		_IOW('p', 0x0c, compat_ulong_t)
#define RTC_EPOCH_READ32	_IOR('p', 0x0d, compat_ulong_t)
#define RTC_EPOCH_SET32		_IOW('p', 0x0e, compat_ulong_t)

static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
{
	mm_segment_t oldfs = get_fs();
	compat_ulong_t val32;
	unsigned long kval;
	int ret;

	switch (cmd) {
	case RTC_IRQP_READ32:
	case RTC_EPOCH_READ32:
		set_fs(KERNEL_DS);
		ret = sys_ioctl(fd, (cmd == RTC_IRQP_READ32) ?
					RTC_IRQP_READ : RTC_EPOCH_READ,
					(unsigned long)&kval);
		set_fs(oldfs);
		if (ret)
			return ret;
		val32 = kval;
		return put_user(val32, (unsigned int __user *)arg);
	case RTC_IRQP_SET32:
	case RTC_EPOCH_SET32:
		ret = get_user(val32, (unsigned int __user *)arg);
		if (ret)
			return ret;
		kval = val32;

		set_fs(KERNEL_DS);
		ret = sys_ioctl(fd, (cmd == RTC_IRQP_SET32) ?
				RTC_IRQP_SET : RTC_EPOCH_SET,
				(unsigned long)&kval);
		set_fs(oldfs);
		return ret;
	default:
		/* unreached */
		return -ENOIOCTLCMD;
	}
}

#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
struct ncp_ioctl_request_32 {
	u32 function;
@@ -2858,6 +2901,10 @@ HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl)
HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl)
HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)
HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl)
HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl)
HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)
HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl)

#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)