Commit 9e226b4b authored by Takashi Iwai's avatar Takashi Iwai

ALSA: vmaster - Free slave-links when freeing the master element

When freeing the vmaster master element, we should release slave-links
properly, not only assumig that slaves will be freed soon later.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent aeb4b88e
...@@ -52,6 +52,7 @@ struct link_slave { ...@@ -52,6 +52,7 @@ struct link_slave {
struct link_ctl_info info; struct link_ctl_info info;
int vals[2]; /* current values */ int vals[2]; /* current values */
unsigned int flags; unsigned int flags;
struct snd_kcontrol *kctl; /* original kcontrol pointer */
struct snd_kcontrol slave; /* the copy of original control entry */ struct snd_kcontrol slave; /* the copy of original control entry */
}; };
...@@ -252,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, ...@@ -252,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave,
slave->count * sizeof(*slave->vd), GFP_KERNEL); slave->count * sizeof(*slave->vd), GFP_KERNEL);
if (!srec) if (!srec)
return -ENOMEM; return -ENOMEM;
srec->kctl = slave;
srec->slave = *slave; srec->slave = *slave;
memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd));
srec->master = master_link; srec->master = master_link;
...@@ -333,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol, ...@@ -333,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol,
static void master_free(struct snd_kcontrol *kcontrol) static void master_free(struct snd_kcontrol *kcontrol)
{ {
struct link_master *master = snd_kcontrol_chip(kcontrol); struct link_master *master = snd_kcontrol_chip(kcontrol);
struct link_slave *slave; struct link_slave *slave, *n;
list_for_each_entry(slave, &master->slaves, list) /* free all slave links and retore the original slave kctls */
slave->master = NULL; list_for_each_entry_safe(slave, n, &master->slaves, list) {
struct snd_kcontrol *sctl = slave->kctl;
struct list_head olist = sctl->list;
memcpy(sctl, &slave->slave, sizeof(*sctl));
memcpy(sctl->vd, slave->slave.vd,
sctl->count * sizeof(*sctl->vd));
sctl->list = olist; /* keep the current linked-list */
kfree(slave);
}
kfree(master); kfree(master);
} }
......
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