diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2015-10-09 08:10:26 +0900 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-10-09 09:57:05 +0200 |
commit | d3ef9cb93aec59eb1d90d01ae0642fd517c25381 (patch) | |
tree | ab00c5e5d1c4ce2b0b12a2614e229d78b806aff6 | |
parent | 585d7cba5e1fcd8703a120042f35695165986b9b (diff) |
ALSA: firewire-lib: add a restriction for a transaction at once
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>
-rw-r--r-- | sound/firewire/lib.c | 9 | ||||
-rw-r--r-- | sound/firewire/lib.h | 1 |
2 files changed, 10 insertions, 0 deletions
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c index 03ada3f1047a..ddc3e88ee0d1 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_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); diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h index 37a7fe4235f2..0af06f44e8c2 100644 --- a/sound/firewire/lib.h +++ b/sound/firewire/lib.h @@ -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; |