in drivers/chan_kern.c [538:570]
void chan_interrupt(struct line *line, int irq)
{
struct tty_port *port = &line->port;
struct chan *chan = line->chan_in;
int err;
char c;
if (!chan || !chan->ops->read)
goto out;
do {
if (!tty_buffer_request_room(port, 1)) {
schedule_delayed_work(&line->task, 1);
goto out;
}
err = chan->ops->read(chan->fd, &c, chan->data);
if (err > 0)
tty_insert_flip_char(port, c, TTY_NORMAL);
} while (err > 0);
if (err == -EIO) {
if (chan->primary) {
tty_port_tty_hangup(&line->port, false);
if (line->chan_out != chan)
close_one_chan(line->chan_out, 1);
}
close_one_chan(chan, 1);
if (chan->primary)
return;
}
out:
tty_flip_buffer_push(port);
}