diff options
author | Randy Dunlap <randy.dunlap@oracle.com> | 2006-07-04 08:25:26 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-07-12 14:07:51 -0400 |
commit | b130807dce4a8f91f9662e93d1aa813d806e14a8 (patch) | |
tree | b8570b43ecf1d0347b46eba67082d623a74c7cc8 /sound/pci/emu10k1/emumpu401.c | |
parent | 40e1a9c0d428740a5c10a5be2335b9d7c39df043 (diff) |
[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: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/emu10k1/emumpu401.c')
-rw-r--r-- | sound/pci/emu10k1/emumpu401.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c index d96eb455103f..950c6bcd6b7d 100644 --- a/sound/pci/emu10k1/emumpu401.c +++ b/sound/pci/emu10k1/emumpu401.c | |||
@@ -116,7 +116,7 @@ static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int st | |||
116 | do_emu10k1_midi_interrupt(emu, &emu->midi2, status); | 116 | do_emu10k1_midi_interrupt(emu, &emu->midi2, status); |
117 | } | 117 | } |
118 | 118 | ||
119 | static void snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack) | 119 | static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack) |
120 | { | 120 | { |
121 | unsigned long flags; | 121 | unsigned long flags; |
122 | int timeout, ok; | 122 | int timeout, ok; |
@@ -141,11 +141,14 @@ static void snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_mi | |||
141 | ok = 1; | 141 | ok = 1; |
142 | } | 142 | } |
143 | spin_unlock_irqrestore(&midi->input_lock, flags); | 143 | spin_unlock_irqrestore(&midi->input_lock, flags); |
144 | if (!ok) | 144 | if (!ok) { |
145 | snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n", | 145 | snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n", |
146 | cmd, emu->port, | 146 | cmd, emu->port, |
147 | mpu401_read_stat(emu, midi), | 147 | mpu401_read_stat(emu, midi), |
148 | mpu401_read_data(emu, midi)); | 148 | mpu401_read_data(emu, midi)); |
149 | return 1; | ||
150 | } | ||
151 | return 0; | ||
149 | } | 152 | } |
150 | 153 | ||
151 | static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream) | 154 | 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 | midi->substream_input = substream; | 164 | midi->substream_input = substream; |
162 | if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) { | 165 | if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) { |
163 | spin_unlock_irqrestore(&midi->open_lock, flags); | 166 | spin_unlock_irqrestore(&midi->open_lock, flags); |
164 | snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1); | 167 | if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1)) |
165 | snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1); | 168 | goto error_out; |
169 | if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1)) | ||
170 | goto error_out; | ||
166 | } else { | 171 | } else { |
167 | spin_unlock_irqrestore(&midi->open_lock, flags); | 172 | spin_unlock_irqrestore(&midi->open_lock, flags); |
168 | } | 173 | } |
169 | return 0; | 174 | return 0; |
175 | |||
176 | error_out: | ||
177 | return -EIO; | ||
170 | } | 178 | } |
171 | 179 | ||
172 | static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream) | 180 | 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 | midi->substream_output = substream; | 190 | midi->substream_output = substream; |
183 | if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) { | 191 | if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) { |
184 | spin_unlock_irqrestore(&midi->open_lock, flags); | 192 | spin_unlock_irqrestore(&midi->open_lock, flags); |
185 | snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1); | 193 | if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1)) |
186 | snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1); | 194 | goto error_out; |
195 | if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1)) | ||
196 | goto error_out; | ||
187 | } else { | 197 | } else { |
188 | spin_unlock_irqrestore(&midi->open_lock, flags); | 198 | spin_unlock_irqrestore(&midi->open_lock, flags); |
189 | } | 199 | } |
190 | return 0; | 200 | return 0; |
201 | |||
202 | error_out: | ||
203 | return -EIO; | ||
191 | } | 204 | } |
192 | 205 | ||
193 | static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream) | 206 | 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 | struct snd_emu10k1 *emu; | 208 | struct snd_emu10k1 *emu; |
196 | struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; | 209 | struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; |
197 | unsigned long flags; | 210 | unsigned long flags; |
211 | int err = 0; | ||
198 | 212 | ||
199 | emu = midi->emu; | 213 | emu = midi->emu; |
200 | snd_assert(emu, return -ENXIO); | 214 | snd_assert(emu, return -ENXIO); |
@@ -204,11 +218,11 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream) | |||
204 | midi->substream_input = NULL; | 218 | midi->substream_input = NULL; |
205 | if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) { | 219 | if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) { |
206 | spin_unlock_irqrestore(&midi->open_lock, flags); | 220 | spin_unlock_irqrestore(&midi->open_lock, flags); |
207 | snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0); | 221 | err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0); |
208 | } else { | 222 | } else { |
209 | spin_unlock_irqrestore(&midi->open_lock, flags); | 223 | spin_unlock_irqrestore(&midi->open_lock, flags); |
210 | } | 224 | } |
211 | return 0; | 225 | return err; |
212 | } | 226 | } |
213 | 227 | ||
214 | static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream) | 228 | 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 | struct snd_emu10k1 *emu; | 230 | struct snd_emu10k1 *emu; |
217 | struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; | 231 | struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; |
218 | unsigned long flags; | 232 | unsigned long flags; |
233 | int err = 0; | ||
219 | 234 | ||
220 | emu = midi->emu; | 235 | emu = midi->emu; |
221 | snd_assert(emu, return -ENXIO); | 236 | snd_assert(emu, return -ENXIO); |
@@ -225,11 +240,11 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream | |||
225 | midi->substream_output = NULL; | 240 | midi->substream_output = NULL; |
226 | if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) { | 241 | if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) { |
227 | spin_unlock_irqrestore(&midi->open_lock, flags); | 242 | spin_unlock_irqrestore(&midi->open_lock, flags); |
228 | snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0); | 243 | err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0); |
229 | } else { | 244 | } else { |
230 | spin_unlock_irqrestore(&midi->open_lock, flags); | 245 | spin_unlock_irqrestore(&midi->open_lock, flags); |
231 | } | 246 | } |
232 | return 0; | 247 | return err; |
233 | } | 248 | } |
234 | 249 | ||
235 | static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) | 250 | static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) |