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: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
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)
{
unsigned long flags;
struct emu10k1x_midi *midi, unsigned char cmd, int ack)
{
unsigned long flags;
ok = 1;
}
spin_unlock_irqrestore(&midi->input_lock, flags);
ok = 1;
}
spin_unlock_irqrestore(&midi->input_lock, flags);
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));
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)
}
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);
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;
} 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)
}
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);
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;
} 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)
}
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;
struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data;
unsigned long flags;
emu = midi->emu;
snd_assert(emu, return -ENXIO);
emu = midi->emu;
snd_assert(emu, return -ENXIO);
midi->substream_input = NULL;
if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
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);
}
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
}
static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream)
}
static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream)
struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data;
unsigned long flags;
struct emu10k1x *emu;
struct emu10k1x_midi *midi = substream->rmidi->private_data;
unsigned long flags;
emu = midi->emu;
snd_assert(emu, return -ENXIO);
emu = midi->emu;
snd_assert(emu, return -ENXIO);
midi->substream_output = NULL;
if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
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);
}
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
}
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)
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;
int timeout, ok;
{
unsigned long flags;
int timeout, ok;
ok = 1;
}
spin_unlock_irqrestore(&midi->input_lock, flags);
ok = 1;
}
spin_unlock_irqrestore(&midi->input_lock, flags);
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));
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_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
}
static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
midi->substream_input = substream;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
midi->substream_input = substream;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
- snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1);
- snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
+ if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
+ goto error_out;
+ if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
+ goto error_out;
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
return 0;
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
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)
midi->substream_output = substream;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
midi->substream_output = substream;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
- snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1);
- snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
+ if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
+ goto error_out;
+ if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
+ goto error_out;
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
return 0;
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
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)
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags;
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags;
emu = midi->emu;
snd_assert(emu, return -ENXIO);
emu = midi->emu;
snd_assert(emu, return -ENXIO);
midi->substream_input = NULL;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
midi->substream_input = NULL;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
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 {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
}
static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream)
}
static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream)
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags;
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags;
emu = midi->emu;
snd_assert(emu, return -ENXIO);
emu = midi->emu;
snd_assert(emu, return -ENXIO);
midi->substream_output = NULL;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
midi->substream_output = NULL;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
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 {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
}
}
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)