Skip to content

Commit

Permalink
ALSA: oxfw: discontinue MIDI substream for scs1x at transaction failure
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
takaswie authored and tiwai committed Feb 24, 2016
1 parent b4c23ab commit 956dea9
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions sound/firewire/oxfw/oxfw-scs1x.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct fw_scs1x {
bool transaction_running;
struct fw_transaction transaction;
unsigned int transaction_bytes;
bool error;
struct fw_device *fw_dev;
};

Expand Down Expand Up @@ -126,8 +127,13 @@ static void scs_write_callback(struct fw_card *card, int rcode,
{
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);
Expand Down Expand Up @@ -178,7 +184,7 @@ static void scs_output_work(struct work_struct *work)
return;

stream = ACCESS_ONCE(scs->output);
if (!stream) {
if (!stream || scs->error) {
scs->output_idle = true;
wake_up(&scs->idle_wait);
return;
Expand Down Expand Up @@ -317,6 +323,7 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *stream, int up)
scs->output_escaped = false;
scs->output_idle = false;
scs->transaction_bytes = 0;
scs->error = false;

ACCESS_ONCE(scs->output) = stream;
schedule_work(&scs->work);
Expand Down

0 comments on commit 956dea9

Please sign in to comment.