Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4cf19b84 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: Remove BKL from open multiplexer



Use a local mutex instead of BKL.  This should suffice since each device
type has also its open_mutex.
Also, a bit of clean-up of the legacy device auto-loading code.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 5b5cd553
Loading
Loading
Loading
Loading
+38 −35
Original line number Diff line number Diff line
@@ -120,19 +120,12 @@ void *snd_lookup_minor_data(unsigned int minor, int type)

EXPORT_SYMBOL(snd_lookup_minor_data);

static int __snd_open(struct inode *inode, struct file *file)
{
	unsigned int minor = iminor(inode);
	struct snd_minor *mptr = NULL;
	const struct file_operations *old_fops;
	int err = 0;

	if (minor >= ARRAY_SIZE(snd_minors))
		return -ENODEV;
	mptr = snd_minors[minor];
	if (mptr == NULL) {
#ifdef CONFIG_MODULES
		int dev = SNDRV_MINOR_DEVICE(minor);
static struct snd_minor *autoload_device(unsigned int minor)
{
	int dev;
	mutex_unlock(&sound_mutex); /* release lock temporarily */
	dev = SNDRV_MINOR_DEVICE(minor);
	if (dev == SNDRV_MINOR_CONTROL) {
		/* /dev/aloadC? */
		int card = SNDRV_MINOR_CARD(minor);
@@ -142,42 +135,52 @@ static int __snd_open(struct inode *inode, struct file *file)
		/* /dev/aloadSEQ */
		snd_request_other(minor);
	}
#ifndef CONFIG_SND_DYNAMIC_MINORS
		/* /dev/snd/{controlC?,seq} */
	mutex_lock(&sound_mutex); /* reacuire lock */
	return snd_minors[minor];
}
#else /* !CONFIG_MODULES */
#define autoload_device(minor)	NULL
#endif /* CONFIG_MODULES */

static int snd_open(struct inode *inode, struct file *file)
{
	unsigned int minor = iminor(inode);
	struct snd_minor *mptr = NULL;
	const struct file_operations *old_fops;
	int err = 0;

	if (minor >= ARRAY_SIZE(snd_minors))
		return -ENODEV;
	mutex_lock(&sound_mutex);
	mptr = snd_minors[minor];
		if (mptr == NULL)
#endif
#endif
	if (mptr == NULL) {
		mptr = autoload_device(minor);
		if (!mptr) {
			mutex_unlock(&sound_mutex);
			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;
		return -ENODEV;
		err = -ENODEV;
	}
	if (file->f_op->open)
	mutex_unlock(&sound_mutex);
	if (err < 0)
		return err;

	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;
}


/* BKL pushdown: nasty #ifdef avoidance wrapper */
static int snd_open(struct inode *inode, struct file *file)
{
	int ret;

	lock_kernel();
	ret = __snd_open(inode, file);
	unlock_kernel();
	return ret;
}

static const struct file_operations snd_fops =
{
	.owner =	THIS_MODULE,