aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Sakamoto2020-05-08 13:36:28 +0900
committerTakashi Iwai2020-05-08 09:44:43 +0200
commit2472cfb3232caf8f68e4d93ae830c569b0bbc25b (patch)
treec7b8add39cb3ec172027730545c1dc4726246262
parent10aa8e4acf51b12a2db4ee2baaed67f70fbee9c2 (diff)
ALSA: firewire-lib: add reference to domain structure from stream structure
In current implementation, AMDTP domain structure and AMDTP stream structure has one way of reference from the former to the latter. For future extension, bidirectional reference is needed. This commit adds a member into stream structure to refer to domain structure to which the stream belongs. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Link: https://lore.kernel.org/r/20200508043635.349339-4-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/firewire/amdtp-stream.c75
-rw-r--r--sound/firewire/amdtp-stream.h3
2 files changed, 23 insertions, 55 deletions
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index fcde01b54d11..ce63ff6b7f03 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -793,14 +793,6 @@ static void process_ctx_payloads(struct amdtp_stream *s,
update_pcm_pointers(s, pcm, pcm_frames);
}
-static void amdtp_stream_master_callback(struct fw_iso_context *context,
- u32 tstamp, size_t header_length,
- void *header, void *private_data);
-
-static void amdtp_stream_master_first_callback(struct fw_iso_context *context,
- u32 tstamp, size_t header_length,
- void *header, void *private_data);
-
static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
size_t header_length, void *header,
void *private_data)
@@ -810,7 +802,6 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
unsigned int events_per_period = s->ctx_data.rx.events_per_period;
unsigned int event_count = s->ctx_data.rx.event_count;
unsigned int packets;
- bool is_irq_target;
int i;
if (s->packet_index < 0)
@@ -823,10 +814,6 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
process_ctx_payloads(s, s->pkt_descs, packets);
- is_irq_target =
- !!(context->callback.sc == amdtp_stream_master_callback ||
- context->callback.sc == amdtp_stream_master_first_callback);
-
for (i = 0; i < packets; ++i) {
const struct pkt_desc *desc = s->pkt_descs + i;
unsigned int syt;
@@ -845,7 +832,7 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
desc->data_blocks, desc->data_block_counter,
syt, i);
- if (is_irq_target) {
+ if (s == s->domain->irq_target) {
event_count += desc->data_blocks;
if (event_count >= events_per_period) {
event_count -= events_per_period;
@@ -898,12 +885,12 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
}
}
-static void amdtp_stream_master_callback(struct fw_iso_context *context,
- u32 tstamp, size_t header_length,
- void *header, void *private_data)
+static void irq_target_callback(struct fw_iso_context *context, u32 tstamp,
+ size_t header_length, void *header,
+ void *private_data)
{
- struct amdtp_domain *d = private_data;
- struct amdtp_stream *irq_target = d->irq_target;
+ struct amdtp_stream *irq_target = private_data;
+ struct amdtp_domain *d = irq_target->domain;
struct amdtp_stream *s;
out_stream_callback(context, tstamp, header_length, header, irq_target);
@@ -952,7 +939,10 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
} else {
cycle = compute_it_cycle(*ctx_header, s->queue_size);
- context->callback.sc = out_stream_callback;
+ if (s == s->domain->irq_target)
+ context->callback.sc = irq_target_callback;
+ else
+ context->callback.sc = out_stream_callback;
}
s->start_cycle = cycle;
@@ -960,32 +950,11 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
context->callback.sc(context, tstamp, header_length, header, s);
}
-static void amdtp_stream_master_first_callback(struct fw_iso_context *context,
- u32 tstamp, size_t header_length,
- void *header, void *private_data)
-{
- struct amdtp_domain *d = private_data;
- struct amdtp_stream *s = d->irq_target;
- const __be32 *ctx_header = header;
-
- s->callbacked = true;
- wake_up(&s->callback_wait);
-
- s->start_cycle = compute_it_cycle(*ctx_header, s->queue_size);
-
- context->callback.sc = amdtp_stream_master_callback;
-
- context->callback.sc(context, tstamp, header_length, header, d);
-}
-
/**
* amdtp_stream_start - start transferring packets
* @s: the AMDTP stream to start
* @channel: the isochronous channel on the bus
* @speed: firewire speed code
- * @d: the AMDTP domain to which the AMDTP stream belongs
- * @is_irq_target: whether isoc context for the AMDTP stream is used to generate
- * hardware IRQ.
* @start_cycle: the isochronous cycle to start the context. Start immediately
* if negative value is given.
*
@@ -994,7 +963,6 @@ static void amdtp_stream_master_first_callback(struct fw_iso_context *context,
* device can be started.
*/
static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
- struct amdtp_domain *d, bool is_irq_target,
int start_cycle)
{
static const struct {
@@ -1009,15 +977,14 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
[CIP_SFC_88200] = { 0, 67 },
[CIP_SFC_176400] = { 0, 67 },
};
- unsigned int events_per_buffer = d->events_per_buffer;
- unsigned int events_per_period = d->events_per_period;
+ bool is_irq_target = (s == s->domain->irq_target);
+ unsigned int events_per_buffer;
+ unsigned int events_per_period;
unsigned int idle_irq_interval;
unsigned int ctx_header_size;
unsigned int max_ctx_payload_size;
enum dma_data_direction dir;
int type, tag, err;
- fw_iso_callback_t ctx_cb;
- void *ctx_data;
mutex_lock(&s->mutex);
@@ -1068,6 +1035,8 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
// This is a case that AMDTP streams in domain run just for MIDI
// substream. Use the number of events equivalent to 10 msec as
// interval of hardware IRQ.
+ events_per_buffer = s->domain->events_per_buffer;
+ events_per_period = s->domain->events_per_period;
if (events_per_period == 0)
events_per_period = amdtp_rate_table[s->sfc] / 100;
if (events_per_buffer == 0)
@@ -1086,16 +1055,11 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed,
if (is_irq_target) {
s->ctx_data.rx.events_per_period = events_per_period;
s->ctx_data.rx.event_count = 0;
- ctx_cb = amdtp_stream_master_first_callback;
- ctx_data = d;
- } else {
- ctx_cb = amdtp_stream_first_callback;
- ctx_data = s;
}
s->context = fw_iso_context_create(fw_parent_device(s->unit)->card,
type, channel, speed, ctx_header_size,
- ctx_cb, ctx_data);
+ amdtp_stream_first_callback, s);
if (IS_ERR(s->context)) {
err = PTR_ERR(s->context);
if (err == -EBUSY)
@@ -1340,6 +1304,7 @@ int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s,
s->channel = channel;
s->speed = speed;
+ s->domain = d;
return 0;
}
@@ -1428,15 +1393,15 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
}
if (s != d->irq_target) {
- err = amdtp_stream_start(s, s->channel, s->speed, d,
- false, cycle_match);
+ err = amdtp_stream_start(s, s->channel, s->speed,
+ cycle_match);
if (err < 0)
goto error;
}
}
s = d->irq_target;
- err = amdtp_stream_start(s, s->channel, s->speed, d, true, -1);
+ err = amdtp_stream_start(s, s->channel, s->speed, -1);
if (err < 0)
goto error;
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index f2d44e2dc3c8..477fbfe713e5 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -108,6 +108,8 @@ typedef unsigned int (*amdtp_stream_process_ctx_payloads_t)(
const struct pkt_desc *desc,
unsigned int packets,
struct snd_pcm_substream *pcm);
+
+struct amdtp_domain;
struct amdtp_stream {
struct fw_unit *unit;
enum cip_flags flags;
@@ -180,6 +182,7 @@ struct amdtp_stream {
int channel;
int speed;
struct list_head list;
+ struct amdtp_domain *domain;
};
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,