Merge branch 'master' of /usr/src/ntfs-2.6/
[pandora-kernel.git] / fs / compat_ioctl.c
index 55d9a3a..5dd0207 100644 (file)
  * ioctls.
  */
 
-#ifdef INCLUDES
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/compat.h>
 #include <linux/kernel.h>
+#include <linux/capability.h>
 #include <linux/compiler.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/capi.h>
 
 #include <scsi/scsi.h>
-/* Ugly hack. */
-#undef __KERNEL__
 #include <scsi/scsi_ioctl.h>
-#define __KERNEL__
 #include <scsi/sg.h>
 
-#include <asm/types.h>
 #include <asm/uaccess.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
@@ -95,7 +91,6 @@
 #include <linux/watchdog.h>
 #include <linux/dm-ioctl.h>
 
-#include <asm/module.h>
 #include <linux/soundcard.h>
 #include <linux/lp.h>
 #include <linux/ppdev.h>
 #include <linux/dvb/dmx.h>
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/video.h>
-
-#undef INCLUDES
-#endif
-
-#ifdef CODE
+#include <linux/lp.h>
 
 /* Aiee. Someone does not find a difference between int and long */
 #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
 #define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)
 #define EXT2_IOC32_SETVERSION             _IOW('v', 2, int)
 
+static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
+                             unsigned long arg, struct file *f)
+{
+       return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
+}
+
 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        mm_segment_t old_fs = get_fs();
@@ -920,6 +917,40 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
        return err;
 }
 
+struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
+       char req_state;
+       char orphan;
+       char sg_io_owned;
+       char problem;
+       int pack_id;
+       compat_uptr_t usr_ptr;
+       unsigned int duration;
+       int unused;
+};
+
+static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       int err, i;
+       sg_req_info_t *r;
+       struct compat_sg_req_info *o = (struct compat_sg_req_info *)arg;
+       r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE);
+       err = sys_ioctl(fd,cmd,(unsigned long)r);
+       if (err < 0)
+               return err;
+       for (i = 0; i < SG_MAX_QUEUE; i++) {
+               void __user *ptr;
+               int d;
+
+               if (copy_in_user(o + i, r + i, offsetof(sg_req_info_t, usr_ptr)) ||
+                   get_user(ptr, &r[i].usr_ptr) ||
+                   get_user(d, &r[i].duration) ||
+                   put_user((u32)(unsigned long)(ptr), &o[i].usr_ptr) ||
+                   put_user(d, &o[i].duration))
+                       return -EFAULT;
+       }
+       return err;
+}
+
 struct sock_fprog32 {
        unsigned short  len;
        compat_caddr_t  filter;
@@ -2475,6 +2506,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;
@@ -2662,10 +2736,34 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon
 }
 #endif
 
-#undef CODE
-#endif
+static int
+lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       struct compat_timeval *tc = (struct compat_timeval *)arg;
+       struct timeval *tn = compat_alloc_user_space(sizeof(struct timeval));
+       struct timeval ts;
+       if (get_user(ts.tv_sec, &tc->tv_sec) ||
+           get_user(ts.tv_usec, &tc->tv_usec) ||
+           put_user(ts.tv_sec, &tn->tv_sec) ||
+           put_user(ts.tv_usec, &tn->tv_usec))
+               return -EFAULT;
+       return sys_ioctl(fd, cmd, (unsigned long)tn);
+}
+
+#define HANDLE_IOCTL(cmd,handler) \
+       { (cmd), (ioctl_trans_handler_t)(handler) },
+
+/* pointer to compatible structure or no argument */
+#define COMPATIBLE_IOCTL(cmd) \
+       { (cmd), do_ioctl32_pointer },
+
+/* argument is an unsigned long integer, not a pointer */
+#define ULONG_IOCTL(cmd) \
+       { (cmd), (ioctl_trans_handler_t)sys_ioctl },
 
-#ifdef DECLARES
+
+struct ioctl_trans ioctl_start[] = {
+#include <linux/compat_ioctl.h>
 HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
 HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
 #ifdef CONFIG_NET
@@ -2745,6 +2843,7 @@ HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans)
 HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans)
 HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans)
 HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
+HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans)
 HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
 HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
 HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans)
@@ -2858,6 +2957,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)
@@ -2875,5 +2978,19 @@ HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)
 HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture)
 HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette)
 
-#undef DECLARES
-#endif
+/* parport */
+COMPATIBLE_IOCTL(LPTIME)
+COMPATIBLE_IOCTL(LPCHAR)
+COMPATIBLE_IOCTL(LPABORTOPEN)
+COMPATIBLE_IOCTL(LPCAREFUL)
+COMPATIBLE_IOCTL(LPWAIT)
+COMPATIBLE_IOCTL(LPSETIRQ)
+COMPATIBLE_IOCTL(LPGETSTATUS)
+COMPATIBLE_IOCTL(LPGETSTATUS)
+COMPATIBLE_IOCTL(LPRESET)
+/*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/
+COMPATIBLE_IOCTL(LPGETFLAGS)
+HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans)
+};
+
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);