diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2006-08-28 07:00:45 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-09-23 04:44:35 -0400 |
commit | 99dabfe716002c54b4dffa545460dc74bc632c22 (patch) | |
tree | facabb1403341d689341481c02e9b90b20b2be60 | |
parent | aaad3653a5f073ce9eaef4efd387cf7fc3a53d18 (diff) |
[ALSA] dbri sparc: fixes TS leak
This patch fixes time slot leak in the dbri driver.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r-- | sound/sparc/dbri.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index cdca8e4a96e4..6b090fb66a8d 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c | |||
@@ -1044,7 +1044,7 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1044 | { | 1044 | { |
1045 | struct dbri_streaminfo *info = &dbri->stream_info[streamno]; | 1045 | struct dbri_streaminfo *info = &dbri->stream_info[streamno]; |
1046 | __u32 dvma_buffer; | 1046 | __u32 dvma_buffer; |
1047 | int desc = 0; | 1047 | int desc; |
1048 | int len; | 1048 | int len; |
1049 | int first_desc = -1; | 1049 | int first_desc = -1; |
1050 | int last_desc = -1; | 1050 | int last_desc = -1; |
@@ -1087,6 +1087,18 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1087 | len &= ~3; | 1087 | len &= ~3; |
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | /* Free descriptors if pipe has any */ | ||
1091 | desc = dbri->pipes[info->pipe].first_desc; | ||
1092 | if ( desc >= 0) | ||
1093 | do { | ||
1094 | dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0; | ||
1095 | desc = dbri->next_desc[desc]; | ||
1096 | } while (desc != -1 && desc != dbri->pipes[info->pipe].first_desc); | ||
1097 | |||
1098 | dbri->pipes[info->pipe].desc = -1; | ||
1099 | dbri->pipes[info->pipe].first_desc = -1; | ||
1100 | |||
1101 | desc = 0; | ||
1090 | while (len > 0) { | 1102 | while (len > 0) { |
1091 | int mylen; | 1103 | int mylen; |
1092 | 1104 | ||
@@ -2054,6 +2066,7 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream) | |||
2054 | struct snd_dbri *dbri = snd_pcm_substream_chip(substream); | 2066 | struct snd_dbri *dbri = snd_pcm_substream_chip(substream); |
2055 | struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream); | 2067 | struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream); |
2056 | int direction; | 2068 | int direction; |
2069 | |||
2057 | dprintk(D_USR, "hw_free.\n"); | 2070 | dprintk(D_USR, "hw_free.\n"); |
2058 | 2071 | ||
2059 | /* hw_free can get called multiple times. Only unmap the DMA once. | 2072 | /* hw_free can get called multiple times. Only unmap the DMA once. |
@@ -2068,7 +2081,10 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream) | |||
2068 | substream->runtime->buffer_size, direction); | 2081 | substream->runtime->buffer_size, direction); |
2069 | info->dvma_buffer = 0; | 2082 | info->dvma_buffer = 0; |
2070 | } | 2083 | } |
2071 | info->pipe = -1; | 2084 | if (info->pipe != -1) { |
2085 | reset_pipe(dbri, info->pipe); | ||
2086 | info->pipe = -1; | ||
2087 | } | ||
2072 | 2088 | ||
2073 | return snd_pcm_lib_free_pages(substream); | 2089 | return snd_pcm_lib_free_pages(substream); |
2074 | } | 2090 | } |