1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/iov.h"
22#include "monitor/monitor.h"
23#include "qemu/queue.h"
24#include "hw/sysbus.h"
25#include "trace.h"
26#include "hw/virtio/virtio-serial.h"
27#include "hw/virtio/virtio-access.h"
28
29static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
30{
31 VirtIOSerialPort *port;
32
33 if (id == VIRTIO_CONSOLE_BAD_ID) {
34 return NULL;
35 }
36
37 QTAILQ_FOREACH(port, &vser->ports, next) {
38 if (port->id == id)
39 return port;
40 }
41 return NULL;
42}
43
44static VirtIOSerialPort *find_port_by_vq(VirtIOSerial *vser, VirtQueue *vq)
45{
46 VirtIOSerialPort *port;
47
48 QTAILQ_FOREACH(port, &vser->ports, next) {
49 if (port->ivq == vq || port->ovq == vq)
50 return port;
51 }
52 return NULL;
53}
54
55static bool use_multiport(VirtIOSerial *vser)
56{
57 VirtIODevice *vdev = VIRTIO_DEVICE(vser);
58 return vdev->guest_features & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
59}
60
61static size_t write_to_port(VirtIOSerialPort *port,
62 const uint8_t *buf, size_t size)
63{
64 VirtQueueElement elem;
65 VirtQueue *vq;
66 size_t offset;
67
68 vq = port->ivq;
69 if (!virtio_queue_ready(vq)) {
70 return 0;
71 }
72
73 offset = 0;
74 while (offset < size) {
75 size_t len;
76
77 if (!virtqueue_pop(vq, &elem)) {
78 break;
79 }
80
81 len = iov_from_buf(elem.in_sg, elem.in_num, 0,
82 buf + offset, size - offset);
83 offset += len;
84
85 virtqueue_push(vq, &elem, len);
86 }
87
88 virtio_notify(VIRTIO_DEVICE(port->vser), vq);
89 return offset;
90}
91
92static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
93{
94 VirtQueueElement elem;
95
96 if (!virtio_queue_ready(vq)) {
97 return;
98 }
99 while (virtqueue_pop(vq, &elem)) {
100 virtqueue_push(vq, &elem, 0);
101 }
102 virtio_notify(vdev, vq);
103}
104
105static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
106 VirtIODevice *vdev)
107{
108 VirtIOSerialPortClass *vsc;
109
110 assert(port);
111 assert(virtio_queue_ready(vq));
112
113 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
114
115 while (!port->throttled) {
116 unsigned int i;
117
118
119 if (!port->elem.out_num) {
120 if (!virtqueue_pop(vq, &port->elem)) {
121 break;
122 }
123 port->iov_idx = 0;
124 port->iov_offset = 0;
125 }
126
127 for (i = port->iov_idx; i < port->elem.out_num; i++) {
128 size_t buf_size;
129 ssize_t ret;
130
131 buf_size = port->elem.out_sg[i].iov_len - port->iov_offset;
132 ret = vsc->have_data(port,
133 port->elem.out_sg[i].iov_base
134 + port->iov_offset,
135 buf_size);
136 if (port->throttled) {
137 port->iov_idx = i;
138 if (ret > 0) {
139 port->iov_offset += ret;
140 }
141 break;
142 }
143 port->iov_offset = 0;
144 }
145 if (port->throttled) {
146 break;
147 }
148 virtqueue_push(vq, &port->elem, 0);
149 port->elem.out_num = 0;
150 }
151 virtio_notify(vdev, vq);
152}
153
154static void flush_queued_data(VirtIOSerialPort *port)
155{
156 assert(port);
157
158 if (!virtio_queue_ready(port->ovq)) {
159 return;
160 }
161 do_flush_queued_data(port, port->ovq, VIRTIO_DEVICE(port->vser));
162}
163
164static size_t send_control_msg(VirtIOSerial *vser, void *buf, size_t len)
165{
166 VirtQueueElement elem;
167 VirtQueue *vq;
168
169 vq = vser->c_ivq;
170 if (!virtio_queue_ready(vq)) {
171 return 0;
172 }
173 if (!virtqueue_pop(vq, &elem)) {
174 return 0;
175 }
176
177 memcpy(elem.in_sg[0].iov_base, buf, len);
178
179 virtqueue_push(vq, &elem, len);
180 virtio_notify(VIRTIO_DEVICE(vser), vq);
181 return len;
182}
183
184static size_t send_control_event(VirtIOSerial *vser, uint32_t port_id,
185 uint16_t event, uint16_t value)
186{
187 VirtIODevice *vdev = VIRTIO_DEVICE(vser);
188 struct virtio_console_control cpkt;
189
190 virtio_stl_p(vdev, &cpkt.id, port_id);
191 virtio_stw_p(vdev, &cpkt.event, event);
192 virtio_stw_p(vdev, &cpkt.value, value);
193
194 trace_virtio_serial_send_control_event(port_id, event, value);
195 return send_control_msg(vser, &cpkt, sizeof(cpkt));
196}
197
198
199int virtio_serial_open(VirtIOSerialPort *port)
200{
201
202 if (port->host_connected) {
203 return 0;
204 }
205
206 port->host_connected = true;
207 send_control_event(port->vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 1);
208
209 return 0;
210}
211
212int virtio_serial_close(VirtIOSerialPort *port)
213{
214 port->host_connected = false;
215
216
217
218
219 port->throttled = false;
220 discard_vq_data(port->ovq, VIRTIO_DEVICE(port->vser));
221
222 send_control_event(port->vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 0);
223
224 return 0;
225}
226
227
228ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,
229 size_t size)
230{
231 if (!port || !port->host_connected || !port->guest_connected) {
232 return 0;
233 }
234 return write_to_port(port, buf, size);
235}
236
237
238
239
240
241size_t virtio_serial_guest_ready(VirtIOSerialPort *port)
242{
243 VirtIODevice *vdev = VIRTIO_DEVICE(port->vser);
244 VirtQueue *vq = port->ivq;
245 unsigned int bytes;
246
247 if (!virtio_queue_ready(vq) ||
248 !(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) ||
249 virtio_queue_empty(vq)) {
250 return 0;
251 }
252 if (use_multiport(port->vser) && !port->guest_connected) {
253 return 0;
254 }
255 virtqueue_get_avail_bytes(vq, &bytes, NULL, 4096, 0);
256 return bytes;
257}
258
259static void flush_queued_data_bh(void *opaque)
260{
261 VirtIOSerialPort *port = opaque;
262
263 flush_queued_data(port);
264}
265
266void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
267{
268 if (!port) {
269 return;
270 }
271
272 trace_virtio_serial_throttle_port(port->id, throttle);
273 port->throttled = throttle;
274 if (throttle) {
275 return;
276 }
277 qemu_bh_schedule(port->bh);
278}
279
280
281static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
282{
283 VirtIODevice *vdev = VIRTIO_DEVICE(vser);
284 struct VirtIOSerialPort *port;
285 VirtIOSerialPortClass *vsc;
286 struct virtio_console_control cpkt, *gcpkt;
287 uint8_t *buffer;
288 size_t buffer_len;
289
290 gcpkt = buf;
291
292 if (len < sizeof(cpkt)) {
293
294 return;
295 }
296
297 cpkt.event = virtio_lduw_p(vdev, &gcpkt->event);
298 cpkt.value = virtio_lduw_p(vdev, &gcpkt->value);
299
300 trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value);
301
302 if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
303 if (!cpkt.value) {
304 error_report("virtio-serial-bus: Guest failure in adding device %s",
305 vser->bus.qbus.name);
306 return;
307 }
308
309
310
311
312 QTAILQ_FOREACH(port, &vser->ports, next) {
313 send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_ADD, 1);
314 }
315 return;
316 }
317
318 port = find_port_by_id(vser, virtio_ldl_p(vdev, &gcpkt->id));
319 if (!port) {
320 error_report("virtio-serial-bus: Unexpected port id %u for device %s",
321 virtio_ldl_p(vdev, &gcpkt->id), vser->bus.qbus.name);
322 return;
323 }
324
325 trace_virtio_serial_handle_control_message_port(port->id);
326
327 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
328
329 switch(cpkt.event) {
330 case VIRTIO_CONSOLE_PORT_READY:
331 if (!cpkt.value) {
332 error_report("virtio-serial-bus: Guest failure in adding port %u for device %s",
333 port->id, vser->bus.qbus.name);
334 break;
335 }
336
337
338
339
340
341
342
343 if (vsc->is_console) {
344 send_control_event(vser, port->id, VIRTIO_CONSOLE_CONSOLE_PORT, 1);
345 }
346
347 if (port->name) {
348 virtio_stl_p(vdev, &cpkt.id, port->id);
349 virtio_stw_p(vdev, &cpkt.event, VIRTIO_CONSOLE_PORT_NAME);
350 virtio_stw_p(vdev, &cpkt.value, 1);
351
352 buffer_len = sizeof(cpkt) + strlen(port->name) + 1;
353 buffer = g_malloc(buffer_len);
354
355 memcpy(buffer, &cpkt, sizeof(cpkt));
356 memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name));
357 buffer[buffer_len - 1] = 0;
358
359 send_control_msg(vser, buffer, buffer_len);
360 g_free(buffer);
361 }
362
363 if (port->host_connected) {
364 send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 1);
365 }
366
367
368
369
370
371
372
373 if (vsc->guest_ready) {
374 vsc->guest_ready(port);
375 }
376 break;
377
378 case VIRTIO_CONSOLE_PORT_OPEN:
379 port->guest_connected = cpkt.value;
380 if (vsc->set_guest_connected) {
381
382 vsc->set_guest_connected(port, cpkt.value);
383 }
384 break;
385 }
386}
387
388static void control_in(VirtIODevice *vdev, VirtQueue *vq)
389{
390}
391
392static void control_out(VirtIODevice *vdev, VirtQueue *vq)
393{
394 VirtQueueElement elem;
395 VirtIOSerial *vser;
396 uint8_t *buf;
397 size_t len;
398
399 vser = VIRTIO_SERIAL(vdev);
400
401 len = 0;
402 buf = NULL;
403 while (virtqueue_pop(vq, &elem)) {
404 size_t cur_len;
405
406 cur_len = iov_size(elem.out_sg, elem.out_num);
407
408
409
410
411 if (cur_len > len) {
412 g_free(buf);
413
414 buf = g_malloc(cur_len);
415 len = cur_len;
416 }
417 iov_to_buf(elem.out_sg, elem.out_num, 0, buf, cur_len);
418
419 handle_control_message(vser, buf, cur_len);
420 virtqueue_push(vq, &elem, 0);
421 }
422 g_free(buf);
423 virtio_notify(vdev, vq);
424}
425
426
427static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
428{
429 VirtIOSerial *vser;
430 VirtIOSerialPort *port;
431
432 vser = VIRTIO_SERIAL(vdev);
433 port = find_port_by_vq(vser, vq);
434
435 if (!port || !port->host_connected) {
436 discard_vq_data(vq, vdev);
437 return;
438 }
439
440 if (!port->throttled) {
441 do_flush_queued_data(port, vq, vdev);
442 return;
443 }
444}
445
446static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
447{
448}
449
450static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
451{
452 VirtIOSerial *vser;
453
454 vser = VIRTIO_SERIAL(vdev);
455
456 if (vser->bus.max_nr_ports > 1) {
457 features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
458 }
459 return features;
460}
461
462
463static void get_config(VirtIODevice *vdev, uint8_t *config_data)
464{
465 VirtIOSerial *vser;
466
467 vser = VIRTIO_SERIAL(vdev);
468 memcpy(config_data, &vser->config, sizeof(struct virtio_console_config));
469}
470
471static void guest_reset(VirtIOSerial *vser)
472{
473 VirtIOSerialPort *port;
474 VirtIOSerialPortClass *vsc;
475
476 QTAILQ_FOREACH(port, &vser->ports, next) {
477 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
478 if (port->guest_connected) {
479 port->guest_connected = false;
480 if (vsc->set_guest_connected) {
481 vsc->set_guest_connected(port, false);
482 }
483 }
484 }
485}
486
487static void set_status(VirtIODevice *vdev, uint8_t status)
488{
489 VirtIOSerial *vser;
490 VirtIOSerialPort *port;
491
492 vser = VIRTIO_SERIAL(vdev);
493 port = find_port_by_id(vser, 0);
494
495 if (port && !use_multiport(port->vser)
496 && (status & VIRTIO_CONFIG_S_DRIVER_OK)) {
497
498
499
500
501
502
503 port->guest_connected = true;
504 }
505 if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
506 guest_reset(vser);
507 }
508}
509
510static void vser_reset(VirtIODevice *vdev)
511{
512 VirtIOSerial *vser;
513
514 vser = VIRTIO_SERIAL(vdev);
515 guest_reset(vser);
516
517
518 vser->config.max_nr_ports =
519 virtio_tswap32(vdev, vser->serial.max_virtserial_ports);
520}
521
522static void virtio_serial_save(QEMUFile *f, void *opaque)
523{
524
525 virtio_save(VIRTIO_DEVICE(opaque), f);
526}
527
528static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)
529{
530 VirtIOSerial *s = VIRTIO_SERIAL(vdev);
531 VirtIOSerialPort *port;
532 uint32_t nr_active_ports;
533 unsigned int i, max_nr_ports;
534
535
536 qemu_put_be16s(f, &s->config.cols);
537 qemu_put_be16s(f, &s->config.rows);
538
539 qemu_put_be32s(f, &s->config.max_nr_ports);
540
541
542 max_nr_ports = virtio_tswap32(vdev, s->config.max_nr_ports);
543 for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
544 qemu_put_be32s(f, &s->ports_map[i]);
545 }
546
547
548
549 nr_active_ports = 0;
550 QTAILQ_FOREACH(port, &s->ports, next) {
551 nr_active_ports++;
552 }
553
554 qemu_put_be32s(f, &nr_active_ports);
555
556
557
558
559 QTAILQ_FOREACH(port, &s->ports, next) {
560 uint32_t elem_popped;
561
562 qemu_put_be32s(f, &port->id);
563 qemu_put_byte(f, port->guest_connected);
564 qemu_put_byte(f, port->host_connected);
565
566 elem_popped = 0;
567 if (port->elem.out_num) {
568 elem_popped = 1;
569 }
570 qemu_put_be32s(f, &elem_popped);
571 if (elem_popped) {
572 qemu_put_be32s(f, &port->iov_idx);
573 qemu_put_be64s(f, &port->iov_offset);
574
575 qemu_put_buffer(f, (unsigned char *)&port->elem,
576 sizeof(port->elem));
577 }
578 }
579}
580
581static void virtio_serial_post_load_timer_cb(void *opaque)
582{
583 uint32_t i;
584 VirtIOSerial *s = VIRTIO_SERIAL(opaque);
585 VirtIOSerialPort *port;
586 uint8_t host_connected;
587 VirtIOSerialPortClass *vsc;
588
589 if (!s->post_load) {
590 return;
591 }
592 for (i = 0 ; i < s->post_load->nr_active_ports; ++i) {
593 port = s->post_load->connected[i].port;
594 host_connected = s->post_load->connected[i].host_connected;
595 if (host_connected != port->host_connected) {
596
597
598
599
600 send_control_event(s, port->id, VIRTIO_CONSOLE_PORT_OPEN,
601 port->host_connected);
602 }
603 vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
604 if (vsc->set_guest_connected) {
605 vsc->set_guest_connected(port, port->guest_connected);
606 }
607 }
608 g_free(s->post_load->connected);
609 timer_free(s->post_load->timer);
610 g_free(s->post_load);
611 s->post_load = NULL;
612}
613
614static int fetch_active_ports_list(QEMUFile *f, int version_id,
615 VirtIOSerial *s, uint32_t nr_active_ports)
616{
617 uint32_t i;
618
619 s->post_load = g_malloc0(sizeof(*s->post_load));
620 s->post_load->nr_active_ports = nr_active_ports;
621 s->post_load->connected =
622 g_malloc0(sizeof(*s->post_load->connected) * nr_active_ports);
623
624 s->post_load->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
625 virtio_serial_post_load_timer_cb,
626 s);
627
628
629 for (i = 0; i < nr_active_ports; i++) {
630 VirtIOSerialPort *port;
631 uint32_t id;
632
633 id = qemu_get_be32(f);
634 port = find_port_by_id(s, id);
635 if (!port) {
636 return -EINVAL;
637 }
638
639 port->guest_connected = qemu_get_byte(f);
640 s->post_load->connected[i].port = port;
641 s->post_load->connected[i].host_connected = qemu_get_byte(f);
642
643 if (version_id > 2) {
644 uint32_t elem_popped;
645
646 qemu_get_be32s(f, &elem_popped);
647 if (elem_popped) {
648 qemu_get_be32s(f, &port->iov_idx);
649 qemu_get_be64s(f, &port->iov_offset);
650
651 qemu_get_buffer(f, (unsigned char *)&port->elem,
652 sizeof(port->elem));
653 virtqueue_map_sg(port->elem.in_sg, port->elem.in_addr,
654 port->elem.in_num, 1);
655 virtqueue_map_sg(port->elem.out_sg, port->elem.out_addr,
656 port->elem.out_num, 1);
657
658
659
660
661
662 virtio_serial_throttle_port(port, false);
663 }
664 }
665 }
666 timer_mod(s->post_load->timer, 1);
667 return 0;
668}
669
670static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
671{
672 if (version_id > 3) {
673 return -EINVAL;
674 }
675
676
677 return virtio_load(VIRTIO_DEVICE(opaque), f, version_id);
678}
679
680static int virtio_serial_load_device(VirtIODevice *vdev, QEMUFile *f,
681 int version_id)
682{
683 VirtIOSerial *s = VIRTIO_SERIAL(vdev);
684 uint32_t max_nr_ports, nr_active_ports, ports_map;
685 unsigned int i;
686 int ret;
687 uint32_t tmp;
688
689 if (version_id < 2) {
690 return 0;
691 }
692
693
694 qemu_get_be16s(f, (uint16_t *) &tmp);
695 qemu_get_be16s(f, (uint16_t *) &tmp);
696 qemu_get_be32s(f, &tmp);
697
698
699
700
701
702
703
704 max_nr_ports = tswap32(s->config.max_nr_ports);
705 for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
706 qemu_get_be32s(f, &ports_map);
707
708 if (ports_map != s->ports_map[i]) {
709
710
711
712
713 return -EINVAL;
714 }
715 }
716
717 qemu_get_be32s(f, &nr_active_ports);
718
719 if (nr_active_ports) {
720 ret = fetch_active_ports_list(f, version_id, s, nr_active_ports);
721 if (ret) {
722 return ret;
723 }
724 }
725 return 0;
726}
727
728static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
729
730static Property virtser_props[] = {
731 DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
732 DEFINE_PROP_STRING("name", VirtIOSerialPort, name),
733 DEFINE_PROP_END_OF_LIST()
734};
735
736#define TYPE_VIRTIO_SERIAL_BUS "virtio-serial-bus"
737#define VIRTIO_SERIAL_BUS(obj) \
738 OBJECT_CHECK(VirtIOSerialBus, (obj), TYPE_VIRTIO_SERIAL_BUS)
739
740static void virtser_bus_class_init(ObjectClass *klass, void *data)
741{
742 BusClass *k = BUS_CLASS(klass);
743 k->print_dev = virtser_bus_dev_print;
744}
745
746static const TypeInfo virtser_bus_info = {
747 .name = TYPE_VIRTIO_SERIAL_BUS,
748 .parent = TYPE_BUS,
749 .instance_size = sizeof(VirtIOSerialBus),
750 .class_init = virtser_bus_class_init,
751};
752
753static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
754{
755 VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
756
757 monitor_printf(mon, "%*sport %d, guest %s, host %s, throttle %s\n",
758 indent, "", port->id,
759 port->guest_connected ? "on" : "off",
760 port->host_connected ? "on" : "off",
761 port->throttled ? "on" : "off");
762}
763
764
765static uint32_t find_free_port_id(VirtIOSerial *vser)
766{
767 VirtIODevice *vdev = VIRTIO_DEVICE(vser);
768 unsigned int i, max_nr_ports;
769
770 max_nr_ports = virtio_tswap32(vdev, vser->config.max_nr_ports);
771 for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
772 uint32_t map, bit;
773
774 map = vser->ports_map[i];
775 bit = ffs(~map);
776 if (bit) {
777 return (bit - 1) + i * 32;
778 }
779 }
780 return VIRTIO_CONSOLE_BAD_ID;
781}
782
783static void mark_port_added(VirtIOSerial *vser, uint32_t port_id)
784{
785 unsigned int i;
786
787 i = port_id / 32;
788 vser->ports_map[i] |= 1U << (port_id % 32);
789}
790
791static void add_port(VirtIOSerial *vser, uint32_t port_id)
792{
793 mark_port_added(vser, port_id);
794 send_control_event(vser, port_id, VIRTIO_CONSOLE_PORT_ADD, 1);
795}
796
797static void remove_port(VirtIOSerial *vser, uint32_t port_id)
798{
799 VirtIOSerialPort *port;
800
801
802
803
804
805
806 if (port_id) {
807 unsigned int i;
808
809 i = port_id / 32;
810 vser->ports_map[i] &= ~(1U << (port_id % 32));
811 }
812
813 port = find_port_by_id(vser, port_id);
814
815
816
817
818 assert(port);
819
820
821 discard_vq_data(port->ovq, VIRTIO_DEVICE(port->vser));
822
823 send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_REMOVE, 1);
824}
825
826static void virtser_port_device_realize(DeviceState *dev, Error **errp)
827{
828 VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
829 VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
830 VirtIOSerialBus *bus = VIRTIO_SERIAL_BUS(qdev_get_parent_bus(dev));
831 VirtIODevice *vdev = VIRTIO_DEVICE(bus->vser);
832 int max_nr_ports;
833 bool plugging_port0;
834 Error *err = NULL;
835
836 port->vser = bus->vser;
837 port->bh = qemu_bh_new(flush_queued_data_bh, port);
838
839 assert(vsc->have_data);
840
841
842
843
844
845
846 plugging_port0 = vsc->is_console && !find_port_by_id(port->vser, 0);
847
848 if (find_port_by_id(port->vser, port->id)) {
849 error_setg(errp, "virtio-serial-bus: A port already exists at id %u",
850 port->id);
851 return;
852 }
853
854 if (port->id == VIRTIO_CONSOLE_BAD_ID) {
855 if (plugging_port0) {
856 port->id = 0;
857 } else {
858 port->id = find_free_port_id(port->vser);
859 if (port->id == VIRTIO_CONSOLE_BAD_ID) {
860 error_setg(errp, "virtio-serial-bus: Maximum port limit for "
861 "this device reached");
862 return;
863 }
864 }
865 }
866
867 max_nr_ports = virtio_tswap32(vdev, port->vser->config.max_nr_ports);
868 if (port->id >= max_nr_ports) {
869 error_setg(errp, "virtio-serial-bus: Out-of-range port id specified, "
870 "max. allowed: %u", max_nr_ports - 1);
871 return;
872 }
873
874 vsc->realize(dev, &err);
875 if (err != NULL) {
876 error_propagate(errp, err);
877 return;
878 }
879
880 port->elem.out_num = 0;
881
882 QTAILQ_INSERT_TAIL(&port->vser->ports, port, next);
883 port->ivq = port->vser->ivqs[port->id];
884 port->ovq = port->vser->ovqs[port->id];
885
886 add_port(port->vser, port->id);
887
888
889 virtio_notify_config(vdev);
890}
891
892static void virtser_port_device_unrealize(DeviceState *dev, Error **errp)
893{
894 VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
895 VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
896 VirtIOSerial *vser = port->vser;
897
898 qemu_bh_delete(port->bh);
899 remove_port(port->vser, port->id);
900
901 QTAILQ_REMOVE(&vser->ports, port, next);
902
903 if (vsc->unrealize) {
904 vsc->unrealize(dev, errp);
905 }
906}
907
908static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
909{
910 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
911 VirtIOSerial *vser = VIRTIO_SERIAL(dev);
912 BusState *bus;
913 uint32_t i, max_supported_ports;
914
915 if (!vser->serial.max_virtserial_ports) {
916 error_setg(errp, "Maximum number of serial ports not specified");
917 return;
918 }
919
920
921 max_supported_ports = VIRTIO_PCI_QUEUE_MAX / 2 - 1;
922
923 if (vser->serial.max_virtserial_ports > max_supported_ports) {
924 error_setg(errp, "maximum ports supported: %u", max_supported_ports);
925 return;
926 }
927
928 virtio_init(vdev, "virtio-serial", VIRTIO_ID_CONSOLE,
929 sizeof(struct virtio_console_config));
930
931
932 qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
933 dev, vdev->bus_name);
934 bus = BUS(&vser->bus);
935 bus->allow_hotplug = 1;
936 vser->bus.vser = vser;
937 QTAILQ_INIT(&vser->ports);
938
939 vser->bus.max_nr_ports = vser->serial.max_virtserial_ports;
940 vser->ivqs = g_malloc(vser->serial.max_virtserial_ports
941 * sizeof(VirtQueue *));
942 vser->ovqs = g_malloc(vser->serial.max_virtserial_ports
943 * sizeof(VirtQueue *));
944
945
946 vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
947
948 vser->ovqs[0] = virtio_add_queue(vdev, 128, handle_output);
949
950
951
952
953
954
955
956
957 vser->c_ivq = virtio_add_queue(vdev, 32, control_in);
958
959 vser->c_ovq = virtio_add_queue(vdev, 32, control_out);
960
961 for (i = 1; i < vser->bus.max_nr_ports; i++) {
962
963 vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input);
964
965 vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
966 }
967
968 vser->config.max_nr_ports =
969 virtio_tswap32(vdev, vser->serial.max_virtserial_ports);
970 vser->ports_map = g_malloc0(((vser->serial.max_virtserial_ports + 31) / 32)
971 * sizeof(vser->ports_map[0]));
972
973
974
975
976 mark_port_added(vser, 0);
977
978 vser->post_load = NULL;
979
980
981
982
983
984 register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save,
985 virtio_serial_load, vser);
986}
987
988static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
989{
990 DeviceClass *k = DEVICE_CLASS(klass);
991
992 set_bit(DEVICE_CATEGORY_INPUT, k->categories);
993 k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
994 k->realize = virtser_port_device_realize;
995 k->unrealize = virtser_port_device_unrealize;
996 k->unplug = qdev_simple_unplug_cb;
997 k->props = virtser_props;
998}
999
1000static const TypeInfo virtio_serial_port_type_info = {
1001 .name = TYPE_VIRTIO_SERIAL_PORT,
1002 .parent = TYPE_DEVICE,
1003 .instance_size = sizeof(VirtIOSerialPort),
1004 .abstract = true,
1005 .class_size = sizeof(VirtIOSerialPortClass),
1006 .class_init = virtio_serial_port_class_init,
1007};
1008
1009static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp)
1010{
1011 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
1012 VirtIOSerial *vser = VIRTIO_SERIAL(dev);
1013
1014 unregister_savevm(dev, "virtio-console", vser);
1015
1016 g_free(vser->ivqs);
1017 g_free(vser->ovqs);
1018 g_free(vser->ports_map);
1019 if (vser->post_load) {
1020 g_free(vser->post_load->connected);
1021 timer_del(vser->post_load->timer);
1022 timer_free(vser->post_load->timer);
1023 g_free(vser->post_load);
1024 }
1025 virtio_cleanup(vdev);
1026}
1027
1028static Property virtio_serial_properties[] = {
1029 DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerial, serial),
1030 DEFINE_PROP_END_OF_LIST(),
1031};
1032
1033static void virtio_serial_class_init(ObjectClass *klass, void *data)
1034{
1035 DeviceClass *dc = DEVICE_CLASS(klass);
1036 VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
1037
1038 dc->props = virtio_serial_properties;
1039 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1040 vdc->realize = virtio_serial_device_realize;
1041 vdc->unrealize = virtio_serial_device_unrealize;
1042 vdc->get_features = get_features;
1043 vdc->get_config = get_config;
1044 vdc->set_status = set_status;
1045 vdc->reset = vser_reset;
1046 vdc->save = virtio_serial_save_device;
1047 vdc->load = virtio_serial_load_device;
1048}
1049
1050static const TypeInfo virtio_device_info = {
1051 .name = TYPE_VIRTIO_SERIAL,
1052 .parent = TYPE_VIRTIO_DEVICE,
1053 .instance_size = sizeof(VirtIOSerial),
1054 .class_init = virtio_serial_class_init,
1055};
1056
1057static void virtio_serial_register_types(void)
1058{
1059 type_register_static(&virtser_bus_info);
1060 type_register_static(&virtio_serial_port_type_info);
1061 type_register_static(&virtio_device_info);
1062}
1063
1064type_init(virtio_serial_register_types)
1065