瀏覽代碼

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: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Clemens Ladisch 16 年之前
父節點
當前提交
5e8e7c3853
共有 1 個文件被更改,包括 4 次插入3 次删除
  1. 4 3
      sound/oss/midibuf.c

+ 4 - 3
sound/oss/midibuf.c

@@ -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]) && ok)
+				while (DATA_AVAIL(midi_out_buf[dev]))
 				{
 				{
+					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--;
 				}
 				}