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;
}
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;
}
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;
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]);
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;
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. */
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;
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
#include "./bebob.h"
-#define CALLBACK_TIMEOUT 2500
-#define FW_ISO_RESOURCE_DELAY 1000
+#define READY_TIMEOUT_MS 2500
/*
* NOTE;
// 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;
}
#include "dice.h"
-#define CALLBACK_TIMEOUT 200
+#define READY_TIMEOUT_MS 200
#define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC)
struct reg_params {
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;
}
}
#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,
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;
}
#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)
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;
}
*/
#include "./fireworks.h"
-#define CALLBACK_TIMEOUT 100
+#define READY_TIMEOUT_MS 100
static int init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
{
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;
}
#include "motu.h"
-#define CALLBACK_TIMEOUT 200
+#define READY_TIMEOUT_MS 200
#define ISOC_COMM_CONTROL_OFFSET 0x0b00
#define ISOC_COMM_CONTROL_MASK 0xffff0000
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;
}
#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:
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;
#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)
{
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;
}