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