mirror of https://gitee.com/openkylin/linux.git
Merge branch 'topic/ctl-list-cleanup' into for-linus
This commit is contained in:
commit
65b3864b85
|
@ -97,9 +97,9 @@ struct snd_device {
|
||||||
|
|
||||||
struct snd_monitor_file {
|
struct snd_monitor_file {
|
||||||
struct file *file;
|
struct file *file;
|
||||||
struct snd_monitor_file *next;
|
|
||||||
const struct file_operations *disconnected_f_op;
|
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 */
|
/* main structure for soundcard */
|
||||||
|
@ -134,7 +134,7 @@ struct snd_card {
|
||||||
struct snd_info_entry *proc_id; /* the card id */
|
struct snd_info_entry *proc_id; /* the card id */
|
||||||
struct proc_dir_entry *proc_root_link; /* number link to real 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
|
struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown
|
||||||
state */
|
state */
|
||||||
spinlock_t files_lock; /* lock the files for this card */
|
spinlock_t files_lock; /* lock the files for this card */
|
||||||
|
|
|
@ -208,6 +208,7 @@ int snd_card_create(int idx, const char *xid,
|
||||||
INIT_LIST_HEAD(&card->controls);
|
INIT_LIST_HEAD(&card->controls);
|
||||||
INIT_LIST_HEAD(&card->ctl_files);
|
INIT_LIST_HEAD(&card->ctl_files);
|
||||||
spin_lock_init(&card->files_lock);
|
spin_lock_init(&card->files_lock);
|
||||||
|
INIT_LIST_HEAD(&card->files_list);
|
||||||
init_waitqueue_head(&card->shutdown_sleep);
|
init_waitqueue_head(&card->shutdown_sleep);
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
mutex_init(&card->power_lock);
|
mutex_init(&card->power_lock);
|
||||||
|
@ -274,6 +275,7 @@ static int snd_disconnect_release(struct inode *inode, struct file *file)
|
||||||
list_for_each_entry(_df, &shutdown_files, shutdown_list) {
|
list_for_each_entry(_df, &shutdown_files, shutdown_list) {
|
||||||
if (_df->file == file) {
|
if (_df->file == file) {
|
||||||
df = _df;
|
df = _df;
|
||||||
|
list_del_init(&df->shutdown_list);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,8 +364,7 @@ int snd_card_disconnect(struct snd_card *card)
|
||||||
/* phase 2: replace file->f_op with special dummy operations */
|
/* phase 2: replace file->f_op with special dummy operations */
|
||||||
|
|
||||||
spin_lock(&card->files_lock);
|
spin_lock(&card->files_lock);
|
||||||
mfile = card->files;
|
list_for_each_entry(mfile, &card->files_list, list) {
|
||||||
while (mfile) {
|
|
||||||
file = mfile->file;
|
file = mfile->file;
|
||||||
|
|
||||||
/* it's critical part, use endless loop */
|
/* it's critical part, use endless loop */
|
||||||
|
@ -376,8 +377,6 @@ int snd_card_disconnect(struct snd_card *card)
|
||||||
|
|
||||||
mfile->file->f_op = &snd_shutdown_f_ops;
|
mfile->file->f_op = &snd_shutdown_f_ops;
|
||||||
fops_get(mfile->file->f_op);
|
fops_get(mfile->file->f_op);
|
||||||
|
|
||||||
mfile = mfile->next;
|
|
||||||
}
|
}
|
||||||
spin_unlock(&card->files_lock);
|
spin_unlock(&card->files_lock);
|
||||||
|
|
||||||
|
@ -457,7 +456,7 @@ int snd_card_free_when_closed(struct snd_card *card)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
spin_lock(&card->files_lock);
|
spin_lock(&card->files_lock);
|
||||||
if (card->files == NULL)
|
if (list_empty(&card->files_list))
|
||||||
free_now = 1;
|
free_now = 1;
|
||||||
else
|
else
|
||||||
card->free_on_last_close = 1;
|
card->free_on_last_close = 1;
|
||||||
|
@ -477,7 +476,7 @@ int snd_card_free(struct snd_card *card)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* wait, until all devices are ready for the free operation */
|
/* 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);
|
snd_card_do_free(card);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -824,15 +823,13 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
mfile->file = file;
|
mfile->file = file;
|
||||||
mfile->disconnected_f_op = NULL;
|
mfile->disconnected_f_op = NULL;
|
||||||
mfile->next = NULL;
|
|
||||||
spin_lock(&card->files_lock);
|
spin_lock(&card->files_lock);
|
||||||
if (card->shutdown) {
|
if (card->shutdown) {
|
||||||
spin_unlock(&card->files_lock);
|
spin_unlock(&card->files_lock);
|
||||||
kfree(mfile);
|
kfree(mfile);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
mfile->next = card->files;
|
list_add(&mfile->list, &card->files_list);
|
||||||
card->files = mfile;
|
|
||||||
spin_unlock(&card->files_lock);
|
spin_unlock(&card->files_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -854,29 +851,20 @@ EXPORT_SYMBOL(snd_card_file_add);
|
||||||
*/
|
*/
|
||||||
int snd_card_file_remove(struct snd_card *card, struct file *file)
|
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;
|
int last_close = 0;
|
||||||
|
|
||||||
spin_lock(&card->files_lock);
|
spin_lock(&card->files_lock);
|
||||||
mfile = card->files;
|
list_for_each_entry(mfile, &card->files_list, list) {
|
||||||
while (mfile) {
|
|
||||||
if (mfile->file == file) {
|
if (mfile->file == file) {
|
||||||
if (pfile)
|
list_del(&mfile->list);
|
||||||
pfile->next = mfile->next;
|
if (mfile->disconnected_f_op)
|
||||||
else
|
fops_put(mfile->disconnected_f_op);
|
||||||
card->files = mfile->next;
|
found = mfile;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pfile = mfile;
|
|
||||||
mfile = mfile->next;
|
|
||||||
}
|
}
|
||||||
if (mfile && mfile->disconnected_f_op) {
|
if (list_empty(&card->files_list))
|
||||||
fops_put(mfile->disconnected_f_op);
|
|
||||||
spin_lock(&shutdown_lock);
|
|
||||||
list_del(&mfile->shutdown_list);
|
|
||||||
spin_unlock(&shutdown_lock);
|
|
||||||
}
|
|
||||||
if (card->files == NULL)
|
|
||||||
last_close = 1;
|
last_close = 1;
|
||||||
spin_unlock(&card->files_lock);
|
spin_unlock(&card->files_lock);
|
||||||
if (last_close) {
|
if (last_close) {
|
||||||
|
@ -884,11 +872,11 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
|
||||||
if (card->free_on_last_close)
|
if (card->free_on_last_close)
|
||||||
snd_card_do_free(card);
|
snd_card_do_free(card);
|
||||||
}
|
}
|
||||||
if (!mfile) {
|
if (!found) {
|
||||||
snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
|
snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
kfree(mfile);
|
kfree(found);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue