]> git.proxmox.com Git - qemu.git/blame - hw/virtio-console.c
virtio-console: Add some trace events
[qemu.git] / hw / virtio-console.c
CommitLineData
98b19252
AS
1/*
2 * Virtio Console and Generic Serial Port Devices
3 *
71c092e9 4 * Copyright Red Hat, Inc. 2009, 2010
98b19252
AS
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"
0b8b716d 14#include "qemu-error.h"
d02e4fa4 15#include "trace.h"
98b19252
AS
16#include "virtio-serial.h"
17
18typedef struct VirtConsole {
19 VirtIOSerialPort port;
20 CharDriverState *chr;
21} VirtConsole;
22
23
24/* Callback function that's called when the guest sends us data */
e300ac27 25static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
98b19252
AS
26{
27 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
d02e4fa4 28 ssize_t ret;
98b19252 29
d02e4fa4
AS
30 ret = qemu_chr_write(vcon->chr, buf, len);
31
32 trace_virtio_console_flush_buf(port->id, len, ret);
33 return ret;
98b19252
AS
34}
35
0b6d2266
HG
36/* Callback function that's called when the guest opens the port */
37static void guest_open(VirtIOSerialPort *port)
38{
39 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
40
41 qemu_chr_guest_open(vcon->chr);
42}
43
44/* Callback function that's called when the guest closes the port */
45static void guest_close(VirtIOSerialPort *port)
46{
47 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
48
49 qemu_chr_guest_close(vcon->chr);
50}
51
98b19252
AS
52/* Readiness of the guest to accept data on a port */
53static int chr_can_read(void *opaque)
54{
55 VirtConsole *vcon = opaque;
56
57 return virtio_serial_guest_ready(&vcon->port);
58}
59
60/* Send data from a char device over to the guest */
61static void chr_read(void *opaque, const uint8_t *buf, int size)
62{
63 VirtConsole *vcon = opaque;
64
d02e4fa4 65 trace_virtio_console_chr_read(vcon->port.id, size);
98b19252
AS
66 virtio_serial_write(&vcon->port, buf, size);
67}
68
69static void chr_event(void *opaque, int event)
70{
71 VirtConsole *vcon = opaque;
72
d02e4fa4 73 trace_virtio_console_chr_event(vcon->port.id, event);
98b19252 74 switch (event) {
28eaf465 75 case CHR_EVENT_OPENED:
98b19252
AS
76 virtio_serial_open(&vcon->port);
77 break;
98b19252
AS
78 case CHR_EVENT_CLOSED:
79 virtio_serial_close(&vcon->port);
80 break;
81 }
82}
83
7edfe652 84static int virtconsole_initfn(VirtIOSerialPort *port)
98b19252 85{
7edfe652 86 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
a15bb0d6
MA
87 VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev,
88 vcon->port.dev.info);
89
7edfe652
MA
90 if (port->id == 0 && !info->is_console) {
91 error_report("Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility.");
92 return -1;
93 }
94
98b19252
AS
95 if (vcon->chr) {
96 qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
97 vcon);
a15bb0d6
MA
98 info->have_data = flush_buf;
99 info->guest_open = guest_open;
100 info->guest_close = guest_close;
98b19252 101 }
cbe77b61 102
7edfe652 103 return 0;
cbe77b61
AS
104}
105
a43f9c90 106static int virtconsole_exitfn(VirtIOSerialPort *port)
98b19252 107{
98b19252
AS
108 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
109
110 if (vcon->chr) {
f9a90f18
AS
111 /*
112 * Instead of closing the chardev, free it so it can be used
113 * for other purposes.
114 */
115 qemu_chr_add_handlers(vcon->chr, NULL, NULL, NULL, NULL);
98b19252
AS
116 }
117
118 return 0;
119}
120
121static VirtIOSerialPortInfo virtconsole_info = {
122 .qdev.name = "virtconsole",
123 .qdev.size = sizeof(VirtConsole),
2a3d57ce 124 .is_console = true,
98b19252
AS
125 .init = virtconsole_initfn,
126 .exit = virtconsole_exitfn,
127 .qdev.props = (Property[]) {
055b889f 128 DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
98b19252 129 DEFINE_PROP_CHR("chardev", VirtConsole, chr),
160600fd 130 DEFINE_PROP_STRING("name", VirtConsole, port.name),
98b19252
AS
131 DEFINE_PROP_END_OF_LIST(),
132 },
133};
134
135static void virtconsole_register(void)
136{
137 virtio_serial_port_qdev_register(&virtconsole_info);
138}
139device_init(virtconsole_register)
b60c470b 140
b60c470b
AS
141static VirtIOSerialPortInfo virtserialport_info = {
142 .qdev.name = "virtserialport",
143 .qdev.size = sizeof(VirtConsole),
7edfe652 144 .init = virtconsole_initfn,
b60c470b
AS
145 .exit = virtconsole_exitfn,
146 .qdev.props = (Property[]) {
055b889f 147 DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
b60c470b
AS
148 DEFINE_PROP_CHR("chardev", VirtConsole, chr),
149 DEFINE_PROP_STRING("name", VirtConsole, port.name),
150 DEFINE_PROP_END_OF_LIST(),
151 },
152};
153
154static void virtserialport_register(void)
155{
156 virtio_serial_port_qdev_register(&virtserialport_info);
157}
158device_init(virtserialport_register)