aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2006-01-09 23:52:11 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-10 11:01:32 -0500
commitec3cad96901373ad0e21611cfbcc372fe09df1f7 (patch)
tree4c4fff817b9e88fe3fd015382913944fe2d946d8
parent3a0f69d59ba41fbcad6a17b6e8aab02bf45e20ce (diff)
[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: Christoph Hellwig <hch@lst.de> Acked-by: Matthew Wilcox <matthew@wil.cx> Acked-by: "David S. Miller" <davem@davemloft.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/parisc/kernel/ioctl32.c19
-rw-r--r--arch/x86_64/ia32/ia32_ioctl.c47
-rw-r--r--fs/compat_ioctl.c47
3 files changed, 47 insertions, 66 deletions
diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
index 4eada1bb27f0..805f31486cf9 100644
--- a/arch/parisc/kernel/ioctl32.c
+++ b/arch/parisc/kernel/ioctl32.c
@@ -36,25 +36,6 @@ HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
36HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc) 36HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
37HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc) 37HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)
38 38
39#if defined(CONFIG_GEN_RTC)
40COMPATIBLE_IOCTL(RTC_AIE_ON)
41COMPATIBLE_IOCTL(RTC_AIE_OFF)
42COMPATIBLE_IOCTL(RTC_UIE_ON)
43COMPATIBLE_IOCTL(RTC_UIE_OFF)
44COMPATIBLE_IOCTL(RTC_PIE_ON)
45COMPATIBLE_IOCTL(RTC_PIE_OFF)
46COMPATIBLE_IOCTL(RTC_WIE_ON)
47COMPATIBLE_IOCTL(RTC_WIE_OFF)
48COMPATIBLE_IOCTL(RTC_ALM_SET) /* struct rtc_time only has ints */
49COMPATIBLE_IOCTL(RTC_ALM_READ) /* struct rtc_time only has ints */
50COMPATIBLE_IOCTL(RTC_RD_TIME) /* struct rtc_time only has ints */
51COMPATIBLE_IOCTL(RTC_SET_TIME) /* struct rtc_time only has ints */
52HANDLE_IOCTL(RTC_IRQP_READ, w_long)
53COMPATIBLE_IOCTL(RTC_IRQP_SET)
54HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
55COMPATIBLE_IOCTL(RTC_EPOCH_SET)
56#endif
57
58IOCTL_TABLE_END 39IOCTL_TABLE_END
59 40
60int ioctl_table_size = ARRAY_SIZE(ioctl_start); 41int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index e335bd0b637d..e11cc5699352 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -16,45 +16,6 @@
16 16
17#define CODE 17#define CODE
18#include "compat_ioctl.c" 18#include "compat_ioctl.c"
19
20#define RTC_IRQP_READ32 _IOR('p', 0x0b, unsigned int) /* Read IRQ rate */
21#define RTC_IRQP_SET32 _IOW('p', 0x0c, unsigned int) /* Set IRQ rate */
22#define RTC_EPOCH_READ32 _IOR('p', 0x0d, unsigned) /* Read epoch */
23#define RTC_EPOCH_SET32 _IOW('p', 0x0e, unsigned) /* Set epoch */
24
25static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
26{
27 unsigned long val;
28 mm_segment_t oldfs = get_fs();
29 int ret;
30
31 switch (cmd) {
32 case RTC_IRQP_READ32:
33 set_fs(KERNEL_DS);
34 ret = sys_ioctl(fd, RTC_IRQP_READ, (unsigned long)&val);
35 set_fs(oldfs);
36 if (!ret)
37 ret = put_user(val, (unsigned int __user *) arg);
38 return ret;
39
40 case RTC_IRQP_SET32:
41 cmd = RTC_IRQP_SET;
42 break;
43
44 case RTC_EPOCH_READ32:
45 set_fs(KERNEL_DS);
46 ret = sys_ioctl(fd, RTC_EPOCH_READ, (unsigned long) &val);
47 set_fs(oldfs);
48 if (!ret)
49 ret = put_user(val, (unsigned int __user *) arg);
50 return ret;
51
52 case RTC_EPOCH_SET32:
53 cmd = RTC_EPOCH_SET;
54 break;
55 }
56 return sys_ioctl(fd,cmd,arg);
57}
58 19
59 20
60#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) }, 21#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) },
@@ -64,14 +25,6 @@ struct ioctl_trans ioctl_start[] = {
64#include <linux/compat_ioctl.h> 25#include <linux/compat_ioctl.h>
65#define DECLARES 26#define DECLARES
66#include "compat_ioctl.c" 27#include "compat_ioctl.c"
67
68/* And these ioctls need translation */
69/* realtime device */
70HANDLE_IOCTL(RTC_IRQP_READ, rtc32_ioctl)
71HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
72HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
73HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
74HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
75/* take care of sizeof(sizeof()) breakage */ 28/* take care of sizeof(sizeof()) breakage */
76}; 29};
77 30
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 55d9a3a954cf..b9aeacc11c8f 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -2475,6 +2475,49 @@ static int old_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg
2475 return -EINVAL; 2475 return -EINVAL;
2476} 2476}
2477 2477
2478#define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t)
2479#define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t)
2480#define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t)
2481#define RTC_EPOCH_SET32 _IOW('p', 0x0e, compat_ulong_t)
2482
2483static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
2484{
2485 mm_segment_t oldfs = get_fs();
2486 compat_ulong_t val32;
2487 unsigned long kval;
2488 int ret;
2489
2490 switch (cmd) {
2491 case RTC_IRQP_READ32:
2492 case RTC_EPOCH_READ32:
2493 set_fs(KERNEL_DS);
2494 ret = sys_ioctl(fd, (cmd == RTC_IRQP_READ32) ?
2495 RTC_IRQP_READ : RTC_EPOCH_READ,
2496 (unsigned long)&kval);
2497 set_fs(oldfs);
2498 if (ret)
2499 return ret;
2500 val32 = kval;
2501 return put_user(val32, (unsigned int __user *)arg);
2502 case RTC_IRQP_SET32:
2503 case RTC_EPOCH_SET32:
2504 ret = get_user(val32, (unsigned int __user *)arg);
2505 if (ret)
2506 return ret;
2507 kval = val32;
2508
2509 set_fs(KERNEL_DS);
2510 ret = sys_ioctl(fd, (cmd == RTC_IRQP_SET32) ?
2511 RTC_IRQP_SET : RTC_EPOCH_SET,
2512 (unsigned long)&kval);
2513 set_fs(oldfs);
2514 return ret;
2515 default:
2516 /* unreached */
2517 return -ENOIOCTLCMD;
2518 }
2519}
2520
2478#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) 2521#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
2479struct ncp_ioctl_request_32 { 2522struct ncp_ioctl_request_32 {
2480 u32 function; 2523 u32 function;
@@ -2858,6 +2901,10 @@ HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl)
2858HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) 2901HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl)
2859HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) 2902HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
2860HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) 2903HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)
2904HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl)
2905HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl)
2906HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)
2907HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl)
2861 2908
2862#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) 2909#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
2863HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) 2910HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)