]> Git Repo - qemu.git/blob - hw/virtio-console.c
virtio-console: Factor out common init between console and generic ports
[qemu.git] / hw / virtio-console.c
1 /*
2  * Virtio Console and Generic Serial Port Devices
3  *
4  * Copyright Red Hat, Inc. 2009, 2010
5  *
6  * Authors:
7  *  Amit Shah <[email protected]>
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 static int generic_port_init(VirtConsole *vcon, VirtIOSerialDevice *dev)
62 {
63     vcon->port.info = dev->info;
64
65     if (vcon->chr) {
66         qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
67                               vcon);
68         vcon->port.info->have_data = flush_buf;
69     }
70     return 0;
71 }
72
73 /* Virtio Console Ports */
74 static int virtconsole_initfn(VirtIOSerialDevice *dev)
75 {
76     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
77     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
78
79     port->is_console = true;
80     return generic_port_init(vcon, dev);
81 }
82
83 static int virtconsole_exitfn(VirtIOSerialDevice *dev)
84 {
85     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
86     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
87
88     if (vcon->chr) {
89         port->info->have_data = NULL;
90         qemu_chr_close(vcon->chr);
91     }
92
93     return 0;
94 }
95
96 static VirtIOSerialPortInfo virtconsole_info = {
97     .qdev.name     = "virtconsole",
98     .qdev.size     = sizeof(VirtConsole),
99     .init          = virtconsole_initfn,
100     .exit          = virtconsole_exitfn,
101     .qdev.props = (Property[]) {
102         DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1),
103         DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
104         DEFINE_PROP_CHR("chardev", VirtConsole, chr),
105         DEFINE_PROP_STRING("name", VirtConsole, port.name),
106         DEFINE_PROP_END_OF_LIST(),
107     },
108 };
109
110 static void virtconsole_register(void)
111 {
112     virtio_serial_port_qdev_register(&virtconsole_info);
113 }
114 device_init(virtconsole_register)
115
116 /* Generic Virtio Serial Ports */
117 static int virtserialport_initfn(VirtIOSerialDevice *dev)
118 {
119     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
120     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
121
122     return generic_port_init(vcon, dev);
123 }
124
125 static VirtIOSerialPortInfo virtserialport_info = {
126     .qdev.name     = "virtserialport",
127     .qdev.size     = sizeof(VirtConsole),
128     .init          = virtserialport_initfn,
129     .exit          = virtconsole_exitfn,
130     .qdev.props = (Property[]) {
131         DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID),
132         DEFINE_PROP_CHR("chardev", VirtConsole, chr),
133         DEFINE_PROP_STRING("name", VirtConsole, port.name),
134         DEFINE_PROP_END_OF_LIST(),
135     },
136 };
137
138 static void virtserialport_register(void)
139 {
140     virtio_serial_port_qdev_register(&virtserialport_info);
141 }
142 device_init(virtserialport_register)
This page took 0.032405 seconds and 4 git commands to generate.