From bb160b850d7e285f8b15906d9c0d1916acfdb953 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 21 Mar 2006 11:58:48 +0100 Subject: [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 Signed-off-by: Takashi Iwai --- sound/mips/au1x00.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'sound') diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index e66b014..961453b 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c @@ -612,14 +612,17 @@ snd_au1000_free(struct snd_card *card) release_and_free_resource(au1000->ac97_res_port); } - if (au1000->stream[PLAYBACK]->dma >= 0) - free_au1000_dma(au1000->stream[PLAYBACK]->dma); - - if (au1000->stream[CAPTURE]->dma >= 0) - free_au1000_dma(au1000->stream[CAPTURE]->dma); + if (au1000->stream[PLAYBACK]) { + if (au1000->stream[PLAYBACK]->dma >= 0) + free_au1000_dma(au1000->stream[PLAYBACK]->dma); + kfree(au1000->stream[PLAYBACK]); + } - kfree(au1000->stream[PLAYBACK]); - kfree(au1000->stream[CAPTURE]); + if (au1000->stream[CAPTURE]) { + if (au1000->stream[CAPTURE]->dma >= 0) + free_au1000_dma(au1000->stream[CAPTURE]->dma); + kfree(au1000->stream[CAPTURE]); + } } @@ -638,15 +641,19 @@ au1000_init(void) card->private_free = snd_au1000_free; au1000 = card->private_data; - /* so that snd_au1000_free will work as intended */ au1000->card = card; - au1000->stream[PLAYBACK]->dma = -1; - au1000->stream[CAPTURE]->dma = -1; - au1000->ac97_res_port = NULL; + au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); - au1000->stream[CAPTURE] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); + au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); + /* so that snd_au1000_free will work as intended */ + au1000->ac97_res_port = NULL; + if (au1000->stream[PLAYBACK]) + au1000->stream[PLAYBACK]->dma = -1; + if (au1000->stream[CAPTURE ]) + au1000->stream[CAPTURE ]->dma = -1; + if (au1000->stream[PLAYBACK] == NULL || - au1000->stream[CAPTURE] == NULL) { + au1000->stream[CAPTURE ] == NULL) { snd_card_free(card); return -ENOMEM; } -- cgit v1.1