aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2015-10-20 10:46:59 -0400
committerTakashi Iwai <tiwai@suse.de>2015-10-20 11:49:15 -0400
commitf937b43d48f1080e39de723d15680b2ad5d7e6fd (patch)
treef39abb05a3edee3fb2619647e3435ee74883a27d
parent123990e930ac1213df2dfa0e2d57cfc0e1dd5e02 (diff)
ALSA: firewire-tascam: clear extra MIDI bytes in an asynchronous transaction
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>
-rw-r--r--sound/firewire/tascam/tascam-transaction.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/sound/firewire/tascam/tascam-transaction.c b/sound/firewire/tascam/tascam-transaction.c
index 99098aa2391e..904ce0329fa1 100644
--- a/sound/firewire/tascam/tascam-transaction.c
+++ b/sound/firewire/tascam/tascam-transaction.c
@@ -93,8 +93,10 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
93 *label = (port << 4) | 0x04; 93 *label = (port << 4) | 0x04;
94 /* We need to fill whole 3 bytes. Go to next change. */ 94 /* We need to fill whole 3 bytes. Go to next change. */
95 } else { 95 } else {
96 consume = 0; 96 return 0;
97 } 97 }
98
99 len = consume;
98 } else { 100 } else {
99 /* The beginning of exclusives. */ 101 /* The beginning of exclusives. */
100 if (msg[0] == 0xf0) { 102 if (msg[0] == 0xf0) {
@@ -115,24 +117,30 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
115 117
116 /* On running-status. */ 118 /* On running-status. */
117 if ((msg[0] & 0x80) != 0x80) { 119 if ((msg[0] & 0x80) != 0x80) {
120 /* Enough MIDI bytes were not retrieved. */
121 if (consume < len - 1)
122 return 0;
123 consume = len - 1;
124
118 msg[2] = msg[1]; 125 msg[2] = msg[1];
119 msg[1] = msg[0]; 126 msg[1] = msg[0];
120 msg[0] = tscm->running_status[port]; 127 msg[0] = tscm->running_status[port];
121 consume--;
122 } else { 128 } else {
129 /* Enough MIDI bytes were not retrieved. */
130 if (consume < len)
131 return 0;
132 consume = len;
133
123 tscm->running_status[port] = msg[0]; 134 tscm->running_status[port] = msg[0];
124 } 135 }
125
126 /* Confirm length. */
127 if (consume < len)
128 return 0;
129 if (consume > len)
130 consume = len;
131 } 136 }
132 137
133 *label = (port << 4) | (msg[0] >> 4); 138 *label = (port << 4) | (msg[0] >> 4);
134 } 139 }
135 140
141 if (len > 0 && len < 3)
142 memset(msg + len, 0, 3 - len);
143
136 return consume; 144 return consume;
137} 145}
138 146