aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_ca0132.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-02-10 05:58:40 -0500
committerTakashi Iwai <tiwai@suse.de>2013-02-10 05:58:40 -0500
commitb3667bd7579e6d4dfe709315f13cff9bc9ee9053 (patch)
tree6edfef15c2a1598de92c6fff7f17700ffb4ec53c /sound/pci/hda/patch_ca0132.c
parent6d67530e2c73e375b9204eba10ee2d589ba353ae (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.c10
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)
2065 struct ca0132_spec *spec = codec->spec; 2065 struct ca0132_spec *spec = codec->spec;
2066 int status; 2066 int status;
2067 2067
2068 if (dma->dmab) 2068 if (dma->dmab->area)
2069 snd_hda_codec_load_dsp_cleanup(codec, dma->dmab); 2069 snd_hda_codec_load_dsp_cleanup(codec, dma->dmab);
2070 2070
2071 status = snd_hda_codec_load_dsp_prepare(codec, 2071 status = snd_hda_codec_load_dsp_prepare(codec,
@@ -2357,10 +2357,14 @@ static int dspxfr_one_seg(struct hda_codec *codec,
2357 chip_addx_remainder, 2357 chip_addx_remainder,
2358 data_remainder, 2358 data_remainder,
2359 remainder_words); 2359 remainder_words);
2360 if (status < 0)
2361 return status;
2360 remainder_words = 0; 2362 remainder_words = 0;
2361 } 2363 }
2362 if (hci_write) { 2364 if (hci_write) {
2363 status = dspxfr_hci_write(codec, hci_write); 2365 status = dspxfr_hci_write(codec, hci_write);
2366 if (status < 0)
2367 return status;
2364 hci_write = NULL; 2368 hci_write = NULL;
2365 } 2369 }
2366 2370
@@ -2376,7 +2380,7 @@ static int dspxfr_one_seg(struct hda_codec *codec,
2376 2380
2377 snd_printdd(KERN_INFO "+++++ DMA complete"); 2381 snd_printdd(KERN_INFO "+++++ DMA complete");
2378 dma_set_state(dma_engine, DMA_STATE_STOP); 2382 dma_set_state(dma_engine, DMA_STATE_STOP);
2379 dma_reset(dma_engine); 2383 status = dma_reset(dma_engine);
2380 2384
2381 if (status < 0) 2385 if (status < 0)
2382 return status; 2386 return status;
@@ -2517,7 +2521,7 @@ exit:
2517 if (ovly && (dma_chan != INVALID_DMA_CHANNEL)) 2521 if (ovly && (dma_chan != INVALID_DMA_CHANNEL))
2518 dspio_free_dma_chan(codec, dma_chan); 2522 dspio_free_dma_chan(codec, dma_chan);
2519 2523
2520 if (dma_engine->dmab) 2524 if (dma_engine->dmab->area)
2521 snd_hda_codec_load_dsp_cleanup(codec, dma_engine->dmab); 2525 snd_hda_codec_load_dsp_cleanup(codec, dma_engine->dmab);
2522 kfree(dma_engine->dmab); 2526 kfree(dma_engine->dmab);
2523 kfree(dma_engine); 2527 kfree(dma_engine);