Commit b130807d authored by Randy Dunlap's avatar Randy Dunlap Committed by Jaroslav Kysela

[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 <randy.dunlap@oracle.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent 40e1a9c0
...@@ -1286,7 +1286,7 @@ static void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int statu ...@@ -1286,7 +1286,7 @@ static void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int statu
do_emu10k1x_midi_interrupt(emu, &emu->midi, status); 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) struct emu10k1x_midi *midi, unsigned char cmd, int ack)
{ {
unsigned long flags; unsigned long flags;
...@@ -1312,11 +1312,14 @@ static void snd_emu10k1x_midi_cmd(struct emu10k1x * emu, ...@@ -1312,11 +1312,14 @@ static void snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
ok = 1; ok = 1;
} }
spin_unlock_irqrestore(&midi->input_lock, flags); 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", snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
cmd, emu->port, cmd, emu->port,
mpu401_read_stat(emu, midi), mpu401_read_stat(emu, midi),
mpu401_read_data(emu, midi)); mpu401_read_data(emu, midi));
return 1;
}
return 0;
} }
static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream) 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) ...@@ -1332,12 +1335,17 @@ static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
midi->substream_input = substream; midi->substream_input = substream;
if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) { if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1); if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1); goto error_out;
if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
goto error_out;
} else { } else {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
} }
return 0; return 0;
error_out:
return -EIO;
} }
static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream) 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 ...@@ -1353,12 +1361,17 @@ static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream
midi->substream_output = substream; midi->substream_output = substream;
if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) { if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1); if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1))
snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1); goto error_out;
if (snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
goto error_out;
} else { } else {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
} }
return 0; return 0;
error_out:
return -EIO;
} }
static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream) 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 ...@@ -1366,6 +1379,7 @@ static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream
struct emu10k1x *emu; struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data; struct emu10k1x_midi *midi = substream->rmidi->private_data;
unsigned long flags; unsigned long flags;
int err = 0;
emu = midi->emu; emu = midi->emu;
snd_assert(emu, return -ENXIO); snd_assert(emu, return -ENXIO);
...@@ -1375,11 +1389,11 @@ static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream ...@@ -1375,11 +1389,11 @@ static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream
midi->substream_input = NULL; midi->substream_input = NULL;
if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) { if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags); 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 { } else {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
} }
return 0; return err;
} }
static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream) 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 ...@@ -1387,6 +1401,7 @@ static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substrea
struct emu10k1x *emu; struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data; struct emu10k1x_midi *midi = substream->rmidi->private_data;
unsigned long flags; unsigned long flags;
int err = 0;
emu = midi->emu; emu = midi->emu;
snd_assert(emu, return -ENXIO); snd_assert(emu, return -ENXIO);
...@@ -1396,11 +1411,11 @@ static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substrea ...@@ -1396,11 +1411,11 @@ static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substrea
midi->substream_output = NULL; midi->substream_output = NULL;
if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) { if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags); 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 { } else {
spin_unlock_irqrestore(&midi->open_lock, flags); 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) static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
......
...@@ -116,7 +116,7 @@ static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int st ...@@ -116,7 +116,7 @@ static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int st
do_emu10k1_midi_interrupt(emu, &emu->midi2, status); do_emu10k1_midi_interrupt(emu, &emu->midi2, status);
} }
static void snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack) static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack)
{ {
unsigned long flags; unsigned long flags;
int timeout, ok; int timeout, ok;
...@@ -141,11 +141,14 @@ static void snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_mi ...@@ -141,11 +141,14 @@ static void snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_mi
ok = 1; ok = 1;
} }
spin_unlock_irqrestore(&midi->input_lock, flags); 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", snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
cmd, emu->port, cmd, emu->port,
mpu401_read_stat(emu, midi), mpu401_read_stat(emu, midi),
mpu401_read_data(emu, midi)); mpu401_read_data(emu, midi));
return 1;
}
return 0;
} }
static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream) static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
...@@ -161,12 +164,17 @@ static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream) ...@@ -161,12 +164,17 @@ static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
midi->substream_input = substream; midi->substream_input = substream;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) { if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1); if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1); goto error_out;
if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
goto error_out;
} else { } else {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
} }
return 0; return 0;
error_out:
return -EIO;
} }
static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream) static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
...@@ -182,12 +190,17 @@ static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream) ...@@ -182,12 +190,17 @@ static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
midi->substream_output = substream; midi->substream_output = substream;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) { if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1); if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1); goto error_out;
if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
goto error_out;
} else { } else {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
} }
return 0; return 0;
error_out:
return -EIO;
} }
static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream) static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
...@@ -195,6 +208,7 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream) ...@@ -195,6 +208,7 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
struct snd_emu10k1 *emu; struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags; unsigned long flags;
int err = 0;
emu = midi->emu; emu = midi->emu;
snd_assert(emu, return -ENXIO); snd_assert(emu, return -ENXIO);
...@@ -204,11 +218,11 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream) ...@@ -204,11 +218,11 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
midi->substream_input = NULL; midi->substream_input = NULL;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) { if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0); err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
} else { } else {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
} }
return 0; return err;
} }
static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream) static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream)
...@@ -216,6 +230,7 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream ...@@ -216,6 +230,7 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream
struct snd_emu10k1 *emu; struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags; unsigned long flags;
int err = 0;
emu = midi->emu; emu = midi->emu;
snd_assert(emu, return -ENXIO); snd_assert(emu, return -ENXIO);
...@@ -225,11 +240,11 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream ...@@ -225,11 +240,11 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream
midi->substream_output = NULL; midi->substream_output = NULL;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) { if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0); err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
} else { } else {
spin_unlock_irqrestore(&midi->open_lock, flags); spin_unlock_irqrestore(&midi->open_lock, flags);
} }
return 0; return err;
} }
static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment