@@ -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,8 @@ static void midi_port_tasklet(unsigned long data)
type = TCODE_WRITE_BLOCK_REQUEST;
/* Start this transaction. */
+ port->idling = false;
+
/*
* In Linux FireWire core, when generation is updated with memory
* barrier, node id has already been updated. In this module, After
@@ -151,6 +159,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);
@@ -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;
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 | 9 +++++++++ sound/firewire/lib.h | 1 + 2 files changed, 10 insertions(+)