File:  [Qemu by Fabrice Bellard] / qemu / hw / virtio-console.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:30:11 2018 UTC (2 years, 11 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0130, HEAD
qemu 0.13.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 void flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
   24: {
   25:     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
   26: 
   27:     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:     }
   55:     case CHR_EVENT_CLOSED:
   56:         virtio_serial_close(&vcon->port);
   57:         break;
   58:     }
   59: }
   60: 
   61: /* Virtio Console Ports */
   62: static int virtconsole_initfn(VirtIOSerialDevice *dev)
   63: {
   64:     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
   65:     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
   66: 
   67:     port->info = dev->info;
   68: 
   69:     port->is_console = true;
   70: 
   71:     if (vcon->chr) {
   72:         qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
   73:                               vcon);
   74:         port->info->have_data = flush_buf;
   75:     }
   76:     return 0;
   77: }
   78: 
   79: static int virtconsole_exitfn(VirtIOSerialDevice *dev)
   80: {
   81:     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
   82:     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
   83: 
   84:     if (vcon->chr) {
   85:         port->info->have_data = NULL;
   86:         qemu_chr_close(vcon->chr);
   87:     }
   88: 
   89:     return 0;
   90: }
   91: 
   92: static VirtIOSerialPortInfo virtconsole_info = {
   93:     .qdev.name     = "virtconsole",
   94:     .qdev.size     = sizeof(VirtConsole),
   95:     .init          = virtconsole_initfn,
   96:     .exit          = virtconsole_exitfn,
   97:     .qdev.props = (Property[]) {
   98:         DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1),
   99:         DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
  100:         DEFINE_PROP_CHR("chardev", VirtConsole, chr),
  101:         DEFINE_PROP_STRING("name", VirtConsole, port.name),
  102:         DEFINE_PROP_END_OF_LIST(),
  103:     },
  104: };
  105: 
  106: static void virtconsole_register(void)
  107: {
  108:     virtio_serial_port_qdev_register(&virtconsole_info);
  109: }
  110: device_init(virtconsole_register)
  111: 
  112: /* Generic Virtio Serial Ports */
  113: static int virtserialport_initfn(VirtIOSerialDevice *dev)
  114: {
  115:     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
  116:     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
  117: 
  118:     port->info = dev->info;
  119: 
  120:     if (vcon->chr) {
  121:         qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
  122:                               vcon);
  123:         port->info->have_data = flush_buf;
  124:     }
  125:     return 0;
  126: }
  127: 
  128: static VirtIOSerialPortInfo virtserialport_info = {
  129:     .qdev.name     = "virtserialport",
  130:     .qdev.size     = sizeof(VirtConsole),
  131:     .init          = virtserialport_initfn,
  132:     .exit          = virtconsole_exitfn,
  133:     .qdev.props = (Property[]) {
  134:         DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
  135:         DEFINE_PROP_CHR("chardev", VirtConsole, chr),
  136:         DEFINE_PROP_STRING("name", VirtConsole, port.name),
  137:         DEFINE_PROP_END_OF_LIST(),
  138:     },
  139: };
  140: 
  141: static void virtserialport_register(void)
  142: {
  143:     virtio_serial_port_qdev_register(&virtserialport_info);
  144: }
  145: device_init(virtserialport_register)

unix.superglobalmegacorp.com