return 0;
}
-static void stop_endpoints(struct snd_usb_substream *subs, bool wait)
+static void sync_pending_stops(struct snd_usb_substream *subs)
+{
+ snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
+ snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
+}
+
+static void stop_endpoints(struct snd_usb_substream *subs)
{
if (test_and_clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags))
snd_usb_endpoint_stop(subs->sync_endpoint);
if (test_and_clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags))
snd_usb_endpoint_stop(subs->data_endpoint);
+}
- if (wait) {
- snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
- snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
+/* PCM sync_stop callback */
+static int snd_usb_pcm_sync_stop(struct snd_pcm_substream *substream)
+{
+ struct snd_usb_substream *subs = substream->runtime->private_data;
+
+ if (!snd_usb_lock_shutdown(subs->stream->chip)) {
+ sync_pending_stops(subs);
+ snd_usb_unlock_shutdown(subs->stream->chip);
}
+ return 0;
}
static int search_roland_implicit_fb(struct usb_device *dev, int ifnum,
int ret;
/* format changed */
- stop_endpoints(subs, true);
+ stop_endpoints(subs);
+ sync_pending_stops(subs);
ret = snd_usb_endpoint_set_params(subs->data_endpoint,
subs->pcm_format,
subs->channels,
subs->cur_rate = 0;
subs->period_bytes = 0;
if (!snd_usb_lock_shutdown(subs->stream->chip)) {
- stop_endpoints(subs, true);
+ stop_endpoints(subs);
+ sync_pending_stops(subs);
snd_usb_endpoint_deactivate(subs->sync_endpoint);
snd_usb_endpoint_deactivate(subs->data_endpoint);
snd_usb_unlock_shutdown(subs->stream->chip);
goto unlock;
}
- snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
- snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
-
ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D0);
if (ret < 0)
goto unlock;
struct snd_usb_substream *subs = &as->substream[direction];
int ret;
- stop_endpoints(subs, true);
snd_media_stop_pipeline(subs);
if (!as->chip->keep_iface &&
subs->running = 1;
return 0;
case SNDRV_PCM_TRIGGER_STOP:
- stop_endpoints(subs, false);
+ stop_endpoints(subs);
subs->running = 0;
return 0;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
subs->running = 1;
return 0;
case SNDRV_PCM_TRIGGER_STOP:
- stop_endpoints(subs, false);
+ stop_endpoints(subs);
subs->running = 0;
return 0;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
.hw_free = snd_usb_hw_free,
.prepare = snd_usb_pcm_prepare,
.trigger = snd_usb_substream_playback_trigger,
+ .sync_stop = snd_usb_pcm_sync_stop,
.pointer = snd_usb_pcm_pointer,
};
.hw_free = snd_usb_hw_free,
.prepare = snd_usb_pcm_prepare,
.trigger = snd_usb_substream_capture_trigger,
+ .sync_stop = snd_usb_pcm_sync_stop,
.pointer = snd_usb_pcm_pointer,
};