diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-02-10 11:58:40 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-02-10 11:58:40 +0100 |
commit | b3667bd7579e6d4dfe709315f13cff9bc9ee9053 (patch) | |
tree | 6edfef15c2a1598de92c6fff7f17700ffb4ec53c /sound/pci/hda/patch_ca0132.c | |
parent | 6d67530e2c73e375b9204eba10ee2d589ba353ae (diff) |
ALSA: hda - Fix memory leak and error handling in CA0132 DSP loader
This patch fixes a few obvious bugs in DSP loader stuff:
- Fix possible memory leaks in the error path
- Avoid double-free calls in dma_reset()
- Properly set/unset WC bits for DMA buffers
- Add missing error status checks
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_ca0132.c')
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 710dae81fc8e..fb7a32e730af 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -2065,7 +2065,7 @@ static int dma_reset(struct dma_engine *dma) struct ca0132_spec *spec = codec->spec; int status; - if (dma->dmab) + if (dma->dmab->area) snd_hda_codec_load_dsp_cleanup(codec, dma->dmab); status = snd_hda_codec_load_dsp_prepare(codec, @@ -2357,10 +2357,14 @@ static int dspxfr_one_seg(struct hda_codec *codec, chip_addx_remainder, data_remainder, remainder_words); + if (status < 0) + return status; remainder_words = 0; } if (hci_write) { status = dspxfr_hci_write(codec, hci_write); + if (status < 0) + return status; hci_write = NULL; } @@ -2376,7 +2380,7 @@ static int dspxfr_one_seg(struct hda_codec *codec, snd_printdd(KERN_INFO "+++++ DMA complete"); dma_set_state(dma_engine, DMA_STATE_STOP); - dma_reset(dma_engine); + status = dma_reset(dma_engine); if (status < 0) return status; @@ -2517,7 +2521,7 @@ exit: if (ovly && (dma_chan != INVALID_DMA_CHANNEL)) dspio_free_dma_chan(codec, dma_chan); - if (dma_engine->dmab) + if (dma_engine->dmab->area) snd_hda_codec_load_dsp_cleanup(codec, dma_engine->dmab); kfree(dma_engine->dmab); kfree(dma_engine); |