static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu) { unsigned char byte; int max = 256; do { if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { if (!snd_mpu401_output_ready(mpu) && !snd_mpu401_output_ready(mpu)) break; mpu->write(mpu, byte, MPU401D(mpu)); snd_rawmidi_transmit_ack(mpu->substream_output, 1); } else { snd_mpu401_uart_remove_timer (mpu, 0); break; } } while (--max > 0); }
/* * write output pending bytes * call with output_lock spinlock held */ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu) { unsigned char byte; int max = 256; do { if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { /* * Try twice because there is hardware that insists on * setting the output busy bit after each write. */ if (!snd_mpu401_output_ready(mpu) && !snd_mpu401_output_ready(mpu)) break; /* Tx FIFO full - try again later */ mpu->write(mpu, byte, MPU401D(mpu)); snd_rawmidi_transmit_ack(mpu->substream_output, 1); } else { snd_mpu401_uart_remove_timer (mpu, 0); break; /* no other data - leave the tx loop */ } } while (--max > 0); }
static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int ack) { unsigned long flags; int timeout, ok; spin_lock_irqsave(&mpu->input_lock, flags); if (mpu->hardware != MPU401_HW_TRID4DWAVE) { mpu->write(mpu, 0x00, MPU401D(mpu)); } if (mpu->hardware != MPU401_HW_SB) { for (timeout = 1000; timeout > 0 && !snd_mpu401_output_ready(mpu); timeout--) udelay(10); #ifdef CONFIG_SND_DEBUG if (!timeout) snd_printk(KERN_ERR "cmd: tx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); #endif } mpu->write(mpu, cmd, MPU401C(mpu)); if (ack && !(mpu->info_flags & MPU401_INFO_NO_ACK)) { ok = 0; timeout = 10000; while (!ok && timeout-- > 0) { if (snd_mpu401_input_avail(mpu)) { if (mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) ok = 1; } } if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) ok = 1; } else ok = 1; spin_unlock_irqrestore(&mpu->input_lock, flags); if (!ok) { snd_printk(KERN_ERR "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; }
/* * write output pending bytes * call with output_lock spinlock held */ static void snd_mpu401_uart_output_write(mpu401_t * mpu) { unsigned char byte; int max = 256, timeout; do { if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { for (timeout = 100; timeout > 0; timeout--) { if (snd_mpu401_output_ready(mpu)) { mpu->write(mpu, byte, MPU401D(mpu)); snd_rawmidi_transmit_ack(mpu->substream_output, 1); break; } } if (timeout == 0) break; /* Tx FIFO full - try again later */ } else { snd_mpu401_uart_remove_timer (mpu, 0); break; /* no other data - leave the tx loop */ } } while (--max > 0); }
static void snd_mpu401_uart_cmd(mpu401_t * mpu, unsigned char cmd, int ack) { unsigned long flags; int timeout, ok; spin_lock_irqsave(&mpu->input_lock, flags); if (mpu->hardware != MPU401_HW_TRID4DWAVE) { mpu->write(mpu, 0x00, MPU401D(mpu)); /*snd_mpu401_uart_clear_rx(mpu);*/ } /* ok. standard MPU-401 initialization */ if (mpu->hardware != MPU401_HW_SB) { for (timeout = 1000; timeout > 0 && !snd_mpu401_output_ready(mpu); timeout--) udelay(10); #ifdef CONFIG_SND_DEBUG if (!timeout) snd_printk("cmd: tx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); #endif } mpu->write(mpu, cmd, MPU401C(mpu)); if (ack) { ok = 0; timeout = 10000; while (!ok && timeout-- > 0) { if (snd_mpu401_input_avail(mpu)) { if (mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) ok = 1; } } if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) ok = 1; } else { 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))); }