--- zzzz-none-000/linux-3.10.107/sound/core/sound.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/sound/core/sound.c 2021-02-04 17:41:59.000000000 +0000 @@ -118,7 +118,7 @@ if (mreg && mreg->type == type) { private_data = mreg->private_data; if (private_data && mreg->card_ptr) - atomic_inc(&mreg->card_ptr->refcount); + get_device(&mreg->card_ptr->card_dev); } else private_data = NULL; mutex_unlock(&sound_mutex); @@ -153,7 +153,7 @@ { unsigned int minor = iminor(inode); struct snd_minor *mptr = NULL; - const struct file_operations *old_fops; + const struct file_operations *new_fops; int err = 0; if (minor >= ARRAY_SIZE(snd_minors)) @@ -167,24 +167,14 @@ return -ENODEV; } } - old_fops = file->f_op; - file->f_op = fops_get(mptr->f_ops); - if (file->f_op == NULL) { - file->f_op = old_fops; - err = -ENODEV; - } + new_fops = fops_get(mptr->f_ops); mutex_unlock(&sound_mutex); - if (err < 0) - return err; + if (!new_fops) + return -ENODEV; + replace_fops(file, new_fops); - if (file->f_op->open) { + if (file->f_op->open) err = file->f_op->open(inode, file); - if (err) { - fops_put(file->f_op); - file->f_op = fops_get(old_fops); - } - } - fops_put(old_fops); return err; } @@ -196,7 +186,7 @@ }; #ifdef CONFIG_SND_DYNAMIC_MINORS -static int snd_find_free_minor(int type) +static int snd_find_free_minor(int type, struct snd_card *card, int dev) { int minor; @@ -219,7 +209,7 @@ return -EBUSY; } #else -static int snd_kernel_minor(int type, struct snd_card *card, int dev) +static int snd_find_free_minor(int type, struct snd_card *card, int dev) { int minor; @@ -247,35 +237,37 @@ } if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OS_MINORS)) return -EINVAL; + if (snd_minors[minor]) + return -EBUSY; return minor; } #endif /** - * snd_register_device_for_dev - Register the ALSA device file for the card + * snd_register_device - Register the ALSA device file for the card * @type: the device type, SNDRV_DEVICE_TYPE_XXX * @card: the card instance * @dev: the device index * @f_ops: the file operations * @private_data: user pointer for f_ops->open() - * @name: the device file name - * @device: the &struct device to link this new device to + * @device: the device to register * * Registers an ALSA device file for the given card. * The operators have to be set in reg parameter. * * Return: Zero if successful, or a negative error code on failure. */ -int snd_register_device_for_dev(int type, struct snd_card *card, int dev, - const struct file_operations *f_ops, - void *private_data, - const char *name, struct device *device) +int snd_register_device(int type, struct snd_card *card, int dev, + const struct file_operations *f_ops, + void *private_data, struct device *device) { int minor; + int err = 0; struct snd_minor *preg; - if (snd_BUG_ON(!name)) + if (snd_BUG_ON(!device)) return -EINVAL; + preg = kmalloc(sizeof *preg, GFP_KERNEL); if (preg == NULL) return -ENOMEM; @@ -286,109 +278,62 @@ preg->private_data = private_data; preg->card_ptr = card; mutex_lock(&sound_mutex); -#ifdef CONFIG_SND_DYNAMIC_MINORS - minor = snd_find_free_minor(type); -#else - minor = snd_kernel_minor(type, card, dev); - if (minor >= 0 && snd_minors[minor]) - minor = -EBUSY; -#endif + minor = snd_find_free_minor(type, card, dev); if (minor < 0) { - mutex_unlock(&sound_mutex); - kfree(preg); - return minor; + err = minor; + goto error; } - snd_minors[minor] = preg; - preg->dev = device_create(sound_class, device, MKDEV(major, minor), - private_data, "%s", name); - if (IS_ERR(preg->dev)) { - snd_minors[minor] = NULL; - mutex_unlock(&sound_mutex); - minor = PTR_ERR(preg->dev); - kfree(preg); - return minor; - } - - mutex_unlock(&sound_mutex); - return 0; -} - -EXPORT_SYMBOL(snd_register_device_for_dev); -/* find the matching minor record - * return the index of snd_minor, or -1 if not found - */ -static int find_snd_minor(int type, struct snd_card *card, int dev) -{ - int cardnum, minor; - struct snd_minor *mptr; + preg->dev = device; + device->devt = MKDEV(major, minor); + err = device_add(device); + if (err < 0) + goto error; - cardnum = card ? card->number : -1; - for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) - if ((mptr = snd_minors[minor]) != NULL && - mptr->type == type && - mptr->card == cardnum && - mptr->device == dev) - return minor; - return -1; + snd_minors[minor] = preg; + error: + mutex_unlock(&sound_mutex); + if (err < 0) + kfree(preg); + return err; } +EXPORT_SYMBOL(snd_register_device); /** * snd_unregister_device - unregister the device on the given card - * @type: the device type, SNDRV_DEVICE_TYPE_XXX - * @card: the card instance - * @dev: the device index + * @dev: the device instance * * Unregisters the device file already registered via * snd_register_device(). * * Return: Zero if successful, or a negative error code on failure. */ -int snd_unregister_device(int type, struct snd_card *card, int dev) +int snd_unregister_device(struct device *dev) { int minor; + struct snd_minor *preg; mutex_lock(&sound_mutex); - minor = find_snd_minor(type, card, dev); - if (minor < 0) { - mutex_unlock(&sound_mutex); - return -EINVAL; + for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) { + preg = snd_minors[minor]; + if (preg && preg->dev == dev) { + snd_minors[minor] = NULL; + device_del(dev); + kfree(preg); + break; + } } - - device_destroy(sound_class, MKDEV(major, minor)); - - kfree(snd_minors[minor]); - snd_minors[minor] = NULL; mutex_unlock(&sound_mutex); + if (minor >= ARRAY_SIZE(snd_minors)) + return -ENOENT; return 0; } - EXPORT_SYMBOL(snd_unregister_device); -int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, - struct device_attribute *attr) -{ - int minor, ret = -EINVAL; - struct device *d; - - mutex_lock(&sound_mutex); - minor = find_snd_minor(type, card, dev); - if (minor >= 0 && (d = snd_minors[minor]->dev) != NULL) - ret = device_create_file(d, attr); - mutex_unlock(&sound_mutex); - return ret; - -} - -EXPORT_SYMBOL(snd_add_device_sysfs_file); - -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SND_PROC_FS /* * INFO PART */ - -static struct snd_info_entry *snd_minor_info_entry; - static const char *snd_device_type_name(int type) { switch (type) { @@ -441,23 +386,12 @@ struct snd_info_entry *entry; entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL); - if (entry) { - entry->c.text.read = snd_minor_info_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - snd_minor_info_entry = entry; - return 0; -} - -int __exit snd_minor_info_done(void) -{ - snd_info_free_entry(snd_minor_info_entry); - return 0; + if (!entry) + return -ENOMEM; + entry->c.text.read = snd_minor_info_read; + return snd_info_register(entry); /* freed in error path */ } -#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_SND_PROC_FS */ /* * INIT PART @@ -468,23 +402,21 @@ snd_major = major; snd_ecards_limit = cards_limit; if (register_chrdev(major, "alsa", &snd_fops)) { - snd_printk(KERN_ERR "unable to register native major device number %d\n", major); + pr_err("ALSA core: unable to register native major device number %d\n", major); return -EIO; } if (snd_info_init() < 0) { unregister_chrdev(major, "alsa"); return -ENOMEM; } - snd_info_minor_register(); #ifndef MODULE - printk(KERN_INFO "Advanced Linux Sound Architecture Driver Initialized.\n"); + pr_info("Advanced Linux Sound Architecture Driver Initialized.\n"); #endif return 0; } static void __exit alsa_sound_exit(void) { - snd_info_minor_unregister(); snd_info_done(); unregister_chrdev(major, "alsa"); }