sound: fix OSS MIDI output data loss
authorClemens Ladisch <clemens@ladisch.de>
Mon, 10 Aug 2009 08:05:23 +0000 (10:05 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 10 Aug 2009 11:15:43 +0000 (13:15 +0200)
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: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/oss/midibuf.c

index a40be0c..782b3b8 100644 (file)
@@ -127,15 +127,16 @@ static void midi_poll(unsigned long dummy)
                for (dev = 0; dev < num_midis; dev++)
                        if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
                        {
-                               int ok = 1;
-
-                               while (DATA_AVAIL(midi_out_buf[dev]) && ok)
+                               while (DATA_AVAIL(midi_out_buf[dev]))
                                {
+                                       int ok;
                                        int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
 
                                        spin_unlock_irqrestore(&lock,flags);/* Give some time to others */
                                        ok = midi_devs[dev]->outputc(dev, c);
                                        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]->len--;
                                }