diff options
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 151 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 4 |
2 files changed, 64 insertions, 91 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 1cf2b0443571..d58581b83c8d 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -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 diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 3423d18e7c86..d6355c6f218f 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -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); |