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; }
static void snd_mpu401_uart_clear_rx(mpu401_t *mpu) { int timeout = 100000; for (; timeout > 0 && snd_mpu401_input_avail(mpu); timeout--) mpu->read(mpu, MPU401D(mpu)); #ifdef CONFIG_SND_DEBUG if (timeout <= 0) snd_printk("cmd: clear rx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); #endif }
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))); }
/* * Check that the MIDI subsystem is operational. If it isn't, * then we will hang the computer if we try to use it ... * * NOTE: This check is based upon observation, not documentation. */ static inline int verify_mpu401(const struct snd_mpu401 * mpu) { return ((inb(MPU401C(mpu)) & 0xc0) == 0x80); }