Commit 118dd6bf authored by Takashi Iwai's avatar Takashi Iwai

ALSA: Clean up snd_monitor_file management

Use the standard linked list for snd_monitor_file management.
Also, move the list deletion of shutdown_list element into
snd_disconnect_release() (for simplification).
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent fec6c6fe
......@@ -97,9 +97,9 @@ struct snd_device {
struct snd_monitor_file {
struct file *file;
struct snd_monitor_file *next;
const struct file_operations *disconnected_f_op;
struct list_head shutdown_list;
struct list_head shutdown_list; /* still need to shutdown */
struct list_head list; /* link of monitor files */
};
/* main structure for soundcard */
......@@ -134,7 +134,7 @@ struct snd_card {
struct snd_info_entry *proc_id; /* the card id */
struct proc_dir_entry *proc_root_link; /* number link to real id */
struct snd_monitor_file *files; /* all files associated to this card */
struct list_head files_list; /* all files associated to this card */
struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown
state */
spinlock_t files_lock; /* lock the files for this card */
......
......@@ -195,6 +195,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
INIT_LIST_HEAD(&card->controls);
INIT_LIST_HEAD(&card->ctl_files);
spin_lock_init(&card->files_lock);
INIT_LIST_HEAD(&card->files_list);
init_waitqueue_head(&card->shutdown_sleep);
#ifdef CONFIG_PM
mutex_init(&card->power_lock);
......@@ -259,6 +260,7 @@ static int snd_disconnect_release(struct inode *inode, struct file *file)
list_for_each_entry(_df, &shutdown_files, shutdown_list) {
if (_df->file == file) {
df = _df;
list_del_init(&df->shutdown_list);
break;
}
}
......@@ -347,8 +349,7 @@ int snd_card_disconnect(struct snd_card *card)
/* phase 2: replace file->f_op with special dummy operations */
spin_lock(&card->files_lock);
mfile = card->files;
while (mfile) {
list_for_each_entry(mfile, &card->files_list, list) {
file = mfile->file;
/* it's critical part, use endless loop */
......@@ -361,8 +362,6 @@ int snd_card_disconnect(struct snd_card *card)
mfile->file->f_op = &snd_shutdown_f_ops;
fops_get(mfile->file->f_op);
mfile = mfile->next;
}
spin_unlock(&card->files_lock);
......@@ -442,7 +441,7 @@ int snd_card_free_when_closed(struct snd_card *card)
return ret;
spin_lock(&card->files_lock);
if (card->files == NULL)
if (list_empty(&card->files_list))
free_now = 1;
else
card->free_on_last_close = 1;
......@@ -462,7 +461,7 @@ int snd_card_free(struct snd_card *card)
return ret;
/* wait, until all devices are ready for the free operation */
wait_event(card->shutdown_sleep, card->files == NULL);
wait_event(card->shutdown_sleep, list_empty(&card->files_list));
snd_card_do_free(card);
return 0;
}
......@@ -809,15 +808,13 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
return -ENOMEM;
mfile->file = file;
mfile->disconnected_f_op = NULL;
mfile->next = NULL;
spin_lock(&card->files_lock);
if (card->shutdown) {
spin_unlock(&card->files_lock);
kfree(mfile);
return -ENODEV;
}
mfile->next = card->files;
card->files = mfile;
list_add(&mfile->list, &card->files_list);
spin_unlock(&card->files_lock);
return 0;
}
......@@ -839,29 +836,20 @@ EXPORT_SYMBOL(snd_card_file_add);
*/
int snd_card_file_remove(struct snd_card *card, struct file *file)
{
struct snd_monitor_file *mfile, *pfile = NULL;
struct snd_monitor_file *mfile, *found = NULL;
int last_close = 0;
spin_lock(&card->files_lock);
mfile = card->files;
while (mfile) {
list_for_each_entry(mfile, &card->files_list, list) {
if (mfile->file == file) {
if (pfile)
pfile->next = mfile->next;
else
card->files = mfile->next;
list_del(&mfile->list);
if (mfile->disconnected_f_op)
fops_put(mfile->disconnected_f_op);
found = mfile;
break;
}
pfile = mfile;
mfile = mfile->next;
}
if (mfile && mfile->disconnected_f_op) {
fops_put(mfile->disconnected_f_op);
spin_lock(&shutdown_lock);
list_del(&mfile->shutdown_list);
spin_unlock(&shutdown_lock);
}
if (card->files == NULL)
if (list_empty(&card->files_list))
last_close = 1;
spin_unlock(&card->files_lock);
if (last_close) {
......@@ -869,11 +857,11 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
if (card->free_on_last_close)
snd_card_do_free(card);
}
if (!mfile) {
if (!found) {
snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
return -ENOENT;
}
kfree(mfile);
kfree(found);
return 0;
}
......
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