Statistics
| Branch: | Revision:

root / hw / virtio-console.c @ ff753bb9

History | View | Annotate | Download (3.8 kB)

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)