summaryrefslogtreecommitdiffstats
path: root/sound/firewire/fireface/ff-stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire/fireface/ff-stream.c')
-rw-r--r--sound/firewire/fireface/ff-stream.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c
index 740963e4e1c9..d9d1b469a8e9 100644
--- a/sound/firewire/fireface/ff-stream.c
+++ b/sound/firewire/fireface/ff-stream.c
@@ -31,12 +31,6 @@ int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc,
return 0;
}
-static void release_resources(struct snd_ff *ff)
-{
- fw_iso_resources_free(&ff->tx_resources);
- fw_iso_resources_free(&ff->rx_resources);
-}
-
static inline void finish_session(struct snd_ff *ff)
{
ff->spec->protocol->finish_session(ff);
@@ -104,36 +98,27 @@ void snd_ff_stream_destroy_duplex(struct snd_ff *ff)
destroy_stream(ff, AMDTP_OUT_STREAM);
}
-int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
+int snd_ff_stream_reserve_duplex(struct snd_ff *ff, unsigned int rate)
{
unsigned int curr_rate;
enum snd_ff_clock_src src;
int err;
- if (ff->substreams_counter == 0)
- return 0;
-
err = ff->spec->protocol->get_clock(ff, &curr_rate, &src);
if (err < 0)
return err;
- if (curr_rate != rate ||
- amdtp_streaming_error(&ff->tx_stream) ||
- amdtp_streaming_error(&ff->rx_stream)) {
- finish_session(ff);
+
+ if (ff->substreams_counter == 0 || curr_rate != rate) {
+ enum snd_ff_stream_mode mode;
+ int i;
amdtp_stream_stop(&ff->tx_stream);
amdtp_stream_stop(&ff->rx_stream);
- release_resources(ff);
- }
+ finish_session(ff);
- /*
- * Regardless of current source of clock signal, drivers transfer some
- * packets. Then, the device transfers packets.
- */
- if (!amdtp_stream_running(&ff->rx_stream)) {
- enum snd_ff_stream_mode mode;
- int i;
+ fw_iso_resources_free(&ff->tx_resources);
+ fw_iso_resources_free(&ff->rx_resources);
for (i = 0; i < CIP_SFC_COUNT; ++i) {
if (amdtp_rate_table[i] == rate)
@@ -158,8 +143,40 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
err = ff->spec->protocol->allocate_resources(ff, rate);
if (err < 0)
- goto error;
+ return err;
+ }
+
+ return 0;
+}
+
+void snd_ff_stream_release_duplex(struct snd_ff *ff)
+{
+ if (ff->substreams_counter == 0) {
+ fw_iso_resources_free(&ff->tx_resources);
+ fw_iso_resources_free(&ff->rx_resources);
+ }
+}
+
+int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
+{
+ int err;
+
+ if (ff->substreams_counter == 0)
+ return 0;
+ if (amdtp_streaming_error(&ff->tx_stream) ||
+ amdtp_streaming_error(&ff->rx_stream)) {
+ amdtp_stream_stop(&ff->tx_stream);
+ amdtp_stream_stop(&ff->rx_stream);
+
+ finish_session(ff);
+ }
+
+ /*
+ * Regardless of current source of clock signal, drivers transfer some
+ * packets. Then, the device transfers packets.
+ */
+ if (!amdtp_stream_running(&ff->rx_stream)) {
err = ff->spec->protocol->begin_session(ff, rate);
if (err < 0)
goto error;
@@ -201,7 +218,6 @@ error:
amdtp_stream_stop(&ff->rx_stream);
finish_session(ff);
- release_resources(ff);
return err;
}
@@ -214,7 +230,6 @@ void snd_ff_stream_stop_duplex(struct snd_ff *ff)
amdtp_stream_stop(&ff->tx_stream);
amdtp_stream_stop(&ff->rx_stream);
finish_session(ff);
- release_resources(ff);
}
void snd_ff_stream_update_duplex(struct snd_ff *ff)