hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/core/pcm_compat.c
....@@ -1,21 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * 32bit -> 64bit ioctl wrapper for PCM API
34 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation; either version 2 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program; if not, write to the Free Software
17
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
- *
195 */
206
217 /* This file included from pcm_native.c */
....@@ -97,19 +83,6 @@
9783 unsigned char reserved[56];
9884 };
9985
100
-/* recalcuate the boundary within 32bit */
101
-static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime)
102
-{
103
- snd_pcm_uframes_t boundary;
104
-
105
- if (! runtime->buffer_size)
106
- return 0;
107
- boundary = runtime->buffer_size;
108
- while (boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
109
- boundary *= 2;
110
- return boundary;
111
-}
112
-
11386 static int snd_pcm_ioctl_sw_params_compat(struct snd_pcm_substream *substream,
11487 struct snd_pcm_sw_params32 __user *src)
11588 {
....@@ -182,97 +155,39 @@
182155 snd_pcm_channel_info_user(s, p)
183156 #endif /* CONFIG_X86_X32 */
184157
185
-struct snd_pcm_status32 {
186
- s32 state;
187
- struct compat_timespec trigger_tstamp;
188
- struct compat_timespec tstamp;
158
+struct compat_snd_pcm_status64 {
159
+ snd_pcm_state_t state;
160
+ u8 rsvd[4]; /* alignment */
161
+ s64 trigger_tstamp_sec;
162
+ s64 trigger_tstamp_nsec;
163
+ s64 tstamp_sec;
164
+ s64 tstamp_nsec;
189165 u32 appl_ptr;
190166 u32 hw_ptr;
191167 s32 delay;
192168 u32 avail;
193169 u32 avail_max;
194170 u32 overrange;
195
- s32 suspended_state;
171
+ snd_pcm_state_t suspended_state;
196172 u32 audio_tstamp_data;
197
- struct compat_timespec audio_tstamp;
198
- struct compat_timespec driver_tstamp;
173
+ s64 audio_tstamp_sec;
174
+ s64 audio_tstamp_nsec;
175
+ s64 driver_tstamp_sec;
176
+ s64 driver_tstamp_nsec;
199177 u32 audio_tstamp_accuracy;
200
- unsigned char reserved[52-2*sizeof(struct compat_timespec)];
201
-} __attribute__((packed));
202
-
203
-
204
-static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
205
- struct snd_pcm_status32 __user *src,
206
- bool ext)
207
-{
208
- struct snd_pcm_status status;
209
- int err;
210
-
211
- memset(&status, 0, sizeof(status));
212
- /*
213
- * with extension, parameters are read/write,
214
- * get audio_tstamp_data from user,
215
- * ignore rest of status structure
216
- */
217
- if (ext && get_user(status.audio_tstamp_data,
218
- (u32 __user *)(&src->audio_tstamp_data)))
219
- return -EFAULT;
220
- err = snd_pcm_status(substream, &status);
221
- if (err < 0)
222
- return err;
223
-
224
- if (clear_user(src, sizeof(*src)))
225
- return -EFAULT;
226
- if (put_user(status.state, &src->state) ||
227
- compat_put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) ||
228
- compat_put_timespec(&status.tstamp, &src->tstamp) ||
229
- put_user(status.appl_ptr, &src->appl_ptr) ||
230
- put_user(status.hw_ptr, &src->hw_ptr) ||
231
- put_user(status.delay, &src->delay) ||
232
- put_user(status.avail, &src->avail) ||
233
- put_user(status.avail_max, &src->avail_max) ||
234
- put_user(status.overrange, &src->overrange) ||
235
- put_user(status.suspended_state, &src->suspended_state) ||
236
- put_user(status.audio_tstamp_data, &src->audio_tstamp_data) ||
237
- compat_put_timespec(&status.audio_tstamp, &src->audio_tstamp) ||
238
- compat_put_timespec(&status.driver_tstamp, &src->driver_tstamp) ||
239
- put_user(status.audio_tstamp_accuracy, &src->audio_tstamp_accuracy))
240
- return -EFAULT;
241
-
242
- return err;
243
-}
244
-
245
-#ifdef CONFIG_X86_X32
246
-/* X32 ABI has 64bit timespec and 64bit alignment */
247
-struct snd_pcm_status_x32 {
248
- s32 state;
249
- u32 rsvd; /* alignment */
250
- struct timespec trigger_tstamp;
251
- struct timespec tstamp;
252
- u32 appl_ptr;
253
- u32 hw_ptr;
254
- s32 delay;
255
- u32 avail;
256
- u32 avail_max;
257
- u32 overrange;
258
- s32 suspended_state;
259
- u32 audio_tstamp_data;
260
- struct timespec audio_tstamp;
261
- struct timespec driver_tstamp;
262
- u32 audio_tstamp_accuracy;
263
- unsigned char reserved[52-2*sizeof(struct timespec)];
178
+ unsigned char reserved[52-4*sizeof(s64)];
264179 } __packed;
265180
266
-#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
267
-
268
-static int snd_pcm_status_user_x32(struct snd_pcm_substream *substream,
269
- struct snd_pcm_status_x32 __user *src,
270
- bool ext)
181
+static int snd_pcm_status_user_compat64(struct snd_pcm_substream *substream,
182
+ struct compat_snd_pcm_status64 __user *src,
183
+ bool ext)
271184 {
272
- struct snd_pcm_status status;
185
+ struct snd_pcm_status64 status;
186
+ struct compat_snd_pcm_status64 compat_status64;
273187 int err;
274188
275189 memset(&status, 0, sizeof(status));
190
+ memset(&compat_status64, 0, sizeof(compat_status64));
276191 /*
277192 * with extension, parameters are read/write,
278193 * get audio_tstamp_data from user,
....@@ -281,31 +196,39 @@
281196 if (ext && get_user(status.audio_tstamp_data,
282197 (u32 __user *)(&src->audio_tstamp_data)))
283198 return -EFAULT;
284
- err = snd_pcm_status(substream, &status);
199
+ err = snd_pcm_status64(substream, &status);
285200 if (err < 0)
286201 return err;
287202
288203 if (clear_user(src, sizeof(*src)))
289204 return -EFAULT;
290
- if (put_user(status.state, &src->state) ||
291
- put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) ||
292
- put_timespec(&status.tstamp, &src->tstamp) ||
293
- put_user(status.appl_ptr, &src->appl_ptr) ||
294
- put_user(status.hw_ptr, &src->hw_ptr) ||
295
- put_user(status.delay, &src->delay) ||
296
- put_user(status.avail, &src->avail) ||
297
- put_user(status.avail_max, &src->avail_max) ||
298
- put_user(status.overrange, &src->overrange) ||
299
- put_user(status.suspended_state, &src->suspended_state) ||
300
- put_user(status.audio_tstamp_data, &src->audio_tstamp_data) ||
301
- put_timespec(&status.audio_tstamp, &src->audio_tstamp) ||
302
- put_timespec(&status.driver_tstamp, &src->driver_tstamp) ||
303
- put_user(status.audio_tstamp_accuracy, &src->audio_tstamp_accuracy))
205
+
206
+ compat_status64 = (struct compat_snd_pcm_status64) {
207
+ .state = status.state,
208
+ .trigger_tstamp_sec = status.trigger_tstamp_sec,
209
+ .trigger_tstamp_nsec = status.trigger_tstamp_nsec,
210
+ .tstamp_sec = status.tstamp_sec,
211
+ .tstamp_nsec = status.tstamp_nsec,
212
+ .appl_ptr = status.appl_ptr,
213
+ .hw_ptr = status.hw_ptr,
214
+ .delay = status.delay,
215
+ .avail = status.avail,
216
+ .avail_max = status.avail_max,
217
+ .overrange = status.overrange,
218
+ .suspended_state = status.suspended_state,
219
+ .audio_tstamp_data = status.audio_tstamp_data,
220
+ .audio_tstamp_sec = status.audio_tstamp_sec,
221
+ .audio_tstamp_nsec = status.audio_tstamp_nsec,
222
+ .driver_tstamp_sec = status.audio_tstamp_sec,
223
+ .driver_tstamp_nsec = status.audio_tstamp_nsec,
224
+ .audio_tstamp_accuracy = status.audio_tstamp_accuracy,
225
+ };
226
+
227
+ if (copy_to_user(src, &compat_status64, sizeof(compat_status64)))
304228 return -EFAULT;
305229
306230 return err;
307231 }
308
-#endif /* CONFIG_X86_X32 */
309232
310233 /* both for HW_PARAMS and HW_REFINE */
311234 static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
....@@ -329,10 +252,14 @@
329252 goto error;
330253 }
331254
332
- if (refine)
255
+ if (refine) {
333256 err = snd_pcm_hw_refine(substream, data);
334
- else
257
+ if (err < 0)
258
+ goto error;
259
+ err = fixup_unreferenced_params(substream, data);
260
+ } else {
335261 err = snd_pcm_hw_params(substream, data);
262
+ }
336263 if (err < 0)
337264 goto error;
338265 if (copy_to_user(data32, data, sizeof(*data32)) ||
....@@ -450,102 +377,19 @@
450377 return err;
451378 }
452379
453
-
454
-struct snd_pcm_mmap_status32 {
455
- s32 state;
456
- s32 pad1;
457
- u32 hw_ptr;
458
- struct compat_timespec tstamp;
459
- s32 suspended_state;
460
- struct compat_timespec audio_tstamp;
461
-} __attribute__((packed));
462
-
463
-struct snd_pcm_mmap_control32 {
464
- u32 appl_ptr;
465
- u32 avail_min;
466
-};
467
-
468
-struct snd_pcm_sync_ptr32 {
469
- u32 flags;
470
- union {
471
- struct snd_pcm_mmap_status32 status;
472
- unsigned char reserved[64];
473
- } s;
474
- union {
475
- struct snd_pcm_mmap_control32 control;
476
- unsigned char reserved[64];
477
- } c;
478
-} __attribute__((packed));
479
-
480
-static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
481
- struct snd_pcm_sync_ptr32 __user *src)
482
-{
483
- struct snd_pcm_runtime *runtime = substream->runtime;
484
- volatile struct snd_pcm_mmap_status *status;
485
- volatile struct snd_pcm_mmap_control *control;
486
- u32 sflags;
487
- struct snd_pcm_mmap_control scontrol;
488
- struct snd_pcm_mmap_status sstatus;
489
- snd_pcm_uframes_t boundary;
490
- int err;
491
-
492
- if (snd_BUG_ON(!runtime))
493
- return -EINVAL;
494
-
495
- if (get_user(sflags, &src->flags) ||
496
- get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
497
- get_user(scontrol.avail_min, &src->c.control.avail_min))
498
- return -EFAULT;
499
- if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
500
- err = snd_pcm_hwsync(substream);
501
- if (err < 0)
502
- return err;
503
- }
504
- status = runtime->status;
505
- control = runtime->control;
506
- boundary = recalculate_boundary(runtime);
507
- if (! boundary)
508
- boundary = 0x7fffffff;
509
- snd_pcm_stream_lock_irq(substream);
510
- /* FIXME: we should consider the boundary for the sync from app */
511
- if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
512
- control->appl_ptr = scontrol.appl_ptr;
513
- else
514
- scontrol.appl_ptr = control->appl_ptr % boundary;
515
- if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
516
- control->avail_min = scontrol.avail_min;
517
- else
518
- scontrol.avail_min = control->avail_min;
519
- sstatus.state = status->state;
520
- sstatus.hw_ptr = status->hw_ptr % boundary;
521
- sstatus.tstamp = status->tstamp;
522
- sstatus.suspended_state = status->suspended_state;
523
- sstatus.audio_tstamp = status->audio_tstamp;
524
- snd_pcm_stream_unlock_irq(substream);
525
- if (put_user(sstatus.state, &src->s.status.state) ||
526
- put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
527
- compat_put_timespec(&sstatus.tstamp, &src->s.status.tstamp) ||
528
- put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
529
- compat_put_timespec(&sstatus.audio_tstamp,
530
- &src->s.status.audio_tstamp) ||
531
- put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
532
- put_user(scontrol.avail_min, &src->c.control.avail_min))
533
- return -EFAULT;
534
-
535
- return 0;
536
-}
537
-
538380 #ifdef CONFIG_X86_X32
539381 /* X32 ABI has 64bit timespec and 64bit alignment */
540382 struct snd_pcm_mmap_status_x32 {
541
- s32 state;
383
+ snd_pcm_state_t state;
542384 s32 pad1;
543385 u32 hw_ptr;
544386 u32 pad2; /* alignment */
545
- struct timespec tstamp;
546
- s32 suspended_state;
387
+ s64 tstamp_sec;
388
+ s64 tstamp_nsec;
389
+ snd_pcm_state_t suspended_state;
547390 s32 pad3;
548
- struct timespec audio_tstamp;
391
+ s64 audio_tstamp_sec;
392
+ s64 audio_tstamp_nsec;
549393 } __packed;
550394
551395 struct snd_pcm_mmap_control_x32 {
....@@ -613,9 +457,11 @@
613457 snd_pcm_stream_unlock_irq(substream);
614458 if (put_user(sstatus.state, &src->s.status.state) ||
615459 put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
616
- put_timespec(&sstatus.tstamp, &src->s.status.tstamp) ||
460
+ put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
461
+ put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp_nsec) ||
617462 put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
618
- put_timespec(&sstatus.audio_tstamp, &src->s.status.audio_tstamp) ||
463
+ put_user(sstatus.audio_tstamp.tv_sec, &src->s.status.audio_tstamp_sec) ||
464
+ put_user(sstatus.audio_tstamp.tv_nsec, &src->s.status.audio_tstamp_nsec) ||
619465 put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
620466 put_user(scontrol.avail_min, &src->c.control.avail_min))
621467 return -EFAULT;
....@@ -624,14 +470,84 @@
624470 }
625471 #endif /* CONFIG_X86_X32 */
626472
473
+#ifdef __BIG_ENDIAN
474
+typedef char __pad_before_u32[4];
475
+typedef char __pad_after_u32[0];
476
+#else
477
+typedef char __pad_before_u32[0];
478
+typedef char __pad_after_u32[4];
479
+#endif
480
+
481
+/* PCM 2.0.15 API definition had a bug in mmap control; it puts the avail_min
482
+ * at the wrong offset due to a typo in padding type.
483
+ * The bug hits only 32bit.
484
+ * A workaround for incorrect read/write is needed only in 32bit compat mode.
485
+ */
486
+struct __snd_pcm_mmap_control64_buggy {
487
+ __pad_before_u32 __pad1;
488
+ __u32 appl_ptr;
489
+ __pad_before_u32 __pad2; /* SiC! here is the bug */
490
+ __pad_before_u32 __pad3;
491
+ __u32 avail_min;
492
+ __pad_after_uframe __pad4;
493
+};
494
+
495
+static int snd_pcm_ioctl_sync_ptr_buggy(struct snd_pcm_substream *substream,
496
+ struct snd_pcm_sync_ptr __user *_sync_ptr)
497
+{
498
+ struct snd_pcm_runtime *runtime = substream->runtime;
499
+ struct snd_pcm_sync_ptr sync_ptr;
500
+ struct __snd_pcm_mmap_control64_buggy *sync_cp;
501
+ volatile struct snd_pcm_mmap_status *status;
502
+ volatile struct snd_pcm_mmap_control *control;
503
+ int err;
504
+
505
+ memset(&sync_ptr, 0, sizeof(sync_ptr));
506
+ sync_cp = (struct __snd_pcm_mmap_control64_buggy *)&sync_ptr.c.control;
507
+ if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
508
+ return -EFAULT;
509
+ if (copy_from_user(sync_cp, &(_sync_ptr->c.control), sizeof(*sync_cp)))
510
+ return -EFAULT;
511
+ status = runtime->status;
512
+ control = runtime->control;
513
+ if (sync_ptr.flags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
514
+ err = snd_pcm_hwsync(substream);
515
+ if (err < 0)
516
+ return err;
517
+ }
518
+ snd_pcm_stream_lock_irq(substream);
519
+ if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) {
520
+ err = pcm_lib_apply_appl_ptr(substream, sync_cp->appl_ptr);
521
+ if (err < 0) {
522
+ snd_pcm_stream_unlock_irq(substream);
523
+ return err;
524
+ }
525
+ } else {
526
+ sync_cp->appl_ptr = control->appl_ptr;
527
+ }
528
+ if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
529
+ control->avail_min = sync_cp->avail_min;
530
+ else
531
+ sync_cp->avail_min = control->avail_min;
532
+ sync_ptr.s.status.state = status->state;
533
+ sync_ptr.s.status.hw_ptr = status->hw_ptr;
534
+ sync_ptr.s.status.tstamp = status->tstamp;
535
+ sync_ptr.s.status.suspended_state = status->suspended_state;
536
+ sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
537
+ snd_pcm_stream_unlock_irq(substream);
538
+ if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
539
+ return -EFAULT;
540
+ return 0;
541
+}
542
+
627543 /*
628544 */
629545 enum {
630546 SNDRV_PCM_IOCTL_HW_REFINE32 = _IOWR('A', 0x10, struct snd_pcm_hw_params32),
631547 SNDRV_PCM_IOCTL_HW_PARAMS32 = _IOWR('A', 0x11, struct snd_pcm_hw_params32),
632548 SNDRV_PCM_IOCTL_SW_PARAMS32 = _IOWR('A', 0x13, struct snd_pcm_sw_params32),
633
- SNDRV_PCM_IOCTL_STATUS32 = _IOR('A', 0x20, struct snd_pcm_status32),
634
- SNDRV_PCM_IOCTL_STATUS_EXT32 = _IOWR('A', 0x24, struct snd_pcm_status32),
549
+ SNDRV_PCM_IOCTL_STATUS_COMPAT32 = _IOR('A', 0x20, struct snd_pcm_status32),
550
+ SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT32 = _IOWR('A', 0x24, struct snd_pcm_status32),
635551 SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32),
636552 SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct snd_pcm_channel_info32),
637553 SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32),
....@@ -640,11 +556,10 @@
640556 SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct snd_xferi32),
641557 SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32),
642558 SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
643
- SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32),
559
+ SNDRV_PCM_IOCTL_STATUS_COMPAT64 = _IOR('A', 0x20, struct compat_snd_pcm_status64),
560
+ SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64 = _IOWR('A', 0x24, struct compat_snd_pcm_status64),
644561 #ifdef CONFIG_X86_X32
645562 SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info),
646
- SNDRV_PCM_IOCTL_STATUS_X32 = _IOR('A', 0x20, struct snd_pcm_status_x32),
647
- SNDRV_PCM_IOCTL_STATUS_EXT_X32 = _IOWR('A', 0x24, struct snd_pcm_status_x32),
648563 SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32),
649564 #endif /* CONFIG_X86_X32 */
650565 };
....@@ -664,8 +579,8 @@
664579
665580 /*
666581 * When PCM is used on 32bit mode, we need to disable
667
- * mmap of PCM status/control records because of the size
668
- * incompatibility.
582
+ * mmap of the old PCM status/control records because
583
+ * of the size incompatibility.
669584 */
670585 pcm_file->no_compat_mmap = 1;
671586
....@@ -687,19 +602,24 @@
687602 case SNDRV_PCM_IOCTL_XRUN:
688603 case SNDRV_PCM_IOCTL_LINK:
689604 case SNDRV_PCM_IOCTL_UNLINK:
605
+ case __SNDRV_PCM_IOCTL_SYNC_PTR32:
690606 return snd_pcm_common_ioctl(file, substream, cmd, argp);
607
+ case __SNDRV_PCM_IOCTL_SYNC_PTR64:
608
+#ifdef CONFIG_X86_X32
609
+ if (in_x32_syscall())
610
+ return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
611
+#endif /* CONFIG_X86_X32 */
612
+ return snd_pcm_ioctl_sync_ptr_buggy(substream, argp);
691613 case SNDRV_PCM_IOCTL_HW_REFINE32:
692614 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
693615 case SNDRV_PCM_IOCTL_HW_PARAMS32:
694616 return snd_pcm_ioctl_hw_params_compat(substream, 0, argp);
695617 case SNDRV_PCM_IOCTL_SW_PARAMS32:
696618 return snd_pcm_ioctl_sw_params_compat(substream, argp);
697
- case SNDRV_PCM_IOCTL_STATUS32:
698
- return snd_pcm_status_user_compat(substream, argp, false);
699
- case SNDRV_PCM_IOCTL_STATUS_EXT32:
700
- return snd_pcm_status_user_compat(substream, argp, true);
701
- case SNDRV_PCM_IOCTL_SYNC_PTR32:
702
- return snd_pcm_ioctl_sync_ptr_compat(substream, argp);
619
+ case SNDRV_PCM_IOCTL_STATUS_COMPAT32:
620
+ return snd_pcm_status_user32(substream, argp, false);
621
+ case SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT32:
622
+ return snd_pcm_status_user32(substream, argp, true);
703623 case SNDRV_PCM_IOCTL_CHANNEL_INFO32:
704624 return snd_pcm_ioctl_channel_info_compat(substream, argp);
705625 case SNDRV_PCM_IOCTL_WRITEI_FRAMES32:
....@@ -716,13 +636,11 @@
716636 return snd_pcm_ioctl_rewind_compat(substream, argp);
717637 case SNDRV_PCM_IOCTL_FORWARD32:
718638 return snd_pcm_ioctl_forward_compat(substream, argp);
639
+ case SNDRV_PCM_IOCTL_STATUS_COMPAT64:
640
+ return snd_pcm_status_user_compat64(substream, argp, false);
641
+ case SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64:
642
+ return snd_pcm_status_user_compat64(substream, argp, true);
719643 #ifdef CONFIG_X86_X32
720
- case SNDRV_PCM_IOCTL_STATUS_X32:
721
- return snd_pcm_status_user_x32(substream, argp, false);
722
- case SNDRV_PCM_IOCTL_STATUS_EXT_X32:
723
- return snd_pcm_status_user_x32(substream, argp, true);
724
- case SNDRV_PCM_IOCTL_SYNC_PTR_X32:
725
- return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
726644 case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32:
727645 return snd_pcm_ioctl_channel_info_x32(substream, argp);
728646 #endif /* CONFIG_X86_X32 */