Annotation of qemu/hw/virtio-console.c, revision 1.1.1.4
1.1 root 1: /*
1.1.1.4 ! root 2: * Virtio Console and Generic Serial Port Devices
1.1 root 3: *
1.1.1.4 ! root 4: * Copyright Red Hat, Inc. 2009, 2010
1.1 root 5: *
6: * Authors:
1.1.1.4 ! root 7: * Amit Shah <amit.shah@redhat.com>
1.1 root 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"
1.1.1.4 ! root 14: #include "virtio-serial.h"
1.1 root 15:
1.1.1.4 ! root 16: typedef struct VirtConsole {
! 17: VirtIOSerialPort port;
1.1 root 18: CharDriverState *chr;
1.1.1.4 ! root 19: } VirtConsole;
1.1 root 20:
21:
1.1.1.4 ! root 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)
1.1 root 24: {
1.1.1.4 ! root 25: VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
1.1 root 26:
1.1.1.4 ! root 27: qemu_chr_write(vcon->chr, buf, len);
1.1 root 28: }
29:
1.1.1.4 ! root 30: /* Readiness of the guest to accept data on a port */
! 31: static int chr_can_read(void *opaque)
1.1 root 32: {
1.1.1.4 ! root 33: VirtConsole *vcon = opaque;
1.1 root 34:
1.1.1.4 ! root 35: return virtio_serial_guest_ready(&vcon->port);
1.1 root 36: }
37:
1.1.1.4 ! root 38: /* Send data from a char device over to the guest */
! 39: static void chr_read(void *opaque, const uint8_t *buf, int size)
1.1 root 40: {
1.1.1.4 ! root 41: VirtConsole *vcon = opaque;
1.1 root 42:
1.1.1.4 ! root 43: virtio_serial_write(&vcon->port, buf, size);
1.1 root 44: }
45:
1.1.1.4 ! root 46: static void chr_event(void *opaque, int event)
1.1 root 47: {
1.1.1.4 ! root 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;
1.1 root 58: }
59: }
60:
1.1.1.4 ! root 61: /* Virtio Console Ports */
! 62: static int virtconsole_initfn(VirtIOSerialDevice *dev)
1.1 root 63: {
1.1.1.4 ! root 64: VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
! 65: VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
1.1 root 66:
1.1.1.4 ! root 67: port->info = dev->info;
1.1 root 68:
1.1.1.4 ! root 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;
1.1 root 77: }
78:
1.1.1.4 ! root 79: static int virtconsole_exitfn(VirtIOSerialDevice *dev)
1.1 root 80: {
1.1.1.4 ! root 81: VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
! 82: VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
1.1 root 83:
1.1.1.4 ! root 84: if (vcon->chr) {
! 85: port->info->have_data = NULL;
! 86: qemu_chr_close(vcon->chr);
! 87: }
1.1 root 88:
89: return 0;
90: }
91:
1.1.1.4 ! root 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: }
1.1 root 127:
1.1.1.4 ! root 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: };
1.1 root 140:
1.1.1.4 ! root 141: static void virtserialport_register(void)
! 142: {
! 143: virtio_serial_port_qdev_register(&virtserialport_info);
1.1 root 144: }
1.1.1.4 ! root 145: device_init(virtserialport_register)
unix.superglobalmegacorp.com