vserver 1.9.3
[linux-2.6.git] / sound / drivers / opl4 / opl4_synth.c
index d4499d1..b146a1c 100644 (file)
@@ -272,12 +272,14 @@ static unsigned char snd_opl4_volume_table[128] = {
  */
 void snd_opl4_synth_reset(opl4_t *opl4)
 {
+       unsigned long flags;
        int i;
 
+       spin_lock_irqsave(&opl4->reg_lock, flags);
        for (i = 0; i < OPL4_MAX_VOICES; i++)
                snd_opl4_write(opl4, OPL4_REG_MISC + i, OPL4_DAMP_BIT);
+       spin_unlock_irqrestore(&opl4->reg_lock, flags);
 
-       spin_lock_init(&opl4->voices_lock);
        INIT_LIST_HEAD(&opl4->off_voices);
        INIT_LIST_HEAD(&opl4->on_voices);
        memset(opl4->voices, 0, sizeof(opl4->voices));
@@ -294,11 +296,14 @@ void snd_opl4_synth_reset(opl4_t *opl4)
  */
 void snd_opl4_synth_shutdown(opl4_t *opl4)
 {
+       unsigned long flags;
        int i;
 
+       spin_lock_irqsave(&opl4->reg_lock, flags);
        for (i = 0; i < OPL4_MAX_VOICES; i++)
                snd_opl4_write(opl4, OPL4_REG_MISC + i,
                               opl4->voices[i].reg_misc & ~OPL4_KEY_ON_BIT);
+       spin_unlock_irqrestore(&opl4->reg_lock, flags);
 }
 
 /*
@@ -311,14 +316,14 @@ static void snd_opl4_do_for_note(opl4_t *opl4, int note, snd_midi_channel_t *cha
        unsigned long flags;
        opl4_voice_t *voice;
 
-       spin_lock_irqsave(&opl4->voices_lock, flags);
+       spin_lock_irqsave(&opl4->reg_lock, flags);
        for (i = 0; i < OPL4_MAX_VOICES; i++) {
                voice = &opl4->voices[i];
                if (voice->chan == chan && voice->note == note) {
                        func(opl4, voice);
                }
        }
-       spin_unlock_irqrestore(&opl4->voices_lock, flags);
+       spin_unlock_irqrestore(&opl4->reg_lock, flags);
 }
 
 /*
@@ -331,14 +336,14 @@ static void snd_opl4_do_for_channel(opl4_t *opl4, snd_midi_channel_t *chan,
        unsigned long flags;
        opl4_voice_t *voice;
 
-       spin_lock_irqsave(&opl4->voices_lock, flags);
+       spin_lock_irqsave(&opl4->reg_lock, flags);
        for (i = 0; i < OPL4_MAX_VOICES; i++) {
                voice = &opl4->voices[i];
                if (voice->chan == chan) {
                        func(opl4, voice);
                }
        }
-       spin_unlock_irqrestore(&opl4->voices_lock, flags);
+       spin_unlock_irqrestore(&opl4->reg_lock, flags);
 }
 
 /*
@@ -351,13 +356,13 @@ static void snd_opl4_do_for_all(opl4_t *opl4,
        unsigned long flags;
        opl4_voice_t *voice;
 
-       spin_lock_irqsave(&opl4->voices_lock, flags);
+       spin_lock_irqsave(&opl4->reg_lock, flags);
        for (i = 0; i < OPL4_MAX_VOICES; i++) {
                voice = &opl4->voices[i];
                if (voice->chan)
                        func(opl4, voice);
        }
-       spin_unlock_irqrestore(&opl4->voices_lock, flags);
+       spin_unlock_irqrestore(&opl4->reg_lock, flags);
 }
 
 static void snd_opl4_update_volume(opl4_t *opl4, opl4_voice_t *voice)
@@ -472,7 +477,7 @@ static void snd_opl4_wait_for_wave_headers(opl4_t *opl4)
 
 void snd_opl4_note_on(void *private_data, int note, int vel, snd_midi_channel_t *chan)
 {
-       opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
+       opl4_t *opl4 = private_data;
        const opl4_region_ptr_t *regions;
        opl4_voice_t *voice[2];
        const opl4_sound_t *sound[2];
@@ -492,7 +497,7 @@ void snd_opl4_note_on(void *private_data, int note, int vel, snd_midi_channel_t
        }
 
        /* allocate and initialize the needed voices */
-       spin_lock_irqsave(&opl4->voices_lock, flags);
+       spin_lock_irqsave(&opl4->reg_lock, flags);
        for (i = 0; i < voices; i++) {
                voice[i] = snd_opl4_get_voice(opl4);
                list_del(&voice[i]->list);
@@ -502,7 +507,6 @@ void snd_opl4_note_on(void *private_data, int note, int vel, snd_midi_channel_t
                voice[i]->velocity = vel & 0x7f;
                voice[i]->sound = sound[i];
        }
-       spin_unlock_irqrestore(&opl4->voices_lock, flags);
 
        /* set tone number (triggers header loading) */
        for (i = 0; i < voices; i++) {
@@ -522,11 +526,13 @@ void snd_opl4_note_on(void *private_data, int note, int vel, snd_midi_channel_t
                voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
                snd_opl4_update_volume(opl4, voice[i]);
        }
+       spin_unlock_irqrestore(&opl4->reg_lock, flags);
 
        /* wait for completion of loading */
        snd_opl4_wait_for_wave_headers(opl4);
 
        /* set remaining parameters */
+       spin_lock_irqsave(&opl4->reg_lock, flags);
        for (i = 0; i < voices; i++) {
                snd_opl4_update_tone_parameters(opl4, voice[i]);
                voice[i]->reg_lfo_vibrato = voice[i]->sound->reg_lfo_vibrato;
@@ -540,6 +546,7 @@ void snd_opl4_note_on(void *private_data, int note, int vel, snd_midi_channel_t
                snd_opl4_write(opl4, OPL4_REG_MISC + voice[i]->number,
                               voice[i]->reg_misc);
        }
+       spin_unlock_irqrestore(&opl4->reg_lock, flags);
 }
 
 static void snd_opl4_voice_off(opl4_t *opl4, opl4_voice_t *voice)
@@ -553,7 +560,7 @@ static void snd_opl4_voice_off(opl4_t *opl4, opl4_voice_t *voice)
 
 void snd_opl4_note_off(void *private_data, int note, int vel, snd_midi_channel_t *chan)
 {
-       opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
+       opl4_t *opl4 = private_data;
 
        snd_opl4_do_for_note(opl4, note, chan, snd_opl4_voice_off);
 }
@@ -569,14 +576,14 @@ static void snd_opl4_terminate_voice(opl4_t *opl4, opl4_voice_t *voice)
 
 void snd_opl4_terminate_note(void *private_data, int note, snd_midi_channel_t *chan)
 {
-       opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
+       opl4_t *opl4 = private_data;
 
        snd_opl4_do_for_note(opl4, note, chan, snd_opl4_terminate_voice);
 }
 
 void snd_opl4_control(void *private_data, int type, snd_midi_channel_t *chan)
 {
-       opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
+       opl4_t *opl4 = private_data;
 
        switch (type) {
        case MIDI_CTL_MSB_MODWHEEL:
@@ -616,7 +623,7 @@ void snd_opl4_control(void *private_data, int type, snd_midi_channel_t *chan)
 void snd_opl4_sysex(void *private_data, unsigned char *buf, int len,
                    int parsed, snd_midi_channel_set_t *chset)
 {
-       opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
+       opl4_t *opl4 = private_data;
 
        if (parsed == SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME)
                snd_opl4_do_for_all(opl4, snd_opl4_update_volume);