[ALSA] Fix no mpu401 interface can cause hard freeze
[pandora-kernel.git] / sound / pci / emu10k1 / emu10k1x.c
index 2167279..d0aa1e1 100644 (file)
@@ -1286,7 +1286,7 @@ static void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int statu
        do_emu10k1x_midi_interrupt(emu, &emu->midi, status);
 }
 
-static void snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
+static int snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
                                  struct emu10k1x_midi *midi, unsigned char cmd, int ack)
 {
        unsigned long flags;
@@ -1312,11 +1312,14 @@ static void snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
                ok = 1;
        }
        spin_unlock_irqrestore(&midi->input_lock, flags);
-       if (!ok)
+       if (!ok) {
                snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
                           cmd, emu->port,
                           mpu401_read_stat(emu, midi),
                           mpu401_read_data(emu, midi));
+               return 1;
+       }
+       return 0;
 }
 
 static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
@@ -1332,12 +1335,17 @@ static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
        midi->substream_input = substream;
        if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
                spin_unlock_irqrestore(&midi->open_lock, flags);
-               snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1);
-               snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
+               if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
+                       goto error_out;
+               if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
+                       goto error_out;
        } else {
                spin_unlock_irqrestore(&midi->open_lock, flags);
        }
        return 0;
+
+error_out:
+       return -EIO;
 }
 
 static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream)
@@ -1353,12 +1361,17 @@ static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream
        midi->substream_output = substream;
        if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
                spin_unlock_irqrestore(&midi->open_lock, flags);
-               snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1);
-               snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
+               if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
+                       goto error_out;
+               if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
+                       goto error_out;
        } else {
                spin_unlock_irqrestore(&midi->open_lock, flags);
        }
        return 0;
+
+error_out:
+       return -EIO;
 }
 
 static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream)
@@ -1366,6 +1379,7 @@ static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream
        struct emu10k1x *emu;
        struct emu10k1x_midi *midi = substream->rmidi->private_data;
        unsigned long flags;
+       int err = 0;
 
        emu = midi->emu;
        snd_assert(emu, return -ENXIO);
@@ -1375,11 +1389,11 @@ static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream
        midi->substream_input = NULL;
        if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
                spin_unlock_irqrestore(&midi->open_lock, flags);
-               snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
+               err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
        } else {
                spin_unlock_irqrestore(&midi->open_lock, flags);
        }
-       return 0;
+       return err;
 }
 
 static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream)
@@ -1387,6 +1401,7 @@ static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substrea
        struct emu10k1x *emu;
        struct emu10k1x_midi *midi = substream->rmidi->private_data;
        unsigned long flags;
+       int err = 0;
 
        emu = midi->emu;
        snd_assert(emu, return -ENXIO);
@@ -1396,11 +1411,11 @@ static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substrea
        midi->substream_output = NULL;
        if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
                spin_unlock_irqrestore(&midi->open_lock, flags);
-               snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
+               err = snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
        } else {
                spin_unlock_irqrestore(&midi->open_lock, flags);
        }
-       return 0;
+       return err;
 }
 
 static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)