diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2006-03-21 05:58:48 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-22 04:43:02 -0500 |
commit | bb160b850d7e285f8b15906d9c0d1916acfdb953 (patch) | |
tree | 2bc00eb5f279a546df358f2159e805f461aa392f /sound/mips | |
parent | 97ec558a88fb03fa23aee0832a88964e76e4a4db (diff) |
[ALSA] AMD Au1x00: fix DMA init/cleanup
Modules: MIPS AU1x00 driver
AMD Au1x00 ALSA driver causes kernel oops in au1000_init() by trying
to set DMA channel to -1 in yet unallocated audio streams. Here's the
patch that staightens up DMA init/cleanup code.
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/mips')
-rw-r--r-- | sound/mips/au1x00.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index e66b0144e3b5..961453b77fc9 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c | |||
@@ -612,14 +612,17 @@ snd_au1000_free(struct snd_card *card) | |||
612 | release_and_free_resource(au1000->ac97_res_port); | 612 | release_and_free_resource(au1000->ac97_res_port); |
613 | } | 613 | } |
614 | 614 | ||
615 | if (au1000->stream[PLAYBACK]->dma >= 0) | 615 | if (au1000->stream[PLAYBACK]) { |
616 | free_au1000_dma(au1000->stream[PLAYBACK]->dma); | 616 | if (au1000->stream[PLAYBACK]->dma >= 0) |
617 | 617 | free_au1000_dma(au1000->stream[PLAYBACK]->dma); | |
618 | if (au1000->stream[CAPTURE]->dma >= 0) | 618 | kfree(au1000->stream[PLAYBACK]); |
619 | free_au1000_dma(au1000->stream[CAPTURE]->dma); | 619 | } |
620 | 620 | ||
621 | kfree(au1000->stream[PLAYBACK]); | 621 | if (au1000->stream[CAPTURE]) { |
622 | kfree(au1000->stream[CAPTURE]); | 622 | if (au1000->stream[CAPTURE]->dma >= 0) |
623 | free_au1000_dma(au1000->stream[CAPTURE]->dma); | ||
624 | kfree(au1000->stream[CAPTURE]); | ||
625 | } | ||
623 | } | 626 | } |
624 | 627 | ||
625 | 628 | ||
@@ -638,15 +641,19 @@ au1000_init(void) | |||
638 | 641 | ||
639 | card->private_free = snd_au1000_free; | 642 | card->private_free = snd_au1000_free; |
640 | au1000 = card->private_data; | 643 | au1000 = card->private_data; |
641 | /* so that snd_au1000_free will work as intended */ | ||
642 | au1000->card = card; | 644 | au1000->card = card; |
643 | au1000->stream[PLAYBACK]->dma = -1; | 645 | |
644 | au1000->stream[CAPTURE]->dma = -1; | ||
645 | au1000->ac97_res_port = NULL; | ||
646 | au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); | 646 | au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); |
647 | au1000->stream[CAPTURE] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); | 647 | au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); |
648 | /* so that snd_au1000_free will work as intended */ | ||
649 | au1000->ac97_res_port = NULL; | ||
650 | if (au1000->stream[PLAYBACK]) | ||
651 | au1000->stream[PLAYBACK]->dma = -1; | ||
652 | if (au1000->stream[CAPTURE ]) | ||
653 | au1000->stream[CAPTURE ]->dma = -1; | ||
654 | |||
648 | if (au1000->stream[PLAYBACK] == NULL || | 655 | if (au1000->stream[PLAYBACK] == NULL || |
649 | au1000->stream[CAPTURE] == NULL) { | 656 | au1000->stream[CAPTURE ] == NULL) { |
650 | snd_card_free(card); | 657 | snd_card_free(card); |
651 | return -ENOMEM; | 658 | return -ENOMEM; |
652 | } | 659 | } |