Commit d3ef9cb9 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

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: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 585d7cba
...@@ -76,6 +76,8 @@ static void async_midi_port_callback(struct fw_card *card, int rcode, ...@@ -76,6 +76,8 @@ static void async_midi_port_callback(struct fw_card *card, int rcode,
if (rcode == RCODE_COMPLETE && substream != NULL) if (rcode == RCODE_COMPLETE && substream != NULL)
snd_rawmidi_transmit_ack(substream, port->consume_bytes); snd_rawmidi_transmit_ack(substream, port->consume_bytes);
port->idling = true;
} }
static void midi_port_work(struct work_struct *work) static void midi_port_work(struct work_struct *work)
...@@ -86,6 +88,10 @@ 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 generation;
int type; int type;
/* Under transacting. */
if (!port->idling)
return;
/* Nothing to do. */ /* Nothing to do. */
if (substream == NULL || snd_rawmidi_transmit_empty(substream)) if (substream == NULL || snd_rawmidi_transmit_empty(substream))
return; return;
...@@ -110,6 +116,8 @@ static void midi_port_work(struct work_struct *work) ...@@ -110,6 +116,8 @@ static void midi_port_work(struct work_struct *work)
type = TCODE_WRITE_BLOCK_REQUEST; type = TCODE_WRITE_BLOCK_REQUEST;
/* Start this transaction. */ /* Start this transaction. */
port->idling = false;
/* /*
* In Linux FireWire core, when generation is updated with memory * In Linux FireWire core, when generation is updated with memory
* barrier, node id has already been updated. In this module, After * 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, ...@@ -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->parent = fw_parent_device(unit);
port->addr = addr; port->addr = addr;
port->fill = fill; port->fill = fill;
port->idling = true;
INIT_WORK(&port->work, midi_port_work); INIT_WORK(&port->work, midi_port_work);
......
...@@ -30,6 +30,7 @@ typedef int (*snd_fw_async_midi_port_fill)( ...@@ -30,6 +30,7 @@ typedef int (*snd_fw_async_midi_port_fill)(
struct snd_fw_async_midi_port { struct snd_fw_async_midi_port {
struct fw_device *parent; struct fw_device *parent;
struct work_struct work; struct work_struct work;
bool idling;
u64 addr; u64 addr;
struct fw_transaction transaction; struct fw_transaction transaction;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment