1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Advanced Linux Sound Architecture 4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 5 */ 6 7 #include <linux/init.h> 8 #include <linux/slab.h> 9 #include <linux/time.h> 10 #include <linux/device.h> 11 #include <linux/module.h> 12 #include <linux/debugfs.h> 13 #include <sound/core.h> 14 #include <sound/minors.h> 15 #include <sound/info.h> 16 #include <sound/control.h> 17 #include <sound/initval.h> 18 #include <linux/kmod.h> 19 #include <linux/mutex.h> 20 21 static int major = CONFIG_SND_MAJOR; 22 int snd_major; 23 EXPORT_SYMBOL(snd_major); 24 25 static int cards_limit = 1; 26 27 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 28 MODULE_DESCRIPTION("Advanced Linux Sound Architecture driver for soundcards."); 29 MODULE_LICENSE("GPL"); 30 module_param(major, int, 0444); 31 MODULE_PARM_DESC(major, "Major # for sound driver."); 32 module_param(cards_limit, int, 0444); 33 MODULE_PARM_DESC(cards_limit, "Count of auto-loadable soundcards."); 34 MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); 35 36 /* this one holds the actual max. card number currently available. 37 * as default, it's identical with cards_limit option. when more 38 * modules are loaded manually, this limit number increases, too. 39 */ 40 int snd_ecards_limit; 41 EXPORT_SYMBOL(snd_ecards_limit); 42 43 #ifdef CONFIG_SND_DEBUG 44 struct dentry *sound_debugfs_root; 45 EXPORT_SYMBOL_GPL(sound_debugfs_root); 46 #endif 47 48 static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; 49 static DEFINE_MUTEX(sound_mutex); 50 51 #ifdef CONFIG_MODULES 52 53 /** 54 * snd_request_card - try to load the card module 55 * @card: the card number 56 * 57 * Tries to load the module "snd-card-X" for the given card number 58 * via request_module. Returns immediately if already loaded. 59 */ 60 void snd_request_card(int card) 61 { 62 if (snd_card_locked(card)) 63 return; 64 if (card < 0 || card >= cards_limit) 65 return; 66 request_module("snd-card-%i", card); 67 } 68 EXPORT_SYMBOL(snd_request_card); 69 70 static void snd_request_other(int minor) 71 { 72 char *str; 73 74 switch (minor) { 75 case SNDRV_MINOR_SEQUENCER: str = "snd-seq"; break; 76 case SNDRV_MINOR_TIMER: str = "snd-timer"; break; 77 default: return; 78 } 79 request_module(str); 80 } 81 82 #endif /* modular kernel */ 83 84 /** 85 * snd_lookup_minor_data - get user data of a registered device 86 * @minor: the minor number 87 * @type: device type (SNDRV_DEVICE_TYPE_XXX) 88 * 89 * Checks that a minor device with the specified type is registered, and returns 90 * its user data pointer. 91 * 92 * This function increments the reference counter of the card instance 93 * if an associated instance with the given minor number and type is found. 94 * The caller must call snd_card_unref() appropriately later. 95 * 96 * Return: The user data pointer if the specified device is found. %NULL 97 * otherwise. 98 */ 99 void *snd_lookup_minor_data(unsigned int minor, int type) 100 { 101 struct snd_minor *mreg; 102 void *private_data; 103 104 if (minor >= ARRAY_SIZE(snd_minors)) 105 return NULL; 106 mutex_lock(&sound_mutex); 107 mreg = snd_minors[minor]; 108 if (mreg && mreg->type == type) { 109 private_data = mreg->private_data; 110 if (private_data && mreg->card_ptr) 111 get_device(&mreg->card_ptr->card_dev); 112 } else 113 private_data = NULL; 114 mutex_unlock(&sound_mutex); 115 return private_data; 116 } 117 EXPORT_SYMBOL(snd_lookup_minor_data); 118 119 #ifdef CONFIG_MODULES 120 static struct snd_minor *autoload_device(unsigned int minor) 121 { 122 int dev; 123 mutex_unlock(&sound_mutex); /* release lock temporarily */ 124 dev = SNDRV_MINOR_DEVICE(minor); 125 if (dev == SNDRV_MINOR_CONTROL) { 126 /* /dev/aloadC? */ 127 int card = SNDRV_MINOR_CARD(minor); 128 struct snd_card *ref = snd_card_ref(card); 129 if (!ref) 130 snd_request_card(card); 131 else 132 snd_card_unref(ref); 133 } else if (dev == SNDRV_MINOR_GLOBAL) { 134 /* /dev/aloadSEQ */ 135 snd_request_other(minor); 136 } 137 mutex_lock(&sound_mutex); /* reacuire lock */ 138 return snd_minors[minor]; 139 } 140 #else /* !CONFIG_MODULES */ 141 #define autoload_device(minor) NULL 142 #endif /* CONFIG_MODULES */ 143 144 static int snd_open(struct inode *inode, struct file *file) 145 { 146 unsigned int minor = iminor(inode); 147 struct snd_minor *mptr = NULL; 148 const struct file_operations *new_fops; 149 int err = 0; 150 151 if (minor >= ARRAY_SIZE(snd_minors)) 152 return -ENODEV; 153 mutex_lock(&sound_mutex); 154 mptr = snd_minors[minor]; 155 if (mptr == NULL) { 156 mptr = autoload_device(minor); 157 if (!mptr) { 158 mutex_unlock(&sound_mutex); 159 return -ENODEV; 160 } 161 } 162 new_fops = fops_get(mptr->f_ops); 163 mutex_unlock(&sound_mutex); 164 if (!new_fops) 165 return -ENODEV; 166 replace_fops(file, new_fops); 167 168 if (file->f_op->open) 169 err = file->f_op->open(inode, file); 170 return err; 171 } 172 173 static const struct file_operations snd_fops = 174 { 175 .owner = THIS_MODULE, 176 .open = snd_open, 177 .llseek = noop_llseek, 178 }; 179 180 #ifdef CONFIG_SND_DYNAMIC_MINORS 181 static int snd_find_free_minor(int type, struct snd_card *card, int dev) 182 { 183 int minor; 184 185 /* static minors for module auto loading */ 186 if (type == SNDRV_DEVICE_TYPE_SEQUENCER) 187 return SNDRV_MINOR_SEQUENCER; 188 if (type == SNDRV_DEVICE_TYPE_TIMER) 189 return SNDRV_MINOR_TIMER; 190 191 for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) { 192 /* skip static minors still used for module auto loading */ 193 if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL) 194 continue; 195 if (minor == SNDRV_MINOR_SEQUENCER || 196 minor == SNDRV_MINOR_TIMER) 197 continue; 198 if (!snd_minors[minor]) 199 return minor; 200 } 201 return -EBUSY; 202 } 203 #else 204 static int snd_find_free_minor(int type, struct snd_card *card, int dev) 205 { 206 int minor; 207 208 switch (type) { 209 case SNDRV_DEVICE_TYPE_SEQUENCER: 210 case SNDRV_DEVICE_TYPE_TIMER: 211 minor = type; 212 break; 213 case SNDRV_DEVICE_TYPE_CONTROL: 214 if (snd_BUG_ON(!card)) 215 return -EINVAL; 216 minor = SNDRV_MINOR(card->number, type); 217 break; 218 case SNDRV_DEVICE_TYPE_HWDEP: 219 case SNDRV_DEVICE_TYPE_RAWMIDI: 220 case SNDRV_DEVICE_TYPE_PCM_PLAYBACK: 221 case SNDRV_DEVICE_TYPE_PCM_CAPTURE: 222 case SNDRV_DEVICE_TYPE_COMPRESS: 223 if (snd_BUG_ON(!card)) 224 return -EINVAL; 225 minor = SNDRV_MINOR(card->number, type + dev); 226 break; 227 default: 228 return -EINVAL; 229 } 230 if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OS_MINORS)) 231 return -EINVAL; 232 if (snd_minors[minor]) 233 return -EBUSY; 234 return minor; 235 } 236 #endif 237 238 /** 239 * snd_register_device - Register the ALSA device file for the card 240 * @type: the device type, SNDRV_DEVICE_TYPE_XXX 241 * @card: the card instance 242 * @dev: the device index 243 * @f_ops: the file operations 244 * @private_data: user pointer for f_ops->open() 245 * @device: the device to register 246 * 247 * Registers an ALSA device file for the given card. 248 * The operators have to be set in reg parameter. 249 * 250 * Return: Zero if successful, or a negative error code on failure. 251 */ 252 int snd_register_device(int type, struct snd_card *card, int dev, 253 const struct file_operations *f_ops, 254 void *private_data, struct device *device) 255 { 256 int minor; 257 int err = 0; 258 struct snd_minor *preg; 259 260 if (snd_BUG_ON(!device)) 261 return -EINVAL; 262 263 preg = kmalloc(sizeof *preg, GFP_KERNEL); 264 if (preg == NULL) 265 return -ENOMEM; 266 preg->type = type; 267 preg->card = card ? card->number : -1; 268 preg->device = dev; 269 preg->f_ops = f_ops; 270 preg->private_data = private_data; 271 preg->card_ptr = card; 272 mutex_lock(&sound_mutex); 273 minor = snd_find_free_minor(type, card, dev); 274 if (minor < 0) { 275 err = minor; 276 goto error; 277 } 278 279 preg->dev = device; 280 device->devt = MKDEV(major, minor); 281 err = device_add(device); 282 if (err < 0) 283 goto error; 284 285 snd_minors[minor] = preg; 286 error: 287 mutex_unlock(&sound_mutex); 288 if (err < 0) 289 kfree(preg); 290 return err; 291 } 292 EXPORT_SYMBOL(snd_register_device); 293 294 /** 295 * snd_unregister_device - unregister the device on the given card 296 * @dev: the device instance 297 * 298 * Unregisters the device file already registered via 299 * snd_register_device(). 300 * 301 * Return: Zero if successful, or a negative error code on failure. 302 */ 303 int snd_unregister_device(struct device *dev) 304 { 305 int minor; 306 struct snd_minor *preg; 307 308 mutex_lock(&sound_mutex); 309 for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) { 310 preg = snd_minors[minor]; 311 if (preg && preg->dev == dev) { 312 snd_minors[minor] = NULL; 313 device_del(dev); 314 kfree(preg); 315 break; 316 } 317 } 318 mutex_unlock(&sound_mutex); 319 if (minor >= ARRAY_SIZE(snd_minors)) 320 return -ENOENT; 321 return 0; 322 } 323 EXPORT_SYMBOL(snd_unregister_device); 324 325 #ifdef CONFIG_SND_PROC_FS 326 /* 327 * INFO PART 328 */ 329 static const char *snd_device_type_name(int type) 330 { 331 switch (type) { 332 case SNDRV_DEVICE_TYPE_CONTROL: 333 return "control"; 334 case SNDRV_DEVICE_TYPE_HWDEP: 335 return "hardware dependent"; 336 case SNDRV_DEVICE_TYPE_RAWMIDI: 337 return "raw midi"; 338 case SNDRV_DEVICE_TYPE_PCM_PLAYBACK: 339 return "digital audio playback"; 340 case SNDRV_DEVICE_TYPE_PCM_CAPTURE: 341 return "digital audio capture"; 342 case SNDRV_DEVICE_TYPE_SEQUENCER: 343 return "sequencer"; 344 case SNDRV_DEVICE_TYPE_TIMER: 345 return "timer"; 346 case SNDRV_DEVICE_TYPE_COMPRESS: 347 return "compress"; 348 default: 349 return "?"; 350 } 351 } 352 353 static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 354 { 355 int minor; 356 struct snd_minor *mptr; 357 358 mutex_lock(&sound_mutex); 359 for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) { 360 if (!(mptr = snd_minors[minor])) 361 continue; 362 if (mptr->card >= 0) { 363 if (mptr->device >= 0) 364 snd_iprintf(buffer, "%3i: [%2i-%2i]: %s\n", 365 minor, mptr->card, mptr->device, 366 snd_device_type_name(mptr->type)); 367 else 368 snd_iprintf(buffer, "%3i: [%2i] : %s\n", 369 minor, mptr->card, 370 snd_device_type_name(mptr->type)); 371 } else 372 snd_iprintf(buffer, "%3i: : %s\n", minor, 373 snd_device_type_name(mptr->type)); 374 } 375 mutex_unlock(&sound_mutex); 376 } 377 378 int __init snd_minor_info_init(void) 379 { 380 struct snd_info_entry *entry; 381 382 entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL); 383 if (!entry) 384 return -ENOMEM; 385 entry->c.text.read = snd_minor_info_read; 386 return snd_info_register(entry); /* freed in error path */ 387 } 388 #endif /* CONFIG_SND_PROC_FS */ 389 390 /* 391 * INIT PART 392 */ 393 394 static int __init alsa_sound_init(void) 395 { 396 snd_major = major; 397 snd_ecards_limit = cards_limit; 398 if (register_chrdev(major, "alsa", &snd_fops)) { 399 pr_err("ALSA core: unable to register native major device number %d\n", major); 400 return -EIO; 401 } 402 if (snd_info_init() < 0) { 403 unregister_chrdev(major, "alsa"); 404 return -ENOMEM; 405 } 406 407 #ifdef CONFIG_SND_DEBUG 408 sound_debugfs_root = debugfs_create_dir("sound", NULL); 409 #endif 410 #ifndef MODULE 411 pr_info("Advanced Linux Sound Architecture Driver Initialized.\n"); 412 #endif 413 return 0; 414 } 415 416 static void __exit alsa_sound_exit(void) 417 { 418 #ifdef CONFIG_SND_DEBUG 419 debugfs_remove(sound_debugfs_root); 420 #endif 421 snd_info_done(); 422 unregister_chrdev(major, "alsa"); 423 } 424 425 subsys_initcall(alsa_sound_init); 426 module_exit(alsa_sound_exit); 427