ALSA: oxfw: discontinue MIDI substream for scs1x at transaction failure
With a previous commit, ALSA oxfw driver retries transferring MIDI
messages at transaction failure for scs1x. On the other hand, there're
fatal transaction error. Then, no MIDI messages reach to the unit anymore.
In this case, MIDI substream should be terminated.
This commit stops MIDI transmission after the fatal error occurs.
Unfortunately, unlike ALSA PCM functionality, ALSA rawmidi core has no
feature to discontinue MIDI substream runtime in kernel side, thus this
commit just stops MIDI transmission without notifying it to userspace.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/firewire/oxfw/oxfw-scs1x.c b/sound/firewire/oxfw/oxfw-scs1x.c
index 72446ac..f897c98 100644
--- a/sound/firewire/oxfw/oxfw-scs1x.c
+++ b/sound/firewire/oxfw/oxfw-scs1x.c
@@ -32,6 +32,7 @@
bool transaction_running;
struct fw_transaction transaction;
unsigned int transaction_bytes;
+ bool error;
struct fw_device *fw_dev;
};
@@ -126,8 +127,13 @@
{
struct fw_scs1x *scs = callback_data;
- if (rcode != RCODE_GENERATION)
- scs->transaction_bytes = 0;
+ if (!rcode_is_permanent_error(rcode)) {
+ /* Don't retry for this data. */
+ if (rcode == RCODE_COMPLETE)
+ scs->transaction_bytes = 0;
+ } else {
+ scs->error = true;
+ }
scs->transaction_running = false;
schedule_work(&scs->work);
@@ -178,7 +184,7 @@
return;
stream = ACCESS_ONCE(scs->output);
- if (!stream) {
+ if (!stream || scs->error) {
scs->output_idle = true;
wake_up(&scs->idle_wait);
return;
@@ -317,6 +323,7 @@
scs->output_escaped = false;
scs->output_idle = false;
scs->transaction_bytes = 0;
+ scs->error = false;
ACCESS_ONCE(scs->output) = stream;
schedule_work(&scs->work);