[04/25] ALSA: firewire-lib: add a restriction for a transaction at once
diff mbox

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

Commit Message

Takashi Sakamoto Aug. 13, 2015, 12:20 a.m. UTC
Currently, when waiting for a response, callers can start another
transaction by scheduling another tasklet. This is not good for error
processing.

This commit serialize request/response transactions, by adding one
boolean member to represent idling state.

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;