diff options
author | Richard Fitzgerald <rf@opensource.wolfsonmicro.com> | 2013-02-11 08:44:53 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-02-11 09:03:48 -0500 |
commit | 17ac8e5c6d3478dcfeb75ed5716ca7e5cee612f0 (patch) | |
tree | dbf86ce267ccd64c980bc496145e596a97769520 /sound/core | |
parent | f664417e23192087bb9bdafdff80e04104994cc0 (diff) |
ALSA: core: don't return uninitialized snd_compr_tstamp
The snd_compr_update_tstamp() can only fill in the snd_compr_tstamp
if the codec implements the pointer() function. If that happened
the code was previously returning uninitialized garbage in the
tstamp because it wasn't initialized anywhere.
This change zero-fills the tstamp in the two places it is used
before calling snd_compr_update_tstamp(), and also has
snd_compr_update_tstamp() return an error indication if it
can't provide a tstamp. For the case of snd_compr_calc_avail()
it ignores this error because we still need to return info on
the available buffer space even if we can't provide tstamp
info - when the tstamp is not valid all fields are now
guaranteed to be zero.
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/compress_offload.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index ad11dc994792..2d620688cfb7 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c | |||
@@ -144,16 +144,17 @@ static int snd_compr_free(struct inode *inode, struct file *f) | |||
144 | return 0; | 144 | return 0; |
145 | } | 145 | } |
146 | 146 | ||
147 | static void snd_compr_update_tstamp(struct snd_compr_stream *stream, | 147 | static int snd_compr_update_tstamp(struct snd_compr_stream *stream, |
148 | struct snd_compr_tstamp *tstamp) | 148 | struct snd_compr_tstamp *tstamp) |
149 | { | 149 | { |
150 | if (!stream->ops->pointer) | 150 | if (!stream->ops->pointer) |
151 | return; | 151 | return -ENOTSUPP; |
152 | stream->ops->pointer(stream, tstamp); | 152 | stream->ops->pointer(stream, tstamp); |
153 | pr_debug("dsp consumed till %d total %d bytes\n", | 153 | pr_debug("dsp consumed till %d total %d bytes\n", |
154 | tstamp->byte_offset, tstamp->copied_total); | 154 | tstamp->byte_offset, tstamp->copied_total); |
155 | stream->runtime->hw_pointer = tstamp->byte_offset; | 155 | stream->runtime->hw_pointer = tstamp->byte_offset; |
156 | stream->runtime->total_bytes_transferred = tstamp->copied_total; | 156 | stream->runtime->total_bytes_transferred = tstamp->copied_total; |
157 | return 0; | ||
157 | } | 158 | } |
158 | 159 | ||
159 | static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, | 160 | static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, |
@@ -161,7 +162,9 @@ static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, | |||
161 | { | 162 | { |
162 | long avail_calc; /*this needs to be signed variable */ | 163 | long avail_calc; /*this needs to be signed variable */ |
163 | 164 | ||
165 | memset(avail, 0, sizeof(*avail)); | ||
164 | snd_compr_update_tstamp(stream, &avail->tstamp); | 166 | snd_compr_update_tstamp(stream, &avail->tstamp); |
167 | /* Still need to return avail even if tstamp can't be filled in */ | ||
165 | 168 | ||
166 | /* FIXME: This needs to be different for capture stream, | 169 | /* FIXME: This needs to be different for capture stream, |
167 | available is # of compressed data, for playback it's | 170 | available is # of compressed data, for playback it's |
@@ -517,11 +520,14 @@ out: | |||
517 | static inline int | 520 | static inline int |
518 | snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) | 521 | snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) |
519 | { | 522 | { |
520 | struct snd_compr_tstamp tstamp; | 523 | struct snd_compr_tstamp tstamp = {0}; |
524 | int ret; | ||
521 | 525 | ||
522 | snd_compr_update_tstamp(stream, &tstamp); | 526 | ret = snd_compr_update_tstamp(stream, &tstamp); |
523 | return copy_to_user((struct snd_compr_tstamp __user *)arg, | 527 | if (ret == 0) |
524 | &tstamp, sizeof(tstamp)) ? -EFAULT : 0; | 528 | ret = copy_to_user((struct snd_compr_tstamp __user *)arg, |
529 | &tstamp, sizeof(tstamp)) ? -EFAULT : 0; | ||
530 | return ret; | ||
525 | } | 531 | } |
526 | 532 | ||
527 | static int snd_compr_pause(struct snd_compr_stream *stream) | 533 | static int snd_compr_pause(struct snd_compr_stream *stream) |