summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-08-10 10:05:23 +0200
committerTakashi Iwai <tiwai@suse.de>2009-08-10 13:15:43 +0200
commit5e8e7c38533a8f86626e9410fa38f5854a6959df (patch)
treed5d3b55d750a3225720f56eb71b2d0dba16fc8fd
parented680c4ad478d0fee9740f7d029087f181346564 (diff)
downloadkernel-crypto-5e8e7c38533a8f86626e9410fa38f5854a6959df.tar.gz
kernel-crypto-5e8e7c38533a8f86626e9410fa38f5854a6959df.tar.xz
kernel-crypto-5e8e7c38533a8f86626e9410fa38f5854a6959df.zip
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>
-rw-r--r--sound/oss/midibuf.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c
index a40be0cf1d9..782b3b84dac 100644
--- a/sound/oss/midibuf.c
+++ b/sound/oss/midibuf.c
@@ -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--;
}