diff options
author | Jens Axboe <axboe@kernel.dk> | 2011-09-27 23:19:53 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2011-11-05 03:35:10 -0400 |
commit | ef0f1587343a4c17b9b0d9061546e36c1c1bb2ec (patch) | |
tree | 3acd32766e0e255693b006555e9ff21845b24324 /drivers/block/mtip32xx | |
parent | 16d02c040bb6769068f7c4b54ea8542f14237362 (diff) |
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: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/mtip32xx')
-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, | |||
1622 | * See ide_taskfile_ioctl() for derivation | 1622 | * See ide_taskfile_ioctl() for derivation |
1623 | */ | 1623 | */ |
1624 | static int exec_drive_taskfile(struct driver_data *dd, | 1624 | static int exec_drive_taskfile(struct driver_data *dd, |
1625 | unsigned long arg, | 1625 | void __user *buf, |
1626 | unsigned char compat) | 1626 | ide_task_request_t *req_task, |
1627 | int outtotal) | ||
1627 | { | 1628 | { |
1628 | struct host_to_dev_fis fis; | 1629 | struct host_to_dev_fis fis; |
1629 | struct host_to_dev_fis *reply; | 1630 | struct host_to_dev_fis *reply; |
1630 | ide_task_request_t *req_task; | ||
1631 | u8 *outbuf = NULL; | 1631 | u8 *outbuf = NULL; |
1632 | u8 *inbuf = NULL; | 1632 | u8 *inbuf = NULL; |
1633 | dma_addr_t outbuf_dma = 0; | 1633 | dma_addr_t outbuf_dma = 0; |
1634 | dma_addr_t inbuf_dma = 0; | 1634 | dma_addr_t inbuf_dma = 0; |
1635 | dma_addr_t dma_buffer = 0; | 1635 | dma_addr_t dma_buffer = 0; |
1636 | int err = 0; | 1636 | int err = 0; |
1637 | int tasksize = sizeof(struct ide_task_request_s); | ||
1638 | unsigned int taskin = 0; | 1637 | unsigned int taskin = 0; |
1639 | unsigned int taskout = 0; | 1638 | unsigned int taskout = 0; |
1640 | u8 nsect = 0; | 1639 | u8 nsect = 0; |
1641 | char __user *buf = (char __user *)arg; | ||
1642 | unsigned int timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; | 1640 | unsigned int timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; |
1643 | unsigned int force_single_sector; | 1641 | unsigned int force_single_sector; |
1644 | unsigned int transfer_size; | 1642 | unsigned int transfer_size; |
1645 | unsigned long task_file_data; | 1643 | unsigned long task_file_data; |
1646 | int intotal, outtotal; | 1644 | int intotal = outtotal + req_task->out_size; |
1647 | #ifdef CONFIG_COMPAT | ||
1648 | struct mtip_compat_ide_task_request_s *compat_req_task = NULL; | ||
1649 | int compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s); | ||
1650 | #endif | ||
1651 | |||
1652 | |||
1653 | req_task = kzalloc(tasksize, GFP_KERNEL); | ||
1654 | if (req_task == NULL) | ||
1655 | return -ENOMEM; | ||
1656 | |||
1657 | if (compat == 1) { | ||
1658 | #ifdef CONFIG_COMPAT | ||
1659 | compat_req_task = | ||
1660 | (struct mtip_compat_ide_task_request_s __user *) arg; | ||
1661 | |||
1662 | if (copy_from_user(req_task, buf, | ||
1663 | compat_tasksize - | ||
1664 | (2 * sizeof(compat_long_t)))) { | ||
1665 | err = -EFAULT; | ||
1666 | goto abort; | ||
1667 | } | ||
1668 | |||
1669 | if (get_user(req_task->out_size, &compat_req_task->out_size)) { | ||
1670 | err = -EFAULT; | ||
1671 | goto abort; | ||
1672 | } | ||
1673 | |||
1674 | if (get_user(req_task->in_size, &compat_req_task->in_size)) { | ||
1675 | err = -EFAULT; | ||
1676 | goto abort; | ||
1677 | } | ||
1678 | |||
1679 | outtotal = compat_tasksize; | ||
1680 | intotal = compat_tasksize + req_task->out_size; | ||
1681 | #else | ||
1682 | outtotal = 0; | ||
1683 | intotal = 0; | ||
1684 | #endif | ||
1685 | } else { | ||
1686 | if (copy_from_user(req_task, buf, tasksize)) { | ||
1687 | kfree(req_task); | ||
1688 | err = -EFAULT; | ||
1689 | goto abort; | ||
1690 | } | ||
1691 | |||
1692 | outtotal = tasksize; | ||
1693 | intotal = tasksize + req_task->out_size; | ||
1694 | } | ||
1695 | 1645 | ||
1696 | taskout = req_task->out_size; | 1646 | taskout = req_task->out_size; |
1697 | taskin = req_task->in_size; | 1647 | taskin = req_task->in_size; |
@@ -1922,30 +1872,6 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
1922 | 1872 | ||
1923 | up_write(&dd->internal_sem); | 1873 | up_write(&dd->internal_sem); |
1924 | 1874 | ||
1925 | if (compat == 1) { | ||
1926 | #ifdef CONFIG_COMPAT | ||
1927 | if (copy_to_user(buf, req_task, | ||
1928 | compat_tasksize - | ||
1929 | (2 * sizeof(compat_long_t)))) { | ||
1930 | err = -EFAULT; | ||
1931 | goto abort; | ||
1932 | } | ||
1933 | if (put_user(req_task->out_size, | ||
1934 | &compat_req_task->out_size)) { | ||
1935 | err = -EFAULT; | ||
1936 | goto abort; | ||
1937 | } | ||
1938 | if (put_user(req_task->in_size, &compat_req_task->in_size)) { | ||
1939 | err = -EFAULT; | ||
1940 | goto abort; | ||
1941 | } | ||
1942 | #endif | ||
1943 | } else { | ||
1944 | if (copy_to_user(buf, req_task, tasksize)) { | ||
1945 | err = -EFAULT; | ||
1946 | goto abort; | ||
1947 | } | ||
1948 | } | ||
1949 | if (taskout) { | 1875 | if (taskout) { |
1950 | if (copy_to_user(buf + outtotal, outbuf, taskout)) { | 1876 | if (copy_to_user(buf + outtotal, outbuf, taskout)) { |
1951 | err = -EFAULT; | 1877 | err = -EFAULT; |
@@ -1965,7 +1891,6 @@ abort: | |||
1965 | if (outbuf_dma) | 1891 | if (outbuf_dma) |
1966 | pci_unmap_single(dd->pdev, outbuf_dma, | 1892 | pci_unmap_single(dd->pdev, outbuf_dma, |
1967 | taskout, DMA_TO_DEVICE); | 1893 | taskout, DMA_TO_DEVICE); |
1968 | kfree(req_task); | ||
1969 | kfree(outbuf); | 1894 | kfree(outbuf); |
1970 | kfree(inbuf); | 1895 | kfree(inbuf); |
1971 | 1896 | ||
@@ -1989,10 +1914,8 @@ abort: | |||
1989 | * -EFAULT An error occurred copying data to a user space buffer. | 1914 | * -EFAULT An error occurred copying data to a user space buffer. |
1990 | * -EIO An error occurred while executing the command. | 1915 | * -EIO An error occurred while executing the command. |
1991 | */ | 1916 | */ |
1992 | int mtip_hw_ioctl(struct driver_data *dd, | 1917 | static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, |
1993 | unsigned int cmd, | 1918 | unsigned long arg) |
1994 | unsigned long arg, | ||
1995 | unsigned char compat) | ||
1996 | { | 1919 | { |
1997 | switch (cmd) { | 1920 | switch (cmd) { |
1998 | case HDIO_GET_IDENTITY: | 1921 | case HDIO_GET_IDENTITY: |
@@ -2049,8 +1972,24 @@ int mtip_hw_ioctl(struct driver_data *dd, | |||
2049 | 1972 | ||
2050 | break; | 1973 | break; |
2051 | } | 1974 | } |
2052 | case HDIO_DRIVE_TASKFILE: | 1975 | case HDIO_DRIVE_TASKFILE: { |
2053 | return exec_drive_taskfile(dd, arg, compat); | 1976 | ide_task_request_t req_task; |
1977 | int ret, outtotal; | ||
1978 | |||
1979 | if (copy_from_user(&req_task, (void __user *) arg, | ||
1980 | sizeof(req_task))) | ||
1981 | return -EFAULT; | ||
1982 | |||
1983 | outtotal = sizeof(req_task); | ||
1984 | |||
1985 | ret = exec_drive_taskfile(dd, (void __user *) arg, | ||
1986 | &req_task, outtotal); | ||
1987 | |||
1988 | if (copy_to_user((void __user *) arg, &req_task, sizeof(req_task))) | ||
1989 | return -EFAULT; | ||
1990 | |||
1991 | return ret; | ||
1992 | } | ||
2054 | 1993 | ||
2055 | default: | 1994 | default: |
2056 | return -EINVAL; | 1995 | return -EINVAL; |
@@ -2881,7 +2820,7 @@ static int mtip_block_ioctl(struct block_device *dev, | |||
2881 | case BLKFLSBUF: | 2820 | case BLKFLSBUF: |
2882 | return 0; | 2821 | return 0; |
2883 | default: | 2822 | default: |
2884 | return mtip_hw_ioctl(dd, cmd, arg, 0); | 2823 | return mtip_hw_ioctl(dd, cmd, arg); |
2885 | } | 2824 | } |
2886 | } | 2825 | } |
2887 | 2826 | ||
@@ -2915,8 +2854,46 @@ static int mtip_block_compat_ioctl(struct block_device *dev, | |||
2915 | switch (cmd) { | 2854 | switch (cmd) { |
2916 | case BLKFLSBUF: | 2855 | case BLKFLSBUF: |
2917 | return 0; | 2856 | return 0; |
2857 | case HDIO_DRIVE_TASKFILE: { | ||
2858 | struct mtip_compat_ide_task_request_s *compat_req_task; | ||
2859 | ide_task_request_t req_task; | ||
2860 | int compat_tasksize, outtotal, ret; | ||
2861 | |||
2862 | compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s); | ||
2863 | |||
2864 | compat_req_task = | ||
2865 | (struct mtip_compat_ide_task_request_s __user *) arg; | ||
2866 | |||
2867 | if (copy_from_user(&req_task, (void __user *) arg, | ||
2868 | compat_tasksize - (2 * sizeof(compat_long_t)))) | ||
2869 | return -EFAULT; | ||
2870 | |||
2871 | if (get_user(req_task.out_size, &compat_req_task->out_size)) | ||
2872 | return -EFAULT; | ||
2873 | |||
2874 | if (get_user(req_task.in_size, &compat_req_task->in_size)) | ||
2875 | return -EFAULT; | ||
2876 | |||
2877 | outtotal = sizeof(struct mtip_compat_ide_task_request_s); | ||
2878 | |||
2879 | ret = exec_drive_taskfile(dd, (void __user *) arg, | ||
2880 | &req_task, outtotal); | ||
2881 | |||
2882 | if (copy_to_user((void __user *) arg, &req_task, | ||
2883 | compat_tasksize - | ||
2884 | (2 * sizeof(compat_long_t)))) | ||
2885 | return -EFAULT; | ||
2886 | |||
2887 | if (put_user(req_task.out_size, &compat_req_task->out_size)) | ||
2888 | return -EFAULT; | ||
2889 | |||
2890 | if (put_user(req_task.in_size, &compat_req_task->in_size)) | ||
2891 | return -EFAULT; | ||
2892 | |||
2893 | return ret; | ||
2894 | } | ||
2918 | default: | 2895 | default: |
2919 | return mtip_hw_ioctl(dd, cmd, arg, 1); | 2896 | return mtip_hw_ioctl(dd, cmd, arg); |
2920 | } | 2897 | } |
2921 | } | 2898 | } |
2922 | #endif | 2899 | #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, | |||
430 | void *data, | 430 | void *data, |
431 | int barrier, | 431 | int barrier, |
432 | int dir); | 432 | int dir); |
433 | extern int mtip_hw_ioctl(struct driver_data *dd, | ||
434 | unsigned int cmd, | ||
435 | unsigned long arg, | ||
436 | unsigned char compat); | ||
437 | extern int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj); | 433 | extern int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj); |
438 | extern int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj); | 434 | extern int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj); |
439 | extern int mtip_hw_resume(struct driver_data *dd); | 435 | extern int mtip_hw_resume(struct driver_data *dd); |