/* This loop should be called with interrupts disabled * We don't want to interrupt this, * as we're already handling an interupt */ static void snd_uart16550_io_loop(snd_uart16550_t * uart) { unsigned char c, status; /* Read Loop */ while ((status = inb(uart->base + UART_LSR)) & UART_LSR_DR) { /* while receive data ready */ c = inb(uart->base + UART_RX); if (uart->filemode & SERIAL_MODE_INPUT_OPEN) { snd_rawmidi_receive(uart->midi_input, &c, 1); } if (status & UART_LSR_OE) snd_printk("%s: Overrun on device at 0x%lx\n", uart->rmidi->name, uart->base); } /* no need of check SERIAL_MODE_OUTPUT_OPEN because if not, buffer is never filled. */ /* Check write status */ if (status & UART_LSR_THRE) { uart->fifo_count = 0; } if (uart->adaptor == SNDRV_SERIAL_MS124W_SA) { /* Can't use FIFO, must send only when CTS is true */ status = inb(uart->base + UART_MSR); if (uart->fifo_count == 0 && (status & UART_MSR_CTS) && uart->buff_in_count > 0) snd_uart16550_buffer_output(uart); } else { /* Write loop */ while (uart->fifo_count < uart->fifo_limit /* Can we write ? */ && uart->buff_in_count > 0) /* Do we want to? */ snd_uart16550_buffer_output(uart); } if (uart->irq < 0 && uart->buff_in_count > 0) snd_uart16550_add_timer(uart); }
/* This loop should be called with interrupts disabled * We don't want to interrupt this, * as we're already handling an interrupt */ static void snd_uart16550_io_loop(snd_uart16550_t * uart) { unsigned char c, status; int substream; /* recall previous stream */ substream = uart->prev_in; /* Read Loop */ while ((status = inb(uart->base + UART_LSR)) & UART_LSR_DR) { /* while receive data ready */ c = inb(uart->base + UART_RX); /* keep track of last status byte */ if (c & 0x80) { uart->rstatus = c; } /* handle stream switch */ if (uart->adaptor == SNDRV_SERIAL_GENERIC) { if (uart->rstatus == 0xf5) { if (c <= SNDRV_SERIAL_MAX_INS && c > 0) substream = c - 1; if (c != 0xf5) uart->rstatus = 0; /* prevent future bytes from being interpreted as streams */ } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) { snd_rawmidi_receive(uart->midi_input[substream], &c, 1); } } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) { snd_rawmidi_receive(uart->midi_input[substream], &c, 1); } if (status & UART_LSR_OE) snd_printk("%s: Overrun on device at 0x%lx\n", uart->rmidi->name, uart->base); } /* remember the last stream */ uart->prev_in = substream; /* no need of check SERIAL_MODE_OUTPUT_OPEN because if not, buffer is never filled. */ /* Check write status */ if (status & UART_LSR_THRE) { uart->fifo_count = 0; } if (uart->adaptor == SNDRV_SERIAL_MS124W_SA || uart->adaptor == SNDRV_SERIAL_GENERIC) { /* Can't use FIFO, must send only when CTS is true */ status = inb(uart->base + UART_MSR); while( (uart->fifo_count == 0) && (status & UART_MSR_CTS) && (uart->buff_in_count > 0) ) { snd_uart16550_buffer_output(uart); status = inb( uart->base + UART_MSR ); } } else { /* Write loop */ while (uart->fifo_count < uart->fifo_limit /* Can we write ? */ && uart->buff_in_count > 0) /* Do we want to? */ snd_uart16550_buffer_output(uart); } if (uart->irq < 0 && uart->buff_in_count > 0) snd_uart16550_add_timer(uart); }