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

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
...@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type) ...@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
EXPORT_SYMBOL(snd_lookup_minor_data); EXPORT_SYMBOL(snd_lookup_minor_data);
static int __snd_open(struct inode *inode, struct file *file) #ifdef CONFIG_MODULES
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);
if (snd_cards[card] == NULL)
snd_request_card(card);
} else if (dev == SNDRV_MINOR_GLOBAL) {
/* /dev/aloadSEQ */
snd_request_other(minor);
}
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); unsigned int minor = iminor(inode);
struct snd_minor *mptr = NULL; struct snd_minor *mptr = NULL;
...@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file) ...@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file)
if (minor >= ARRAY_SIZE(snd_minors)) if (minor >= ARRAY_SIZE(snd_minors))
return -ENODEV; return -ENODEV;
mutex_lock(&sound_mutex);
mptr = snd_minors[minor]; mptr = snd_minors[minor];
if (mptr == NULL) { if (mptr == NULL) {
#ifdef CONFIG_MODULES mptr = autoload_device(minor);
int dev = SNDRV_MINOR_DEVICE(minor); if (!mptr) {
if (dev == SNDRV_MINOR_CONTROL) { mutex_unlock(&sound_mutex);
/* /dev/aloadC? */
int card = SNDRV_MINOR_CARD(minor);
if (snd_cards[card] == NULL)
snd_request_card(card);
} else if (dev == SNDRV_MINOR_GLOBAL) {
/* /dev/aloadSEQ */
snd_request_other(minor);
}
#ifndef CONFIG_SND_DYNAMIC_MINORS
/* /dev/snd/{controlC?,seq} */
mptr = snd_minors[minor];
if (mptr == NULL)
#endif
#endif
return -ENODEV; return -ENODEV;
}
} }
old_fops = file->f_op; old_fops = file->f_op;
file->f_op = fops_get(mptr->f_ops); file->f_op = fops_get(mptr->f_ops);
if (file->f_op == NULL) { if (file->f_op == NULL) {
file->f_op = old_fops; 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); err = file->f_op->open(inode, file);
if (err) { if (err) {
fops_put(file->f_op); fops_put(file->f_op);
file->f_op = fops_get(old_fops); file->f_op = fops_get(old_fops);
}
} }
fops_put(old_fops); fops_put(old_fops);
return err; 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 = static const struct file_operations snd_fops =
{ {
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment