aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 8687ae3c66b8..b49a45cbf67a 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -183,7 +183,8 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
183 183
184 */ 184 */
185 185
186static void snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int ack) 186static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
187 int ack)
187{ 188{
188 unsigned long flags; 189 unsigned long flags;
189 int timeout, ok; 190 int timeout, ok;
@@ -218,9 +219,11 @@ static void snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int
218 ok = 1; 219 ok = 1;
219 } 220 }
220 spin_unlock_irqrestore(&mpu->input_lock, flags); 221 spin_unlock_irqrestore(&mpu->input_lock, flags);
221 if (! ok) 222 if (!ok) {
222 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))); 223 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)));
223 // 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))); 224 return 1;
225 }
226 return 0;
224} 227}
225 228
226/* 229/*
@@ -235,12 +238,19 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
235 if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) 238 if (mpu->open_input && (err = mpu->open_input(mpu)) < 0)
236 return err; 239 return err;
237 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { 240 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) {
238 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); 241 if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
239 snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); 242 goto error_out;
243 if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
244 goto error_out;
240 } 245 }
241 mpu->substream_input = substream; 246 mpu->substream_input = substream;
242 set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); 247 set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
243 return 0; 248 return 0;
249
250error_out:
251 if (mpu->open_input && mpu->close_input)
252 mpu->close_input(mpu);
253 return -EIO;
244} 254}
245 255
246static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) 256static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
@@ -252,39 +262,52 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
252 if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) 262 if (mpu->open_output && (err = mpu->open_output(mpu)) < 0)
253 return err; 263 return err;
254 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { 264 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
255 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); 265 if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
256 snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); 266 goto error_out;
267 if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
268 goto error_out;
257 } 269 }
258 mpu->substream_output = substream; 270 mpu->substream_output = substream;
259 set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); 271 set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
260 return 0; 272 return 0;
273
274error_out:
275 if (mpu->open_output && mpu->close_output)
276 mpu->close_output(mpu);
277 return -EIO;
261} 278}
262 279
263static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream) 280static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream)
264{ 281{
265 struct snd_mpu401 *mpu; 282 struct snd_mpu401 *mpu;
283 int err = 0;
266 284
267 mpu = substream->rmidi->private_data; 285 mpu = substream->rmidi->private_data;
268 clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); 286 clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
269 mpu->substream_input = NULL; 287 mpu->substream_input = NULL;
270 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) 288 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode))
271 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); 289 err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
272 if (mpu->close_input) 290 if (mpu->close_input)
273 mpu->close_input(mpu); 291 mpu->close_input(mpu);
292 if (err)
293 return -EIO;
274 return 0; 294 return 0;
275} 295}
276 296
277static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream) 297static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream)
278{ 298{
279 struct snd_mpu401 *mpu; 299 struct snd_mpu401 *mpu;
300 int err = 0;
280 301
281 mpu = substream->rmidi->private_data; 302 mpu = substream->rmidi->private_data;
282 clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); 303 clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
283 mpu->substream_output = NULL; 304 mpu->substream_output = NULL;
284 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) 305 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
285 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); 306 err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
286 if (mpu->close_output) 307 if (mpu->close_output)
287 mpu->close_output(mpu); 308 mpu->close_output(mpu);
309 if (err)
310 return -EIO;
288 return 0; 311 return 0;
289} 312}
290 313
@@ -316,6 +339,7 @@ static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substrea
316 snd_mpu401_uart_remove_timer(mpu, 1); 339 snd_mpu401_uart_remove_timer(mpu, 1);
317 clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); 340 clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode);
318 } 341 }
342
319} 343}
320 344
321/* 345/*