Commit bb160b850d7e285f8b15906d9c0d1916acfdb953
Committed by
Jaroslav Kysela
1 parent
97ec558a88
Exists in
master
and in
4 other branches
[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>
Showing 1 changed file with 20 additions and 13 deletions Side-by-side Diff
sound/mips/au1x00.c
... | ... | @@ -612,14 +612,17 @@ |
612 | 612 | release_and_free_resource(au1000->ac97_res_port); |
613 | 613 | } |
614 | 614 | |
615 | - if (au1000->stream[PLAYBACK]->dma >= 0) | |
616 | - free_au1000_dma(au1000->stream[PLAYBACK]->dma); | |
615 | + if (au1000->stream[PLAYBACK]) { | |
616 | + if (au1000->stream[PLAYBACK]->dma >= 0) | |
617 | + free_au1000_dma(au1000->stream[PLAYBACK]->dma); | |
618 | + kfree(au1000->stream[PLAYBACK]); | |
619 | + } | |
617 | 620 | |
618 | - if (au1000->stream[CAPTURE]->dma >= 0) | |
619 | - free_au1000_dma(au1000->stream[CAPTURE]->dma); | |
620 | - | |
621 | - kfree(au1000->stream[PLAYBACK]); | |
622 | - kfree(au1000->stream[CAPTURE]); | |
621 | + if (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 | |
626 | 629 | |
627 | 630 | |
628 | 631 | |
... | ... | @@ -638,15 +641,19 @@ |
638 | 641 | |
639 | 642 | card->private_free = snd_au1000_free; |
640 | 643 | au1000 = card->private_data; |
641 | - /* so that snd_au1000_free will work as intended */ | |
642 | 644 | au1000->card = card; |
643 | - au1000->stream[PLAYBACK]->dma = -1; | |
644 | - au1000->stream[CAPTURE]->dma = -1; | |
645 | - au1000->ac97_res_port = NULL; | |
645 | + | |
646 | 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 | 655 | if (au1000->stream[PLAYBACK] == NULL || |
649 | - au1000->stream[CAPTURE] == NULL) { | |
656 | + au1000->stream[CAPTURE ] == NULL) { | |
650 | 657 | snd_card_free(card); |
651 | 658 | return -ENOMEM; |
652 | 659 | } |