]> git.proxmox.com Git - qemu.git/blame - hw/virtio-console.c
Fix OpenSolaris gcc4 warnings: iovec type mismatches, missing 'static'
[qemu.git] / hw / virtio-console.c
CommitLineData
970d878c
AL
1/*
2 * Virtio Console Device
3 *
4 * Copyright IBM, Corp. 2008
5 *
6 * Authors:
7 * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.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
14#include "hw.h"
15#include "qemu-char.h"
16#include "virtio.h"
17#include "virtio-console.h"
18
19
20typedef struct VirtIOConsole
21{
22 VirtIODevice vdev;
23 VirtQueue *ivq, *dvq;
24 CharDriverState *chr;
25} VirtIOConsole;
26
27static VirtIOConsole *to_virtio_console(VirtIODevice *vdev)
28{
29 return (VirtIOConsole *)vdev;
30}
31
32static void virtio_console_handle_output(VirtIODevice *vdev, VirtQueue *vq)
33{
34 VirtIOConsole *s = to_virtio_console(vdev);
35 VirtQueueElement elem;
36
37 while (virtqueue_pop(vq, &elem)) {
38 ssize_t len = 0;
39 int d;
40
3f4cb3d3
BS
41 for (d = 0; d < elem.out_num; d++) {
42 len += qemu_chr_write(s->chr, (uint8_t *)elem.out_sg[d].iov_base,
43 elem.out_sg[d].iov_len);
44 }
970d878c
AL
45 virtqueue_push(vq, &elem, len);
46 virtio_notify(vdev, vq);
47 }
48}
49
50static void virtio_console_handle_input(VirtIODevice *vdev, VirtQueue *vq)
51{
52}
53
54static uint32_t virtio_console_get_features(VirtIODevice *vdev)
55{
56 return 0;
57}
58
59static int vcon_can_read(void *opaque)
60{
61 VirtIOConsole *s = (VirtIOConsole *) opaque;
62
63 if (!virtio_queue_ready(s->ivq) ||
64 !(s->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK) ||
65 virtio_queue_empty(s->ivq))
66 return 0;
67
68 /* current implementations have a page sized buffer.
69 * We fall back to a one byte per read if there is not enough room.
70 * It would be cool to have a function that returns the available byte
71 * instead of checking for a limit */
72 if (virtqueue_avail_bytes(s->ivq, TARGET_PAGE_SIZE, 0))
73 return TARGET_PAGE_SIZE;
74 if (virtqueue_avail_bytes(s->ivq, 1, 0))
75 return 1;
76 return 0;
77}
78
79static void vcon_read(void *opaque, const uint8_t *buf, int size)
80{
81 VirtIOConsole *s = (VirtIOConsole *) opaque;
82 VirtQueueElement elem;
83 int offset = 0;
84
85 /* The current kernel implementation has only one outstanding input
86 * buffer of PAGE_SIZE. Nevertheless, this function is prepared to
87 * handle multiple buffers with multiple sg element for input */
88 while (offset < size) {
89 int i = 0;
90 if (!virtqueue_pop(s->ivq, &elem))
91 break;
92 while (offset < size && i < elem.in_num) {
93 int len = MIN(elem.in_sg[i].iov_len, size - offset);
94 memcpy(elem.in_sg[i].iov_base, buf + offset, len);
95 offset += len;
96 i++;
97 }
98 virtqueue_push(s->ivq, &elem, size);
99 }
100 virtio_notify(&s->vdev, s->ivq);
101}
102
103static void vcon_event(void *opaque, int event)
104{
105 /* we will ignore any event for the time being */
106}
107
108static void virtio_console_save(QEMUFile *f, void *opaque)
109{
110 VirtIOConsole *s = opaque;
111
112 virtio_save(&s->vdev, f);
113}
114
115static int virtio_console_load(QEMUFile *f, void *opaque, int version_id)
116{
117 VirtIOConsole *s = opaque;
118
119 if (version_id != 1)
120 return -EINVAL;
121
122 virtio_load(&s->vdev, f);
123 return 0;
124}
125
126void *virtio_console_init(PCIBus *bus, CharDriverState *chr)
127{
128 VirtIOConsole *s;
129
130 s = (VirtIOConsole *)virtio_init_pci(bus, "virtio-console",
14d50bef
AL
131 PCI_VENDOR_ID_REDHAT_QUMRANET,
132 PCI_DEVICE_ID_VIRTIO_CONSOLE,
99b3718e
AL
133 PCI_VENDOR_ID_REDHAT_QUMRANET,
134 VIRTIO_ID_CONSOLE,
173a543b 135 PCI_CLASS_DISPLAY_OTHER, 0x00,
970d878c
AL
136 0, sizeof(VirtIOConsole));
137 if (s == NULL)
138 return NULL;
139
140 s->vdev.get_features = virtio_console_get_features;
141
142 s->ivq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_input);
143 s->dvq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_output);
144
145 s->chr = chr;
146 qemu_chr_add_handlers(chr, vcon_can_read, vcon_read, vcon_event, s);
147
148 register_savevm("virtio-console", -1, 1, virtio_console_save, virtio_console_load, s);
149
150 return &s->vdev;
151}