]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/ide/ide-ioctls.c
Merge tag 'microblaze-v5.6-rc1' of git://git.monstr.eu/linux-2.6-microblaze
[linux.git] / drivers / ide / ide-ioctls.c
index d48c17003874540a161be616c0552cd730929b69..09491098047bffaf430f17b5b6979c0a88ee905d 100644 (file)
@@ -3,11 +3,20 @@
  * IDE ioctls handling.
  */
 
+#include <linux/compat.h>
 #include <linux/export.h>
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/slab.h>
 
+static int put_user_long(long val, unsigned long arg)
+{
+       if (in_compat_syscall())
+               return put_user(val, (compat_long_t __user *)compat_ptr(arg));
+
+       return put_user(val, (long __user *)arg);
+}
+
 static const struct ide_ioctl_devset ide_ioctl_settings[] = {
 { HDIO_GET_32BIT,       HDIO_SET_32BIT,        &ide_devset_io_32bit  },
 { HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS,        &ide_devset_keepsettings },
@@ -37,7 +46,7 @@ int ide_setting_ioctl(ide_drive_t *drive, struct block_device *bdev,
        mutex_lock(&ide_setting_mtx);
        err = ds->get(drive);
        mutex_unlock(&ide_setting_mtx);
-       return err >= 0 ? put_user(err, (long __user *)arg) : err;
+       return err >= 0 ? put_user_long(err, arg) : err;
 
 set_val:
        if (bdev != bdev->bd_contains)
@@ -56,7 +65,7 @@ int ide_setting_ioctl(ide_drive_t *drive, struct block_device *bdev,
 EXPORT_SYMBOL_GPL(ide_setting_ioctl);
 
 static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd,
-                                 unsigned long arg)
+                                 void __user *argp)
 {
        u16 *id = NULL;
        int size = (cmd == HDIO_GET_IDENTITY) ? (ATA_ID_WORDS * 2) : 142;
@@ -77,7 +86,7 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd,
        memcpy(id, drive->id, size);
        ata_id_to_hd_driveid(id);
 
-       if (copy_to_user((void __user *)arg, id, size))
+       if (copy_to_user(argp, id, size))
                rc = -EFAULT;
 
        kfree(id);
@@ -87,10 +96,10 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd,
 
 static int ide_get_nice_ioctl(ide_drive_t *drive, unsigned long arg)
 {
-       return put_user((!!(drive->dev_flags & IDE_DFLAG_DSC_OVERLAP)
+       return put_user_long((!!(drive->dev_flags & IDE_DFLAG_DSC_OVERLAP)
                         << IDE_NICE_DSC_OVERLAP) |
                        (!!(drive->dev_flags & IDE_DFLAG_NICE1)
-                        << IDE_NICE_1), (long __user *)arg);
+                        << IDE_NICE_1), arg);
 }
 
 static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg)
@@ -115,7 +124,7 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg)
        return 0;
 }
 
-static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
+static int ide_cmd_ioctl(ide_drive_t *drive, void __user *argp)
 {
        u8 *buf = NULL;
        int bufsize = 0, err = 0;
@@ -123,7 +132,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
        struct ide_cmd cmd;
        struct ide_taskfile *tf = &cmd.tf;
 
-       if (NULL == (void *) arg) {
+       if (NULL == argp) {
                struct request *rq;
 
                rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, 0);
@@ -135,7 +144,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
                return err;
        }
 
-       if (copy_from_user(args, (void __user *)arg, 4))
+       if (copy_from_user(args, argp, 4))
                return -EFAULT;
 
        memset(&cmd, 0, sizeof(cmd));
@@ -181,19 +190,18 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
        args[1] = tf->error;
        args[2] = tf->nsect;
 abort:
-       if (copy_to_user((void __user *)arg, &args, 4))
+       if (copy_to_user(argp, &args, 4))
                err = -EFAULT;
        if (buf) {
-               if (copy_to_user((void __user *)(arg + 4), buf, bufsize))
+               if (copy_to_user((argp + 4), buf, bufsize))
                        err = -EFAULT;
                kfree(buf);
        }
        return err;
 }
 
-static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
+static int ide_task_ioctl(ide_drive_t *drive, void __user *p)
 {
-       void __user *p = (void __user *)arg;
        int err = 0;
        u8 args[7];
        struct ide_cmd cmd;
@@ -237,6 +245,10 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev,
                      unsigned int cmd, unsigned long arg)
 {
        int err;
+       void __user *argp = (void __user *)arg;
+
+       if (in_compat_syscall())
+               argp = compat_ptr(arg);
 
        err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_ioctl_settings);
        if (err != -EOPNOTSUPP)
@@ -247,7 +259,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev,
        case HDIO_GET_IDENTITY:
                if (bdev != bdev->bd_contains)
                        return -EINVAL;
-               return ide_get_identity_ioctl(drive, cmd, arg);
+               return ide_get_identity_ioctl(drive, cmd, argp);
        case HDIO_GET_NICE:
                return ide_get_nice_ioctl(drive, arg);
        case HDIO_SET_NICE:
@@ -258,6 +270,9 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev,
        case HDIO_DRIVE_TASKFILE:
                if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
                        return -EACCES;
+               /* missing compat handler for HDIO_DRIVE_TASKFILE */
+               if (in_compat_syscall())
+                       return -ENOTTY;
                if (drive->media == ide_disk)
                        return ide_taskfile_ioctl(drive, arg);
                return -ENOMSG;
@@ -265,11 +280,11 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev,
        case HDIO_DRIVE_CMD:
                if (!capable(CAP_SYS_RAWIO))
                        return -EACCES;
-               return ide_cmd_ioctl(drive, arg);
+               return ide_cmd_ioctl(drive, argp);
        case HDIO_DRIVE_TASK:
                if (!capable(CAP_SYS_RAWIO))
                        return -EACCES;
-               return ide_task_ioctl(drive, arg);
+               return ide_task_ioctl(drive, argp);
        case HDIO_DRIVE_RESET:
                if (!capable(CAP_SYS_ADMIN))
                        return -EACCES;
@@ -277,7 +292,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev,
        case HDIO_GET_BUSSTATE:
                if (!capable(CAP_SYS_ADMIN))
                        return -EACCES;
-               if (put_user(BUSSTATE_ON, (long __user *)arg))
+               if (put_user_long(BUSSTATE_ON, arg))
                        return -EFAULT;
                return 0;
        case HDIO_SET_BUSSTATE: