[PATCH] move rtc compat ioctl handling to fs/compat_ioctl.c
Christoph Hellwig [Tue, 10 Jan 2006 04:52:11 +0000 (20:52 -0800)]
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>

arch/parisc/kernel/ioctl32.c
arch/x86_64/ia32/ia32_ioctl.c
fs/compat_ioctl.c

index 4eada1b..805f314 100644 (file)
@@ -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);
index e335bd0..e11cc56 100644 (file)
 
 #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) }, 
@@ -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 */
 }; 
 
index 55d9a3a..b9aeacc 100644 (file)
@@ -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)