ALSA: firewire-tascam: clear extra MIDI bytes in an asynchronous transaction
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 20 Oct 2015 14:46:59 +0000 (23:46 +0900)
committerTakashi Iwai <tiwai@suse.de>
Tue, 20 Oct 2015 15:49:15 +0000 (17:49 +0200)
When MIDI buffer stores two or more MIDI messages, TASCAM driver
transfers asynchronous transactions including one MIDI message and
extra bytes from second MIDI message.

This commit fixes this bug by clearing needless bytes in the buffer. The
consumed bytes are already calculated correctly, thus the sequence of
transactions is already correct.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/tascam/tascam-transaction.c

index 99098aa2391e40919bd543f0d8e4d322d71eeaf4..904ce0329fa1ac3d7e3364d66664d6ba60d6b6d8 100644 (file)
@@ -93,8 +93,10 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
                        *label = (port << 4) | 0x04;
                /* We need to fill whole 3 bytes. Go to next change. */
                } else {
-                       consume = 0;
+                       return 0;
                }
+
+               len = consume;
        } else {
                /* The beginning of exclusives. */
                if (msg[0] == 0xf0) {
@@ -115,24 +117,30 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
 
                        /* On running-status. */
                        if ((msg[0] & 0x80) != 0x80) {
+                               /* Enough MIDI bytes were not retrieved. */
+                               if (consume < len - 1)
+                                       return 0;
+                               consume = len - 1;
+
                                msg[2] = msg[1];
                                msg[1] = msg[0];
                                msg[0] = tscm->running_status[port];
-                               consume--;
                        } else {
+                               /* Enough MIDI bytes were not retrieved. */
+                               if (consume < len)
+                                       return 0;
+                               consume = len;
+
                                tscm->running_status[port] = msg[0];
                        }
-
-                       /* Confirm length. */
-                       if (consume < len)
-                               return 0;
-                       if (consume > len)
-                               consume = len;
                }
 
                *label = (port << 4) | (msg[0] >> 4);
        }
 
+       if (len > 0 && len < 3)
+               memset(msg + len, 0, 3 - len);
+
        return consume;
 }
 
This page took 0.026608 seconds and 5 git commands to generate.