Commit 5e8e7c38 authored by Clemens Ladisch's avatar Clemens Ladisch Committed by Takashi Iwai

sound: fix OSS MIDI output data loss

In the 2.1.6 kernel, the output loop in midi_poll() was changed to
enable interrupts during the outputc() call.  Unfortunately, the check
whether the device has accepted the current byte ("ok") was moved behind
the code that removes the byte from the output queue, so one byte would
be lost every time the hardware FIFO is full.
Signed-off-by: default avatarClemens Ladisch <clemens@ladisch.de>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent ed680c4a
...@@ -127,15 +127,16 @@ static void midi_poll(unsigned long dummy) ...@@ -127,15 +127,16 @@ static void midi_poll(unsigned long dummy)
for (dev = 0; dev < num_midis; dev++) for (dev = 0; dev < num_midis; dev++)
if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL) if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
{ {
int ok = 1; while (DATA_AVAIL(midi_out_buf[dev]))
while (DATA_AVAIL(midi_out_buf[dev]) && ok)
{ {
int ok;
int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head]; int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
spin_unlock_irqrestore(&lock,flags);/* Give some time to others */ spin_unlock_irqrestore(&lock,flags);/* Give some time to others */
ok = midi_devs[dev]->outputc(dev, c); ok = midi_devs[dev]->outputc(dev, c);
spin_lock_irqsave(&lock, flags); spin_lock_irqsave(&lock, flags);
if (!ok)
break;
midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE; midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
midi_out_buf[dev]->len--; midi_out_buf[dev]->len--;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment