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(&info, src, 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(ptr); 31 32 return snd_hwdep_dsp_load(hw, &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(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, (unsigned long)argp); 49 case SNDRV_HWDEP_IOCTL_DSP_LOAD32: 50 return snd_hwdep_dsp_load_compat(hw, argp); 51 } 52 if (hw->ops.ioctl_compat) 53 return hw->ops.ioctl_compat(hw, file, cmd, arg); 54 return -ENOIOCTLCMD; 55 } 56