|
@@ -123,7 +123,6 @@ static int snd_compr_open(struct inode *inode, struct file *f)
|
|
|
}
|
|
|
runtime->state = SNDRV_PCM_STATE_OPEN;
|
|
|
init_waitqueue_head(&runtime->sleep);
|
|
|
- init_waitqueue_head(&runtime->wait);
|
|
|
data->stream.runtime = runtime;
|
|
|
f->private_data = (void *)data;
|
|
|
mutex_lock(&compr->lock);
|
|
@@ -681,8 +680,6 @@ 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;
|
|
@@ -692,6 +689,8 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
|
|
|
|
|
|
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
|
|
@@ -703,12 +702,24 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
|
|
|
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
|
|
|
mutex_unlock(&stream->device->lock);
|
|
|
|
|
|
- wait_event(stream->runtime->wait, stream->runtime->drain_wake);
|
|
|
+ /* 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 0;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int snd_compr_drain(struct snd_compr_stream *stream)
|
|
@@ -719,17 +730,14 @@ static int snd_compr_drain(struct snd_compr_stream *stream)
|
|
|
stream->runtime->state == SNDRV_PCM_STATE_SETUP)
|
|
|
return -EPERM;
|
|
|
|
|
|
- stream->runtime->drain_wake = 0;
|
|
|
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
|
|
|
if (retval) {
|
|
|
- pr_err("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
|
|
|
+ pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
|
|
|
wake_up(&stream->runtime->sleep);
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
- retval = snd_compress_wait_for_drain(stream);
|
|
|
- stream->runtime->state = SNDRV_PCM_STATE_SETUP;
|
|
|
- return retval;
|
|
|
+ return snd_compress_wait_for_drain(stream);
|
|
|
}
|
|
|
|
|
|
static int snd_compr_next_track(struct snd_compr_stream *stream)
|
|
@@ -764,10 +772,9 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream)
|
|
|
if (stream->next_track == false)
|
|
|
return -EPERM;
|
|
|
|
|
|
- stream->runtime->drain_wake = 0;
|
|
|
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN);
|
|
|
if (retval) {
|
|
|
- pr_err("Partial drain returned failure\n");
|
|
|
+ pr_debug("Partial drain returned failure\n");
|
|
|
wake_up(&stream->runtime->sleep);
|
|
|
return retval;
|
|
|
}
|