mtip32xx: cleanup compat ioctl handling
[firefly-linux-kernel-4.4.55.git] / drivers / block / mtip32xx / mtip32xx.c
index 847b8ff7b8c24d74dcb40e3d3e2f3b1164c59587..d58581b83c8dcce451e60083feddbe12c30e4c47 100644 (file)
@@ -85,6 +85,7 @@ int mtip_major;
 static DEFINE_SPINLOCK(rssd_index_lock);
 static DEFINE_IDA(rssd_index_ida);
 
+#ifdef CONFIG_COMPAT
 struct mtip_compat_ide_task_request_s {
        __u8            io_ports[8];
        __u8            hob_ports[8];
@@ -95,6 +96,7 @@ struct mtip_compat_ide_task_request_s {
        compat_ulong_t  out_size;
        compat_ulong_t  in_size;
 };
+#endif
 
 static int mtip_exec_internal_command(struct mtip_port *port,
                                void *fis,
@@ -1620,68 +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 = (dma_addr_t)NULL;
-       dma_addr_t inbuf_dma = (dma_addr_t)NULL;
-       dma_addr_t dma_buffer = (dma_addr_t)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;
-       struct mtip_compat_ide_task_request_s *compat_req_task = NULL;
-       int compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s);
-
-       req_task = kzalloc(tasksize, GFP_KERNEL);
-       if (req_task == NULL)
-               return -ENOMEM;
-
-       if (compat == 1) {
-               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 {
-               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;
@@ -1705,7 +1665,7 @@ static int exec_drive_taskfile(struct driver_data *dd,
                                         outbuf,
                                         taskout,
                                         DMA_TO_DEVICE);
-               if (outbuf_dma == (dma_addr_t)NULL) {
+               if (outbuf_dma == 0) {
                        err = -ENOMEM;
                        goto abort;
                }
@@ -1726,7 +1686,7 @@ static int exec_drive_taskfile(struct driver_data *dd,
                inbuf_dma = pci_map_single(dd->pdev,
                                         inbuf,
                                         taskin, DMA_FROM_DEVICE);
-               if (inbuf_dma == (dma_addr_t)NULL) {
+               if (inbuf_dma == 0) {
                        err = -ENOMEM;
                        goto abort;
                }
@@ -1868,8 +1828,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
        if (outbuf_dma)
                pci_unmap_single(dd->pdev, outbuf_dma,
                        taskout, DMA_TO_DEVICE);
-       inbuf_dma  = (dma_addr_t) NULL;
-       outbuf_dma = (dma_addr_t) NULL;
+       inbuf_dma  = 0;
+       outbuf_dma = 0;
 
        /* return the ATA registers to the caller.*/
        req_task->io_ports[1] = reply->features;
@@ -1912,28 +1872,6 @@ static int exec_drive_taskfile(struct driver_data *dd,
 
        up_write(&dd->internal_sem);
 
-       if (compat == 1) {
-               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;
-               }
-       } 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;
@@ -1953,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);
 
@@ -1977,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:
@@ -2037,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;
@@ -2869,10 +2820,11 @@ 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);
        }
 }
 
+#ifdef CONFIG_COMPAT
 /*
  * Block layer compat IOCTL handler.
  *
@@ -2902,10 +2854,49 @@ 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
 
 /*
  * Obtain the geometry of the device.
@@ -2959,7 +2950,9 @@ static int mtip_block_getgeo(struct block_device *dev,
  */
 static const struct block_device_operations mtip_block_ops = {
        .ioctl          = mtip_block_ioctl,
+#ifdef CONFIG_COMPAT
        .compat_ioctl   = mtip_block_compat_ioctl,
+#endif
        .getgeo         = mtip_block_getgeo,
        .owner          = THIS_MODULE
 };