diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-03-21 10:07:13 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-22 04:43:56 -0500 |
commit | c6077b3000184c7f69c4798b9025e5fbd69c8c62 (patch) | |
tree | 7ba83932972197bc4f2fd2c29cf5448fc34c2d26 /sound | |
parent | c5c079e31cba3e6f93ef098911e216b79d0a84e8 (diff) |
[ALSA] Fix memory leaks in error path of control.c
Modules: Control Midlevel
Fix memory leaks in error path of control.c (only with CONFIG_SND_DEBUG=y).
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/control.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index 9742bdba0de1..574745314e70 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -309,28 +309,29 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
309 | { | 309 | { |
310 | struct snd_ctl_elem_id id; | 310 | struct snd_ctl_elem_id id; |
311 | unsigned int idx; | 311 | unsigned int idx; |
312 | int err = -EINVAL; | ||
312 | 313 | ||
313 | snd_assert(card != NULL, return -EINVAL); | ||
314 | if (! kcontrol) | 314 | if (! kcontrol) |
315 | return -EINVAL; | 315 | return err; |
316 | snd_assert(kcontrol->info != NULL, return -EINVAL); | 316 | snd_assert(card != NULL, goto error); |
317 | snd_assert(kcontrol->info != NULL, goto error); | ||
317 | id = kcontrol->id; | 318 | id = kcontrol->id; |
318 | down_write(&card->controls_rwsem); | 319 | down_write(&card->controls_rwsem); |
319 | if (snd_ctl_find_id(card, &id)) { | 320 | if (snd_ctl_find_id(card, &id)) { |
320 | up_write(&card->controls_rwsem); | 321 | up_write(&card->controls_rwsem); |
321 | snd_ctl_free_one(kcontrol); | ||
322 | snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n", | 322 | snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n", |
323 | id.iface, | 323 | id.iface, |
324 | id.device, | 324 | id.device, |
325 | id.subdevice, | 325 | id.subdevice, |
326 | id.name, | 326 | id.name, |
327 | id.index); | 327 | id.index); |
328 | return -EBUSY; | 328 | err = -EBUSY; |
329 | goto error; | ||
329 | } | 330 | } |
330 | if (snd_ctl_find_hole(card, kcontrol->count) < 0) { | 331 | if (snd_ctl_find_hole(card, kcontrol->count) < 0) { |
331 | up_write(&card->controls_rwsem); | 332 | up_write(&card->controls_rwsem); |
332 | snd_ctl_free_one(kcontrol); | 333 | err = -ENOMEM; |
333 | return -ENOMEM; | 334 | goto error; |
334 | } | 335 | } |
335 | list_add_tail(&kcontrol->list, &card->controls); | 336 | list_add_tail(&kcontrol->list, &card->controls); |
336 | card->controls_count += kcontrol->count; | 337 | card->controls_count += kcontrol->count; |
@@ -340,6 +341,10 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
340 | for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) | 341 | for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) |
341 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); | 342 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); |
342 | return 0; | 343 | return 0; |
344 | |||
345 | error: | ||
346 | snd_ctl_free_one(kcontrol); | ||
347 | return err; | ||
343 | } | 348 | } |
344 | 349 | ||
345 | /** | 350 | /** |