예제 #1
0
파일: n_tty.c 프로젝트: benbee/Learning
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
			      char *fp, int count)
{
	const unsigned char *p;
	char *f, flags = 0;
	int	i;

	if (!tty->read_buf)
		return;

	if (tty->real_raw) {
		i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
				   N_TTY_BUF_SIZE - tty->read_head));
		memcpy(tty->read_buf + tty->read_head, cp, i);
		tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
		tty->read_cnt += i;
		cp += i;
		count -= i;

		i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
			       N_TTY_BUF_SIZE - tty->read_head));
		memcpy(tty->read_buf + tty->read_head, cp, i);
		tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
		tty->read_cnt += i;
	} else {
		for (i=count, p = cp, f = fp; i; i--, p++) {
			if (f)
				flags = *f++;
			switch (flags) {
			case TTY_NORMAL:
				n_tty_receive_char(tty, *p);
				break;
			case TTY_BREAK:
				n_tty_receive_break(tty);
				break;
			case TTY_PARITY:
			case TTY_FRAME:
				n_tty_receive_parity_error(tty, *p);
				break;
			case TTY_OVERRUN:
				n_tty_receive_overrun(tty);
				break;
			default:
				printk("%s: unknown flag %d\n", tty_name(tty),
				       flags);
				break;
			}
		}
		if (tty->driver.flush_chars)
			tty->driver.flush_chars(tty);
	}

	if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
		if (tty->fasync)
			kill_fasync(tty->fasync, SIGIO);
		if (tty->read_wait)
			wake_up_interruptible(&tty->read_wait);
	}

	if ((tty->read_cnt >= TTY_THRESHOLD_THROTTLE) &&
	    tty->driver.throttle &&
	    !set_bit(TTY_THROTTLED, &tty->flags))
		tty->driver.throttle(tty);
}
예제 #2
0
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
			      char *fp, int count)
{
	const unsigned char *p;
	char *f, flags = TTY_NORMAL;
	int	i;
	char	buf[64];
	unsigned long cpuflags;

	if (!tty->read_buf)
		return;

	if (tty->real_raw) {
		spin_lock_irqsave(&tty->read_lock, cpuflags);
		i = min(N_TTY_BUF_SIZE - tty->read_cnt,
			N_TTY_BUF_SIZE - tty->read_head);
		i = min(count, i);
		memcpy(tty->read_buf + tty->read_head, cp, i);
		tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
		tty->read_cnt += i;
		cp += i;
		count -= i;

		i = min(N_TTY_BUF_SIZE - tty->read_cnt,
			N_TTY_BUF_SIZE - tty->read_head);
		i = min(count, i);
		memcpy(tty->read_buf + tty->read_head, cp, i);
		tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
		tty->read_cnt += i;
		spin_unlock_irqrestore(&tty->read_lock, cpuflags);
	} else {
		for (i = count, p = cp, f = fp; i; i--, p++) {
			if (f)
				flags = *f++;
			switch (flags) {
			case TTY_NORMAL:
				n_tty_receive_char(tty, *p);
				break;
			case TTY_BREAK:
				n_tty_receive_break(tty);
				break;
			case TTY_PARITY:
			case TTY_FRAME:
				n_tty_receive_parity_error(tty, *p);
				break;
			case TTY_OVERRUN:
				n_tty_receive_overrun(tty);
				break;
			default:
				printk(KERN_ERR "%s: unknown flag %d\n",
				       tty_name(tty, buf), flags);
				break;
			}
		}
		if (tty->ops->flush_chars)
			tty->ops->flush_chars(tty);
	}

	n_tty_set_room(tty);

	if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
		L_EXTPROC(tty)) {
		kill_fasync(&tty->fasync, SIGIO, POLL_IN);
		if (waitqueue_active(&tty->read_wait))
			wake_up_interruptible(&tty->read_wait);
	}

	if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
		tty_throttle(tty);
}
예제 #3
0
파일: n_tty.c 프로젝트: benbee/Learning
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
			      char *fp, int count)
{
	const unsigned char *p;
	char *f, flags = TTY_NORMAL;
	int	i;
	char	buf[64];

	if (!tty->read_buf)
		return;

	if (tty->real_raw) {
		i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
				   N_TTY_BUF_SIZE - tty->read_head));
		memcpy(tty->read_buf + tty->read_head, cp, i);
		tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
		tty->read_cnt += i;
		cp += i;
		count -= i;

		i = MIN(count, MIN(N_TTY_BUF_SIZE - tty->read_cnt,
			       N_TTY_BUF_SIZE - tty->read_head));
		memcpy(tty->read_buf + tty->read_head, cp, i);
		tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
		tty->read_cnt += i;
	} else {
		for (i=count, p = cp, f = fp; i; i--, p++) {
			if (f)
				flags = *f++;
			switch (flags) {
			case TTY_NORMAL:
				n_tty_receive_char(tty, *p);
				break;
			case TTY_BREAK:
				n_tty_receive_break(tty);
				break;
			case TTY_PARITY:
			case TTY_FRAME:
				n_tty_receive_parity_error(tty, *p);
				break;
			case TTY_OVERRUN:
				n_tty_receive_overrun(tty);
				break;
			default:
				printk("%s: unknown flag %d\n",
				       tty_name(tty, buf), flags);
				break;
			}
		}
		if (tty->driver.flush_chars)
			tty->driver.flush_chars(tty);
	}

	if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
		if (tty->fasync)
			kill_fasync(tty->fasync, SIGIO);
		if (tty->read_wait)
			wake_up_interruptible(&tty->read_wait);
	}

	/*
	 * Check the remaining room for the input canonicalization
	 * mode.  We don't want to throttle the driver if we're in
	 * canonical mode and don't have a newline yet!
	 */
	if (n_tty_receive_room(tty) < TTY_THRESHOLD_THROTTLE) {
		/* check TTY_THROTTLED first so it indicates our state */
		if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
		    tty->driver.throttle)
			tty->driver.throttle(tty);
	}
}