File:  [Qemu by Fabrice Bellard] / qemu / hw / virtio-console.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:39:37 2018 UTC (18 months, 2 weeks ago) by root
Branches: qemu, MAIN
CVS tags: qemu0150, qemu0141, qemu0140, HEAD
qemu 0.14.0

    1: /*
    2:  * Virtio Console and Generic Serial Port Devices
    3:  *
    4:  * Copyright Red Hat, Inc. 2009, 2010
    5:  *
    6:  * Authors:
    7:  *  Amit Shah <amit.shah@redhat.com>
    8:  *
    9:  * This work is licensed under the terms of the GNU GPL, version 2.  See
   10:  * the COPYING file in the top-level directory.
   11:  */
   12: 
   13: #include "qemu-char.h"
   14: #include "virtio-serial.h"
   15: 
   16: typedef struct VirtConsole {
   17:     VirtIOSerialPort port;
   18:     CharDriverState *chr;
   19: } VirtConsole;
   20: 
   21: 
   22: /* Callback function that's called when the guest sends us data */
   23: static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
   24: {
   25:     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
   26: 
   27:     return qemu_chr_write(vcon->chr, buf, len);
   28: }
   29: 
   30: /* Readiness of the guest to accept data on a port */
   31: static int chr_can_read(void *opaque)
   32: {
   33:     VirtConsole *vcon = opaque;
   34: 
   35:     return virtio_serial_guest_ready(&vcon->port);
   36: }
   37: 
   38: /* Send data from a char device over to the guest */
   39: static void chr_read(void *opaque, const uint8_t *buf, int size)
   40: {
   41:     VirtConsole *vcon = opaque;
   42: 
   43:     virtio_serial_write(&vcon->port, buf, size);
   44: }
   45: 
   46: static void chr_event(void *opaque, int event)
   47: {
   48:     VirtConsole *vcon = opaque;
   49: 
   50:     switch (event) {
   51:     case CHR_EVENT_OPENED:
   52:         virtio_serial_open(&vcon->port);
   53:         break;
   54:     case CHR_EVENT_CLOSED:
   55:         virtio_serial_close(&vcon->port);
   56:         break;
   57:     }
   58: }
   59: 
   60: static int generic_port_init(VirtConsole *vcon, VirtIOSerialDevice *dev)
   61: {
   62:     vcon->port.info = dev->info;
   63: 
   64:     if (vcon->chr) {
   65:         qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
   66:                               vcon);
   67:         vcon->port.info->have_data = flush_buf;
   68:     }
   69:     return 0;
   70: }
   71: 
   72: /* Virtio Console Ports */
   73: static int virtconsole_initfn(VirtIOSerialDevice *dev)
   74: {
   75:     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
   76:     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
   77: 
   78:     port->is_console = true;
   79:     return generic_port_init(vcon, dev);
   80: }
   81: 
   82: static int virtconsole_exitfn(VirtIOSerialDevice *dev)
   83: {
   84:     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
   85:     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
   86: 
   87:     if (vcon->chr) {
   88:         port->info->have_data = NULL;
   89:         qemu_chr_close(vcon->chr);
   90:     }
   91: 
   92:     return 0;
   93: }
   94: 
   95: static VirtIOSerialPortInfo virtconsole_info = {
   96:     .qdev.name     = "virtconsole",
   97:     .qdev.size     = sizeof(VirtConsole),
   98:     .init          = virtconsole_initfn,
   99:     .exit          = virtconsole_exitfn,
  100:     .qdev.props = (Property[]) {
  101:         DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1),
  102:         DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
  103:         DEFINE_PROP_CHR("chardev", VirtConsole, chr),
  104:         DEFINE_PROP_STRING("name", VirtConsole, port.name),
  105:         DEFINE_PROP_END_OF_LIST(),
  106:     },
  107: };
  108: 
  109: static void virtconsole_register(void)
  110: {
  111:     virtio_serial_port_qdev_register(&virtconsole_info);
  112: }
  113: device_init(virtconsole_register)
  114: 
  115: /* Generic Virtio Serial Ports */
  116: static int virtserialport_initfn(VirtIOSerialDevice *dev)
  117: {
  118:     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
  119:     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
  120: 
  121:     return generic_port_init(vcon, dev);
  122: }
  123: 
  124: static VirtIOSerialPortInfo virtserialport_info = {
  125:     .qdev.name     = "virtserialport",
  126:     .qdev.size     = sizeof(VirtConsole),
  127:     .init          = virtserialport_initfn,
  128:     .exit          = virtconsole_exitfn,
  129:     .qdev.props = (Property[]) {
  130:         DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
  131:         DEFINE_PROP_CHR("chardev", VirtConsole, chr),
  132:         DEFINE_PROP_STRING("name", VirtConsole, port.name),
  133:         DEFINE_PROP_END_OF_LIST(),
  134:     },
  135: };
  136: 
  137: static void virtserialport_register(void)
  138: {
  139:     virtio_serial_port_qdev_register(&virtserialport_info);
  140: }
  141: device_init(virtserialport_register)

unix.superglobalmegacorp.com