2 * A bus for connecting virtio serial and console ports
4 * Copyright (C) 2009, 2010 Red Hat, Inc.
7 * Amit Shah <amit.shah@redhat.com>
9 * Some earlier parts are:
10 * Copyright IBM, Corp. 2008
12 * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
14 * This work is licensed under the terms of the GNU GPL, version 2. See
15 * the COPYING file in the top-level directory.
17 * Contributions after 2012-01-13 are licensed under the terms of the
18 * GNU GPL, version 2 or (at your option) any later version.
23 #include "qemu-queue.h"
26 #include "virtio-serial.h"
28 /* The virtio-serial bus on top of which the ports will ride as devices */
29 struct VirtIOSerialBus
{
32 /* This is the parent device that provides the bus for ports. */
35 /* The maximum number of ports that can ride on top of this bus */
36 uint32_t max_nr_ports
;
42 VirtQueue
*c_ivq
, *c_ovq
;
43 /* Arrays of ivqs and ovqs: one per port */
44 VirtQueue
**ivqs
, **ovqs
;
50 QTAILQ_HEAD(, VirtIOSerialPort
) ports
;
52 /* bitmap for identifying active ports */
55 struct virtio_console_config config
;
61 VirtIOSerialPort
*port
;
62 uint8_t host_connected
;
67 static VirtIOSerialPort
*find_port_by_id(VirtIOSerial
*vser
, uint32_t id
)
69 VirtIOSerialPort
*port
;
71 if (id
== VIRTIO_CONSOLE_BAD_ID
) {
75 QTAILQ_FOREACH(port
, &vser
->ports
, next
) {
82 static VirtIOSerialPort
*find_port_by_vq(VirtIOSerial
*vser
, VirtQueue
*vq
)
84 VirtIOSerialPort
*port
;
86 QTAILQ_FOREACH(port
, &vser
->ports
, next
) {
87 if (port
->ivq
== vq
|| port
->ovq
== vq
)
93 static bool use_multiport(VirtIOSerial
*vser
)
95 return vser
->vdev
.guest_features
& (1 << VIRTIO_CONSOLE_F_MULTIPORT
);
98 static size_t write_to_port(VirtIOSerialPort
*port
,
99 const uint8_t *buf
, size_t size
)
101 VirtQueueElement elem
;
106 if (!virtio_queue_ready(vq
)) {
111 while (offset
< size
) {
114 if (!virtqueue_pop(vq
, &elem
)) {
118 len
= iov_from_buf(elem
.in_sg
, elem
.in_num
, 0,
119 buf
+ offset
, size
- offset
);
122 virtqueue_push(vq
, &elem
, len
);
125 virtio_notify(&port
->vser
->vdev
, vq
);
129 static void discard_vq_data(VirtQueue
*vq
, VirtIODevice
*vdev
)
131 VirtQueueElement elem
;
133 if (!virtio_queue_ready(vq
)) {
136 while (virtqueue_pop(vq
, &elem
)) {
137 virtqueue_push(vq
, &elem
, 0);
139 virtio_notify(vdev
, vq
);
142 static void do_flush_queued_data(VirtIOSerialPort
*port
, VirtQueue
*vq
,
145 VirtIOSerialPortClass
*vsc
;
148 assert(virtio_queue_ready(vq
));
150 vsc
= VIRTIO_SERIAL_PORT_GET_CLASS(port
);
152 while (!port
->throttled
) {
155 /* Pop an elem only if we haven't left off a previous one mid-way */
156 if (!port
->elem
.out_num
) {
157 if (!virtqueue_pop(vq
, &port
->elem
)) {
161 port
->iov_offset
= 0;
164 for (i
= port
->iov_idx
; i
< port
->elem
.out_num
; i
++) {
168 buf_size
= port
->elem
.out_sg
[i
].iov_len
- port
->iov_offset
;
169 ret
= vsc
->have_data(port
,
170 port
->elem
.out_sg
[i
].iov_base
173 if (ret
< 0 && ret
!= -EAGAIN
) {
174 /* We don't handle any other type of errors here */
177 if (ret
== -EAGAIN
|| (ret
>= 0 && ret
< buf_size
)) {
179 * this is a temporary check until chardevs can signal to
180 * frontends that they are writable again. This prevents
181 * the console from going into throttled mode (forever)
182 * if virtio-console is connected to a pty without a
183 * listener. Otherwise the guest spins forever.
184 * We can revert this if
185 * 1: chardevs can notify frondends
186 * 2: the guest driver does not spin in these cases
188 if (!vsc
->is_console
) {
189 virtio_serial_throttle_port(port
, true);
193 port
->iov_offset
+= ret
;
197 port
->iov_offset
= 0;
199 if (port
->throttled
) {
202 virtqueue_push(vq
, &port
->elem
, 0);
203 port
->elem
.out_num
= 0;
205 virtio_notify(vdev
, vq
);
208 static void flush_queued_data(VirtIOSerialPort
*port
)
212 if (!virtio_queue_ready(port
->ovq
)) {
215 do_flush_queued_data(port
, port
->ovq
, &port
->vser
->vdev
);
218 static size_t send_control_msg(VirtIOSerialPort
*port
, void *buf
, size_t len
)
220 VirtQueueElement elem
;
222 struct virtio_console_control
*cpkt
;
224 vq
= port
->vser
->c_ivq
;
225 if (!virtio_queue_ready(vq
)) {
228 if (!virtqueue_pop(vq
, &elem
)) {
232 cpkt
= (struct virtio_console_control
*)buf
;
233 stl_p(&cpkt
->id
, port
->id
);
234 memcpy(elem
.in_sg
[0].iov_base
, buf
, len
);
236 virtqueue_push(vq
, &elem
, len
);
237 virtio_notify(&port
->vser
->vdev
, vq
);
241 static size_t send_control_event(VirtIOSerialPort
*port
, uint16_t event
,
244 struct virtio_console_control cpkt
;
246 stw_p(&cpkt
.event
, event
);
247 stw_p(&cpkt
.value
, value
);
249 trace_virtio_serial_send_control_event(port
->id
, event
, value
);
250 return send_control_msg(port
, &cpkt
, sizeof(cpkt
));
253 /* Functions for use inside qemu to open and read from/write to ports */
254 int virtio_serial_open(VirtIOSerialPort
*port
)
256 /* Don't allow opening an already-open port */
257 if (port
->host_connected
) {
260 /* Send port open notification to the guest */
261 port
->host_connected
= true;
262 send_control_event(port
, VIRTIO_CONSOLE_PORT_OPEN
, 1);
267 int virtio_serial_close(VirtIOSerialPort
*port
)
269 port
->host_connected
= false;
271 * If there's any data the guest sent which the app didn't
272 * consume, reset the throttling flag and discard the data.
274 port
->throttled
= false;
275 discard_vq_data(port
->ovq
, &port
->vser
->vdev
);
277 send_control_event(port
, VIRTIO_CONSOLE_PORT_OPEN
, 0);
282 /* Individual ports/apps call this function to write to the guest. */
283 ssize_t
virtio_serial_write(VirtIOSerialPort
*port
, const uint8_t *buf
,
286 if (!port
|| !port
->host_connected
|| !port
->guest_connected
) {
289 return write_to_port(port
, buf
, size
);
293 * Readiness of the guest to accept data on a port.
294 * Returns max. data the guest can receive
296 size_t virtio_serial_guest_ready(VirtIOSerialPort
*port
)
298 VirtQueue
*vq
= port
->ivq
;
301 if (!virtio_queue_ready(vq
) ||
302 !(port
->vser
->vdev
.status
& VIRTIO_CONFIG_S_DRIVER_OK
) ||
303 virtio_queue_empty(vq
)) {
306 if (use_multiport(port
->vser
) && !port
->guest_connected
) {
309 virtqueue_get_avail_bytes(vq
, &bytes
, NULL
, 4096, 0);
313 static void flush_queued_data_bh(void *opaque
)
315 VirtIOSerialPort
*port
= opaque
;
317 flush_queued_data(port
);
320 void virtio_serial_throttle_port(VirtIOSerialPort
*port
, bool throttle
)
326 trace_virtio_serial_throttle_port(port
->id
, throttle
);
327 port
->throttled
= throttle
;
331 qemu_bh_schedule(port
->bh
);
334 /* Guest wants to notify us of some event */
335 static void handle_control_message(VirtIOSerial
*vser
, void *buf
, size_t len
)
337 struct VirtIOSerialPort
*port
;
338 VirtIOSerialPortClass
*vsc
;
339 struct virtio_console_control cpkt
, *gcpkt
;
345 if (len
< sizeof(cpkt
)) {
346 /* The guest sent an invalid control packet */
350 cpkt
.event
= lduw_p(&gcpkt
->event
);
351 cpkt
.value
= lduw_p(&gcpkt
->value
);
353 trace_virtio_serial_handle_control_message(cpkt
.event
, cpkt
.value
);
355 if (cpkt
.event
== VIRTIO_CONSOLE_DEVICE_READY
) {
357 error_report("virtio-serial-bus: Guest failure in adding device %s",
358 vser
->bus
.qbus
.name
);
362 * The device is up, we can now tell the device about all the
363 * ports we have here.
365 QTAILQ_FOREACH(port
, &vser
->ports
, next
) {
366 send_control_event(port
, VIRTIO_CONSOLE_PORT_ADD
, 1);
371 port
= find_port_by_id(vser
, ldl_p(&gcpkt
->id
));
373 error_report("virtio-serial-bus: Unexpected port id %u for device %s",
374 ldl_p(&gcpkt
->id
), vser
->bus
.qbus
.name
);
378 trace_virtio_serial_handle_control_message_port(port
->id
);
380 vsc
= VIRTIO_SERIAL_PORT_GET_CLASS(port
);
383 case VIRTIO_CONSOLE_PORT_READY
:
385 error_report("virtio-serial-bus: Guest failure in adding port %u for device %s",
386 port
->id
, vser
->bus
.qbus
.name
);
390 * Now that we know the guest asked for the port name, we're
391 * sure the guest has initialised whatever state is necessary
392 * for this port. Now's a good time to let the guest know if
393 * this port is a console port so that the guest can hook it
396 if (vsc
->is_console
) {
397 send_control_event(port
, VIRTIO_CONSOLE_CONSOLE_PORT
, 1);
401 stw_p(&cpkt
.event
, VIRTIO_CONSOLE_PORT_NAME
);
402 stw_p(&cpkt
.value
, 1);
404 buffer_len
= sizeof(cpkt
) + strlen(port
->name
) + 1;
405 buffer
= g_malloc(buffer_len
);
407 memcpy(buffer
, &cpkt
, sizeof(cpkt
));
408 memcpy(buffer
+ sizeof(cpkt
), port
->name
, strlen(port
->name
));
409 buffer
[buffer_len
- 1] = 0;
411 send_control_msg(port
, buffer
, buffer_len
);
415 if (port
->host_connected
) {
416 send_control_event(port
, VIRTIO_CONSOLE_PORT_OPEN
, 1);
420 * When the guest has asked us for this information it means
421 * the guest is all setup and has its virtqueues
422 * initialised. If some app is interested in knowing about
423 * this event, let it know.
425 if (vsc
->guest_ready
) {
426 vsc
->guest_ready(port
);
430 case VIRTIO_CONSOLE_PORT_OPEN
:
431 port
->guest_connected
= cpkt
.value
;
432 if (cpkt
.value
&& vsc
->guest_open
) {
433 /* Send the guest opened notification if an app is interested */
434 vsc
->guest_open(port
);
437 if (!cpkt
.value
&& vsc
->guest_close
) {
438 /* Send the guest closed notification if an app is interested */
439 vsc
->guest_close(port
);
445 static void control_in(VirtIODevice
*vdev
, VirtQueue
*vq
)
449 static void control_out(VirtIODevice
*vdev
, VirtQueue
*vq
)
451 VirtQueueElement elem
;
456 vser
= DO_UPCAST(VirtIOSerial
, vdev
, vdev
);
460 while (virtqueue_pop(vq
, &elem
)) {
463 cur_len
= iov_size(elem
.out_sg
, elem
.out_num
);
465 * Allocate a new buf only if we didn't have one previously or
466 * if the size of the buf differs
471 buf
= g_malloc(cur_len
);
474 iov_to_buf(elem
.out_sg
, elem
.out_num
, 0, buf
, cur_len
);
476 handle_control_message(vser
, buf
, cur_len
);
477 virtqueue_push(vq
, &elem
, 0);
480 virtio_notify(vdev
, vq
);
483 /* Guest wrote something to some port. */
484 static void handle_output(VirtIODevice
*vdev
, VirtQueue
*vq
)
487 VirtIOSerialPort
*port
;
489 vser
= DO_UPCAST(VirtIOSerial
, vdev
, vdev
);
490 port
= find_port_by_vq(vser
, vq
);
492 if (!port
|| !port
->host_connected
) {
493 discard_vq_data(vq
, vdev
);
497 if (!port
->throttled
) {
498 do_flush_queued_data(port
, vq
, vdev
);
503 static void handle_input(VirtIODevice
*vdev
, VirtQueue
*vq
)
507 static uint32_t get_features(VirtIODevice
*vdev
, uint32_t features
)
511 vser
= DO_UPCAST(VirtIOSerial
, vdev
, vdev
);
513 if (vser
->bus
.max_nr_ports
> 1) {
514 features
|= (1 << VIRTIO_CONSOLE_F_MULTIPORT
);
519 /* Guest requested config info */
520 static void get_config(VirtIODevice
*vdev
, uint8_t *config_data
)
524 vser
= DO_UPCAST(VirtIOSerial
, vdev
, vdev
);
525 memcpy(config_data
, &vser
->config
, sizeof(struct virtio_console_config
));
528 static void set_config(VirtIODevice
*vdev
, const uint8_t *config_data
)
530 struct virtio_console_config config
;
532 memcpy(&config
, config_data
, sizeof(config
));
535 static void guest_reset(VirtIOSerial
*vser
)
537 VirtIOSerialPort
*port
;
538 VirtIOSerialPortClass
*vsc
;
540 QTAILQ_FOREACH(port
, &vser
->ports
, next
) {
541 vsc
= VIRTIO_SERIAL_PORT_GET_CLASS(port
);
542 if (port
->guest_connected
) {
543 port
->guest_connected
= false;
545 if (vsc
->guest_close
)
546 vsc
->guest_close(port
);
551 static void set_status(VirtIODevice
*vdev
, uint8_t status
)
554 VirtIOSerialPort
*port
;
556 vser
= DO_UPCAST(VirtIOSerial
, vdev
, vdev
);
557 port
= find_port_by_id(vser
, 0);
559 if (port
&& !use_multiport(port
->vser
)
560 && (status
& VIRTIO_CONFIG_S_DRIVER_OK
)) {
562 * Non-multiport guests won't be able to tell us guest
563 * open/close status. Such guests can only have a port at id
564 * 0, so set guest_connected for such ports as soon as guest
567 port
->guest_connected
= true;
569 if (!(status
& VIRTIO_CONFIG_S_DRIVER_OK
)) {
574 static void vser_reset(VirtIODevice
*vdev
)
578 vser
= DO_UPCAST(VirtIOSerial
, vdev
, vdev
);
582 static void virtio_serial_save(QEMUFile
*f
, void *opaque
)
584 VirtIOSerial
*s
= opaque
;
585 VirtIOSerialPort
*port
;
586 uint32_t nr_active_ports
;
587 unsigned int i
, max_nr_ports
;
589 /* The virtio device */
590 virtio_save(&s
->vdev
, f
);
592 /* The config space */
593 qemu_put_be16s(f
, &s
->config
.cols
);
594 qemu_put_be16s(f
, &s
->config
.rows
);
596 qemu_put_be32s(f
, &s
->config
.max_nr_ports
);
599 max_nr_ports
= tswap32(s
->config
.max_nr_ports
);
600 for (i
= 0; i
< (max_nr_ports
+ 31) / 32; i
++) {
601 qemu_put_be32s(f
, &s
->ports_map
[i
]);
607 QTAILQ_FOREACH(port
, &s
->ports
, next
) {
611 qemu_put_be32s(f
, &nr_active_ports
);
614 * Items in struct VirtIOSerialPort.
616 QTAILQ_FOREACH(port
, &s
->ports
, next
) {
617 uint32_t elem_popped
;
619 qemu_put_be32s(f
, &port
->id
);
620 qemu_put_byte(f
, port
->guest_connected
);
621 qemu_put_byte(f
, port
->host_connected
);
624 if (port
->elem
.out_num
) {
627 qemu_put_be32s(f
, &elem_popped
);
629 qemu_put_be32s(f
, &port
->iov_idx
);
630 qemu_put_be64s(f
, &port
->iov_offset
);
632 qemu_put_buffer(f
, (unsigned char *)&port
->elem
,
638 static void virtio_serial_post_load_timer_cb(void *opaque
)
641 VirtIOSerial
*s
= opaque
;
642 VirtIOSerialPort
*port
;
643 uint8_t host_connected
;
645 for (i
= 0 ; i
< s
->post_load
.nr_active_ports
; ++i
) {
646 port
= s
->post_load
.connected
[i
].port
;
647 host_connected
= s
->post_load
.connected
[i
].host_connected
;
648 if (host_connected
!= port
->host_connected
) {
650 * We have to let the guest know of the host connection
653 send_control_event(port
, VIRTIO_CONSOLE_PORT_OPEN
,
654 port
->host_connected
);
657 g_free(s
->post_load
.connected
);
658 s
->post_load
.connected
= NULL
;
661 static int virtio_serial_load(QEMUFile
*f
, void *opaque
, int version_id
)
663 VirtIOSerial
*s
= opaque
;
664 VirtIOSerialPort
*port
;
665 uint32_t max_nr_ports
, nr_active_ports
, ports_map
;
669 if (version_id
> 3) {
673 /* The virtio device */
674 ret
= virtio_load(&s
->vdev
, f
);
679 if (version_id
< 2) {
683 /* The config space */
684 qemu_get_be16s(f
, &s
->config
.cols
);
685 qemu_get_be16s(f
, &s
->config
.rows
);
687 qemu_get_be32s(f
, &max_nr_ports
);
688 tswap32s(&max_nr_ports
);
689 if (max_nr_ports
> tswap32(s
->config
.max_nr_ports
)) {
690 /* Source could have had more ports than us. Fail migration. */
694 for (i
= 0; i
< (max_nr_ports
+ 31) / 32; i
++) {
695 qemu_get_be32s(f
, &ports_map
);
697 if (ports_map
!= s
->ports_map
[i
]) {
699 * Ports active on source and destination don't
700 * match. Fail migration.
706 qemu_get_be32s(f
, &nr_active_ports
);
708 s
->post_load
.nr_active_ports
= nr_active_ports
;
709 s
->post_load
.connected
=
710 g_malloc0(sizeof(*s
->post_load
.connected
) * nr_active_ports
);
712 /* Items in struct VirtIOSerialPort */
713 for (i
= 0; i
< nr_active_ports
; i
++) {
716 id
= qemu_get_be32(f
);
717 port
= find_port_by_id(s
, id
);
722 port
->guest_connected
= qemu_get_byte(f
);
723 s
->post_load
.connected
[i
].port
= port
;
724 s
->post_load
.connected
[i
].host_connected
= qemu_get_byte(f
);
726 if (version_id
> 2) {
727 uint32_t elem_popped
;
729 qemu_get_be32s(f
, &elem_popped
);
731 qemu_get_be32s(f
, &port
->iov_idx
);
732 qemu_get_be64s(f
, &port
->iov_offset
);
734 qemu_get_buffer(f
, (unsigned char *)&port
->elem
,
736 virtqueue_map_sg(port
->elem
.in_sg
, port
->elem
.in_addr
,
737 port
->elem
.in_num
, 1);
738 virtqueue_map_sg(port
->elem
.out_sg
, port
->elem
.out_addr
,
739 port
->elem
.out_num
, 1);
742 * Port was throttled on source machine. Let's
743 * unthrottle it here so data starts flowing again.
745 virtio_serial_throttle_port(port
, false);
749 qemu_mod_timer(s
->post_load
.timer
, 1);
753 static void virtser_bus_dev_print(Monitor
*mon
, DeviceState
*qdev
, int indent
);
755 static Property virtser_props
[] = {
756 DEFINE_PROP_UINT32("nr", VirtIOSerialPort
, id
, VIRTIO_CONSOLE_BAD_ID
),
757 DEFINE_PROP_STRING("name", VirtIOSerialPort
, name
),
758 DEFINE_PROP_END_OF_LIST()
761 #define TYPE_VIRTIO_SERIAL_BUS "virtio-serial-bus"
762 #define VIRTIO_SERIAL_BUS(obj) \
763 OBJECT_CHECK(VirtIOSerialBus, (obj), TYPE_VIRTIO_SERIAL_BUS)
765 static void virtser_bus_class_init(ObjectClass
*klass
, void *data
)
767 BusClass
*k
= BUS_CLASS(klass
);
768 k
->print_dev
= virtser_bus_dev_print
;
771 static const TypeInfo virtser_bus_info
= {
772 .name
= TYPE_VIRTIO_SERIAL_BUS
,
774 .instance_size
= sizeof(VirtIOSerialBus
),
775 .class_init
= virtser_bus_class_init
,
778 static void virtser_bus_dev_print(Monitor
*mon
, DeviceState
*qdev
, int indent
)
780 VirtIOSerialPort
*port
= DO_UPCAST(VirtIOSerialPort
, dev
, qdev
);
782 monitor_printf(mon
, "%*sport %d, guest %s, host %s, throttle %s\n",
783 indent
, "", port
->id
,
784 port
->guest_connected
? "on" : "off",
785 port
->host_connected
? "on" : "off",
786 port
->throttled
? "on" : "off");
789 /* This function is only used if a port id is not provided by the user */
790 static uint32_t find_free_port_id(VirtIOSerial
*vser
)
792 unsigned int i
, max_nr_ports
;
794 max_nr_ports
= tswap32(vser
->config
.max_nr_ports
);
795 for (i
= 0; i
< (max_nr_ports
+ 31) / 32; i
++) {
798 map
= vser
->ports_map
[i
];
801 return (bit
- 1) + i
* 32;
804 return VIRTIO_CONSOLE_BAD_ID
;
807 static void mark_port_added(VirtIOSerial
*vser
, uint32_t port_id
)
812 vser
->ports_map
[i
] |= 1U << (port_id
% 32);
815 static void add_port(VirtIOSerial
*vser
, uint32_t port_id
)
817 mark_port_added(vser
, port_id
);
819 send_control_event(find_port_by_id(vser
, port_id
),
820 VIRTIO_CONSOLE_PORT_ADD
, 1);
823 static void remove_port(VirtIOSerial
*vser
, uint32_t port_id
)
825 VirtIOSerialPort
*port
;
829 vser
->ports_map
[i
] &= ~(1U << (port_id
% 32));
831 port
= find_port_by_id(vser
, port_id
);
832 /* Flush out any unconsumed buffers first */
833 discard_vq_data(port
->ovq
, &port
->vser
->vdev
);
835 send_control_event(port
, VIRTIO_CONSOLE_PORT_REMOVE
, 1);
838 static int virtser_port_qdev_init(DeviceState
*qdev
)
840 VirtIOSerialPort
*port
= DO_UPCAST(VirtIOSerialPort
, dev
, qdev
);
841 VirtIOSerialPortClass
*vsc
= VIRTIO_SERIAL_PORT_GET_CLASS(port
);
842 VirtIOSerialBus
*bus
= DO_UPCAST(VirtIOSerialBus
, qbus
, qdev
->parent_bus
);
843 int ret
, max_nr_ports
;
846 port
->vser
= bus
->vser
;
847 port
->bh
= qemu_bh_new(flush_queued_data_bh
, port
);
849 assert(vsc
->have_data
);
852 * Is the first console port we're seeing? If so, put it up at
853 * location 0. This is done for backward compatibility (old
856 plugging_port0
= vsc
->is_console
&& !find_port_by_id(port
->vser
, 0);
858 if (find_port_by_id(port
->vser
, port
->id
)) {
859 error_report("virtio-serial-bus: A port already exists at id %u",
864 if (port
->id
== VIRTIO_CONSOLE_BAD_ID
) {
865 if (plugging_port0
) {
868 port
->id
= find_free_port_id(port
->vser
);
869 if (port
->id
== VIRTIO_CONSOLE_BAD_ID
) {
870 error_report("virtio-serial-bus: Maximum port limit for this device reached");
876 max_nr_ports
= tswap32(port
->vser
->config
.max_nr_ports
);
877 if (port
->id
>= max_nr_ports
) {
878 error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u",
883 ret
= vsc
->init(port
);
888 port
->elem
.out_num
= 0;
890 QTAILQ_INSERT_TAIL(&port
->vser
->ports
, port
, next
);
891 port
->ivq
= port
->vser
->ivqs
[port
->id
];
892 port
->ovq
= port
->vser
->ovqs
[port
->id
];
894 add_port(port
->vser
, port
->id
);
896 /* Send an update to the guest about this new port added */
897 virtio_notify_config(&port
->vser
->vdev
);
902 static int virtser_port_qdev_exit(DeviceState
*qdev
)
904 VirtIOSerialPort
*port
= DO_UPCAST(VirtIOSerialPort
, dev
, qdev
);
905 VirtIOSerialPortClass
*vsc
= VIRTIO_SERIAL_PORT_GET_CLASS(port
);
906 VirtIOSerial
*vser
= port
->vser
;
908 qemu_bh_delete(port
->bh
);
909 remove_port(port
->vser
, port
->id
);
911 QTAILQ_REMOVE(&vser
->ports
, port
, next
);
919 VirtIODevice
*virtio_serial_init(DeviceState
*dev
, virtio_serial_conf
*conf
)
923 uint32_t i
, max_supported_ports
;
925 if (!conf
->max_virtserial_ports
)
928 /* Each port takes 2 queues, and one pair is for the control queue */
929 max_supported_ports
= VIRTIO_PCI_QUEUE_MAX
/ 2 - 1;
931 if (conf
->max_virtserial_ports
> max_supported_ports
) {
932 error_report("maximum ports supported: %u", max_supported_ports
);
936 vdev
= virtio_common_init("virtio-serial", VIRTIO_ID_CONSOLE
,
937 sizeof(struct virtio_console_config
),
938 sizeof(VirtIOSerial
));
940 vser
= DO_UPCAST(VirtIOSerial
, vdev
, vdev
);
942 /* Spawn a new virtio-serial bus on which the ports will ride as devices */
943 qbus_create_inplace(&vser
->bus
.qbus
, TYPE_VIRTIO_SERIAL_BUS
, dev
, NULL
);
944 vser
->bus
.qbus
.allow_hotplug
= 1;
945 vser
->bus
.vser
= vser
;
946 QTAILQ_INIT(&vser
->ports
);
948 vser
->bus
.max_nr_ports
= conf
->max_virtserial_ports
;
949 vser
->ivqs
= g_malloc(conf
->max_virtserial_ports
* sizeof(VirtQueue
*));
950 vser
->ovqs
= g_malloc(conf
->max_virtserial_ports
* sizeof(VirtQueue
*));
952 /* Add a queue for host to guest transfers for port 0 (backward compat) */
953 vser
->ivqs
[0] = virtio_add_queue(vdev
, 128, handle_input
);
954 /* Add a queue for guest to host transfers for port 0 (backward compat) */
955 vser
->ovqs
[0] = virtio_add_queue(vdev
, 128, handle_output
);
957 /* TODO: host to guest notifications can get dropped
958 * if the queue fills up. Implement queueing in host,
959 * this might also make it possible to reduce the control
960 * queue size: as guest preposts buffers there,
961 * this will save 4Kbyte of guest memory per entry. */
963 /* control queue: host to guest */
964 vser
->c_ivq
= virtio_add_queue(vdev
, 32, control_in
);
965 /* control queue: guest to host */
966 vser
->c_ovq
= virtio_add_queue(vdev
, 32, control_out
);
968 for (i
= 1; i
< vser
->bus
.max_nr_ports
; i
++) {
969 /* Add a per-port queue for host to guest transfers */
970 vser
->ivqs
[i
] = virtio_add_queue(vdev
, 128, handle_input
);
971 /* Add a per-per queue for guest to host transfers */
972 vser
->ovqs
[i
] = virtio_add_queue(vdev
, 128, handle_output
);
975 vser
->config
.max_nr_ports
= tswap32(conf
->max_virtserial_ports
);
976 vser
->ports_map
= g_malloc0(((conf
->max_virtserial_ports
+ 31) / 32)
977 * sizeof(vser
->ports_map
[0]));
979 * Reserve location 0 for a console port for backward compat
980 * (old kernel, new qemu)
982 mark_port_added(vser
, 0);
984 vser
->vdev
.get_features
= get_features
;
985 vser
->vdev
.get_config
= get_config
;
986 vser
->vdev
.set_config
= set_config
;
987 vser
->vdev
.set_status
= set_status
;
988 vser
->vdev
.reset
= vser_reset
;
993 * Register for the savevm section with the virtio-console name
994 * to preserve backward compat
996 register_savevm(dev
, "virtio-console", -1, 3, virtio_serial_save
,
997 virtio_serial_load
, vser
);
999 vser
->post_load
.timer
= qemu_new_timer_ns(vm_clock
,
1000 virtio_serial_post_load_timer_cb
, vser
);
1005 void virtio_serial_exit(VirtIODevice
*vdev
)
1007 VirtIOSerial
*vser
= DO_UPCAST(VirtIOSerial
, vdev
, vdev
);
1009 unregister_savevm(vser
->qdev
, "virtio-console", vser
);
1013 g_free(vser
->ports_map
);
1014 g_free(vser
->post_load
.connected
);
1015 qemu_free_timer(vser
->post_load
.timer
);
1017 virtio_cleanup(vdev
);
1020 static void virtio_serial_port_class_init(ObjectClass
*klass
, void *data
)
1022 DeviceClass
*k
= DEVICE_CLASS(klass
);
1023 k
->init
= virtser_port_qdev_init
;
1024 k
->bus_type
= TYPE_VIRTIO_SERIAL_BUS
;
1025 k
->exit
= virtser_port_qdev_exit
;
1026 k
->unplug
= qdev_simple_unplug_cb
;
1027 k
->props
= virtser_props
;
1030 static TypeInfo virtio_serial_port_type_info
= {
1031 .name
= TYPE_VIRTIO_SERIAL_PORT
,
1032 .parent
= TYPE_DEVICE
,
1033 .instance_size
= sizeof(VirtIOSerialPort
),
1035 .class_size
= sizeof(VirtIOSerialPortClass
),
1036 .class_init
= virtio_serial_port_class_init
,
1039 static void virtio_serial_register_types(void)
1041 type_register_static(&virtser_bus_info
);
1042 type_register_static(&virtio_serial_port_type_info
);
1045 type_init(virtio_serial_register_types
)