Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions drivers/char/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -1192,13 +1192,51 @@ static void notifier_del_vio(struct hvc_struct *hp, int data)
hp->irq_requested = 0;
}

static void virtio_console_set_termios(struct hvc_struct *hp, const struct ktermios *old)
{
struct tty_struct *tty = hp->port.tty;
struct port *port;
uint16_t value;

port = find_port_by_vtermno(hp->vtermno);
if (!port)
return;

if(!virtio_has_feature(port->portdev->vdev, VIRTIO_CONSOLE_F_SET_TERMIO))
return;

if (tty->termios.c_ospeed != old->c_ospeed) {
value = (uint16_t)(tty->termios.c_cflag & CBAUD);
printk("baud %x\n", value);

__send_control_msg(port->portdev, port->id,
VIRTIO_CONSOLE_SET_TERMIO_OBAUD, value);
}

if (tty->termios.c_ispeed != old->c_ispeed) {
value = (uint16_t)((tty->termios.c_cflag >> IBSHIFT) & CBAUD);
printk("ibaud %x\n", value);
if (value == B0)
value = (uint16_t)(tty->termios.c_cflag & CBAUD);
__send_control_msg(port->portdev, port->id,
VIRTIO_CONSOLE_SET_TERMIO_IBAUD, value);
}

if ((tty->termios.c_cflag ^ old->c_cflag) & CRTSCTS) {
value = (tty->termios.c_cflag & CRTSCTS) ? 1 : 0;
__send_control_msg(port->portdev, port->id,
VIRTIO_CONSOLE_SET_TERMIO_CRTSCTS, value);
}
}

/* The operations for console ports. */
static const struct hv_ops hv_ops = {
.get_chars = get_chars,
.put_chars = put_chars,
.notifier_add = notifier_add_vio,
.notifier_del = notifier_del_vio,
.notifier_hangup = notifier_del_vio,
.hvc_set_termios = virtio_console_set_termios,
};

/*
Expand Down Expand Up @@ -2133,6 +2171,7 @@ MODULE_DEVICE_TABLE(virtio, id_table);
static const unsigned int features[] = {
VIRTIO_CONSOLE_F_SIZE,
VIRTIO_CONSOLE_F_MULTIPORT,
VIRTIO_CONSOLE_F_SET_TERMIO,
};

static const struct virtio_device_id rproc_serial_id_table[] = {
Expand Down Expand Up @@ -2248,6 +2287,7 @@ static int __init virtio_console_init(void)
{
int err;

printk("virtio_console_init 999999\n");
err = class_register(&port_class);
if (err)
return err;
Expand Down
10 changes: 10 additions & 0 deletions drivers/tty/hvc/hvc_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,15 @@ static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch)
}
#endif

static void hvc_set_termios(struct tty_struct *tty,
const struct ktermios *old_termios)
{
struct hvc_struct *hp = tty->driver_data;

if (hp && hp->ops->hvc_set_termios)
hp->ops->hvc_set_termios(hp, old_termios);
}

static const struct tty_operations hvc_ops = {
.install = hvc_install,
.open = hvc_open,
Expand All @@ -895,6 +904,7 @@ static const struct tty_operations hvc_ops = {
.unthrottle = hvc_unthrottle,
.write_room = hvc_write_room,
.chars_in_buffer = hvc_chars_in_buffer,
.set_termios = hvc_set_termios,
.tiocmget = hvc_tiocmget,
.tiocmset = hvc_tiocmset,
#ifdef CONFIG_CONSOLE_POLL
Expand Down
2 changes: 2 additions & 0 deletions drivers/tty/hvc/hvc_console.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ struct hv_ops {
void (*notifier_del)(struct hvc_struct *hp, int irq);
void (*notifier_hangup)(struct hvc_struct *hp, int irq);

/* Handler for tty set_termios implementation */
void (*hvc_set_termios)(struct hvc_struct *hp, const struct ktermios *old);
/* tiocmget/set implementation */
int (*tiocmget)(struct hvc_struct *hp);
int (*tiocmset)(struct hvc_struct *hp, unsigned int set, unsigned int clear);
Expand Down
4 changes: 4 additions & 0 deletions include/uapi/linux/virtio_console.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */
#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */
#define VIRTIO_CONSOLE_F_EMERG_WRITE 2 /* Does host support emergency write? */
#define VIRTIO_CONSOLE_F_SET_TERMIO 23 /* Does host support set termio ? */

#define VIRTIO_CONSOLE_BAD_ID (~(__u32)0)

Expand Down Expand Up @@ -73,6 +74,9 @@ struct virtio_console_control {
#define VIRTIO_CONSOLE_RESIZE 5
#define VIRTIO_CONSOLE_PORT_OPEN 6
#define VIRTIO_CONSOLE_PORT_NAME 7
#define VIRTIO_CONSOLE_SET_TERMIO_OBAUD 1000
#define VIRTIO_CONSOLE_SET_TERMIO_IBAUD 1001
#define VIRTIO_CONSOLE_SET_TERMIO_CRTSCTS 1002


#endif /* _UAPI_LINUX_VIRTIO_CONSOLE_H */