ASoC: compress: Correct handling of copy callback

The soc_compr_copy callback is currently broken. Since the
changes to move the compr_ops over to the component the return
value is not correctly propagated, always returning zero on
success rather than the number of bytes copied. This causes
user-space to stall continuously reading as it does not believe
it has received any data.

Furthermore, the changes to move the compr_ops over to the
component iterate through the list of components and will call
the copy callback for any that have compressed ops. There isn't
currently any consensus on the mechanism to combine the results
of multiple copy callbacks.

To fix this issue for now halt searching the component list when
we locate a copy callback and return the result of that single
callback. Additional work should probably be done to look at the
other ops, tidy things up, and work out if we want to support
multiple components on a single compressed, but this is the only
fix required to get things working again.

Fixes: 9e7e3738ab ("ASoC: snd_soc_component_driver has snd_compr_ops")
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
This commit is contained in:
Charles Keepax 2018-01-26 13:08:43 +00:00 committed by Mark Brown
parent 4fbd8d194f
commit 290df4d3ab
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0

View file

@ -944,7 +944,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_component *component;
struct snd_soc_rtdcom_list *rtdcom;
int ret = 0, __ret;
int ret = 0;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@ -965,10 +965,10 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
!component->driver->compr_ops->copy)
continue;
__ret = component->driver->compr_ops->copy(cstream, buf, count);
if (__ret < 0)
ret = __ret;
ret = component->driver->compr_ops->copy(cstream, buf, count);
break;
}
err:
mutex_unlock(&rtd->pcm_mutex);
return ret;