[PATCH 03/10] ALSA: firewire-lib: add reference to domain structure from stream structure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxx>
---
 sound/firewire/amdtp-stream.c | 75 ++++++++++-------------------------
 sound/firewire/amdtp-stream.h |  3 ++
 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,
-- 
2.25.1




[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux