diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/s390/char/tape_char.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 2125ec7d95f0..539045acaad4 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/proc_fs.h> | 18 | #include <linux/proc_fs.h> |
| 19 | #include <linux/mtio.h> | 19 | #include <linux/mtio.h> |
| 20 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
| 21 | #include <linux/compat.h> | ||
| 21 | 22 | ||
| 22 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
| 23 | 24 | ||
| @@ -37,8 +38,9 @@ static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t | |||
| 37 | static int tapechar_open(struct inode *,struct file *); | 38 | static int tapechar_open(struct inode *,struct file *); |
| 38 | static int tapechar_release(struct inode *,struct file *); | 39 | static int tapechar_release(struct inode *,struct file *); |
| 39 | static long tapechar_ioctl(struct file *, unsigned int, unsigned long); | 40 | static long tapechar_ioctl(struct file *, unsigned int, unsigned long); |
| 40 | static long tapechar_compat_ioctl(struct file *, unsigned int, | 41 | #ifdef CONFIG_COMPAT |
| 41 | unsigned long); | 42 | static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long); |
| 43 | #endif | ||
| 42 | 44 | ||
| 43 | static const struct file_operations tape_fops = | 45 | static const struct file_operations tape_fops = |
| 44 | { | 46 | { |
| @@ -46,7 +48,9 @@ static const struct file_operations tape_fops = | |||
| 46 | .read = tapechar_read, | 48 | .read = tapechar_read, |
| 47 | .write = tapechar_write, | 49 | .write = tapechar_write, |
| 48 | .unlocked_ioctl = tapechar_ioctl, | 50 | .unlocked_ioctl = tapechar_ioctl, |
| 51 | #ifdef CONFIG_COMPAT | ||
| 49 | .compat_ioctl = tapechar_compat_ioctl, | 52 | .compat_ioctl = tapechar_compat_ioctl, |
| 53 | #endif | ||
| 50 | .open = tapechar_open, | 54 | .open = tapechar_open, |
| 51 | .release = tapechar_release, | 55 | .release = tapechar_release, |
| 52 | }; | 56 | }; |
| @@ -457,15 +461,22 @@ tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) | |||
| 457 | return rc; | 461 | return rc; |
| 458 | } | 462 | } |
| 459 | 463 | ||
| 464 | #ifdef CONFIG_COMPAT | ||
| 460 | static long | 465 | static long |
| 461 | tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) | 466 | tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) |
| 462 | { | 467 | { |
| 463 | struct tape_device *device = filp->private_data; | 468 | struct tape_device *device = filp->private_data; |
| 464 | int rval = -ENOIOCTLCMD; | 469 | int rval = -ENOIOCTLCMD; |
| 470 | unsigned long argp; | ||
| 465 | 471 | ||
| 472 | /* The 'arg' argument of any ioctl function may only be used for | ||
| 473 | * pointers because of the compat pointer conversion. | ||
| 474 | * Consider this when adding new ioctls. | ||
| 475 | */ | ||
| 476 | argp = (unsigned long) compat_ptr(data); | ||
| 466 | if (device->discipline->ioctl_fn) { | 477 | if (device->discipline->ioctl_fn) { |
| 467 | mutex_lock(&device->mutex); | 478 | mutex_lock(&device->mutex); |
| 468 | rval = device->discipline->ioctl_fn(device, no, data); | 479 | rval = device->discipline->ioctl_fn(device, no, argp); |
| 469 | mutex_unlock(&device->mutex); | 480 | mutex_unlock(&device->mutex); |
| 470 | if (rval == -EINVAL) | 481 | if (rval == -EINVAL) |
| 471 | rval = -ENOIOCTLCMD; | 482 | rval = -ENOIOCTLCMD; |
| @@ -473,6 +484,7 @@ tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) | |||
| 473 | 484 | ||
| 474 | return rval; | 485 | return rval; |
| 475 | } | 486 | } |
| 487 | #endif /* CONFIG_COMPAT */ | ||
| 476 | 488 | ||
| 477 | /* | 489 | /* |
| 478 | * Initialize character device frontend. | 490 | * Initialize character device frontend. |
