diff options
Diffstat (limited to 'drivers/s390/char/tape_char.c')
-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. |