コード例 #1
0
ファイル: 8250_aspeed_vuart.c プロジェクト: Lyude/linux
/*
 * Custom interrupt handler to manage finer-grained flow control. Although we
 * have throttle/unthrottle callbacks, we've seen that the VUART device can
 * deliver characters faster than the ldisc has a chance to check buffer space
 * against the throttle threshold. This results in dropped characters before
 * the throttle.
 *
 * We do this by checking for flip buffer space before RX. If we have no space,
 * throttle now and schedule an unthrottle for later, once the ldisc has had
 * a chance to drain the buffers.
 */
static int aspeed_vuart_handle_irq(struct uart_port *port)
{
	struct uart_8250_port *up = up_to_u8250p(port);
	unsigned int iir, lsr;
	unsigned long flags;
	int space, count;

	iir = serial_port_in(port, UART_IIR);

	if (iir & UART_IIR_NO_INT)
		return 0;

	spin_lock_irqsave(&port->lock, flags);

	lsr = serial_port_in(port, UART_LSR);

	if (lsr & (UART_LSR_DR | UART_LSR_BI)) {
		space = tty_buffer_space_avail(&port->state->port);

		if (!space) {
			/* throttle and schedule an unthrottle later */
			struct aspeed_vuart *vuart = port->private_data;
			__aspeed_vuart_set_throttle(up, true);

			if (!timer_pending(&vuart->unthrottle_timer)) {
				vuart->port = up;
				mod_timer(&vuart->unthrottle_timer,
					  jiffies + unthrottle_timeout);
			}

		} else {
			count = min(space, 256);

			do {
				serial8250_read_char(up, lsr);
				lsr = serial_in(up, UART_LSR);
				if (--count == 0)
					break;
			} while (lsr & (UART_LSR_DR | UART_LSR_BI));

			tty_flip_buffer_push(&port->state->port);
		}
	}

	serial8250_modem_status(up);
	if (lsr & UART_LSR_THRE)
		serial8250_tx_chars(up);

	spin_unlock_irqrestore(&port->lock, flags);

	return 1;
}
コード例 #2
0
ファイル: 8250_aspeed_vuart.c プロジェクト: Lyude/linux
static void aspeed_vuart_unthrottle_exp(struct timer_list *timer)
{
	struct aspeed_vuart *vuart = from_timer(vuart, timer, unthrottle_timer);
	struct uart_8250_port *up = vuart->port;

	if (!tty_buffer_space_avail(&up->port.state->port)) {
		mod_timer(&vuart->unthrottle_timer,
			  jiffies + unthrottle_timeout);
		return;
	}

	aspeed_vuart_unthrottle(&up->port);
}
コード例 #3
0
ファイル: pty.c プロジェクト: 7799/linux
static int pty_space(struct tty_struct *to)
{
	int n = tty_buffer_space_avail(to->port);
	return min(n, 8192);
}
コード例 #4
0
ファイル: pty.c プロジェクト: DenisLug/mptcp
static int pty_write_room(struct tty_struct *tty)
{
	if (tty->stopped)
		return 0;
	return tty_buffer_space_avail(tty->link->port);
}