summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-11-21 08:08:06 (GMT)
committerTakashi Iwai <tiwai@suse.de>2008-11-21 08:08:06 (GMT)
commitb94d3539de59ec6481e38f83c455324fd3aeabc1 (patch)
treecc6034e70d130f02d0e87bcedb9fc4ccf71b66ce
parent0623536ca3e8fd7cb8b7468b0fd4d61d80f0b6ea (diff)
downloadlinux-b94d3539de59ec6481e38f83c455324fd3aeabc1.tar.xz
ALSA: hda - Fix double free of jack instances
The jack instances created in patch_sigmatel.c may be double-freed. The device management code checks the invalid element, and thus there is no real breakage, but it spews annoying warning messages. But, we can't simply remove the release calls of these jack instances because they have to be freed when the codec is re-configured. Now, a new flag, bus->shutdown is introduced to indicate that the bus is really being unloaded, i.e. the objects managed by the device manager will be automatically deleted. We release these objects only when this flag isn't set. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_codec.c1
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/patch_sigmatel.c3
3 files changed, 4 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 5d5e801..a98ce5b 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -464,6 +464,7 @@ static int snd_hda_bus_free(struct hda_bus *bus)
static int snd_hda_bus_dev_free(struct snd_device *device)
{
struct hda_bus *bus = device->device_data;
+ bus->shutdown = 1;
return snd_hda_bus_free(bus);
}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index ee122b0..a70b181 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -617,6 +617,7 @@ struct hda_bus {
/* misc op flags */
unsigned int needs_damn_long_delay :1;
+ unsigned int shutdown :1; /* being unloaded */
};
/*
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index a501c91..4fa5189 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -3921,8 +3921,9 @@ static int stac92xx_init(struct hda_codec *codec)
static void stac92xx_free_jacks(struct hda_codec *codec)
{
#ifdef CONFIG_SND_JACK
+ /* free jack instances manually when clearing/reconfiguring */
struct sigmatel_spec *spec = codec->spec;
- if (spec->jacks.list) {
+ if (!codec->bus->shutdown && spec->jacks.list) {
struct sigmatel_jack *jacks = spec->jacks.list;
int i;
for (i = 0; i < spec->jacks.used; i++)