提交 ef0f1587 编写于 作者: J Jens Axboe

mtip32xx: cleanup compat ioctl handling

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: NJens Axboe <axboe@kernel.dk>
上级 16d02c04
...@@ -1622,76 +1622,26 @@ static unsigned int implicit_sector(unsigned char command, ...@@ -1622,76 +1622,26 @@ static unsigned int implicit_sector(unsigned char command,
* See ide_taskfile_ioctl() for derivation * See ide_taskfile_ioctl() for derivation
*/ */
static int exec_drive_taskfile(struct driver_data *dd, static int exec_drive_taskfile(struct driver_data *dd,
unsigned long arg, void __user *buf,
unsigned char compat) ide_task_request_t *req_task,
int outtotal)
{ {
struct host_to_dev_fis fis; struct host_to_dev_fis fis;
struct host_to_dev_fis *reply; struct host_to_dev_fis *reply;
ide_task_request_t *req_task;
u8 *outbuf = NULL; u8 *outbuf = NULL;
u8 *inbuf = NULL; u8 *inbuf = NULL;
dma_addr_t outbuf_dma = 0; dma_addr_t outbuf_dma = 0;
dma_addr_t inbuf_dma = 0; dma_addr_t inbuf_dma = 0;
dma_addr_t dma_buffer = 0; dma_addr_t dma_buffer = 0;
int err = 0; int err = 0;
int tasksize = sizeof(struct ide_task_request_s);
unsigned int taskin = 0; unsigned int taskin = 0;
unsigned int taskout = 0; unsigned int taskout = 0;
u8 nsect = 0; u8 nsect = 0;
char __user *buf = (char __user *)arg;
unsigned int timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; unsigned int timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS;
unsigned int force_single_sector; unsigned int force_single_sector;
unsigned int transfer_size; unsigned int transfer_size;
unsigned long task_file_data; unsigned long task_file_data;
int intotal, outtotal; int intotal = outtotal + req_task->out_size;
#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;
}
taskout = req_task->out_size; taskout = req_task->out_size;
taskin = req_task->in_size; taskin = req_task->in_size;
...@@ -1922,30 +1872,6 @@ static int exec_drive_taskfile(struct driver_data *dd, ...@@ -1922,30 +1872,6 @@ static int exec_drive_taskfile(struct driver_data *dd,
up_write(&dd->internal_sem); 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 (taskout) {
if (copy_to_user(buf + outtotal, outbuf, taskout)) { if (copy_to_user(buf + outtotal, outbuf, taskout)) {
err = -EFAULT; err = -EFAULT;
...@@ -1965,7 +1891,6 @@ static int exec_drive_taskfile(struct driver_data *dd, ...@@ -1965,7 +1891,6 @@ static int exec_drive_taskfile(struct driver_data *dd,
if (outbuf_dma) if (outbuf_dma)
pci_unmap_single(dd->pdev, outbuf_dma, pci_unmap_single(dd->pdev, outbuf_dma,
taskout, DMA_TO_DEVICE); taskout, DMA_TO_DEVICE);
kfree(req_task);
kfree(outbuf); kfree(outbuf);
kfree(inbuf); kfree(inbuf);
...@@ -1989,10 +1914,8 @@ static int exec_drive_taskfile(struct driver_data *dd, ...@@ -1989,10 +1914,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
* -EFAULT An error occurred copying data to a user space buffer. * -EFAULT An error occurred copying data to a user space buffer.
* -EIO An error occurred while executing the command. * -EIO An error occurred while executing the command.
*/ */
int mtip_hw_ioctl(struct driver_data *dd, static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
unsigned int cmd, unsigned long arg)
unsigned long arg,
unsigned char compat)
{ {
switch (cmd) { switch (cmd) {
case HDIO_GET_IDENTITY: case HDIO_GET_IDENTITY:
...@@ -2049,8 +1972,24 @@ int mtip_hw_ioctl(struct driver_data *dd, ...@@ -2049,8 +1972,24 @@ int mtip_hw_ioctl(struct driver_data *dd,
break; break;
} }
case HDIO_DRIVE_TASKFILE: case HDIO_DRIVE_TASKFILE: {
return exec_drive_taskfile(dd, arg, compat); 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: default:
return -EINVAL; return -EINVAL;
...@@ -2881,7 +2820,7 @@ static int mtip_block_ioctl(struct block_device *dev, ...@@ -2881,7 +2820,7 @@ static int mtip_block_ioctl(struct block_device *dev,
case BLKFLSBUF: case BLKFLSBUF:
return 0; return 0;
default: 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, ...@@ -2915,8 +2854,46 @@ static int mtip_block_compat_ioctl(struct block_device *dev,
switch (cmd) { switch (cmd) {
case BLKFLSBUF: case BLKFLSBUF:
return 0; 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: default:
return mtip_hw_ioctl(dd, cmd, arg, 1); return mtip_hw_ioctl(dd, cmd, arg);
} }
} }
#endif #endif
......
...@@ -430,10 +430,6 @@ extern void mtip_hw_submit_io(struct driver_data *dd, ...@@ -430,10 +430,6 @@ extern void mtip_hw_submit_io(struct driver_data *dd,
void *data, void *data,
int barrier, int barrier,
int dir); 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_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_sysfs_exit(struct driver_data *dd, struct kobject *kobj);
extern int mtip_hw_resume(struct driver_data *dd); extern int mtip_hw_resume(struct driver_data *dd);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册