The patch titled sound: fix hang in mpu401_uart.c has been removed from the -mm tree. Its filename is sound-fix-hang-in-mpu401_uartc.patch This patch was probably dropped from -mm because it has now been merged into a subsystem tree or into Linus's tree, or because it was folded into its parent patch in the -mm tree. From: Jon Masters <jcm@xxxxxxxxxxxxxx> This fixes a hang in mpu401_uart.c that can occur when the mpu401 interface is non-existent or otherwise doesn't respond to commands but we issue IO anyway. snd_mpu401_uart_cmd now returns an error code that is passed up the stack so that an open() will fail immediately in such cases. Eventually discovered after wine/cxoffice would constantly cause hard lockups on my desktop immediately after loading (emulating Windows too well). Turned out that I'd recently moved my sound cards around and using /dev/sequencer now talks to a sound card with a broken MPU. Signed-off-by: Jon Masters <jcm@xxxxxxxxxxxxxx> Cc: Jaroslav Kysela <perex@xxxxxxx> Cc: Takashi Iwai <tiwai@xxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- sound/drivers/mpu401/mpu401_uart.c | 38 +++++++++++++++++++-------- 1 files changed, 27 insertions(+), 11 deletions(-) diff -puN sound/drivers/mpu401/mpu401_uart.c~sound-fix-hang-in-mpu401_uartc sound/drivers/mpu401/mpu401_uart.c --- devel/sound/drivers/mpu401/mpu401_uart.c~sound-fix-hang-in-mpu401_uartc 2006-04-18 20:57:43.000000000 -0700 +++ devel-akpm/sound/drivers/mpu401/mpu401_uart.c 2006-04-18 20:57:50.000000000 -0700 @@ -183,7 +183,8 @@ static void snd_mpu401_uart_remove_timer */ -static void snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int ack) +static int snd_mpu401_uart_cmd(struct snd_mpu401 *mpu, unsigned char cmd, + int ack) { unsigned long flags; int timeout, ok; @@ -218,9 +219,14 @@ static void snd_mpu401_uart_cmd(struct s ok = 1; } spin_unlock_irqrestore(&mpu->input_lock, flags); - if (! ok) - snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); - // snd_printk("cmd: 0x%x at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); + if (!ok) { + snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = " + "0x%x)\n", + cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), + mpu->read(mpu, MPU401D(mpu))); + return 1; + } + return 0; } /* @@ -235,8 +241,10 @@ static int snd_mpu401_uart_input_open(st if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) return err; if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { - snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); - snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); + if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) + return -EFAULT; + if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) + return -EFAULT; } mpu->substream_input = substream; set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); @@ -251,9 +259,11 @@ static int snd_mpu401_uart_output_open(s mpu = substream->rmidi->private_data; if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) return err; - if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { - snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); - snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); + if (!test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { + if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) + return -EFAULT; + if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) + return -EFAULT; } mpu->substream_output = substream; set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); @@ -263,28 +273,34 @@ static int snd_mpu401_uart_output_open(s static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream) { struct snd_mpu401 *mpu; + int err = 0; mpu = substream->rmidi->private_data; clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); mpu->substream_input = NULL; if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) - snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); + err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); if (mpu->close_input) mpu->close_input(mpu); + if (err) + return -EFAULT; return 0; } static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream) { struct snd_mpu401 *mpu; + int err = 0; mpu = substream->rmidi->private_data; clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); mpu->substream_output = NULL; if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) - snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); + err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); if (mpu->close_output) mpu->close_output(mpu); + if (err) + return -EFAULT; return 0; } _ Patches currently in -mm which might be from jcm@xxxxxxxxxxxxxx are sound-fix-hang-in-mpu401_uartc.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html