patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / fs / compat_ioctl.c
index 56ef913..fc3fb9f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/smp_lock.h>
 #include <linux/ioctl.h>
 #include <linux/if.h>
+#include <linux/if_bridge.h>
 #include <linux/slab.h>
 #include <linux/hdreg.h>
 #include <linux/raid/md.h>
@@ -134,7 +135,7 @@ static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
        set_fs (KERNEL_DS);
        err = sys_ioctl(fd, cmd, (unsigned long)&val);
        set_fs (old_fs);
-       if (!err && put_user(val, (u32 *)compat_ptr(arg)))
+       if (!err && put_user(val, (u32 __user *)compat_ptr(arg)))
                return -EFAULT;
        return err;
 }
@@ -142,7 +143,7 @@ static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
 static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        mm_segment_t old_fs = get_fs();
-       u32 *argptr = compat_ptr(arg);
+       u32 __user *argptr = compat_ptr(arg);
        int err;
        unsigned long val;
        
@@ -176,7 +177,7 @@ struct video_tuner32 {
        u16 mode, signal;
 };
 
-static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
+static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
 {
        int i;
 
@@ -192,7 +193,7 @@ static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
        return 0;
 }
 
-static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
+static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
 {
        int i;
 
@@ -213,13 +214,18 @@ struct video_buffer32 {
        compat_int_t height, width, depth, bytesperline;
 };
 
-static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
+static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
 {
        u32 tmp;
 
-       if(get_user(tmp, &up->base))
+       if (get_user(tmp, &up->base))
                return -EFAULT;
-       kp->base = compat_ptr(tmp);
+
+       /* This is actually a physical address stored
+        * as a void pointer.
+        */
+       kp->base = (void *)(unsigned long) tmp;
+
        __get_user(kp->height, &up->height);
        __get_user(kp->width, &up->width);
        __get_user(kp->depth, &up->depth);
@@ -227,7 +233,7 @@ static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up
        return 0;
 }
 
-static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
+static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
 {
        u32 tmp = (u32)((unsigned long)kp->base);
 
@@ -260,9 +266,9 @@ static void free_kvideo_clips(struct video_window *kp)
                kfree(cp);
 }
 
-static int get_video_window32(struct video_window *kp, struct video_window32 *up)
+static int get_video_window32(struct video_window *kp, struct video_window32 __user *up)
 {
-       struct video_clip32 *ucp;
+       struct video_clip32 __user *ucp;
        struct video_clip *kcp;
        int nclips, err, i;
        u32 tmp;
@@ -312,7 +318,7 @@ cleanup_and_err:
 }
 
 /* You get back everything except the clips... */
-static int put_video_window32(struct video_window *kp, struct video_window32 *up)
+static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
 {
        if(put_user(kp->x, &up->x))
                return -EFAULT;
@@ -343,7 +349,7 @@ static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
                unsigned long vx;
        } karg;
        mm_segment_t old_fs = get_fs();
-       void *up = compat_ptr(arg);
+       void __user *up = compat_ptr(arg);
        int err = 0;
 
        /* First, convert the command. */
@@ -373,7 +379,7 @@ static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
                break;
 
        case VIDIOCSFREQ:
-               err = get_user(karg.vx, (u32 *)up);
+               err = get_user(karg.vx, (u32 __user *)up);
                break;
        };
        if(err)
@@ -401,7 +407,7 @@ static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
                        break;
 
                case VIDIOCGFREQ:
-                       err = put_user(((u32)karg.vx), (u32 *)up);
+                       err = put_user(((u32)karg.vx), (u32 __user *)up);
                        break;
                };
        }
@@ -411,7 +417,7 @@ out:
 
 static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct compat_timeval *up = compat_ptr(arg);
+       struct compat_timeval __user *up = compat_ptr(arg);
        struct timeval ktv;
        mm_segment_t old_fs = get_fs();
        int err;
@@ -489,83 +495,79 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        struct ifconf32 ifc32;
        struct ifconf ifc;
-       struct ifreq32 *ifr32;
-       struct ifreq *ifr;
-       mm_segment_t old_fs;
+       struct ifconf __user *uifc;
+       struct ifreq32 __user *ifr32;
+       struct ifreq __user *ifr;
        unsigned int i, j;
        int err;
 
        if (copy_from_user(&ifc32, compat_ptr(arg), sizeof(struct ifconf32)))
                return -EFAULT;
 
-       if(ifc32.ifcbuf == 0) {
+       if (ifc32.ifcbuf == 0) {
                ifc32.ifc_len = 0;
                ifc.ifc_len = 0;
-               ifc.ifc_buf = NULL;
+               ifc.ifc_req = NULL;
+               uifc = compat_alloc_user_space(sizeof(struct ifconf));
        } else {
-               ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
+               size_t len =((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
                        sizeof (struct ifreq);
-               /* should the size be limited? -arnd */
-               ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
-               if (!ifc.ifc_buf)
-                       return -ENOMEM;
+               uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
+               ifc.ifc_len = len;
+               ifr = ifc.ifc_req = (void __user *)(uifc + 1);
+               ifr32 = compat_ptr(ifc32.ifcbuf);
+               for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
+                       if (copy_in_user(ifr, ifr32, sizeof(struct ifreq32)))
+                               return -EFAULT;
+                       ifr++;
+                       ifr32++; 
+               }
        }
+       if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
+               return -EFAULT;
+
+       err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc); 
+       if (err)
+               return err;
+
+       if (copy_from_user(&ifc, uifc, sizeof(struct ifconf))) 
+               return -EFAULT;
+
        ifr = ifc.ifc_req;
        ifr32 = compat_ptr(ifc32.ifcbuf);
-       for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
-               if (copy_from_user(ifr, ifr32, sizeof (struct ifreq32))) {
-                       kfree (ifc.ifc_buf);
+       for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
+            i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
+               if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32)))
                        return -EFAULT;
-               }
+               ifr32++;
                ifr++;
-               ifr32++; 
        }
-       old_fs = get_fs(); set_fs (KERNEL_DS);
-       err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc); 
-       set_fs (old_fs);
-       if (!err) {
-               ifr = ifc.ifc_req;
-               ifr32 = compat_ptr(ifc32.ifcbuf);
-               for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
-                    i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
-                       int k = copy_to_user(ifr32, ifr, sizeof (struct ifreq32));
-                       ifr32++;
-                       ifr++;
-                       if (k) {
-                               err = -EFAULT;
-                               break;
-                       }
-                      
-               }
-               if (!err) {
-                       if (ifc32.ifcbuf == 0) {
-                               /* Translate from 64-bit structure multiple to
-                                * a 32-bit one.
-                                */
-                               i = ifc.ifc_len;
-                               i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
-                               ifc32.ifc_len = i;
-                       } else {
-                               if (i <= ifc32.ifc_len)
-                                       ifc32.ifc_len = i;
-                               else
-                                       ifc32.ifc_len = i - sizeof (struct ifreq32);
-                       }
-                       if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32)))
-                               err = -EFAULT;
-               }
+
+       if (ifc32.ifcbuf == 0) {
+               /* Translate from 64-bit structure multiple to
+                * a 32-bit one.
+                */
+               i = ifc.ifc_len;
+               i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
+               ifc32.ifc_len = i;
+       } else {
+               if (i <= ifc32.ifc_len)
+                       ifc32.ifc_len = i;
+               else
+                       ifc32.ifc_len = i - sizeof (struct ifreq32);
        }
-       if(ifc.ifc_buf != NULL)
-               kfree (ifc.ifc_buf);
-       return err;
+       if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32)))
+               return -EFAULT;
+
+       return 0;
 }
 
 static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct ifreq *ifr;
-       struct ifreq32 *ifr32;
+       struct ifreq __user *ifr;
+       struct ifreq32 __user *ifr32;
        u32 data;
-       void *datap;
+       void __user *datap;
        
        ifr = compat_alloc_user_space(sizeof(*ifr));
        ifr32 = compat_ptr(arg);
@@ -586,12 +588,12 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        struct ifreq kifr;
-       struct ifreq *uifr;
-       struct ifreq32 *ifr32 = compat_ptr(arg);
+       struct ifreq __user *uifr;
+       struct ifreq32 __user *ifr32 = compat_ptr(arg);
        mm_segment_t old_fs;
        int err;
        u32 data;
-       void *datap;
+       void __user *datap;
 
        switch (cmd) {
        case SIOCBONDENSLAVE:
@@ -628,10 +630,10 @@ static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 
 int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct ifreq *u_ifreq64;
-       struct ifreq32 *u_ifreq32 = compat_ptr(arg);
+       struct ifreq __user *u_ifreq64;
+       struct ifreq32 __user *u_ifreq32 = compat_ptr(arg);
        char tmp_buf[IFNAMSIZ];
-       void *data64;
+       void __user *data64;
        u32 data32;
 
        if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
@@ -655,8 +657,8 @@ int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        struct ifreq ifr;
-       struct ifreq32 *uifr32;
-       struct ifmap32 *uifmap32;
+       struct ifreq32 __user *uifr32;
+       struct ifmap32 __user *uifmap32;
        mm_segment_t old_fs;
        int err;
        
@@ -760,7 +762,7 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
        struct socket *mysock = sockfd_lookup(fd, &ret);
 
        if (mysock && mysock->sk && mysock->sk->sk_family == AF_INET6) { /* ipv6 */
-               struct in6_rtmsg32 *ur6 = compat_ptr(arg);
+               struct in6_rtmsg32 __user *ur6 = compat_ptr(arg);
                ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst),
                        3 * sizeof(struct in6_addr));
                ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type));
@@ -773,7 +775,7 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
                
                r = (void *) &r6;
        } else { /* ipv4 */
-               struct rtentry32 *ur4 = compat_ptr(arg);
+               struct rtentry32 __user *ur4 = compat_ptr(arg);
                ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst),
                                        3 * sizeof(struct sockaddr));
                ret |= __get_user (r4.rt_flags, &(ur4->rt_flags));
@@ -815,7 +817,7 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        mm_segment_t old_fs = get_fs();
        struct hd_geometry geo;
-       struct hd_geometry32 *ugeo;
+       struct hd_geometry32 __user *ugeo;
        int err;
        
        set_fs (KERNEL_DS);
@@ -855,23 +857,11 @@ struct fb_cmap32 {
        compat_caddr_t  transp;
 };
 
-static int do_cmap_ptr(__u16 **ptr64, __u32 *ptr32)
-{
-       __u32 data;
-       void *datap;
-
-       if (get_user(data, ptr32))
-               return -EFAULT;
-       datap = compat_ptr(data);
-       if (put_user(datap, ptr64))
-               return -EFAULT;
-       return 0;
-}
-
 static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct fb_cmap *cmap;
-       struct fb_cmap32 *cmap32;
+       struct fb_cmap __user *cmap;
+       struct fb_cmap32 __user *cmap32;
+       __u32 data;
        int err;
 
        cmap = compat_alloc_user_space(sizeof(*cmap));
@@ -880,10 +870,14 @@ static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg)
        if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
                return -EFAULT;
 
-       if (do_cmap_ptr(&cmap->red, &cmap32->red) ||
-           do_cmap_ptr(&cmap->green, &cmap32->green) ||
-           do_cmap_ptr(&cmap->blue, &cmap32->blue) ||
-           do_cmap_ptr(&cmap->transp, &cmap32->transp))
+       if (get_user(data, &cmap32->red) ||
+           put_user(compat_ptr(data), &cmap->red) ||
+           get_user(data, &cmap32->green) ||
+           put_user(compat_ptr(data), &cmap->green) ||
+           get_user(data, &cmap32->blue) ||
+           put_user(compat_ptr(data), &cmap->blue) ||
+           get_user(data, &cmap32->transp) ||
+           put_user(compat_ptr(data), &cmap->transp))
                return -EFAULT;
 
        err = sys_ioctl(fd, cmd, (unsigned long) cmap);
@@ -898,7 +892,7 @@ static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg)
 }
 
 static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
-                                 struct fb_fix_screeninfo32 *fix32)
+                                 struct fb_fix_screeninfo32 __user *fix32)
 {
        __u32 data;
        int err;
@@ -932,7 +926,7 @@ static int fb_get_fscreeninfo(unsigned int fd, unsigned int cmd, unsigned long a
 {
        mm_segment_t old_fs;
        struct fb_fix_screeninfo fix;
-       struct fb_fix_screeninfo32 *fix32;
+       struct fb_fix_screeninfo32 __user *fix32;
        int err;
 
        fix32 = compat_ptr(arg);
@@ -981,7 +975,7 @@ static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg
 {
        mm_segment_t old_fs = get_fs();
        unsigned long kval;
-       unsigned int *uvp;
+       unsigned int __user *uvp;
        int error;
 
        set_fs(KERNEL_DS);
@@ -1028,10 +1022,10 @@ typedef struct sg_iovec32 {
        compat_uint_t iov_len;
 } sg_iovec32_t;
 
-static int sg_build_iovec(sg_io_hdr_t *sgio, void *dxferp, u16 iovec_count)
+static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iovec_count)
 {
-       sg_iovec_t *iov = (sg_iovec_t *) (sgio + 1);
-       sg_iovec32_t *iov32 = dxferp;
+       sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio + 1);
+       sg_iovec32_t __user *iov32 = dxferp;
        int i;
 
        for (i = 0; i < iovec_count; i++) {
@@ -1044,17 +1038,18 @@ static int sg_build_iovec(sg_io_hdr_t *sgio, void *dxferp, u16 iovec_count)
                        return -EFAULT;
        }
 
-       sgio->dxferp = iov; /* FIXME: dereferencing user pointer? */
+       if (put_user(iov, &sgio->dxferp))
+               return -EFAULT;
        return 0;
 }
 
 static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       sg_io_hdr_t *sgio;
-       sg_io_hdr32_t *sgio32;
+       sg_io_hdr_t __user *sgio;
+       sg_io_hdr32_t __user *sgio32;
        u16 iovec_count;
        u32 data;
-       void *dxferp;
+       void __user *dxferp;
        int err;
 
        sgio32 = compat_ptr(arg);
@@ -1062,12 +1057,9 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                return -EFAULT;
 
        {
-               void *new, *top;
-
-               top = compat_alloc_user_space(0);
-               new = compat_alloc_user_space(sizeof(sg_io_hdr_t) +
-                                      (iovec_count *
-                                       sizeof(sg_iovec_t)));
+               void __user *top = compat_alloc_user_space(0);
+               void __user *new = compat_alloc_user_space(sizeof(sg_io_hdr_t) +
+                                      (iovec_count * sizeof(sg_iovec_t)));
                if (new > top)
                        return -EINVAL;
 
@@ -1094,7 +1086,8 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
        }
 
        {
-               unsigned char *cmdp, *sbp;
+               unsigned char __user *cmdp;
+               unsigned char __user *sbp;
 
                if (get_user(data, &sgio32->cmdp))
                        return -EFAULT;
@@ -1127,7 +1120,7 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
        err = sys_ioctl(fd, cmd, (unsigned long) sgio);
 
        if (err >= 0) {
-               void *datap;
+               void __user *datap;
 
                if (copy_in_user(&sgio32->pack_id, &sgio->pack_id,
                                 sizeof(int)) ||
@@ -1154,9 +1147,9 @@ struct sock_fprog32 {
 
 static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct sock_fprog32 *u_fprog32 = compat_ptr(arg);
-       struct sock_fprog *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog));
-       void *fptr64;
+       struct sock_fprog32 __user *u_fprog32 = compat_ptr(arg);
+       struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog));
+       void __user *fptr64;
        u32 fptr32;
        u16 flen;
 
@@ -1193,8 +1186,8 @@ struct ppp_idle32 {
 
 static int ppp_gidle(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct ppp_idle *idle;
-       struct ppp_idle32 *idle32;
+       struct ppp_idle __user *idle;
+       struct ppp_idle32 __user *idle32;
        __kernel_time_t xmit, recv;
        int err;
 
@@ -1215,10 +1208,10 @@ static int ppp_gidle(unsigned int fd, unsigned int cmd, unsigned long arg)
 
 static int ppp_scompress(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct ppp_option_data *odata;
-       struct ppp_option_data32 *odata32;
+       struct ppp_option_data __user *odata;
+       struct ppp_option_data32 __user *odata32;
        __u32 data;
-       void *datap;
+       void __user *datap;
 
        odata = compat_alloc_user_space(sizeof(*odata));
        odata32 = compat_ptr(arg);
@@ -1310,11 +1303,11 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        mm_segment_t old_fs = get_fs();
        struct mtconfiginfo info;
-       struct mtconfiginfo32 *uinfo32;
+       struct mtconfiginfo32 __user *uinfo32;
        struct mtget get;
-       struct mtget32 *umget32;
+       struct mtget32 __user *umget32;
        struct mtpos pos;
-       struct mtpos32 *upos32;
+       struct mtpos32 __user *upos32;
        unsigned long kcmd;
        void *karg;
        int err = 0;
@@ -1344,7 +1337,7 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                err |= __get_user(info.debug, &uinfo32->debug);
                err |= __copy_from_user((char *)&info.debug
                                     + sizeof(info.debug),
-                                    (char *)&uinfo32->debug
+                                    (char __user *)&uinfo32->debug
                                     + sizeof(uinfo32->debug), sizeof(__u32));
                if (err)
                        return -EFAULT;
@@ -1387,7 +1380,7 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                err |= __put_user(info.dmanr, &uinfo32->dmanr);
                err |= __put_user(info.port, &uinfo32->port);
                err |= __put_user(info.debug, &uinfo32->debug);
-               err |= __copy_to_user((char *)&uinfo32->debug
+               err |= __copy_to_user((char __user *)&uinfo32->debug
                                           + sizeof(uinfo32->debug),
                                           (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
                break;
@@ -1418,10 +1411,10 @@ struct cdrom_generic_command32 {
   
 static int cdrom_do_read_audio(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct cdrom_read_audio *cdread_audio;
-       struct cdrom_read_audio32 *cdread_audio32;
+       struct cdrom_read_audio __user *cdread_audio;
+       struct cdrom_read_audio32 __user *cdread_audio32;
        __u32 data;
-       void *datap;
+       void __user *datap;
 
        cdread_audio = compat_alloc_user_space(sizeof(*cdread_audio));
        cdread_audio32 = compat_ptr(arg);
@@ -1441,24 +1434,11 @@ static int cdrom_do_read_audio(unsigned int fd, unsigned int cmd, unsigned long
        return sys_ioctl(fd, cmd, (unsigned long) cdread_audio);
 }
 
-static int __cgc_do_ptr(void **ptr64, __u32 *ptr32)
-{
-       u32 data;
-       void *datap;
-
-       if (get_user(data, ptr32))
-               return -EFAULT;
-       datap = compat_ptr(data);
-       if (put_user(datap, ptr64))
-               return -EFAULT;
-
-       return 0;
-}
-
 static int cdrom_do_generic_command(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct cdrom_generic_command *cgc;
-       struct cdrom_generic_command32 *cgc32;
+       struct cdrom_generic_command __user *cgc;
+       struct cdrom_generic_command32 __user *cgc32;
+       u32 data;
        unsigned char dir;
        int itmp;
 
@@ -1466,25 +1446,20 @@ static int cdrom_do_generic_command(unsigned int fd, unsigned int cmd, unsigned
        cgc32 = compat_ptr(arg);
 
        if (copy_in_user(&cgc->cmd, &cgc32->cmd, sizeof(cgc->cmd)) ||
-           __cgc_do_ptr((void **) &cgc->buffer, &cgc32->buffer) ||
+           get_user(data, &cgc32->buffer) ||
+           put_user(compat_ptr(data), &cgc->buffer) ||
            copy_in_user(&cgc->buflen, &cgc32->buflen,
                         (sizeof(unsigned int) + sizeof(int))) ||
-           __cgc_do_ptr((void **) &cgc->sense, &cgc32->sense))
-               return -EFAULT;
-
-       if (get_user(dir, &cgc32->data_direction) ||
-           put_user(dir, &cgc->data_direction))
-               return -EFAULT;
-
-       if (get_user(itmp, &cgc32->quiet) ||
-           put_user(itmp, &cgc->quiet))
-               return -EFAULT;
-
-       if (get_user(itmp, &cgc32->timeout) ||
-           put_user(itmp, &cgc->timeout))
-               return -EFAULT;
-
-       if (__cgc_do_ptr(&cgc->reserved[0], &cgc32->reserved[0]))
+           get_user(data, &cgc32->sense) ||
+           put_user(compat_ptr(data), &cgc->sense) ||
+           get_user(dir, &cgc32->data_direction) ||
+           put_user(dir, &cgc->data_direction) ||
+           get_user(itmp, &cgc32->quiet) ||
+           put_user(itmp, &cgc->quiet) ||
+           get_user(itmp, &cgc32->timeout) ||
+           put_user(itmp, &cgc->timeout) ||
+           get_user(data, &cgc32->reserved[0]) ||
+           put_user(compat_ptr(data), &cgc->reserved[0]))
                return -EFAULT;
 
        return sys_ioctl(fd, cmd, (unsigned long) cgc);
@@ -1537,7 +1512,7 @@ static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        mm_segment_t old_fs = get_fs();
        struct loop_info l;
-       struct loop_info32 *ul;
+       struct loop_info32 __user *ul;
        int err = -EINVAL;
 
        ul = compat_ptr(arg);
@@ -1619,19 +1594,14 @@ struct consolefontdesc32 {
 
 static int do_fontx_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
 {
-       struct consolefontdesc cfdarg;
+       struct consolefontdesc32 __user *user_cfd = compat_ptr(arg);
        struct console_font_op op;
-       struct consolefontdesc32 *user_cfd = compat_ptr(arg);
+       compat_caddr_t data;
        int i, perm;
 
        perm = vt_check(file);
        if (perm < 0) return perm;
        
-       if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32)))
-               return -EFAULT;
-       
-       cfdarg.chardata = compat_ptr(((struct consolefontdesc32 *)&cfdarg)->chardata);
-       
        switch (cmd) {
        case PIO_FONTX:
                if (!perm)
@@ -1639,26 +1609,30 @@ static int do_fontx_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
                op.op = KD_FONT_OP_SET;
                op.flags = 0;
                op.width = 8;
-               op.height = cfdarg.charheight;
-               op.charcount = cfdarg.charcount;
-               op.data = cfdarg.chardata;
+               if (get_user(op.height, &user_cfd->charheight) ||
+                   get_user(op.charcount, &user_cfd->charcount) ||
+                   get_user(data, &user_cfd->chardata))
+                       return -EFAULT;
+               op.data = compat_ptr(data);
                return con_font_op(fg_console, &op);
        case GIO_FONTX:
-               if (!cfdarg.chardata)
-                       return 0;
                op.op = KD_FONT_OP_GET;
                op.flags = 0;
                op.width = 8;
-               op.height = cfdarg.charheight;
-               op.charcount = cfdarg.charcount;
-               op.data = cfdarg.chardata;
+               if (get_user(op.height, &user_cfd->charheight) ||
+                   get_user(op.charcount, &user_cfd->charcount) ||
+                   get_user(data, &user_cfd->chardata))
+                       return -EFAULT;
+               if (!data)
+                       return 0;
+               op.data = compat_ptr(data);
                i = con_font_op(fg_console, &op);
                if (i)
                        return i;
-               cfdarg.charheight = op.height;
-               cfdarg.charcount = op.charcount;
-               ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata;
-               if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32)))
+               if (put_user(op.height, &user_cfd->charheight) ||
+                   put_user(op.charcount, &user_cfd->charcount) ||
+                   put_user((compat_caddr_t)(unsigned long)op.data,
+                               &user_cfd->chardata))
                        return -EFAULT;
                return 0;
        }
@@ -1676,13 +1650,13 @@ struct console_font_op32 {
 static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
 {
        struct console_font_op op;
-       struct console_font_op32 *fontop = compat_ptr(arg);
+       struct console_font_op32 __user *fontop = compat_ptr(arg);
        int perm = vt_check(file), i;
        struct vt_struct *vt;
        
        if (perm < 0) return perm;
        
-       if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32)))
+       if (copy_from_user(&op, fontop, sizeof(struct console_font_op32)))
                return -EFAULT;
        if (!perm && op.op != KD_FONT_OP_GET)
                return -EPERM;
@@ -1692,7 +1666,7 @@ static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
        i = con_font_op(vt->vc_num, &op);
        if (i) return i;
        ((struct console_font_op32 *)&op)->data = (unsigned long)op.data;
-       if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32)))
+       if (copy_to_user(fontop, &op, sizeof(struct console_font_op32)))
                return -EFAULT;
        return 0;
 }
@@ -1705,7 +1679,7 @@ struct unimapdesc32 {
 static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
 {
        struct unimapdesc32 tmp;
-       struct unimapdesc32 *user_ud = compat_ptr(arg);
+       struct unimapdesc32 __user *user_ud = compat_ptr(arg);
        int perm = vt_check(file);
        
        if (perm < 0) return perm;
@@ -1736,7 +1710,7 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long a
        set_fs(old_fs);
 
        if (err >= 0)
-               err = put_user(kuid, (compat_uid_t *)compat_ptr(arg));
+               err = put_user(kuid, (compat_uid_t __user *)compat_ptr(arg));
 
        return err;
 }
@@ -1798,10 +1772,10 @@ static struct {
 
 static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct atm_iobuf   *iobuf;
-       struct atm_iobuf32 *iobuf32;
+       struct atm_iobuf   __user *iobuf;
+       struct atm_iobuf32 __user *iobuf32;
        u32 data;
-       void *datap;
+       void __user *datap;
        int len, err;
 
        iobuf = compat_alloc_user_space(sizeof(*iobuf));
@@ -1828,10 +1802,10 @@ static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
 
 static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-        struct atmif_sioc   *sioc;
-       struct atmif_sioc32 *sioc32;
+        struct atmif_sioc   __user *sioc;
+       struct atmif_sioc32 __user *sioc32;
        u32 data;
-       void *datap;
+       void __user *datap;
        int err;
         
        sioc = compat_alloc_user_space(sizeof(*sioc));
@@ -1926,39 +1900,24 @@ struct blkpg_ioctl_arg32 {
 
 static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct blkpg_ioctl_arg a;
-       struct blkpg_ioctl_arg32 *ua32;
-       struct blkpg_partition p;
-       struct blkpg_partition *up32;
+       struct blkpg_ioctl_arg32 __user *ua32 = compat_ptr(arg);
+       struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a));
        compat_caddr_t udata;
+       compat_int_t n;
        int err;
-       mm_segment_t old_fs = get_fs();
        
-       ua32 = compat_ptr(arg);
-       err = get_user(a.op, &ua32->op);
-       err |= __get_user(a.flags, &ua32->flags);
-       err |= __get_user(a.datalen, &ua32->datalen);
-       err |= __get_user(udata, &ua32->data);
-       up32 = compat_ptr(udata);
+       err = get_user(n, &ua32->op);
+       err |= put_user(n, &a->op);
+       err |= get_user(n, &ua32->flags);
+       err |= put_user(n, &a->flags);
+       err |= get_user(n, &ua32->datalen);
+       err |= put_user(n, &a->datalen);
+       err |= get_user(udata, &ua32->data);
+       err |= put_user(compat_ptr(udata), &a->data);
        if (err)
                return err;
 
-       switch (a.op) {
-       case BLKPG_ADD_PARTITION:
-       case BLKPG_DEL_PARTITION:
-               if (a.datalen < sizeof(struct blkpg_partition))
-                       return -EINVAL;
-                if (copy_from_user(&p, up32, sizeof(struct blkpg_partition)))
-                       return -EFAULT;
-               a.data = &p;
-               set_fs (KERNEL_DS);
-               err = sys_ioctl(fd, cmd, (unsigned long)&a);
-               set_fs (old_fs);
-               break;
-       default:
-               return -EINVAL;
-       }                                        
-       return err;
+       return sys_ioctl(fd, cmd, (unsigned long)a);
 }
 
 static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -2127,7 +2086,7 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                case FDGETPRM32:
                {
                        compat_uptr_t name;
-                       struct floppy_struct32 *uf;
+                       struct floppy_struct32 __user *uf;
                        struct floppy_struct *f;
 
                        uf = compat_ptr(arg);
@@ -2156,7 +2115,7 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                case FDSETDRVPRM32:
                case FDGETDRVPRM32:
                {
-                       struct floppy_drive_params32 *uf;
+                       struct floppy_drive_params32 __user *uf;
                        struct floppy_drive_params *f;
 
                        uf = compat_ptr(arg);
@@ -2218,22 +2177,23 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                case FDGETPRM32:
                {
                        struct floppy_struct *f = karg;
+                       struct floppy_struct32 __user *uf = compat_ptr(arg);
 
-                       err = __put_user(f->size, &((struct floppy_struct32 *)arg)->size);
-                       err |= __put_user(f->sect, &((struct floppy_struct32 *)arg)->sect);
-                       err |= __put_user(f->head, &((struct floppy_struct32 *)arg)->head);
-                       err |= __put_user(f->track, &((struct floppy_struct32 *)arg)->track);
-                       err |= __put_user(f->stretch, &((struct floppy_struct32 *)arg)->stretch);
-                       err |= __put_user(f->gap, &((struct floppy_struct32 *)arg)->gap);
-                       err |= __put_user(f->rate, &((struct floppy_struct32 *)arg)->rate);
-                       err |= __put_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
-                       err |= __put_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
-                       err |= __put_user((u64)f->name, (compat_caddr_t*)&((struct floppy_struct32 *)arg)->name);
+                       err = __put_user(f->size, &uf->size);
+                       err |= __put_user(f->sect, &uf->sect);
+                       err |= __put_user(f->head, &uf->head);
+                       err |= __put_user(f->track, &uf->track);
+                       err |= __put_user(f->stretch, &uf->stretch);
+                       err |= __put_user(f->gap, &uf->gap);
+                       err |= __put_user(f->rate, &uf->rate);
+                       err |= __put_user(f->spec1, &uf->spec1);
+                       err |= __put_user(f->fmt_gap, &uf->fmt_gap);
+                       err |= __put_user((u64)f->name, (compat_caddr_t __user *)&uf->name);
                        break;
                }
                case FDGETDRVPRM32:
                {
-                       struct floppy_drive_params32 *uf;
+                       struct floppy_drive_params32 __user *uf;
                        struct floppy_drive_params *f = karg;
 
                        uf = compat_ptr(arg);
@@ -2261,7 +2221,7 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                case FDGETDRVSTAT32:
                case FDPOLLDRVSTAT32:
                {
-                       struct floppy_drive_struct32 *uf;
+                       struct floppy_drive_struct32 __user *uf;
                        struct floppy_drive_struct *f = karg;
 
                        uf = compat_ptr(arg);
@@ -2284,7 +2244,7 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                }
                case FDGETFDCSTAT32:
                {
-                       struct floppy_fdc_state32 *uf;
+                       struct floppy_fdc_state32 __user *uf;
                        struct floppy_fdc_state *f = karg;
 
                        uf = compat_ptr(arg);
@@ -2294,7 +2254,7 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                        err |= __put_user(f->version, &uf->version);
                        err |= __put_user(f->dor, &uf->dor);
                        err |= __put_user(f->address, &uf->address);
-                       err |= __copy_to_user((char *)&uf->address + sizeof(uf->address),
+                       err |= __copy_to_user((char __user *)&uf->address + sizeof(uf->address),
                                           (char *)&f->address + sizeof(f->address), sizeof(int));
                        err |= __put_user(f->driver_version, &uf->driver_version);
                        err |= __copy_to_user(uf->track, f->track, sizeof(f->track));
@@ -2302,7 +2262,7 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
                }
                case FDWERRORGET32:
                {
-                       struct floppy_write_errors32 *uf;
+                       struct floppy_write_errors32 __user *uf;
                        struct floppy_write_errors *f = karg;
 
                        uf = compat_ptr(arg);
@@ -2335,10 +2295,10 @@ struct mtd_oob_buf32 {
 
 static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct mtd_oob_buf      *buf = compat_alloc_user_space(sizeof(*buf));
-       struct mtd_oob_buf32    *buf32 = compat_ptr(arg);
+       struct mtd_oob_buf __user *buf = compat_alloc_user_space(sizeof(*buf));
+       struct mtd_oob_buf32 __user *buf32 = compat_ptr(arg);
        u32 data;
-       char *datap;
+       char __user *datap;
        unsigned int real_cmd;
        int err;
 
@@ -2368,7 +2328,7 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
 #define        VFAT_IOCTL_READDIR_SHORT32      _IOR('r', 2, struct compat_dirent[2])
 
 static long
-put_dirent32 (struct dirent *d, struct compat_dirent *d32)
+put_dirent32 (struct dirent *d, struct compat_dirent __user *d32)
 {
         int ret;
 
@@ -2385,6 +2345,7 @@ put_dirent32 (struct dirent *d, struct compat_dirent *d32)
 
 static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg)
 {
+       struct compat_dirent __user *p = compat_ptr(arg);
        int ret;
        mm_segment_t oldfs = get_fs();
        struct dirent d[2];
@@ -2403,8 +2364,8 @@ static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg)
        ret = sys_ioctl(fd,cmd,(unsigned long)&d);
        set_fs(oldfs);
        if (ret >= 0) {
-               ret |= put_dirent32(&d[0], (struct compat_dirent *)compat_ptr(arg));
-               ret |= put_dirent32(&d[1], ((struct compat_dirent *)compat_ptr(arg)) + 1);
+               ret |= put_dirent32(&d[0], p);
+               ret |= put_dirent32(&d[1], p + 1);
        }
        return ret;
 }
@@ -2426,28 +2387,22 @@ struct raw32_config_request
         __u64   block_minor;
 } __attribute__((packed));
 
-static int get_raw32_request(struct raw_config_request *req, struct raw32_config_request *user_req)
+static int get_raw32_request(struct raw_config_request *req, struct raw32_config_request __user *user_req)
 {
-        __u32   lo_maj, hi_maj, lo_min, hi_min;
         int ret;
 
         if ((ret = verify_area(VERIFY_READ, user_req,
                                sizeof(struct raw32_config_request))))
                 return ret;
 
-        __get_user(req->raw_minor, &user_req->raw_minor);
-        __get_user(lo_maj, (__u32*)&user_req->block_major);
-        __get_user(hi_maj, ((__u32*)(&user_req->block_major) + 1));
-        __get_user(lo_min, (__u32*)&user_req->block_minor);
-        __get_user(hi_min, ((__u32*)(&user_req->block_minor) + 1));
+        ret = __get_user(req->raw_minor, &user_req->raw_minor);
+        ret |= __get_user(req->block_major, &user_req->block_major);
+        ret |= __get_user(req->block_minor, &user_req->block_minor);
 
-        req->block_major = lo_maj | (((__u64)hi_maj) << 32);
-        req->block_minor = lo_min | (((__u64)hi_min) << 32);
-
-        return ret;
+        return ret ? -EFAULT : 0;
 }
 
-static int set_raw32_request(struct raw_config_request *req, struct raw32_config_request *user_req)
+static int set_raw32_request(struct raw_config_request *req, struct raw32_config_request __user *user_req)
 {
        int ret;
 
@@ -2455,13 +2410,11 @@ static int set_raw32_request(struct raw_config_request *req, struct raw32_config
                                sizeof(struct raw32_config_request))))
                 return ret;
 
-        __put_user(req->raw_minor, &user_req->raw_minor);
-        __put_user((__u32)(req->block_major), (__u32*)&user_req->block_major);
-        __put_user((__u32)(req->block_major >> 32), ((__u32*)(&user_req->block_major) + 1));
-        __put_user((__u32)(req->block_minor), (__u32*)&user_req->block_minor);
-        __put_user((__u32)(req->block_minor >> 32), ((__u32*)(&user_req->block_minor) + 1));
+        ret = __put_user(req->raw_minor, &user_req->raw_minor);
+        ret |= __put_user(req->block_major, &user_req->block_major);
+        ret |= __put_user(req->block_minor, &user_req->block_minor);
 
-        return ret;
+        return ret ? -EFAULT : 0;
 }
 
 static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
@@ -2472,7 +2425,7 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
         case RAW_SETBIND:
         case RAW_GETBIND: {
                 struct raw_config_request req;
-                struct raw32_config_request *user_req = compat_ptr(arg);
+                struct raw32_config_request __user *user_req = compat_ptr(arg);
                 mm_segment_t oldfs = get_fs();
 
                 if ((ret = get_raw32_request(&req, user_req)))
@@ -2520,7 +2473,7 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
 {
         typedef struct serial_struct SS;
         typedef struct serial_struct32 SS32;
-        struct serial_struct32 *ss32 = compat_ptr(arg);
+        struct serial_struct32 __user *ss32 = compat_ptr(arg);
         int err;
         struct serial_struct ss;
         mm_segment_t oldseg = get_fs();
@@ -2568,10 +2521,11 @@ struct usbdevfs_ctrltransfer32 {
 static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
         struct usbdevfs_ctrltransfer kctrl;
-        struct usbdevfs_ctrltransfer32 *uctrl;
+        struct usbdevfs_ctrltransfer32 __user *uctrl;
         mm_segment_t old_fs;
         __u32 udata;
-        void *uptr, *kptr;
+        void __user *uptr;
+        void *kptr;
         int err;
 
         uctrl = compat_ptr(arg);
@@ -2629,10 +2583,11 @@ struct usbdevfs_bulktransfer32 {
 static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
         struct usbdevfs_bulktransfer kbulk;
-        struct usbdevfs_bulktransfer32 *ubulk;
+        struct usbdevfs_bulktransfer32 __user *ubulk;
         mm_segment_t old_fs;
         __u32 udata;
-        void *uptr, *kptr;
+        void __user *uptr;
+        void *kptr;
         int err;
 
        ubulk = compat_ptr(arg);
@@ -2895,7 +2850,7 @@ static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long
         set_fs(old_fs);
 
         if (err >= 0 &&
-            put_user((u32)(u64)kptr, (u32 *)compat_ptr(arg)))
+            put_user((u32)(u64)kptr, (u32 __user *)compat_ptr(arg)))
                 err = -EFAULT;
 
         return err;
@@ -2911,7 +2866,7 @@ struct usbdevfs_disconnectsignal32 {
 static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
         struct usbdevfs_disconnectsignal kdis;
-        struct usbdevfs_disconnectsignal32 *udis;
+        struct usbdevfs_disconnectsignal32 __user *udis;
         mm_segment_t old_fs;
         u32 uctx;
         int err;
@@ -2957,10 +2912,10 @@ struct i2c_smbus_ioctl_data32 {
 
 static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct i2c_rdwr_ioctl_data      *tdata;
-       struct i2c_rdwr_ioctl_data32    *udata;
-       struct i2c_msg                  *tmsgs;
-       struct i2c_msg32                *umsgs;
+       struct i2c_rdwr_ioctl_data      __user *tdata;
+       struct i2c_rdwr_ioctl_data32    __user *udata;
+       struct i2c_msg                  __user *tmsgs;
+       struct i2c_msg32                __user *umsgs;
        compat_caddr_t                  datap;
        int                             nmsgs, i;
 
@@ -2970,7 +2925,7 @@ static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
        if (verify_area(VERIFY_WRITE, tdata, sizeof(*tdata)))
                return -EFAULT;
 
-       udata = (struct i2c_rdwr_ioctl_data32 *)compat_ptr(arg);
+       udata = compat_ptr(arg);
        if (verify_area(VERIFY_READ, udata, sizeof(*udata)))
                return -EFAULT;
        if (__get_user(nmsgs, &udata->nmsgs) || __put_user(nmsgs, &tdata->nmsgs))
@@ -2979,7 +2934,7 @@ static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
                return -EINVAL;
        if (__get_user(datap, &udata->msgs))
                return -EFAULT;
-       umsgs = (struct i2c_msg32 *)compat_ptr(datap);
+       umsgs = compat_ptr(datap);
        if (verify_area(VERIFY_READ, umsgs, sizeof(struct i2c_msg) * nmsgs))
                return -EFAULT;
 
@@ -3004,8 +2959,8 @@ static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
 
 static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct i2c_smbus_ioctl_data     *tdata;
-       struct i2c_smbus_ioctl_data32   *udata;
+       struct i2c_smbus_ioctl_data     __user *tdata;
+       struct i2c_smbus_ioctl_data32   __user *udata;
        compat_caddr_t                  datap;
 
        tdata = compat_alloc_user_space(sizeof(*tdata));
@@ -3014,7 +2969,7 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long a
        if (verify_area(VERIFY_WRITE, tdata, sizeof(*tdata)))
                return -EFAULT;
 
-       udata = (struct i2c_smbus_ioctl_data32 *)compat_ptr(arg);
+       udata = compat_ptr(arg);
        if (verify_area(VERIFY_READ, udata, sizeof(*udata)))
                return -EFAULT;
 
@@ -3037,14 +2992,15 @@ struct compat_iw_point {
 
 static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct iwreq *iwr, *iwr_u;
-       struct iw_point *iwp;
-       struct compat_iw_point *iwp_u;
+       struct iwreq __user *iwr;
+       struct iwreq __user *iwr_u;
+       struct iw_point __user *iwp;
+       struct compat_iw_point __user *iwp_u;
        compat_caddr_t pointer;
        __u16 length, flags;
 
-       iwr_u = (struct iwreq *) compat_ptr(arg);
-       iwp_u = (struct compat_iw_point *) &iwr_u->u.data;
+       iwr_u = compat_ptr(arg);
+       iwp_u = (struct compat_iw_point __user *) &iwr_u->u.data;
        iwr = compat_alloc_user_space(sizeof(*iwr));
        if (iwr == NULL)
                return -ENOMEM;
@@ -3072,20 +3028,208 @@ static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
        return sys_ioctl(fd, cmd, (unsigned long) iwr);
 }
 
-/* Emulate old style bridge ioctls */
-static int do_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
+ * for some operations; this forces use of the newer bridge-utils that
+ * use compatiable ioctls
+ */
+static int old_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        u32 tmp;
-       unsigned long *argbuf = compat_alloc_user_space(3 * sizeof(unsigned long)); 
-       int i;  
-       for (i = 0; i < 3; i++) {
-               if (get_user(tmp, i + ((u32 *)arg)) ||
-                   put_user(tmp, i + argbuf))
-                       return -EFAULT;
+
+       if (get_user(tmp, (u32 __user *) arg))
+               return -EFAULT;
+       if (tmp == BRCTL_GET_VERSION)
+               return BRCTL_VERSION + 1;
+       return -EINVAL;
+}
+
+#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
+struct ncp_ioctl_request_32 {
+       u32 function;
+       u32 size;
+       compat_caddr_t data;
+};
+
+struct ncp_fs_info_v2_32 {
+       s32 version;
+       u32 mounted_uid;
+       u32 connection;
+       u32 buffer_size;
+
+       u32 volume_number;
+       u32 directory_id;
+
+       u32 dummy1;
+       u32 dummy2;
+       u32 dummy3;
+};
+
+struct ncp_objectname_ioctl_32
+{
+       s32             auth_type;
+       u32             object_name_len;
+       compat_caddr_t  object_name;    /* an userspace data, in most cases user name */
+};
+
+struct ncp_privatedata_ioctl_32
+{
+       u32             len;
+       compat_caddr_t  data;           /* ~1000 for NDS */
+};
+
+#define        NCP_IOC_NCPREQUEST_32           _IOR('n', 1, struct ncp_ioctl_request_32)
+#define NCP_IOC_GETMOUNTUID2_32                _IOW('n', 2, u32)
+#define NCP_IOC_GET_FS_INFO_V2_32      _IOWR('n', 4, struct ncp_fs_info_v2_32)
+#define NCP_IOC_GETOBJECTNAME_32       _IOWR('n', 9, struct ncp_objectname_ioctl_32)
+#define NCP_IOC_SETOBJECTNAME_32       _IOR('n', 9, struct ncp_objectname_ioctl_32)
+#define NCP_IOC_GETPRIVATEDATA_32      _IOWR('n', 10, struct ncp_privatedata_ioctl_32)
+#define NCP_IOC_SETPRIVATEDATA_32      _IOR('n', 10, struct ncp_privatedata_ioctl_32)
+
+static int do_ncp_ncprequest(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       struct ncp_ioctl_request_32 n32;
+       struct ncp_ioctl_request __user *p = compat_alloc_user_space(sizeof(*p));
+
+       if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32)) ||
+           put_user(n32.function, &p->function) ||
+           put_user(n32.size, &p->size) ||
+           put_user(compat_ptr(n32.data), &p->data))
+               return -EFAULT;
+
+       return sys_ioctl(fd, NCP_IOC_NCPREQUEST, (unsigned long)p);
+}
+
+static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       mm_segment_t old_fs = get_fs();
+       __kernel_uid_t kuid;
+       int err;
+
+       cmd = NCP_IOC_GETMOUNTUID2;
+
+       set_fs(KERNEL_DS);
+       err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
+       set_fs(old_fs);
+
+       if (!err)
+               err = put_user(kuid,
+                              (unsigned int __user *) compat_ptr(arg));
+
+       return err;
+}
+
+static int do_ncp_getfsinfo2(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       mm_segment_t old_fs = get_fs();
+       struct ncp_fs_info_v2_32 n32;
+       struct ncp_fs_info_v2 n;
+       int err;
+
+       if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32)))
+               return -EFAULT;
+       if (n32.version != NCP_GET_FS_INFO_VERSION_V2)
+               return -EINVAL;
+       n.version = NCP_GET_FS_INFO_VERSION_V2;
+
+       set_fs(KERNEL_DS);
+       err = sys_ioctl(fd, NCP_IOC_GET_FS_INFO_V2, (unsigned long)&n);
+       set_fs(old_fs);
+
+       if (!err) {
+               n32.version = n.version;
+               n32.mounted_uid = n.mounted_uid;
+               n32.connection = n.connection;
+               n32.buffer_size = n.buffer_size;
+               n32.volume_number = n.volume_number;
+               n32.directory_id = n.directory_id;
+               n32.dummy1 = n.dummy1;
+               n32.dummy2 = n.dummy2;
+               n32.dummy3 = n.dummy3;
+               err = copy_to_user(compat_ptr(arg), &n32, sizeof(n32)) ? -EFAULT : 0;
        }
-       return sys_ioctl(fd, cmd, (unsigned long)argbuf);
+       return err;
 }
 
+static int do_ncp_getobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg);
+       struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p));
+       s32 auth_type;
+       u32 name_len;
+       int err;
+
+       if (copy_from_user(&n32, p32, sizeof(n32)) ||
+           put_user(n32.object_name_len, &p->object_name_len) ||
+           put_user(compat_ptr(n32.object_name), &p->object_name))
+               return -EFAULT;
+
+       err = sys_ioctl(fd, NCP_IOC_GETOBJECTNAME, (unsigned long)p);
+        if (err)
+               return err;
+
+       if (get_user(auth_type, &p->auth_type) ||
+           put_user(auth_type, &p32->auth_type) ||
+           get_user(name_len, &p->object_name_len) ||
+           put_user(name_len, &p32->object_name_len))
+               return -EFAULT;
+
+       return 0;
+}
+
+static int do_ncp_setobjectname(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg);
+       struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p));
+
+       if (copy_from_user(&n32, p32, sizeof(n32)) ||
+           put_user(n32.auth_type, &p->auth_type) ||
+           put_user(n32.object_name_len, &p->object_name_len) ||
+           put_user(compat_ptr(n32.object_name), &p->object_name))
+               return -EFAULT;
+
+       return sys_ioctl(fd, NCP_IOC_SETOBJECTNAME, (unsigned long)p);
+}
+
+static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       struct ncp_privatedata_ioctl_32 n32, __user *p32 = compat_ptr(arg);
+       struct ncp_privatedata_ioctl __user *p =
+               compat_alloc_user_space(sizeof(*p));
+       u32 len;
+       int err;
+
+       if (copy_from_user(&n32, p32, sizeof(n32)) ||
+           put_user(n32.len, &p->len) ||
+           put_user(compat_ptr(n32.data), &p->data))
+               return -EFAULT;
+
+       err = sys_ioctl(fd, NCP_IOC_GETPRIVATEDATA, (unsigned long)p);
+        if (err)
+               return err;
+
+       if (get_user(len, &p->len) ||
+           put_user(len, &p32->len))
+               return -EFAULT;
+
+       return 0;
+}
+
+static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       struct ncp_privatedata_ioctl_32 n32;
+       struct ncp_privatedata_ioctl_32 __user *p32 = compat_ptr(arg);
+       struct ncp_privatedata_ioctl __user *p =
+               compat_alloc_user_space(sizeof(*p));
+
+       if (copy_from_user(&n32, p32, sizeof(n32)) ||
+           put_user(n32.len, &p->len) ||
+           put_user(compat_ptr(n32.data), &p->data))
+               return -EFAULT;
+
+       return sys_ioctl(fd, NCP_IOC_SETPRIVATEDATA, (unsigned long)p);
+}
+#endif
+
 #undef CODE
 #endif
 
@@ -3133,6 +3277,8 @@ HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl)
 HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl)
 HANDLE_IOCTL(SIOCADDRT, routing_ioctl)
 HANDLE_IOCTL(SIOCDELRT, routing_ioctl)
+HANDLE_IOCTL(SIOCBRADDIF, dev_ifsioc)
+HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc)
 /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
 HANDLE_IOCTL(SIOCRTMSG, ret_einval)
 HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
@@ -3263,8 +3409,18 @@ HANDLE_IOCTL(SIOCSIWNICKN, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl)
-HANDLE_IOCTL(SIOCSIFBR, do_bridge_ioctl)
-HANDLE_IOCTL(SIOCGIFBR, do_bridge_ioctl)
+HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
+HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)
+
+#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
+HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)
+HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2)
+HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2)
+HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname)
+HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname)
+HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata)
+HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata)
+#endif
 
 #undef DECLARES
 #endif