1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * 32bit -> 64bit ioctl wrapper for hwdep API |
4 | * Copyright (c) by Takashi Iwai <tiwai@suse.de> |
5 | */ |
6 | |
7 | /* This file is included from hwdep.c */ |
8 | |
9 | #include <linux/compat.h> |
10 | |
11 | struct snd_hwdep_dsp_image32 { |
12 | u32 index; |
13 | unsigned char name[64]; |
14 | u32 image; /* pointer */ |
15 | u32 length; |
16 | u32 driver_data; |
17 | } /* don't set packed attribute here */; |
18 | |
19 | static int snd_hwdep_dsp_load_compat(struct snd_hwdep *hw, |
20 | struct snd_hwdep_dsp_image32 __user *src) |
21 | { |
22 | struct snd_hwdep_dsp_image info = {}; |
23 | compat_caddr_t ptr; |
24 | |
25 | if (copy_from_user(to: &info, from: src, n: 4 + 64) || |
26 | get_user(ptr, &src->image) || |
27 | get_user(info.length, &src->length) || |
28 | get_user(info.driver_data, &src->driver_data)) |
29 | return -EFAULT; |
30 | info.image = compat_ptr(uptr: ptr); |
31 | |
32 | return snd_hwdep_dsp_load(hw, info: &info); |
33 | } |
34 | |
35 | enum { |
36 | SNDRV_HWDEP_IOCTL_DSP_LOAD32 = _IOW('H', 0x03, struct snd_hwdep_dsp_image32) |
37 | }; |
38 | |
39 | static long snd_hwdep_ioctl_compat(struct file * file, unsigned int cmd, |
40 | unsigned long arg) |
41 | { |
42 | struct snd_hwdep *hw = file->private_data; |
43 | void __user *argp = compat_ptr(uptr: arg); |
44 | switch (cmd) { |
45 | case SNDRV_HWDEP_IOCTL_PVERSION: |
46 | case SNDRV_HWDEP_IOCTL_INFO: |
47 | case SNDRV_HWDEP_IOCTL_DSP_STATUS: |
48 | return snd_hwdep_ioctl(file, cmd, arg: (unsigned long)argp); |
49 | case SNDRV_HWDEP_IOCTL_DSP_LOAD32: |
50 | return snd_hwdep_dsp_load_compat(hw, src: argp); |
51 | } |
52 | if (hw->ops.ioctl_compat) |
53 | return hw->ops.ioctl_compat(hw, file, cmd, arg); |
54 | return -ENOIOCTLCMD; |
55 | } |
56 | |