aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/mtip32xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/mtip32xx')
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c151
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h4
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 */
1624static int exec_drive_taskfile(struct driver_data *dd, 1624static 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 */
1992int mtip_hw_ioctl(struct driver_data *dd, 1917static 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);
433extern int mtip_hw_ioctl(struct driver_data *dd,
434 unsigned int cmd,
435 unsigned long arg,
436 unsigned char compat);
437extern int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj); 433extern int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj);
438extern int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj); 434extern int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj);
439extern int mtip_hw_resume(struct driver_data *dd); 435extern int mtip_hw_resume(struct driver_data *dd);