diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2006-03-21 11:58:48 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-22 10:43:02 +0100 |
commit | bb160b850d7e285f8b15906d9c0d1916acfdb953 (patch) | |
tree | 2bc00eb5f279a546df358f2159e805f461aa392f | |
parent | 97ec558a88fb03fa23aee0832a88964e76e4a4db (diff) | |
download | lwn-bb160b850d7e285f8b15906d9c0d1916acfdb953.tar.gz lwn-bb160b850d7e285f8b15906d9c0d1916acfdb953.zip |
[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>
-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) 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; } |