]> Pileus Git - ~andy/linux/commitdiff
mtip32xx: cleanup compat ioctl handling
authorJens Axboe <axboe@kernel.dk>
Wed, 28 Sep 2011 03:19:53 +0000 (21:19 -0600)
committerJens Axboe <axboe@kernel.dk>
Sat, 5 Nov 2011 07:35:10 +0000 (08:35 +0100)
Do the conversion/copy up front instead of passing in a compat flag
to the ioctl handler and subsequently to the exec_drive_taskfile()
function.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/mtip32xx/mtip32xx.c
drivers/block/mtip32xx/mtip32xx.h

index 1cf2b0443571f273bd57d8a0fc449c06803c36f4..d58581b83c8dcce451e60083feddbe12c30e4c47 100644 (file)
@@ -1622,76 +1622,26 @@ static unsigned int implicit_sector(unsigned char command,
  * See ide_taskfile_ioctl() for derivation
  */
 static int exec_drive_taskfile(struct driver_data *dd,
-                               unsigned long arg,
-                               unsigned char compat)
+                              void __user *buf,
+                              ide_task_request_t *req_task,
+                              int outtotal)
 {
        struct host_to_dev_fis  fis;
        struct host_to_dev_fis *reply;
-       ide_task_request_t *req_task;
        u8 *outbuf = NULL;
        u8 *inbuf = NULL;
        dma_addr_t outbuf_dma = 0;
        dma_addr_t inbuf_dma = 0;
        dma_addr_t dma_buffer = 0;
        int err = 0;
-       int tasksize = sizeof(struct ide_task_request_s);
        unsigned int taskin = 0;
        unsigned int taskout = 0;
        u8 nsect = 0;
-       char __user *buf = (char __user *)arg;
        unsigned int timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS;
        unsigned int force_single_sector;
        unsigned int transfer_size;
        unsigned long task_file_data;
-       int intotal, outtotal;
-#ifdef CONFIG_COMPAT
-       struct mtip_compat_ide_task_request_s *compat_req_task = NULL;
-       int compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s);
-#endif
-
-
-       req_task = kzalloc(tasksize, GFP_KERNEL);
-       if (req_task == NULL)
-               return -ENOMEM;
-
-       if (compat == 1) {
-#ifdef CONFIG_COMPAT
-               compat_req_task =
-                       (struct mtip_compat_ide_task_request_s __user *) arg;
-
-               if (copy_from_user(req_task, buf,
-                               compat_tasksize -
-                               (2 * sizeof(compat_long_t)))) {
-                       err = -EFAULT;
-                       goto abort;
-               }
-
-               if (get_user(req_task->out_size, &compat_req_task->out_size)) {
-                       err = -EFAULT;
-                       goto abort;
-               }
-
-               if (get_user(req_task->in_size, &compat_req_task->in_size)) {
-                       err = -EFAULT;
-                       goto abort;
-               }
-
-               outtotal = compat_tasksize;
-               intotal = compat_tasksize + req_task->out_size;
-#else
-               outtotal = 0;
-               intotal = 0;
-#endif
-       } else {
-               if (copy_from_user(req_task, buf, tasksize)) {
-                       kfree(req_task);
-                       err = -EFAULT;
-                       goto abort;
-               }
-
-               outtotal = tasksize;
-               intotal = tasksize + req_task->out_size;
-       }
+       int intotal = outtotal + req_task->out_size;
 
        taskout = req_task->out_size;
        taskin = req_task->in_size;
@@ -1922,30 +1872,6 @@ static int exec_drive_taskfile(struct driver_data *dd,
 
        up_write(&dd->internal_sem);
 
-       if (compat == 1) {
-#ifdef CONFIG_COMPAT
-               if (copy_to_user(buf, req_task,
-                               compat_tasksize -
-                               (2 * sizeof(compat_long_t)))) {
-                       err = -EFAULT;
-                       goto abort;
-               }
-               if (put_user(req_task->out_size,
-                               &compat_req_task->out_size)) {
-                       err = -EFAULT;
-                       goto abort;
-               }
-               if (put_user(req_task->in_size, &compat_req_task->in_size)) {
-                       err = -EFAULT;
-                       goto abort;
-               }
-#endif
-       } else {
-               if (copy_to_user(buf, req_task, tasksize)) {
-                       err = -EFAULT;
-                       goto abort;
-               }
-       }
        if (taskout) {
                if (copy_to_user(buf + outtotal, outbuf, taskout)) {
                        err = -EFAULT;
@@ -1965,7 +1891,6 @@ abort:
        if (outbuf_dma)
                pci_unmap_single(dd->pdev, outbuf_dma,
                                        taskout, DMA_TO_DEVICE);
-       kfree(req_task);
        kfree(outbuf);
        kfree(inbuf);
 
@@ -1989,10 +1914,8 @@ abort:
  *     -EFAULT An error occurred copying data to a user space buffer.
  *     -EIO    An error occurred while executing the command.
  */
-int mtip_hw_ioctl(struct driver_data *dd,
-                 unsigned int cmd,
-                 unsigned long arg,
-                 unsigned char compat)
+static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
+                        unsigned long arg)
 {
        switch (cmd) {
        case HDIO_GET_IDENTITY:
@@ -2049,8 +1972,24 @@ int mtip_hw_ioctl(struct driver_data *dd,
 
                break;
        }
-       case HDIO_DRIVE_TASKFILE:
-               return exec_drive_taskfile(dd, arg, compat);
+       case HDIO_DRIVE_TASKFILE: {
+               ide_task_request_t req_task;
+               int ret, outtotal;
+
+               if (copy_from_user(&req_task, (void __user *) arg,
+                                       sizeof(req_task)))
+                       return -EFAULT;
+
+               outtotal = sizeof(req_task);
+
+               ret = exec_drive_taskfile(dd, (void __user *) arg,
+                                               &req_task, outtotal);
+
+               if (copy_to_user((void __user *) arg, &req_task, sizeof(req_task)))
+                       return -EFAULT;
+
+               return ret;
+       }
 
        default:
                return -EINVAL;
@@ -2881,7 +2820,7 @@ static int mtip_block_ioctl(struct block_device *dev,
        case BLKFLSBUF:
                return 0;
        default:
-               return mtip_hw_ioctl(dd, cmd, arg, 0);
+               return mtip_hw_ioctl(dd, cmd, arg);
        }
 }
 
@@ -2915,8 +2854,46 @@ static int mtip_block_compat_ioctl(struct block_device *dev,
        switch (cmd) {
        case BLKFLSBUF:
                return 0;
+       case HDIO_DRIVE_TASKFILE: {
+               struct mtip_compat_ide_task_request_s *compat_req_task;
+               ide_task_request_t req_task;
+               int compat_tasksize, outtotal, ret;
+
+               compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s);
+
+               compat_req_task =
+                       (struct mtip_compat_ide_task_request_s __user *) arg;
+
+               if (copy_from_user(&req_task, (void __user *) arg,
+                               compat_tasksize - (2 * sizeof(compat_long_t))))
+                       return -EFAULT;
+
+               if (get_user(req_task.out_size, &compat_req_task->out_size))
+                       return -EFAULT;
+
+               if (get_user(req_task.in_size, &compat_req_task->in_size))
+                       return -EFAULT;
+
+               outtotal = sizeof(struct mtip_compat_ide_task_request_s);
+
+               ret = exec_drive_taskfile(dd, (void __user *) arg,
+                                               &req_task, outtotal);
+
+               if (copy_to_user((void __user *) arg, &req_task,
+                               compat_tasksize -
+                               (2 * sizeof(compat_long_t))))
+                       return -EFAULT;
+
+               if (put_user(req_task.out_size, &compat_req_task->out_size))
+                       return -EFAULT;
+
+               if (put_user(req_task.in_size, &compat_req_task->in_size))
+                       return -EFAULT;
+
+               return ret;
+       }
        default:
-               return mtip_hw_ioctl(dd, cmd, arg, 1);
+               return mtip_hw_ioctl(dd, cmd, arg);
        }
 }
 #endif
index 3423d18e7c8619802c31047ffea54c4f224a9248..d6355c6f218fa2364d64ed24c9e38ffeecf8cb62 100644 (file)
@@ -430,10 +430,6 @@ extern void mtip_hw_submit_io(struct driver_data *dd,
                        void *data,
                        int barrier,
                        int dir);
-extern int mtip_hw_ioctl(struct driver_data *dd,
-                       unsigned int cmd,
-                       unsigned long arg,
-                       unsigned char compat);
 extern int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj);
 extern int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj);
 extern int mtip_hw_resume(struct driver_data *dd);