~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/synth/emux/emux_hwdep.c

Version: ~ [ linux-5.16-rc1 ] ~ [ linux-5.15.2 ] ~ [ linux-5.14.18 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.79 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.159 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.217 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.255 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.290 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.292 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  *  Interface for hwdep device
  4  *
  5  *  Copyright (C) 2004 Takashi Iwai <tiwai@suse.de>
  6  */
  7 
  8 #include <sound/core.h>
  9 #include <sound/hwdep.h>
 10 #include <linux/uaccess.h>
 11 #include <linux/nospec.h>
 12 #include "emux_voice.h"
 13 
 14 #define TMP_CLIENT_ID   0x1001
 15 
 16 /*
 17  * load patch
 18  */
 19 static int
 20 snd_emux_hwdep_load_patch(struct snd_emux *emu, void __user *arg)
 21 {
 22         int err;
 23         struct soundfont_patch_info patch;
 24 
 25         if (copy_from_user(&patch, arg, sizeof(patch)))
 26                 return -EFAULT;
 27 
 28         if (patch.key == GUS_PATCH)
 29                 return snd_soundfont_load_guspatch(emu->sflist, arg,
 30                                                    patch.len + sizeof(patch),
 31                                                    TMP_CLIENT_ID);
 32 
 33         if (patch.type >= SNDRV_SFNT_LOAD_INFO &&
 34             patch.type <= SNDRV_SFNT_PROBE_DATA) {
 35                 err = snd_soundfont_load(emu->sflist, arg, patch.len + sizeof(patch), TMP_CLIENT_ID);
 36                 if (err < 0)
 37                         return err;
 38         } else {
 39                 if (emu->ops.load_fx)
 40                         return emu->ops.load_fx(emu, patch.type, patch.optarg, arg, patch.len + sizeof(patch));
 41                 else
 42                         return -EINVAL;
 43         }
 44         return 0;
 45 }
 46 
 47 /*
 48  * set misc mode
 49  */
 50 static int
 51 snd_emux_hwdep_misc_mode(struct snd_emux *emu, void __user *arg)
 52 {
 53         struct snd_emux_misc_mode info;
 54         int i;
 55 
 56         if (copy_from_user(&info, arg, sizeof(info)))
 57                 return -EFAULT;
 58         if (info.mode < 0 || info.mode >= EMUX_MD_END)
 59                 return -EINVAL;
 60         info.mode = array_index_nospec(info.mode, EMUX_MD_END);
 61 
 62         if (info.port < 0) {
 63                 for (i = 0; i < emu->num_ports; i++)
 64                         emu->portptrs[i]->ctrls[info.mode] = info.value;
 65         } else {
 66                 if (info.port < emu->num_ports) {
 67                         info.port = array_index_nospec(info.port, emu->num_ports);
 68                         emu->portptrs[info.port]->ctrls[info.mode] = info.value;
 69                 }
 70         }
 71         return 0;
 72 }
 73 
 74 
 75 /*
 76  * ioctl
 77  */
 78 static int
 79 snd_emux_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
 80                      unsigned int cmd, unsigned long arg)
 81 {
 82         struct snd_emux *emu = hw->private_data;
 83 
 84         switch (cmd) {
 85         case SNDRV_EMUX_IOCTL_VERSION:
 86                 return put_user(SNDRV_EMUX_VERSION, (unsigned int __user *)arg);
 87         case SNDRV_EMUX_IOCTL_LOAD_PATCH:
 88                 return snd_emux_hwdep_load_patch(emu, (void __user *)arg);
 89         case SNDRV_EMUX_IOCTL_RESET_SAMPLES:
 90                 snd_soundfont_remove_samples(emu->sflist);
 91                 break;
 92         case SNDRV_EMUX_IOCTL_REMOVE_LAST_SAMPLES:
 93                 snd_soundfont_remove_unlocked(emu->sflist);
 94                 break;
 95         case SNDRV_EMUX_IOCTL_MEM_AVAIL:
 96                 if (emu->memhdr) {
 97                         int size = snd_util_mem_avail(emu->memhdr);
 98                         return put_user(size, (unsigned int __user *)arg);
 99                 }
100                 break;
101         case SNDRV_EMUX_IOCTL_MISC_MODE:
102                 return snd_emux_hwdep_misc_mode(emu, (void __user *)arg);
103         }
104 
105         return 0;
106 }
107 
108 
109 /*
110  * register hwdep device
111  */
112 
113 int
114 snd_emux_init_hwdep(struct snd_emux *emu)
115 {
116         struct snd_hwdep *hw;
117         int err;
118 
119         if ((err = snd_hwdep_new(emu->card, SNDRV_EMUX_HWDEP_NAME, emu->hwdep_idx, &hw)) < 0)
120                 return err;
121         emu->hwdep = hw;
122         strcpy(hw->name, SNDRV_EMUX_HWDEP_NAME);
123         hw->iface = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE;
124         hw->ops.ioctl = snd_emux_hwdep_ioctl;
125         /* The ioctl parameter types are compatible between 32- and
126          * 64-bit architectures, so use the same function. */
127         hw->ops.ioctl_compat = snd_emux_hwdep_ioctl;
128         hw->exclusive = 1;
129         hw->private_data = emu;
130         if ((err = snd_card_register(emu->card)) < 0)
131                 return err;
132 
133         return 0;
134 }
135 
136 
137 /*
138  * unregister
139  */
140 void
141 snd_emux_delete_hwdep(struct snd_emux *emu)
142 {
143         if (emu->hwdep) {
144                 snd_device_free(emu->card, emu->hwdep);
145                 emu->hwdep = NULL;
146         }
147 }
148 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp