ALSA: msnd: Optimize / harden DSP and MIDI loops
[sfrench/cifs-2.6.git] / sound / isa / msnd / msnd_midi.c
index 912b5a9ccbab5468f30e2059523b3ca942605bf5..013d8d1170fe02e16ebb364f54cd19a6421e8250 100644 (file)
@@ -120,24 +120,24 @@ void snd_msndmidi_input_read(void *mpuv)
        unsigned long flags;
        struct snd_msndmidi *mpu = mpuv;
        void *pwMIDQData = mpu->dev->mappedbase + MIDQ_DATA_BUFF;
+       u16 head, tail, size;
 
        spin_lock_irqsave(&mpu->input_lock, flags);
-       while (readw(mpu->dev->MIDQ + JQS_wTail) !=
-              readw(mpu->dev->MIDQ + JQS_wHead)) {
-               u16 wTmp, val;
-               val = readw(pwMIDQData + 2 * readw(mpu->dev->MIDQ + JQS_wHead));
-
-                       if (test_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER,
-                                    &mpu->mode))
-                               snd_rawmidi_receive(mpu->substream_input,
-                                                   (unsigned char *)&val, 1);
-
-               wTmp = readw(mpu->dev->MIDQ + JQS_wHead) + 1;
-               if (wTmp > readw(mpu->dev->MIDQ + JQS_wSize))
-                       writew(0,  mpu->dev->MIDQ + JQS_wHead);
-               else
-                       writew(wTmp,  mpu->dev->MIDQ + JQS_wHead);
+       head = readw(mpu->dev->MIDQ + JQS_wHead);
+       tail = readw(mpu->dev->MIDQ + JQS_wTail);
+       size = readw(mpu->dev->MIDQ + JQS_wSize);
+       if (head > size || tail > size)
+               goto out;
+       while (head != tail) {
+               unsigned char val = readw(pwMIDQData + 2 * head);
+
+               if (test_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
+                       snd_rawmidi_receive(mpu->substream_input, &val, 1);
+               if (++head > size)
+                       head = 0;
+               writew(head, mpu->dev->MIDQ + JQS_wHead);
        }
+ out:
        spin_unlock_irqrestore(&mpu->input_lock, flags);
 }
 EXPORT_SYMBOL(snd_msndmidi_input_read);