diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2015-10-08 19:10:26 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-10-09 03:57:05 -0400 |
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, | |||
76 | 76 | ||
77 | if (rcode == RCODE_COMPLETE && substream != NULL) | 77 | if (rcode == RCODE_COMPLETE && substream != NULL) |
78 | snd_rawmidi_transmit_ack(substream, port->consume_bytes); | 78 | snd_rawmidi_transmit_ack(substream, port->consume_bytes); |
79 | |||
80 | port->idling = true; | ||
79 | } | 81 | } |
80 | 82 | ||
81 | static void midi_port_work(struct work_struct *work) | 83 | static void midi_port_work(struct work_struct *work) |
@@ -86,6 +88,10 @@ static void midi_port_work(struct work_struct *work) | |||
86 | int generation; | 88 | int generation; |
87 | int type; | 89 | int type; |
88 | 90 | ||
91 | /* Under transacting. */ | ||
92 | if (!port->idling) | ||
93 | return; | ||
94 | |||
89 | /* Nothing to do. */ | 95 | /* Nothing to do. */ |
90 | if (substream == NULL || snd_rawmidi_transmit_empty(substream)) | 96 | if (substream == NULL || snd_rawmidi_transmit_empty(substream)) |
91 | return; | 97 | return; |
@@ -110,6 +116,8 @@ static void midi_port_work(struct work_struct *work) | |||
110 | type = TCODE_WRITE_BLOCK_REQUEST; | 116 | type = TCODE_WRITE_BLOCK_REQUEST; |
111 | 117 | ||
112 | /* Start this transaction. */ | 118 | /* Start this transaction. */ |
119 | port->idling = false; | ||
120 | |||
113 | /* | 121 | /* |
114 | * In Linux FireWire core, when generation is updated with memory | 122 | * In Linux FireWire core, when generation is updated with memory |
115 | * barrier, node id has already been updated. In this module, After | 123 | * 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 | port->parent = fw_parent_device(unit); | 158 | port->parent = fw_parent_device(unit); |
151 | port->addr = addr; | 159 | port->addr = addr; |
152 | port->fill = fill; | 160 | port->fill = fill; |
161 | port->idling = true; | ||
153 | 162 | ||
154 | INIT_WORK(&port->work, midi_port_work); | 163 | INIT_WORK(&port->work, midi_port_work); |
155 | 164 | ||
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)( | |||
30 | struct snd_fw_async_midi_port { | 30 | struct snd_fw_async_midi_port { |
31 | struct fw_device *parent; | 31 | struct fw_device *parent; |
32 | struct work_struct work; | 32 | struct work_struct work; |
33 | bool idling; | ||
33 | 34 | ||
34 | u64 addr; | 35 | u64 addr; |
35 | struct fw_transaction transaction; | 36 | struct fw_transaction transaction; |