]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ALSA: firewire-lib: add a restriction for a transaction at once
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Thu, 8 Oct 2015 23:10:26 +0000 (08:10 +0900)
committerTakashi Iwai <tiwai@suse.de>
Fri, 9 Oct 2015 07:57:05 +0000 (09:57 +0200)
Currently, when waiting for a response, callers can start another
transaction by scheduling another work. This is not good for error
processing of transaction, especially the first response is too late.

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

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/lib.c
sound/firewire/lib.h

index 03ada3f1047a49ec7a0f45f7a64304e3d9e03d3f..ddc3e88ee0d197c668fdfe620f3eb43989db9f6e 100644 (file)
@@ -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_work(struct work_struct *work)
@@ -86,6 +88,10 @@ static void midi_port_work(struct work_struct *work)
        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_work(struct work_struct *work)
                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
@@ -150,6 +158,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->fill = fill;
+       port->idling = true;
 
        INIT_WORK(&port->work, midi_port_work);
 
index 37a7fe4235f27d29d39ba09bd65b967788ae8b8b..0af06f44e8c27bd71a94744ee354815c9a5628a8 100644 (file)
@@ -30,6 +30,7 @@ typedef int (*snd_fw_async_midi_port_fill)(
 struct snd_fw_async_midi_port {
        struct fw_device *parent;
        struct work_struct work;
+       bool idling;
 
        u64 addr;
        struct fw_transaction transaction;