}
 }
 
+#ifdef CONFIG_COMPAT
+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 put_compat_request_table(struct compat_sg_req_info __user *o,
+                                   struct sg_req_info *rinfo)
+{
+       int i;
+       for (i = 0; i < SG_MAX_QUEUE; i++) {
+               if (copy_to_user(o + i, rinfo + i, offsetof(sg_req_info_t, usr_ptr)) ||
+                   put_user((uintptr_t)rinfo[i].usr_ptr, &o[i].usr_ptr) ||
+                   put_user(rinfo[i].duration, &o[i].duration) ||
+                   put_user(rinfo[i].unused, &o[i].unused))
+                       return -EFAULT;
+       }
+       return 0;
+}
+#endif
+
 static long
 sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
 {
                val = (sdp->device ? 1 : 0);
                return put_user(val, ip);
        case SG_GET_REQUEST_TABLE:
-               if (!access_ok(p, SZ_SG_REQ_INFO * SG_MAX_QUEUE))
-                       return -EFAULT;
-               else {
+               {
                        sg_req_info_t *rinfo;
 
                        rinfo = kcalloc(SG_MAX_QUEUE, SZ_SG_REQ_INFO,
                        read_lock_irqsave(&sfp->rq_list_lock, iflags);
                        sg_fill_request_table(sfp, rinfo);
                        read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
-                       result = __copy_to_user(p, rinfo,
-                                               SZ_SG_REQ_INFO * SG_MAX_QUEUE);
+       #ifdef CONFIG_COMPAT
+                       if (in_compat_syscall())
+                               result = put_compat_request_table(p, rinfo);
+                       else
+       #endif
+                               result = copy_to_user(p, rinfo,
+                                                     SZ_SG_REQ_INFO * SG_MAX_QUEUE);
                        result = result ? -EFAULT : 0;
                        kfree(rinfo);
                        return result;
 
 
 #include <linux/sort.h>
 
-#ifdef CONFIG_BLOCK
-static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       int err;
-
-       err = security_file_ioctl(file, cmd, arg);
-       if (err)
-               return err;
-
-       return vfs_ioctl(file, cmd, arg);
-}
-
-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(struct file *file,
-               unsigned int cmd, struct compat_sg_req_info __user *o)
-{
-       int err, i;
-       sg_req_info_t __user *r;
-       r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE);
-       err = do_ioctl(file, 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;
-}
-#endif /* CONFIG_BLOCK */
-
 /*
  * simple reversible transform to make our table more evenly
  * distributed after sorting.
 #ifdef CONFIG_BLOCK
 /* SG stuff */
 COMPATIBLE_IOCTL(SG_IO)
+COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
 COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
 COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
 COMPATIBLE_IOCTL(SG_EMULATED_HOST)
 static long do_ioctl_trans(unsigned int cmd,
                 unsigned long arg, struct file *file)
 {
-#ifdef CONFIG_BLOCK
-       void __user *argp = compat_ptr(arg);
-
-       switch (cmd) {
-       case SG_GET_REQUEST_TABLE:
-               return sg_grt_trans(file, cmd, argp);
-       }
-#endif
-
        return -ENOIOCTLCMD;
 }