summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/firewire/amdtp-stream.c16
-rw-r--r--sound/firewire/amdtp-stream.h44
-rw-r--r--sound/firewire/bebob/bebob_stream.c8
-rw-r--r--sound/firewire/dice/dice-stream.c15
-rw-r--r--sound/firewire/digi00x/digi00x-stream.c7
-rw-r--r--sound/firewire/fireface/ff-stream.c7
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c8
-rw-r--r--sound/firewire/motu/motu-stream.c7
-rw-r--r--sound/firewire/oxfw/oxfw-stream.c14
-rw-r--r--sound/firewire/tascam/tascam-stream.c7
10 files changed, 54 insertions, 79 deletions
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index e9bdb609f2eb..a6a7a72a2452 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -107,7 +107,7 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
INIT_WORK(&s->period_work, pcm_period_work);
s->packet_index = 0;
- init_waitqueue_head(&s->callback_wait);
+ init_waitqueue_head(&s->ready_wait);
s->callbacked = false;
s->fmt = fmt;
@@ -1029,6 +1029,9 @@ static void process_rx_packets_intermediately(struct fw_iso_context *context, u3
}
if (offset < packets) {
+ s->ready_processing = true;
+ wake_up(&s->ready_wait);
+
process_rx_packets(context, tstamp, header_length, ctx_header, private_data);
if (amdtp_streaming_error(s))
return;
@@ -1145,6 +1148,9 @@ static void process_tx_packets_intermediately(struct fw_iso_context *context, u3
}
if (offset < packets) {
+ s->ready_processing = true;
+ wake_up(&s->ready_wait);
+
process_tx_packets(context, tstamp, header_length, ctx_header, s);
if (amdtp_streaming_error(s))
return;
@@ -1286,12 +1292,9 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
const __be32 *ctx_header = header;
u32 cycle;
- /*
- * For in-stream, first packet has come.
- * For out-stream, prepared to transmit first packet
- */
+ // For in-stream, first packet has come.
+ // For out-stream, prepared to transmit first packet
s->callbacked = true;
- wake_up(&s->callback_wait);
if (s->direction == AMDTP_IN_STREAM) {
cycle = compute_ohci_cycle_count(ctx_header[1]);
@@ -1464,6 +1467,7 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
tag |= FW_ISO_CONTEXT_MATCH_TAG0;
s->callbacked = false;
+ s->ready_processing = false;
err = fw_iso_context_start(s->context, -1, 0, tag);
if (err < 0)
goto err_pkt_descs;
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index 7725d9793458..b362a6499265 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -167,9 +167,11 @@ struct amdtp_stream {
snd_pcm_uframes_t pcm_buffer_pointer;
unsigned int pcm_period_pointer;
- /* To wait for first packet. */
- bool callbacked;
- wait_queue_head_t callback_wait;
+ // To start processing content of packets at the same cycle in several contexts for
+ // each direction.
+ bool callbacked:1;
+ bool ready_processing:1;
+ wait_queue_head_t ready_wait;
unsigned int next_cycle;
/* For backends to process data blocks. */
@@ -259,21 +261,6 @@ static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc)
return sfc & 1;
}
-/**
- * amdtp_stream_wait_callback - sleep till callbacked or timeout
- * @s: the AMDTP stream
- * @timeout: msec till timeout
- *
- * If this function return false, the AMDTP stream should be stopped.
- */
-static inline bool amdtp_stream_wait_callback(struct amdtp_stream *s,
- unsigned int timeout)
-{
- return wait_event_timeout(s->callback_wait,
- s->callbacked,
- msecs_to_jiffies(timeout)) > 0;
-}
-
struct seq_desc {
unsigned int syt_offset;
unsigned int data_blocks;
@@ -327,4 +314,25 @@ unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d,
struct amdtp_stream *s);
int amdtp_domain_stream_pcm_ack(struct amdtp_domain *d, struct amdtp_stream *s);
+/**
+ * amdtp_domain_wait_ready - sleep till being ready to process packets or timeout
+ * @d: the AMDTP domain
+ * @timeout_ms: msec till timeout
+ *
+ * If this function return false, the AMDTP domain should be stopped.
+ */
+static inline bool amdtp_domain_wait_ready(struct amdtp_domain *d, unsigned int timeout_ms)
+{
+ struct amdtp_stream *s;
+
+ list_for_each_entry(s, &d->streams, list) {
+ unsigned int j = msecs_to_jiffies(timeout_ms);
+
+ if (wait_event_interruptible_timeout(s->ready_wait, s->ready_processing, j) <= 0)
+ return false;
+ }
+
+ return true;
+}
+
#endif
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
index 8053d02b68f0..df764171f84b 100644
--- a/sound/firewire/bebob/bebob_stream.c
+++ b/sound/firewire/bebob/bebob_stream.c
@@ -7,8 +7,7 @@
#include "./bebob.h"
-#define CALLBACK_TIMEOUT 2500
-#define FW_ISO_RESOURCE_DELAY 1000
+#define READY_TIMEOUT_MS 2500
/*
* NOTE;
@@ -679,10 +678,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
// Some devices postpone start of transmission mostly for 1 sec after receives
// packets firstly.
- if (!amdtp_stream_wait_callback(&bebob->rx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&bebob->tx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&bebob->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index c4dfe76500c2..a9a0fe9635dd 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -8,7 +8,7 @@
#include "dice.h"
-#define CALLBACK_TIMEOUT 200
+#define READY_TIMEOUT_MS 200
#define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC)
struct reg_params {
@@ -463,16 +463,9 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice)
if (err < 0)
goto error;
- for (i = 0; i < MAX_STREAMS; i++) {
- if ((i < tx_params.count &&
- !amdtp_stream_wait_callback(&dice->tx_stream[i],
- CALLBACK_TIMEOUT)) ||
- (i < rx_params.count &&
- !amdtp_stream_wait_callback(&dice->rx_stream[i],
- CALLBACK_TIMEOUT))) {
- err = -ETIMEDOUT;
- goto error;
- }
+ if (!amdtp_domain_wait_ready(&dice->domain, READY_TIMEOUT_MS)) {
+ err = -ETIMEDOUT;
+ goto error;
}
}
diff --git a/sound/firewire/digi00x/digi00x-stream.c b/sound/firewire/digi00x/digi00x-stream.c
index 405d6903bfbc..f11aaff2e248 100644
--- a/sound/firewire/digi00x/digi00x-stream.c
+++ b/sound/firewire/digi00x/digi00x-stream.c
@@ -7,7 +7,7 @@
#include "digi00x.h"
-#define CALLBACK_TIMEOUT 500
+#define READY_TIMEOUT_MS 500
const unsigned int snd_dg00x_stream_rates[SND_DG00X_RATE_COUNT] = {
[SND_DG00X_RATE_44100] = 44100,
@@ -379,10 +379,7 @@ int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x)
if (err < 0)
goto error;
- if (!amdtp_stream_wait_callback(&dg00x->rx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&dg00x->tx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&dg00x->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c
index 5452115c0ef9..53a21fb95add 100644
--- a/sound/firewire/fireface/ff-stream.c
+++ b/sound/firewire/fireface/ff-stream.c
@@ -7,7 +7,7 @@
#include "ff.h"
-#define CALLBACK_TIMEOUT_MS 200
+#define READY_TIMEOUT_MS 200
int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc,
enum snd_ff_stream_mode *mode)
@@ -203,10 +203,7 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
if (err < 0)
goto error;
- if (!amdtp_stream_wait_callback(&ff->rx_stream,
- CALLBACK_TIMEOUT_MS) ||
- !amdtp_stream_wait_callback(&ff->tx_stream,
- CALLBACK_TIMEOUT_MS)) {
+ if (!amdtp_domain_wait_ready(&ff->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index 2206af0fef42..858cd6085c1f 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -6,7 +6,7 @@
*/
#include "./fireworks.h"
-#define CALLBACK_TIMEOUT 100
+#define READY_TIMEOUT_MS 100
static int init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
{
@@ -276,11 +276,7 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw)
if (err < 0)
goto error;
- // Wait first callback.
- if (!amdtp_stream_wait_callback(&efw->rx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&efw->tx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&efw->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c
index 2028c5419f6f..925241ae2551 100644
--- a/sound/firewire/motu/motu-stream.c
+++ b/sound/firewire/motu/motu-stream.c
@@ -7,7 +7,7 @@
#include "motu.h"
-#define CALLBACK_TIMEOUT 200
+#define READY_TIMEOUT_MS 200
#define ISOC_COMM_CONTROL_OFFSET 0x0b00
#define ISOC_COMM_CONTROL_MASK 0xffff0000
@@ -264,10 +264,7 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu)
if (err < 0)
goto stop_streams;
- if (!amdtp_stream_wait_callback(&motu->tx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&motu->rx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&motu->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto stop_streams;
}
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c
index e9b6a9f171bf..4121d95e161f 100644
--- a/sound/firewire/oxfw/oxfw-stream.c
+++ b/sound/firewire/oxfw/oxfw-stream.c
@@ -9,7 +9,7 @@
#include <linux/delay.h>
#define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512
-#define CALLBACK_TIMEOUT 200
+#define READY_TIMEOUT_MS 200
/*
* According to datasheet of Oxford Semiconductor:
@@ -358,20 +358,10 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
if (err < 0)
goto error;
- // Wait first packet.
- if (!amdtp_stream_wait_callback(&oxfw->rx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&oxfw->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}
-
- if (oxfw->has_output) {
- if (!amdtp_stream_wait_callback(&oxfw->tx_stream,
- CALLBACK_TIMEOUT)) {
- err = -ETIMEDOUT;
- goto error;
- }
- }
}
return 0;
diff --git a/sound/firewire/tascam/tascam-stream.c b/sound/firewire/tascam/tascam-stream.c
index eb07e1decf9b..296ecf5f6ddc 100644
--- a/sound/firewire/tascam/tascam-stream.c
+++ b/sound/firewire/tascam/tascam-stream.c
@@ -11,7 +11,7 @@
#define CLOCK_STATUS_MASK 0xffff0000
#define CLOCK_CONFIG_MASK 0x0000ffff
-#define CALLBACK_TIMEOUT 500
+#define READY_TIMEOUT_MS 500
static int get_clock(struct snd_tscm *tscm, u32 *data)
{
@@ -477,10 +477,7 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
if (err < 0)
return err;
- if (!amdtp_stream_wait_callback(&tscm->rx_stream,
- CALLBACK_TIMEOUT) ||
- !amdtp_stream_wait_callback(&tscm->tx_stream,
- CALLBACK_TIMEOUT)) {
+ if (!amdtp_domain_wait_ready(&tscm->domain, READY_TIMEOUT_MS)) {
err = -ETIMEDOUT;
goto error;
}