Updated from Linux LTS 3.10.20 to 3.10.21
This commit is contained in:
@@ -668,14 +668,48 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
|
||||
return -EPERM;
|
||||
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
|
||||
if (!retval) {
|
||||
stream->runtime->state = SNDRV_PCM_STATE_SETUP;
|
||||
wake_up(&stream->runtime->sleep);
|
||||
snd_compr_drain_notify(stream);
|
||||
stream->runtime->total_bytes_available = 0;
|
||||
stream->runtime->total_bytes_transferred = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* We are called with lock held. So drop the lock while we wait for
|
||||
* drain complete notfication from the driver
|
||||
*
|
||||
* It is expected that driver will notify the drain completion and then
|
||||
* stream will be moved to SETUP state, even if draining resulted in an
|
||||
* error. We can trigger next track after this.
|
||||
*/
|
||||
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
|
||||
mutex_unlock(&stream->device->lock);
|
||||
|
||||
/* we wait for drain to complete here, drain can return when
|
||||
* interruption occurred, wait returned error or success.
|
||||
* For the first two cases we don't do anything different here and
|
||||
* return after waking up
|
||||
*/
|
||||
|
||||
ret = wait_event_interruptible(stream->runtime->sleep,
|
||||
(stream->runtime->state != SNDRV_PCM_STATE_DRAINING));
|
||||
if (ret == -ERESTARTSYS)
|
||||
pr_debug("wait aborted by a signal");
|
||||
else if (ret)
|
||||
pr_debug("wait for drain failed with %d\n", ret);
|
||||
|
||||
|
||||
wake_up(&stream->runtime->sleep);
|
||||
mutex_lock(&stream->device->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int snd_compr_drain(struct snd_compr_stream *stream)
|
||||
{
|
||||
int retval;
|
||||
@@ -683,12 +717,15 @@ static int snd_compr_drain(struct snd_compr_stream *stream)
|
||||
if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED ||
|
||||
stream->runtime->state == SNDRV_PCM_STATE_SETUP)
|
||||
return -EPERM;
|
||||
|
||||
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
|
||||
if (!retval) {
|
||||
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
|
||||
if (retval) {
|
||||
pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
|
||||
wake_up(&stream->runtime->sleep);
|
||||
return retval;
|
||||
}
|
||||
return retval;
|
||||
|
||||
return snd_compress_wait_for_drain(stream);
|
||||
}
|
||||
|
||||
static int snd_compr_next_track(struct snd_compr_stream *stream)
|
||||
@@ -724,9 +761,14 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream)
|
||||
return -EPERM;
|
||||
|
||||
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN);
|
||||
if (retval) {
|
||||
pr_debug("Partial drain returned failure\n");
|
||||
wake_up(&stream->runtime->sleep);
|
||||
return retval;
|
||||
}
|
||||
|
||||
stream->next_track = false;
|
||||
return retval;
|
||||
return snd_compress_wait_for_drain(stream);
|
||||
}
|
||||
|
||||
static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
|
||||
|
||||
Reference in New Issue
Block a user