From b130807dce4a8f91f9662e93d1aa813d806e14a8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 4 Jul 2006 14:25:26 +0200 Subject: [ALSA] Fix no mpu401 interface can cause hard freeze This patch fixes the remaining instances in our tree where a non- existent mpu401 interface can cause a hard freeze when i/o is issued. This commit closes Malone #34831. Bug: https://launchpad.net/distros/ubuntu/+source/linux-source-2.6.15/+bug/34831 patch location: http://www.kernel.org/git/?p=linux/kernel/git/bcollins/ubuntu-dapper.git;a=commitdiff;h=b422309cdd980cfefe99379796c04e961d3c1544 From: Randy Dunlap Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/emu10k1/emu10k1x.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'sound/pci/emu10k1/emu10k1x.c') diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 2167279429b8..d0aa1e1031d6 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -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) -- cgit v1.2.3