コード例 #1
0
static _INLINE_ void transmit_chars(struct xmb_serial *info,
		volatile unsigned int *uartp)
{
	if (info->x_char) {
		/* Send special char, probably flow control */
		unsigned int ch = info->x_char;
		uartp[XUL_TX_FIFO_OFFSET/4] = ch;
		info->x_char=0;
		info->stats.tx++;
	}

	/* Don't send anything if there's nothing to send or tty is stopped */
	if ((info->xmit_cnt <= 0) || info->tty->stopped) {
		return;
	}
	
	/* Fill the UART TX buffer again */
	while (!(uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_FULL)) {
		unsigned int ch = info->xmit_buf[info->xmit_tail++];
		uartp[XUL_TX_FIFO_OFFSET/4] = ch;
		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
		info->stats.tx++;
		if (--info->xmit_cnt <= 0)
			break;
	}

	if (info->xmit_cnt < WAKEUP_CHARS)
		xmbrs_sched_event(info, RS_EVENT_WRITE_WAKEUP);

	return;
}
コード例 #2
0
/* Force a refill of the TX FIFO.  This happens in user space, outside of
   interrupts so we cli() for the duration to prevent corruption of the
   output buffer data structure */
void force_tx_fifo_fill(struct xmb_serial *info)
{
	unsigned int flags;
	volatile unsigned int *uartp=(volatile unsigned int *)info->addr;

	save_flags(flags);

	/* Block until TX FIFO can take more chars */
	while(uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_FULL)
		;
	cli();

	/* Force out any special character */
	if (info->x_char) {
		/* Send special char, probably flow control */
		unsigned int ch = info->x_char;
		uartp[XUL_TX_FIFO_OFFSET/4]=ch;
		info->x_char=0;
		info->stats.tx++;
	}

	restore_flags(flags);

	cli();
	/* Don't send anything if there's nothing to send or tty is stopped */
	if ((info->xmit_cnt <= 0) || info->tty->stopped) {
		restore_flags(flags);
		return;
	}
	restore_flags(flags);
	
	/* Fill the UART TX buffer again */
	while(1) {
		unsigned int ch;

		if(uartp[XUL_STATUS_REG_OFFSET/4] & XUL_SR_TX_FIFO_FULL)
			break;

		cli();
		ch = info->xmit_buf[info->xmit_tail++];
		uartp[XUL_TX_FIFO_OFFSET/4]=ch;
		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
		info->stats.tx++;
		if (--info->xmit_cnt <= 0)
			break;
		restore_flags(flags);
	}

	restore_flags(flags);

	if (info->xmit_cnt < WAKEUP_CHARS)
		xmbrs_sched_event(info, RS_EVENT_WRITE_WAKEUP);

	return;
}