root/sound/core/seq/oss/seq_oss.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. register_proc
  2. unregister_proc
  3. alsa_seq_oss_init
  4. alsa_seq_oss_exit
  5. module_init
  6. odev_release
  7. odev_read
  8. odev_write
  9. odev_ioctl
  10. odev_ioctl_compat
  11. odev_poll
  12. register_device
  13. unregister_device
  14. info_read
  15. register_proc
  16. unregister_proc

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * OSS compatible sequencer driver
   4  *
   5  * registration of device and proc
   6  *
   7  * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
   8  */
   9 
  10 #include <linux/init.h>
  11 #include <linux/module.h>
  12 #include <linux/mutex.h>
  13 #include <linux/compat.h>
  14 #include <sound/core.h>
  15 #include <sound/minors.h>
  16 #include <sound/initval.h>
  17 #include "seq_oss_device.h"
  18 #include "seq_oss_synth.h"
  19 
  20 /*
  21  * module option
  22  */
  23 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
  24 MODULE_DESCRIPTION("OSS-compatible sequencer module");
  25 MODULE_LICENSE("GPL");
  26 /* Takashi says this is really only for sound-service-0-, but this is OK. */
  27 MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_SEQUENCER);
  28 MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_MUSIC);
  29 
  30 
  31 /*
  32  * prototypes
  33  */
  34 static int register_device(void);
  35 static void unregister_device(void);
  36 #ifdef CONFIG_SND_PROC_FS
  37 static int register_proc(void);
  38 static void unregister_proc(void);
  39 #else
  40 static inline int register_proc(void) { return 0; }
  41 static inline void unregister_proc(void) {}
  42 #endif
  43 
  44 static int odev_open(struct inode *inode, struct file *file);
  45 static int odev_release(struct inode *inode, struct file *file);
  46 static ssize_t odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset);
  47 static ssize_t odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);
  48 static long odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
  49 static __poll_t odev_poll(struct file *file, poll_table * wait);
  50 
  51 
  52 /*
  53  * module interface
  54  */
  55 
  56 static struct snd_seq_driver seq_oss_synth_driver = {
  57         .driver = {
  58                 .name = KBUILD_MODNAME,
  59                 .probe = snd_seq_oss_synth_probe,
  60                 .remove = snd_seq_oss_synth_remove,
  61         },
  62         .id = SNDRV_SEQ_DEV_ID_OSS,
  63         .argsize = sizeof(struct snd_seq_oss_reg),
  64 };
  65 
  66 static int __init alsa_seq_oss_init(void)
  67 {
  68         int rc;
  69 
  70         if ((rc = register_device()) < 0)
  71                 goto error;
  72         if ((rc = register_proc()) < 0) {
  73                 unregister_device();
  74                 goto error;
  75         }
  76         if ((rc = snd_seq_oss_create_client()) < 0) {
  77                 unregister_proc();
  78                 unregister_device();
  79                 goto error;
  80         }
  81 
  82         rc = snd_seq_driver_register(&seq_oss_synth_driver);
  83         if (rc < 0) {
  84                 snd_seq_oss_delete_client();
  85                 unregister_proc();
  86                 unregister_device();
  87                 goto error;
  88         }
  89 
  90         /* success */
  91         snd_seq_oss_synth_init();
  92 
  93  error:
  94         return rc;
  95 }
  96 
  97 static void __exit alsa_seq_oss_exit(void)
  98 {
  99         snd_seq_driver_unregister(&seq_oss_synth_driver);
 100         snd_seq_oss_delete_client();
 101         unregister_proc();
 102         unregister_device();
 103 }
 104 
 105 module_init(alsa_seq_oss_init)
 106 module_exit(alsa_seq_oss_exit)
 107 
 108 /*
 109  * ALSA minor device interface
 110  */
 111 
 112 static DEFINE_MUTEX(register_mutex);
 113 
 114 static int
 115 odev_open(struct inode *inode, struct file *file)
 116 {
 117         int level, rc;
 118 
 119         if (iminor(inode) == SNDRV_MINOR_OSS_MUSIC)
 120                 level = SNDRV_SEQ_OSS_MODE_MUSIC;
 121         else
 122                 level = SNDRV_SEQ_OSS_MODE_SYNTH;
 123 
 124         mutex_lock(&register_mutex);
 125         rc = snd_seq_oss_open(file, level);
 126         mutex_unlock(&register_mutex);
 127 
 128         return rc;
 129 }
 130 
 131 static int
 132 odev_release(struct inode *inode, struct file *file)
 133 {
 134         struct seq_oss_devinfo *dp;
 135 
 136         if ((dp = file->private_data) == NULL)
 137                 return 0;
 138 
 139         mutex_lock(&register_mutex);
 140         snd_seq_oss_release(dp);
 141         mutex_unlock(&register_mutex);
 142 
 143         return 0;
 144 }
 145 
 146 static ssize_t
 147 odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 148 {
 149         struct seq_oss_devinfo *dp;
 150         dp = file->private_data;
 151         if (snd_BUG_ON(!dp))
 152                 return -ENXIO;
 153         return snd_seq_oss_read(dp, buf, count);
 154 }
 155 
 156 
 157 static ssize_t
 158 odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
 159 {
 160         struct seq_oss_devinfo *dp;
 161         dp = file->private_data;
 162         if (snd_BUG_ON(!dp))
 163                 return -ENXIO;
 164         return snd_seq_oss_write(dp, buf, count, file);
 165 }
 166 
 167 static long
 168 odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 169 {
 170         struct seq_oss_devinfo *dp;
 171         dp = file->private_data;
 172         if (snd_BUG_ON(!dp))
 173                 return -ENXIO;
 174         return snd_seq_oss_ioctl(dp, cmd, arg);
 175 }
 176 
 177 #ifdef CONFIG_COMPAT
 178 static long odev_ioctl_compat(struct file *file, unsigned int cmd,
 179                               unsigned long arg)
 180 {
 181         return odev_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
 182 }
 183 #else
 184 #define odev_ioctl_compat       NULL
 185 #endif
 186 
 187 static __poll_t
 188 odev_poll(struct file *file, poll_table * wait)
 189 {
 190         struct seq_oss_devinfo *dp;
 191         dp = file->private_data;
 192         if (snd_BUG_ON(!dp))
 193                 return EPOLLERR;
 194         return snd_seq_oss_poll(dp, file, wait);
 195 }
 196 
 197 /*
 198  * registration of sequencer minor device
 199  */
 200 
 201 static const struct file_operations seq_oss_f_ops =
 202 {
 203         .owner =        THIS_MODULE,
 204         .read =         odev_read,
 205         .write =        odev_write,
 206         .open =         odev_open,
 207         .release =      odev_release,
 208         .poll =         odev_poll,
 209         .unlocked_ioctl =       odev_ioctl,
 210         .compat_ioctl = odev_ioctl_compat,
 211         .llseek =       noop_llseek,
 212 };
 213 
 214 static int __init
 215 register_device(void)
 216 {
 217         int rc;
 218 
 219         mutex_lock(&register_mutex);
 220         if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
 221                                           NULL, 0,
 222                                           &seq_oss_f_ops, NULL)) < 0) {
 223                 pr_err("ALSA: seq_oss: can't register device seq\n");
 224                 mutex_unlock(&register_mutex);
 225                 return rc;
 226         }
 227         if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
 228                                           NULL, 0,
 229                                           &seq_oss_f_ops, NULL)) < 0) {
 230                 pr_err("ALSA: seq_oss: can't register device music\n");
 231                 snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0);
 232                 mutex_unlock(&register_mutex);
 233                 return rc;
 234         }
 235         mutex_unlock(&register_mutex);
 236         return 0;
 237 }
 238 
 239 static void
 240 unregister_device(void)
 241 {
 242         mutex_lock(&register_mutex);
 243         if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0)                
 244                 pr_err("ALSA: seq_oss: error unregister device music\n");
 245         if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0)
 246                 pr_err("ALSA: seq_oss: error unregister device seq\n");
 247         mutex_unlock(&register_mutex);
 248 }
 249 
 250 /*
 251  * /proc interface
 252  */
 253 
 254 #ifdef CONFIG_SND_PROC_FS
 255 
 256 static struct snd_info_entry *info_entry;
 257 
 258 static void
 259 info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
 260 {
 261         mutex_lock(&register_mutex);
 262         snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR);
 263         snd_seq_oss_system_info_read(buf);
 264         snd_seq_oss_synth_info_read(buf);
 265         snd_seq_oss_midi_info_read(buf);
 266         mutex_unlock(&register_mutex);
 267 }
 268 
 269 
 270 static int __init
 271 register_proc(void)
 272 {
 273         struct snd_info_entry *entry;
 274 
 275         entry = snd_info_create_module_entry(THIS_MODULE, SNDRV_SEQ_OSS_PROCNAME, snd_seq_root);
 276         if (entry == NULL)
 277                 return -ENOMEM;
 278 
 279         entry->content = SNDRV_INFO_CONTENT_TEXT;
 280         entry->private_data = NULL;
 281         entry->c.text.read = info_read;
 282         if (snd_info_register(entry) < 0) {
 283                 snd_info_free_entry(entry);
 284                 return -ENOMEM;
 285         }
 286         info_entry = entry;
 287         return 0;
 288 }
 289 
 290 static void
 291 unregister_proc(void)
 292 {
 293         snd_info_free_entry(info_entry);
 294         info_entry = NULL;
 295 }
 296 #endif /* CONFIG_SND_PROC_FS */

/* [<][>][^][v][top][bottom][index][help] */