Commit 56d7a964 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote branch 'amit/for-anthony' into staging

parents 24e838b7 2d6c1ef4
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -351,8 +351,13 @@ static int parse_chr(DeviceState *dev, Property *prop, const char *str)
    CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);

    *ptr = qemu_chr_find(str);
    if (*ptr == NULL)
    if (*ptr == NULL) {
        return -ENOENT;
    }
    if ((*ptr)->assigned) {
        return -EEXIST;
    }
    (*ptr)->assigned = 1;
    return 0;
}

+14 −2
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
 */

#include "qemu-char.h"
#include "qemu-error.h"
#include "virtio-serial.h"

typedef struct VirtConsole {
@@ -81,8 +82,11 @@ static int virtconsole_exitfn(VirtIOSerialPort *port)
    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);

    if (vcon->chr) {
        port->info->have_data = NULL;
        qemu_chr_close(vcon->chr);
	/*
	 * Instead of closing the chardev, free it so it can be used
	 * for other purposes.
	 */
	qemu_chr_add_handlers(vcon->chr, NULL, NULL, NULL, NULL);
    }

    return 0;
@@ -113,6 +117,14 @@ static int virtserialport_initfn(VirtIOSerialPort *port)
{
    VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);

    if (port->id == 0) {
        /*
         * Disallow a generic port at id 0, that's reserved for
         * console ports.
         */
        error_report("Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility.");
        return -1;
    }
    return generic_port_init(vcon, port);
}

+9 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "virtio.h"
#include "virtio-blk.h"
#include "virtio-net.h"
#include "virtio-serial.h"
#include "pci.h"
#include "qemu-error.h"
#include "msix.h"
@@ -109,8 +110,7 @@ typedef struct {
#ifdef CONFIG_LINUX
    V9fsConf fsconf;
#endif
    /* Max. number of ports we can have for a the virtio-serial device */
    uint32_t max_virtserial_ports;
    virtio_serial_conf serial;
    virtio_net_conf net;
    bool ioeventfd_disabled;
    bool ioeventfd_started;
@@ -770,12 +770,12 @@ static int virtio_serial_init_pci(PCIDevice *pci_dev)
        proxy->class_code != PCI_CLASS_OTHERS)          /* qemu-kvm  */
        proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;

    vdev = virtio_serial_init(&pci_dev->qdev, proxy->max_virtserial_ports);
    vdev = virtio_serial_init(&pci_dev->qdev, &proxy->serial);
    if (!vdev) {
        return -1;
    }
    vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
                                        ? proxy->max_virtserial_ports + 1
                                        ? proxy->serial.max_virtserial_ports + 1
                                        : proxy->nvectors;
    virtio_init_pci(proxy, vdev,
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
@@ -789,6 +789,7 @@ static int virtio_serial_exit_pci(PCIDevice *pci_dev)
{
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);

    virtio_pci_stop_ioeventfd(proxy);
    virtio_serial_exit(proxy->vdev);
    return virtio_exit_pci(pci_dev);
}
@@ -898,12 +899,14 @@ static PCIDeviceInfo virtio_info[] = {
        .init      = virtio_serial_init_pci,
        .exit      = virtio_serial_exit_pci,
        .qdev.props = (Property[]) {
            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
                               DEV_NVECTORS_UNSPECIFIED),
            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
            DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports,
                               31),
            DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy,
                               serial.max_virtserial_ports, 31),
            DEFINE_PROP_END_OF_LIST(),
        },
        .qdev.reset = virtio_pci_reset,
+11 −17
Original line number Diff line number Diff line
@@ -442,25 +442,19 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
    VirtIOSerial *vser;
    VirtIOSerialPort *port;
    bool discard;

    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
    port = find_port_by_vq(vser, vq);

    discard = false;
    if (!port || !port->host_connected || !port->info->have_data) {
        discard = true;
    }

    if (discard) {
        discard_vq_data(vq, vdev);
        return;
    }
    if (port->throttled) {
        return;
    }

    if (!port->throttled) {
        do_flush_queued_data(port, vq, vdev);
        return;
    }
}

static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
@@ -811,19 +805,19 @@ void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info)
    qdev_register(&info->qdev);
}

VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
{
    VirtIOSerial *vser;
    VirtIODevice *vdev;
    uint32_t i, max_supported_ports;

    if (!max_nr_ports)
    if (!conf->max_virtserial_ports)
        return NULL;

    /* Each port takes 2 queues, and one pair is for the control queue */
    max_supported_ports = VIRTIO_PCI_QUEUE_MAX / 2 - 1;

    if (max_nr_ports > max_supported_ports) {
    if (conf->max_virtserial_ports > max_supported_ports) {
        error_report("maximum ports supported: %u", max_supported_ports);
        return NULL;
    }
@@ -839,9 +833,9 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
    vser->bus->vser = vser;
    QTAILQ_INIT(&vser->ports);

    vser->bus->max_nr_ports = max_nr_ports;
    vser->ivqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
    vser->ovqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
    vser->bus->max_nr_ports = conf->max_virtserial_ports;
    vser->ivqs = qemu_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
    vser->ovqs = qemu_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));

    /* Add a queue for host to guest transfers for port 0 (backward compat) */
    vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
@@ -866,8 +860,8 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
        vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
    }

    vser->config.max_nr_ports = max_nr_ports;
    vser->ports_map = qemu_mallocz(((max_nr_ports + 31) / 32)
    vser->config.max_nr_ports = conf->max_virtserial_ports;
    vser->ports_map = qemu_mallocz(((conf->max_virtserial_ports + 31) / 32)
        * sizeof(vser->ports_map[0]));
    /*
     * Reserve location 0 for a console port for backward compat
+5 −0
Original line number Diff line number Diff line
@@ -45,6 +45,11 @@ struct virtio_console_control {
    uint16_t value;		/* Extra information for the key */
};

struct virtio_serial_conf {
    /* Max. number of ports we can have for a virtio-serial device */
    uint32_t max_virtserial_ports;
};

/* Some events for the internal messages (control packets) */
#define VIRTIO_CONSOLE_DEVICE_READY	0
#define VIRTIO_CONSOLE_PORT_ADD		1
Loading