[RFC,04/37] ALSA: firewire-lib: serialize request transaction and response transaction
diff mbox

Message ID 1436623968-10780-5-git-send-email-o-takashi@sakamocchi.jp
State New
Headers show

Commit Message

Takashi Sakamoto July 11, 2015, 2:12 p.m. UTC
The helper functions for asynchronous MIDI port use 'tasklet' to run IEEE
1394 asynchronous transactions, while running transactions need to wait
for response. In this reason, one transaction should be transferred at
one tasklet scheduling, because tasklet runs one kernel thread available
for the other tasks

For these reasons, this commit serialize request/response transactions,
by adding one boolean member.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/lib.c | 8 ++++++++
 sound/firewire/lib.h | 1 +
 2 files changed, 9 insertions(+)

Patch
diff mbox

diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c
index f5b5526..a66e011 100644
--- a/sound/firewire/lib.c
+++ b/sound/firewire/lib.c
@@ -76,6 +76,8 @@  static void async_midi_port_callback(struct fw_card *card, int rcode,
 
 	if (rcode == RCODE_COMPLETE && substream != NULL)
 		snd_rawmidi_transmit_ack(substream, port->consume_bytes);
+
+	port->idling = true;
 }
 
 static void midi_port_tasklet(unsigned long data)
@@ -86,6 +88,10 @@  static void midi_port_tasklet(unsigned long data)
 	int generation;
 	int type;
 
+	/* Under transacting. */
+	if (!port->idling)
+		return;
+
 	/* Nothing to do. */
 	if (substream == NULL || snd_rawmidi_transmit_empty(substream))
 		return;
@@ -110,6 +116,7 @@  static void midi_port_tasklet(unsigned long data)
 		type = TCODE_WRITE_BLOCK_REQUEST;
 
 	/* Start this transaction. */
+	port->idling = false;
 	generation = port->parent->generation;
 	smp_rmb(); /* node_id vs. generation */
 	fw_send_request(port->parent->card, &port->transaction, type,
@@ -142,6 +149,7 @@  int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
 	port->parent = fw_parent_device(unit);
 	port->addr = addr;
 	port->packetize = packetize;
+	port->idling = true;
 
 	tasklet_init(&port->tasklet, midi_port_tasklet, (unsigned long)port);
 
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
index c662bf9..9d76f5c 100644
--- a/sound/firewire/lib.h
+++ b/sound/firewire/lib.h
@@ -25,6 +25,7 @@  static inline bool rcode_is_permanent_error(int rcode)
 struct snd_fw_async_midi_port {
 	struct fw_device *parent;
 	struct tasklet_struct tasklet;
+	bool idling;
 
 	__u64 addr;
 	struct fw_transaction transaction;