aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-11-21 03:08:06 -0500
committerTakashi Iwai <tiwai@suse.de>2008-11-21 03:08:06 -0500
commitb94d3539de59ec6481e38f83c455324fd3aeabc1 (patch)
treecc6034e70d130f02d0e87bcedb9fc4ccf71b66ce /sound
parent0623536ca3e8fd7cb8b7468b0fd4d61d80f0b6ea (diff)
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>
Diffstat (limited to 'sound')
-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 5d5e8012d6a5..a98ce5b11188 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)
464static int snd_hda_bus_dev_free(struct snd_device *device) 464static int snd_hda_bus_dev_free(struct snd_device *device)
465{ 465{
466 struct hda_bus *bus = device->device_data; 466 struct hda_bus *bus = device->device_data;
467 bus->shutdown = 1;
467 return snd_hda_bus_free(bus); 468 return snd_hda_bus_free(bus);
468} 469}
469 470
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index ee122b009fd4..a70b181bbace 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -617,6 +617,7 @@ struct hda_bus {
617 617
618 /* misc op flags */ 618 /* misc op flags */
619 unsigned int needs_damn_long_delay :1; 619 unsigned int needs_damn_long_delay :1;
620 unsigned int shutdown :1; /* being unloaded */
620}; 621};
621 622
622/* 623/*
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index a501c9121649..4fa5189264b7 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)
3921static void stac92xx_free_jacks(struct hda_codec *codec) 3921static void stac92xx_free_jacks(struct hda_codec *codec)
3922{ 3922{
3923#ifdef CONFIG_SND_JACK 3923#ifdef CONFIG_SND_JACK
3924 /* free jack instances manually when clearing/reconfiguring */
3924 struct sigmatel_spec *spec = codec->spec; 3925 struct sigmatel_spec *spec = codec->spec;
3925 if (spec->jacks.list) { 3926 if (!codec->bus->shutdown && spec->jacks.list) {
3926 struct sigmatel_jack *jacks = spec->jacks.list; 3927 struct sigmatel_jack *jacks = spec->jacks.list;
3927 int i; 3928 int i;
3928 for (i = 0; i < spec->jacks.used; i++) 3929 for (i = 0; i < spec->jacks.used; i++)