Example #1
0
/* 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);
}