]>
Commit | Line | Data |
---|---|---|
1a59d1b8 | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4 LT |
2 | /* |
3 | * 32bit -> 64bit ioctl wrapper for raw MIDI API | |
4 | * Copyright (c) by Takashi Iwai <[email protected]> | |
1da177e4 LT |
5 | */ |
6 | ||
7 | /* This file included from rawmidi.c */ | |
8 | ||
9 | #include <linux/compat.h> | |
10 | ||
48c9d417 | 11 | struct snd_rawmidi_params32 { |
1da177e4 LT |
12 | s32 stream; |
13 | u32 buffer_size; | |
14 | u32 avail_min; | |
15 | unsigned int no_active_sensing; /* avoid bit-field */ | |
08fdced6 DH |
16 | unsigned int mode; |
17 | unsigned char reserved[12]; | |
1da177e4 LT |
18 | } __attribute__((packed)); |
19 | ||
48c9d417 TI |
20 | static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile, |
21 | struct snd_rawmidi_params32 __user *src) | |
1da177e4 | 22 | { |
48c9d417 | 23 | struct snd_rawmidi_params params; |
1da177e4 LT |
24 | unsigned int val; |
25 | ||
1da177e4 LT |
26 | if (get_user(params.stream, &src->stream) || |
27 | get_user(params.buffer_size, &src->buffer_size) || | |
28 | get_user(params.avail_min, &src->avail_min) || | |
08fdced6 | 29 | get_user(params.mode, &src->mode) || |
1da177e4 LT |
30 | get_user(val, &src->no_active_sensing)) |
31 | return -EFAULT; | |
32 | params.no_active_sensing = val; | |
33 | switch (params.stream) { | |
34 | case SNDRV_RAWMIDI_STREAM_OUTPUT: | |
8a56ef4f TI |
35 | if (!rfile->output) |
36 | return -EINVAL; | |
1da177e4 LT |
37 | return snd_rawmidi_output_params(rfile->output, ¶ms); |
38 | case SNDRV_RAWMIDI_STREAM_INPUT: | |
8a56ef4f TI |
39 | if (!rfile->input) |
40 | return -EINVAL; | |
1da177e4 LT |
41 | return snd_rawmidi_input_params(rfile->input, ¶ms); |
42 | } | |
43 | return -EINVAL; | |
44 | } | |
45 | ||
d9e5582c | 46 | struct compat_snd_rawmidi_status64 { |
1da177e4 | 47 | s32 stream; |
d9e5582c BW |
48 | u8 rsvd[4]; /* alignment */ |
49 | s64 tstamp_sec; | |
50 | s64 tstamp_nsec; | |
1da177e4 LT |
51 | u32 avail; |
52 | u32 xruns; | |
53 | unsigned char reserved[16]; | |
54 | } __attribute__((packed)); | |
55 | ||
d9e5582c BW |
56 | static int snd_rawmidi_ioctl_status_compat64(struct snd_rawmidi_file *rfile, |
57 | struct compat_snd_rawmidi_status64 __user *src) | |
1da177e4 LT |
58 | { |
59 | int err; | |
d9e5582c BW |
60 | struct snd_rawmidi_status64 status; |
61 | struct compat_snd_rawmidi_status64 compat_status; | |
1da177e4 | 62 | |
1da177e4 LT |
63 | if (get_user(status.stream, &src->stream)) |
64 | return -EFAULT; | |
65 | ||
66 | switch (status.stream) { | |
67 | case SNDRV_RAWMIDI_STREAM_OUTPUT: | |
8a56ef4f TI |
68 | if (!rfile->output) |
69 | return -EINVAL; | |
1da177e4 LT |
70 | err = snd_rawmidi_output_status(rfile->output, &status); |
71 | break; | |
72 | case SNDRV_RAWMIDI_STREAM_INPUT: | |
8a56ef4f TI |
73 | if (!rfile->input) |
74 | return -EINVAL; | |
1da177e4 LT |
75 | err = snd_rawmidi_input_status(rfile->input, &status); |
76 | break; | |
77 | default: | |
78 | return -EINVAL; | |
79 | } | |
80 | if (err < 0) | |
81 | return err; | |
82 | ||
d9e5582c BW |
83 | compat_status = (struct compat_snd_rawmidi_status64) { |
84 | .stream = status.stream, | |
85 | .tstamp_sec = status.tstamp_sec, | |
86 | .tstamp_nsec = status.tstamp_nsec, | |
87 | .avail = status.avail, | |
88 | .xruns = status.xruns, | |
89 | }; | |
2251fbbc | 90 | |
d9e5582c | 91 | if (copy_to_user(src, &compat_status, sizeof(*src))) |
2251fbbc TI |
92 | return -EFAULT; |
93 | ||
94 | return 0; | |
95 | } | |
2251fbbc | 96 | |
1da177e4 | 97 | enum { |
48c9d417 | 98 | SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32), |
d9e5582c BW |
99 | SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT32 = _IOWR('W', 0x20, struct snd_rawmidi_status32), |
100 | SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64 = _IOWR('W', 0x20, struct compat_snd_rawmidi_status64), | |
1da177e4 LT |
101 | }; |
102 | ||
103 | static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) | |
104 | { | |
48c9d417 | 105 | struct snd_rawmidi_file *rfile; |
1da177e4 LT |
106 | void __user *argp = compat_ptr(arg); |
107 | ||
108 | rfile = file->private_data; | |
109 | switch (cmd) { | |
110 | case SNDRV_RAWMIDI_IOCTL_PVERSION: | |
111 | case SNDRV_RAWMIDI_IOCTL_INFO: | |
112 | case SNDRV_RAWMIDI_IOCTL_DROP: | |
113 | case SNDRV_RAWMIDI_IOCTL_DRAIN: | |
114 | return snd_rawmidi_ioctl(file, cmd, (unsigned long)argp); | |
115 | case SNDRV_RAWMIDI_IOCTL_PARAMS32: | |
116 | return snd_rawmidi_ioctl_params_compat(rfile, argp); | |
d9e5582c BW |
117 | case SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT32: |
118 | return snd_rawmidi_ioctl_status32(rfile, argp); | |
119 | case SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64: | |
120 | return snd_rawmidi_ioctl_status_compat64(rfile, argp); | |
1da177e4 LT |
121 | } |
122 | return -ENOIOCTLCMD; | |
123 | } |