Statistics
| Branch: | Revision:

root / hw / virtio-serial-bus.c @ 055b889f

History | View | Annotate | Download (19.2 kB)

1
/*
2
 * A bus for connecting virtio serial and console ports
3
 *
4
 * Copyright (C) 2009 Red Hat, Inc.
5
 *
6
 * Author(s):
7
 *  Amit Shah <amit.shah@redhat.com>
8
 *
9
 * Some earlier parts are:
10
 *  Copyright IBM, Corp. 2008
11
 * authored by
12
 *  Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
13
 *
14
 * This work is licensed under the terms of the GNU GPL, version 2.  See
15
 * the COPYING file in the top-level directory.
16
 */
17

    
18
#include "monitor.h"
19
#include "qemu-queue.h"
20
#include "sysbus.h"
21
#include "virtio-serial.h"
22

    
23
/* The virtio-serial bus on top of which the ports will ride as devices */
24
struct VirtIOSerialBus {
25
    BusState qbus;
26

    
27
    /* This is the parent device that provides the bus for ports. */
28
    VirtIOSerial *vser;
29

    
30
    /* The maximum number of ports that can ride on top of this bus */
31
    uint32_t max_nr_ports;
32
};
33

    
34
struct VirtIOSerial {
35
    VirtIODevice vdev;
36

    
37
    VirtQueue *c_ivq, *c_ovq;
38
    /* Arrays of ivqs and ovqs: one per port */
39
    VirtQueue **ivqs, **ovqs;
40

    
41
    VirtIOSerialBus *bus;
42

    
43
    QTAILQ_HEAD(, VirtIOSerialPort) ports;
44

    
45
    /* bitmap for identifying active ports */
46
    uint32_t *ports_map;
47

    
48
    struct virtio_console_config config;
49
};
50

    
51
static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
52
{
53
    VirtIOSerialPort *port;
54

    
55
    if (id == VIRTIO_CONSOLE_BAD_ID) {
56
        return NULL;
57
    }
58

    
59
    QTAILQ_FOREACH(port, &vser->ports, next) {
60
        if (port->id == id)
61
            return port;
62
    }
63
    return NULL;
64
}
65

    
66
static VirtIOSerialPort *find_port_by_vq(VirtIOSerial *vser, VirtQueue *vq)
67
{
68
    VirtIOSerialPort *port;
69

    
70
    QTAILQ_FOREACH(port, &vser->ports, next) {
71
        if (port->ivq == vq || port->ovq == vq)
72
            return port;
73
    }
74
    return NULL;
75
}
76

    
77
static bool use_multiport(VirtIOSerial *vser)
78
{
79
    return vser->vdev.guest_features & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
80
}
81

    
82
static size_t write_to_port(VirtIOSerialPort *port,
83
                            const uint8_t *buf, size_t size)
84
{
85
    VirtQueueElement elem;
86
    VirtQueue *vq;
87
    size_t offset = 0;
88
    size_t len = 0;
89

    
90
    vq = port->ivq;
91
    if (!virtio_queue_ready(vq)) {
92
        return 0;
93
    }
94
    if (!size) {
95
        return 0;
96
    }
97

    
98
    while (offset < size) {
99
        int i;
100

    
101
        if (!virtqueue_pop(vq, &elem)) {
102
            break;
103
        }
104

    
105
        for (i = 0; offset < size && i < elem.in_num; i++) {
106
            len = MIN(elem.in_sg[i].iov_len, size - offset);
107

    
108
            memcpy(elem.in_sg[i].iov_base, buf + offset, len);
109
            offset += len;
110
        }
111
        virtqueue_push(vq, &elem, len);
112
    }
113

    
114
    virtio_notify(&port->vser->vdev, vq);
115
    return offset;
116
}
117

    
118
static size_t send_control_msg(VirtIOSerialPort *port, void *buf, size_t len)
119
{
120
    VirtQueueElement elem;
121
    VirtQueue *vq;
122
    struct virtio_console_control *cpkt;
123

    
124
    vq = port->vser->c_ivq;
125
    if (!virtio_queue_ready(vq)) {
126
        return 0;
127
    }
128
    if (!virtqueue_pop(vq, &elem)) {
129
        return 0;
130
    }
131

    
132
    cpkt = (struct virtio_console_control *)buf;
133
    stl_p(&cpkt->id, port->id);
134
    memcpy(elem.in_sg[0].iov_base, buf, len);
135

    
136
    virtqueue_push(vq, &elem, len);
137
    virtio_notify(&port->vser->vdev, vq);
138
    return len;
139
}
140

    
141
static size_t send_control_event(VirtIOSerialPort *port, uint16_t event,
142
                                 uint16_t value)
143
{
144
    struct virtio_console_control cpkt;
145

    
146
    stw_p(&cpkt.event, event);
147
    stw_p(&cpkt.value, value);
148

    
149
    return send_control_msg(port, &cpkt, sizeof(cpkt));
150
}
151

    
152
/* Functions for use inside qemu to open and read from/write to ports */
153
int virtio_serial_open(VirtIOSerialPort *port)
154
{
155
    /* Don't allow opening an already-open port */
156
    if (port->host_connected) {
157
        return 0;
158
    }
159
    /* Send port open notification to the guest */
160
    port->host_connected = true;
161
    send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
162

    
163
    return 0;
164
}
165

    
166
int virtio_serial_close(VirtIOSerialPort *port)
167
{
168
    port->host_connected = false;
169
    send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
170

    
171
    return 0;
172
}
173

    
174
/* Individual ports/apps call this function to write to the guest. */
175
ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,
176
                            size_t size)
177
{
178
    if (!port || !port->host_connected || !port->guest_connected) {
179
        return 0;
180
    }
181
    return write_to_port(port, buf, size);
182
}
183

    
184
/*
185
 * Readiness of the guest to accept data on a port.
186
 * Returns max. data the guest can receive
187
 */
188
size_t virtio_serial_guest_ready(VirtIOSerialPort *port)
189
{
190
    VirtQueue *vq = port->ivq;
191

    
192
    if (!virtio_queue_ready(vq) ||
193
        !(port->vser->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK) ||
194
        virtio_queue_empty(vq)) {
195
        return 0;
196
    }
197
    if (use_multiport(port->vser) && !port->guest_connected) {
198
        return 0;
199
    }
200

    
201
    if (virtqueue_avail_bytes(vq, 4096, 0)) {
202
        return 4096;
203
    }
204
    if (virtqueue_avail_bytes(vq, 1, 0)) {
205
        return 1;
206
    }
207
    return 0;
208
}
209

    
210
/* Guest wants to notify us of some event */
211
static void handle_control_message(VirtIOSerial *vser, void *buf)
212
{
213
    struct VirtIOSerialPort *port;
214
    struct virtio_console_control cpkt, *gcpkt;
215
    uint8_t *buffer;
216
    size_t buffer_len;
217

    
218
    gcpkt = buf;
219

    
220
    cpkt.event = lduw_p(&gcpkt->event);
221
    cpkt.value = lduw_p(&gcpkt->value);
222

    
223
    port = find_port_by_id(vser, ldl_p(&gcpkt->id));
224
    if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY)
225
        return;
226

    
227
    switch(cpkt.event) {
228
    case VIRTIO_CONSOLE_DEVICE_READY:
229
        /*
230
         * The device is up, we can now tell the device about all the
231
         * ports we have here.
232
         */
233
        QTAILQ_FOREACH(port, &vser->ports, next) {
234
            send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);
235
        }
236
        break;
237

    
238
    case VIRTIO_CONSOLE_PORT_READY:
239
        /*
240
         * Now that we know the guest asked for the port name, we're
241
         * sure the guest has initialised whatever state is necessary
242
         * for this port. Now's a good time to let the guest know if
243
         * this port is a console port so that the guest can hook it
244
         * up to hvc.
245
         */
246
        if (port->is_console) {
247
            send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1);
248
        }
249

    
250
        if (port->name) {
251
            stw_p(&cpkt.event, VIRTIO_CONSOLE_PORT_NAME);
252
            stw_p(&cpkt.value, 1);
253

    
254
            buffer_len = sizeof(cpkt) + strlen(port->name) + 1;
255
            buffer = qemu_malloc(buffer_len);
256

    
257
            memcpy(buffer, &cpkt, sizeof(cpkt));
258
            memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name));
259
            buffer[buffer_len - 1] = 0;
260

    
261
            send_control_msg(port, buffer, buffer_len);
262
            qemu_free(buffer);
263
        }
264

    
265
        if (port->host_connected) {
266
            send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
267
        }
268

    
269
        /*
270
         * When the guest has asked us for this information it means
271
         * the guest is all setup and has its virtqueues
272
         * initialised. If some app is interested in knowing about
273
         * this event, let it know.
274
         */
275
        if (port->info->guest_ready) {
276
            port->info->guest_ready(port);
277
        }
278
        break;
279

    
280
    case VIRTIO_CONSOLE_PORT_OPEN:
281
        port->guest_connected = cpkt.value;
282
        if (cpkt.value && port->info->guest_open) {
283
            /* Send the guest opened notification if an app is interested */
284
            port->info->guest_open(port);
285
        }
286

    
287
        if (!cpkt.value && port->info->guest_close) {
288
            /* Send the guest closed notification if an app is interested */
289
            port->info->guest_close(port);
290
        }
291
        break;
292
    }
293
}
294

    
295
static void control_in(VirtIODevice *vdev, VirtQueue *vq)
296
{
297
}
298

    
299
static void control_out(VirtIODevice *vdev, VirtQueue *vq)
300
{
301
    VirtQueueElement elem;
302
    VirtIOSerial *vser;
303

    
304
    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
305

    
306
    while (virtqueue_pop(vq, &elem)) {
307
        handle_control_message(vser, elem.out_sg[0].iov_base);
308
        virtqueue_push(vq, &elem, elem.out_sg[0].iov_len);
309
    }
310
    virtio_notify(vdev, vq);
311
}
312

    
313
/* Guest wrote something to some port. */
314
static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
315
{
316
    VirtIOSerial *vser;
317
    VirtQueueElement elem;
318

    
319
    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
320

    
321
    while (virtqueue_pop(vq, &elem)) {
322
        VirtIOSerialPort *port;
323
        size_t ret;
324

    
325
        port = find_port_by_vq(vser, vq);
326
        if (!port) {
327
            ret = 0;
328
            goto next_buf;
329
        }
330

    
331
        /*
332
         * A port may not have any handler registered for consuming the
333
         * data that the guest sends or it may not have a chardev associated
334
         * with it. Just ignore the data in that case.
335
         */
336
        if (!port->info->have_data) {
337
            ret = 0;
338
            goto next_buf;
339
        }
340

    
341
        /* The guest always sends only one sg */
342
        ret = port->info->have_data(port, elem.out_sg[0].iov_base,
343
                                    elem.out_sg[0].iov_len);
344

    
345
    next_buf:
346
        virtqueue_push(vq, &elem, ret);
347
    }
348
    virtio_notify(vdev, vq);
349
}
350

    
351
static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
352
{
353
}
354

    
355
static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
356
{
357
    VirtIOSerial *vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
358
    if (vser->bus->max_nr_ports > 1) {
359
        features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
360
    }
361
    return features;
362
}
363

    
364
/* Guest requested config info */
365
static void get_config(VirtIODevice *vdev, uint8_t *config_data)
366
{
367
    VirtIOSerial *vser;
368

    
369
    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
370
    memcpy(config_data, &vser->config, sizeof(struct virtio_console_config));
371
}
372

    
373
static void set_config(VirtIODevice *vdev, const uint8_t *config_data)
374
{
375
    struct virtio_console_config config;
376

    
377
    memcpy(&config, config_data, sizeof(config));
378
}
379

    
380
static void virtio_serial_save(QEMUFile *f, void *opaque)
381
{
382
    VirtIOSerial *s = opaque;
383
    VirtIOSerialPort *port;
384
    uint32_t nr_active_ports;
385
    unsigned int i;
386

    
387
    /* The virtio device */
388
    virtio_save(&s->vdev, f);
389

    
390
    /* The config space */
391
    qemu_put_be16s(f, &s->config.cols);
392
    qemu_put_be16s(f, &s->config.rows);
393

    
394
    qemu_put_be32s(f, &s->config.max_nr_ports);
395

    
396
    /* The ports map */
397

    
398
    for (i = 0; i < (s->config.max_nr_ports + 31) / 32; i++) {
399
        qemu_put_be32s(f, &s->ports_map[i]);
400
    }
401

    
402
    /* Ports */
403

    
404
    nr_active_ports = 0;
405
    QTAILQ_FOREACH(port, &s->ports, next) {
406
        nr_active_ports++;
407
    }
408

    
409
    qemu_put_be32s(f, &nr_active_ports);
410

    
411
    /*
412
     * Items in struct VirtIOSerialPort.
413
     */
414
    QTAILQ_FOREACH(port, &s->ports, next) {
415
        qemu_put_be32s(f, &port->id);
416
        qemu_put_byte(f, port->guest_connected);
417
        qemu_put_byte(f, port->host_connected);
418
    }
419
}
420

    
421
static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
422
{
423
    VirtIOSerial *s = opaque;
424
    VirtIOSerialPort *port;
425
    size_t ports_map_size;
426
    uint32_t max_nr_ports, nr_active_ports, *ports_map;
427
    unsigned int i;
428

    
429
    if (version_id > 2) {
430
        return -EINVAL;
431
    }
432

    
433
    /* The virtio device */
434
    virtio_load(&s->vdev, f);
435

    
436
    if (version_id < 2) {
437
        return 0;
438
    }
439

    
440
    /* The config space */
441
    qemu_get_be16s(f, &s->config.cols);
442
    qemu_get_be16s(f, &s->config.rows);
443

    
444
    qemu_get_be32s(f, &max_nr_ports);
445
    if (max_nr_ports > s->config.max_nr_ports) {
446
        /* Source could have had more ports than us. Fail migration. */
447
        return -EINVAL;
448
    }
449

    
450
    ports_map_size = sizeof(uint32_t) * (max_nr_ports + 31) / 32;
451
    ports_map = qemu_malloc(ports_map_size);
452

    
453
    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
454
        qemu_get_be32s(f, &ports_map[i]);
455

    
456
        if (ports_map[i] != s->ports_map[i]) {
457
            /*
458
             * Ports active on source and destination don't
459
             * match. Fail migration.
460
             */
461
            qemu_free(ports_map);
462
            return -EINVAL;
463
        }
464
    }
465
    qemu_free(ports_map);
466

    
467
    qemu_get_be32s(f, &nr_active_ports);
468

    
469
    /* Items in struct VirtIOSerialPort */
470
    for (i = 0; i < nr_active_ports; i++) {
471
        uint32_t id;
472
        bool host_connected;
473

    
474
        id = qemu_get_be32(f);
475
        port = find_port_by_id(s, id);
476

    
477
        port->guest_connected = qemu_get_byte(f);
478
        host_connected = qemu_get_byte(f);
479
        if (host_connected != port->host_connected) {
480
            /*
481
             * We have to let the guest know of the host connection
482
             * status change
483
             */
484
            send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN,
485
                               port->host_connected);
486
        }
487
    }
488
    return 0;
489
}
490

    
491
static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
492

    
493
static struct BusInfo virtser_bus_info = {
494
    .name      = "virtio-serial-bus",
495
    .size      = sizeof(VirtIOSerialBus),
496
    .print_dev = virtser_bus_dev_print,
497
};
498

    
499
static VirtIOSerialBus *virtser_bus_new(DeviceState *dev)
500
{
501
    VirtIOSerialBus *bus;
502

    
503
    bus = FROM_QBUS(VirtIOSerialBus, qbus_create(&virtser_bus_info, dev, NULL));
504
    bus->qbus.allow_hotplug = 1;
505

    
506
    return bus;
507
}
508

    
509
static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
510
{
511
    VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev);
512
    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
513

    
514
    monitor_printf(mon, "%*s dev-prop-int: id: %u\n",
515
                   indent, "", port->id);
516
    monitor_printf(mon, "%*s dev-prop-int: guest_connected: %d\n",
517
                   indent, "", port->guest_connected);
518
    monitor_printf(mon, "%*s dev-prop-int: host_connected: %d\n",
519
                   indent, "", port->host_connected);
520
}
521

    
522
/* This function is only used if a port id is not provided by the user */
523
static uint32_t find_free_port_id(VirtIOSerial *vser)
524
{
525
    unsigned int i;
526

    
527
    for (i = 0; i < (vser->config.max_nr_ports + 31) / 32; i++) {
528
        uint32_t map, bit;
529

    
530
        map = vser->ports_map[i];
531
        bit = ffs(~map);
532
        if (bit) {
533
            return (bit - 1) + i * 32;
534
        }
535
    }
536
    return VIRTIO_CONSOLE_BAD_ID;
537
}
538

    
539
static void mark_port_added(VirtIOSerial *vser, uint32_t port_id)
540
{
541
    unsigned int i;
542

    
543
    i = port_id / 32;
544
    vser->ports_map[i] |= 1U << (port_id % 32);
545
}
546

    
547
static void add_port(VirtIOSerial *vser, uint32_t port_id)
548
{
549
    mark_port_added(vser, port_id);
550

    
551
    send_control_event(find_port_by_id(vser, port_id),
552
                       VIRTIO_CONSOLE_PORT_ADD, 1);
553
}
554

    
555
static void remove_port(VirtIOSerial *vser, uint32_t port_id)
556
{
557
    unsigned int i;
558

    
559
    i = port_id / 32;
560
    vser->ports_map[i] &= ~(1U << (port_id % 32));
561

    
562
    send_control_event(find_port_by_id(vser, port_id),
563
                       VIRTIO_CONSOLE_PORT_REMOVE, 1);
564
}
565

    
566
static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
567
{
568
    VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev);
569
    VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, base);
570
    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
571
    VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
572
    int ret;
573
    bool plugging_port0;
574

    
575
    port->vser = bus->vser;
576

    
577
    /*
578
     * Is the first console port we're seeing? If so, put it up at
579
     * location 0. This is done for backward compatibility (old
580
     * kernel, new qemu).
581
     */
582
    plugging_port0 = port->is_console && !find_port_by_id(port->vser, 0);
583

    
584
    if (find_port_by_id(port->vser, port->id)) {
585
        error_report("virtio-serial-bus: A port already exists at id %u\n",
586
                     port->id);
587
        return -1;
588
    }
589

    
590
    if (port->id == VIRTIO_CONSOLE_BAD_ID) {
591
        if (plugging_port0) {
592
            port->id = 0;
593
        } else {
594
            port->id = find_free_port_id(port->vser);
595
            if (port->id == VIRTIO_CONSOLE_BAD_ID) {
596
                error_report("virtio-serial-bus: Maximum port limit for this device reached\n");
597
                return -1;
598
            }
599
        }
600
    }
601

    
602
    if (port->id >= port->vser->config.max_nr_ports) {
603
        error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n",
604
                     port->vser->config.max_nr_ports - 1);
605
        return -1;
606
    }
607

    
608
    dev->info = info;
609
    ret = info->init(dev);
610
    if (ret) {
611
        return ret;
612
    }
613

    
614
    if (!use_multiport(port->vser)) {
615
        /*
616
         * Allow writes to guest in this case; we have no way of
617
         * knowing if a guest port is connected.
618
         */
619
        port->guest_connected = true;
620
    }
621

    
622
    QTAILQ_INSERT_TAIL(&port->vser->ports, port, next);
623
    port->ivq = port->vser->ivqs[port->id];
624
    port->ovq = port->vser->ovqs[port->id];
625

    
626
    add_port(port->vser, port->id);
627

    
628
    /* Send an update to the guest about this new port added */
629
    virtio_notify_config(&port->vser->vdev);
630

    
631
    return ret;
632
}
633

    
634
static int virtser_port_qdev_exit(DeviceState *qdev)
635
{
636
    VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev);
637
    VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
638
    VirtIOSerial *vser = port->vser;
639

    
640
    remove_port(port->vser, port->id);
641

    
642
    QTAILQ_REMOVE(&vser->ports, port, next);
643

    
644
    if (port->info->exit)
645
        port->info->exit(dev);
646

    
647
    return 0;
648
}
649

    
650
void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info)
651
{
652
    info->qdev.init = virtser_port_qdev_init;
653
    info->qdev.bus_info = &virtser_bus_info;
654
    info->qdev.exit = virtser_port_qdev_exit;
655
    info->qdev.unplug = qdev_simple_unplug_cb;
656
    qdev_register(&info->qdev);
657
}
658

    
659
VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
660
{
661
    VirtIOSerial *vser;
662
    VirtIODevice *vdev;
663
    uint32_t i;
664

    
665
    if (!max_nr_ports)
666
        return NULL;
667

    
668
    vdev = virtio_common_init("virtio-serial", VIRTIO_ID_CONSOLE,
669
                              sizeof(struct virtio_console_config),
670
                              sizeof(VirtIOSerial));
671

    
672
    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
673

    
674
    /* Spawn a new virtio-serial bus on which the ports will ride as devices */
675
    vser->bus = virtser_bus_new(dev);
676
    vser->bus->vser = vser;
677
    QTAILQ_INIT(&vser->ports);
678

    
679
    vser->bus->max_nr_ports = max_nr_ports;
680
    vser->ivqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
681
    vser->ovqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
682

    
683
    /* Add a queue for host to guest transfers for port 0 (backward compat) */
684
    vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
685
    /* Add a queue for guest to host transfers for port 0 (backward compat) */
686
    vser->ovqs[0] = virtio_add_queue(vdev, 128, handle_output);
687

    
688
    /* control queue: host to guest */
689
    vser->c_ivq = virtio_add_queue(vdev, 16, control_in);
690
    /* control queue: guest to host */
691
    vser->c_ovq = virtio_add_queue(vdev, 16, control_out);
692

    
693
    for (i = 1; i < vser->bus->max_nr_ports; i++) {
694
        /* Add a per-port queue for host to guest transfers */
695
        vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input);
696
        /* Add a per-per queue for guest to host transfers */
697
        vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
698
    }
699

    
700
    vser->config.max_nr_ports = max_nr_ports;
701
    vser->ports_map = qemu_mallocz((max_nr_ports + 31) / 32);
702
    /*
703
     * Reserve location 0 for a console port for backward compat
704
     * (old kernel, new qemu)
705
     */
706
    mark_port_added(vser, 0);
707

    
708
    vser->vdev.get_features = get_features;
709
    vser->vdev.get_config = get_config;
710
    vser->vdev.set_config = set_config;
711

    
712
    /*
713
     * Register for the savevm section with the virtio-console name
714
     * to preserve backward compat
715
     */
716
    register_savevm("virtio-console", -1, 2, virtio_serial_save,
717
                    virtio_serial_load, vser);
718

    
719
    return vdev;
720
}