Пример #1
0
/* Plug the VirtIODevice */
int virtio_bus_plug_device(VirtIODevice *vdev)
{
    DeviceState *qdev = DEVICE(vdev);
    BusState *qbus = BUS(qdev_get_parent_bus(qdev));
    VirtioBusState *bus = VIRTIO_BUS(qbus);
    VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
    DPRINTF("%s: plug device.\n", qbus->name);

    bus->vdev = vdev;

    /*
     * The lines below will disappear when we drop VirtIOBindings, at the end
     * of the series.
     */
    bus->bindings.notify = klass->notify;
    bus->bindings.save_config = klass->save_config;
    bus->bindings.save_queue = klass->save_queue;
    bus->bindings.load_config = klass->load_config;
    bus->bindings.load_queue = klass->load_queue;
    bus->bindings.load_done = klass->load_done;
    bus->bindings.get_features = klass->get_features;
    bus->bindings.query_guest_notifiers = klass->query_guest_notifiers;
    bus->bindings.set_guest_notifiers = klass->set_guest_notifiers;
    bus->bindings.set_host_notifier = klass->set_host_notifier;
    bus->bindings.vmstate_change = klass->vmstate_change;
    virtio_bind_device(bus->vdev, &bus->bindings, qbus->parent);

    if (klass->device_plugged != NULL) {
        klass->device_plugged(qbus->parent);
    }

    return 0;
}
Пример #2
0
static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
{
    int iomemtype;

    proxy->vdev = vdev;

    sysbus_init_irq(&proxy->busdev, &proxy->irq);
    iomemtype = cpu_register_io_memory(0, syborg_virtio_readfn,
                                       syborg_virtio_writefn, proxy);
    sysbus_init_mmio(&proxy->busdev, 0x1000, iomemtype);

    proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id;

    virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
}
Пример #3
0
static int syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
{
    proxy->vdev = vdev;

    /* Don't support multiple vectors */
    proxy->vdev->nvectors = 0;
    sysbus_init_irq(&proxy->busdev, &proxy->irq);
    memory_region_init_io(&proxy->iomem, &syborg_virtio_ops, proxy,
                          "virtio", 0x1000);
    sysbus_init_mmio(&proxy->busdev, &proxy->iomem);

    proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id;

    qemu_register_reset(virtio_reset, vdev);

    virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
    proxy->host_features |= (0x1 << VIRTIO_F_NOTIFY_ON_EMPTY);
    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
    return 0;
}
Пример #4
0
static int syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
{
    int iomemtype;

    proxy->vdev = vdev;

    /* Don't support multiple vectors */
    proxy->vdev->nvectors = 0;
    sysbus_init_irq(&proxy->busdev, &proxy->irq);
    iomemtype = cpu_register_io_memory(syborg_virtio_readfn,
                                       syborg_virtio_writefn, proxy);
    sysbus_init_mmio(&proxy->busdev, 0x1000, iomemtype);

    proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id;

    qemu_register_reset(virtio_reset, vdev);

    virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
    return 0;
}
Пример #5
0
static int syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
{
    int iomemtype;

    proxy->vdev = vdev;

    /* Don't support multiple vectors */
    proxy->vdev->nvectors = 0;
    sysbus_init_irq(&proxy->busdev, &proxy->irq);
    iomemtype = cpu_register_io_memory(syborg_virtio_readfn,
                                       syborg_virtio_writefn, proxy,
                                       DEVICE_NATIVE_ENDIAN);
    sysbus_init_mmio(&proxy->busdev, 0x1000, iomemtype);

    proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id;

    qemu_register_reset(virtio_reset, vdev);

    virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
    proxy->host_features |= (0x1 << VIRTIO_F_NOTIFY_ON_EMPTY);
    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
    return 0;
}
Пример #6
0
static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
{
    unsigned int cssid = 0;
    unsigned int ssid = 0;
    unsigned int schid;
    unsigned int devno;
    bool have_devno = false;
    bool found = false;
    SubchDev *sch;
    int ret;
    int num;
    DeviceState *parent = DEVICE(dev);

    sch = g_malloc0(sizeof(SubchDev));

    sch->driver_data = dev;
    dev->sch = sch;

    dev->vdev = vdev;
    dev->indicators = 0;

    /* Initialize subchannel structure. */
    sch->channel_prog = 0x0;
    sch->last_cmd_valid = false;
    sch->orb = NULL;
    /*
     * Use a device number if provided. Otherwise, fall back to subchannel
     * number.
     */
    if (dev->bus_id) {
        num = sscanf(dev->bus_id, "%x.%x.%04x", &cssid, &ssid, &devno);
        if (num == 3) {
            if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
                ret = -EINVAL;
                error_report("Invalid cssid or ssid: cssid %x, ssid %x",
                             cssid, ssid);
                goto out_err;
            }
            /* Enforce use of virtual cssid. */
            if (cssid != VIRTUAL_CSSID) {
                ret = -EINVAL;
                error_report("cssid %x not valid for virtio devices", cssid);
                goto out_err;
            }
            if (css_devno_used(cssid, ssid, devno)) {
                ret = -EEXIST;
                error_report("Device %x.%x.%04x already exists", cssid, ssid,
                             devno);
                goto out_err;
            }
            sch->cssid = cssid;
            sch->ssid = ssid;
            sch->devno = devno;
            have_devno = true;
        } else {
            ret = -EINVAL;
            error_report("Malformed devno parameter '%s'", dev->bus_id);
            goto out_err;
        }
    }

    /* Find the next free id. */
    if (have_devno) {
        for (schid = 0; schid <= MAX_SCHID; schid++) {
            if (!css_find_subch(1, cssid, ssid, schid)) {
                sch->schid = schid;
                css_subch_assign(cssid, ssid, schid, devno, sch);
                found = true;
                break;
            }
        }
        if (!found) {
            ret = -ENODEV;
            error_report("No free subchannel found for %x.%x.%04x", cssid, ssid,
                         devno);
            goto out_err;
        }
        trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
                                    "user-configured");
    } else {
        cssid = VIRTUAL_CSSID;
        for (ssid = 0; ssid <= MAX_SSID; ssid++) {
            for (schid = 0; schid <= MAX_SCHID; schid++) {
                if (!css_find_subch(1, cssid, ssid, schid)) {
                    sch->cssid = cssid;
                    sch->ssid = ssid;
                    sch->schid = schid;
                    devno = schid;
                    /*
                     * If the devno is already taken, look further in this
                     * subchannel set.
                     */
                    while (css_devno_used(cssid, ssid, devno)) {
                        if (devno == MAX_SCHID) {
                            devno = 0;
                        } else if (devno == schid - 1) {
                            ret = -ENODEV;
                            error_report("No free devno found");
                            goto out_err;
                        } else {
                            devno++;
                        }
                    }
                    sch->devno = devno;
                    css_subch_assign(cssid, ssid, schid, devno, sch);
                    found = true;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (!found) {
            ret = -ENODEV;
            error_report("Virtual channel subsystem is full!");
            goto out_err;
        }
        trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
                                    "auto-configured");
    }

    /* Build initial schib. */
    css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);

    sch->ccw_cb = virtio_ccw_cb;

    /* Build senseid data. */
    memset(&sch->id, 0, sizeof(SenseId));
    sch->id.reserved = 0xff;
    sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
    sch->id.cu_model = dev->vdev->device_id;

    virtio_bind_device(vdev, &virtio_ccw_bindings, DEVICE(dev));
    /* Only the first 32 feature bits are used. */
    dev->host_features[0] = vdev->get_features(vdev, dev->host_features[0]);
    dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
    dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE;

    css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
                          parent->hotplugged, 1);
    return 0;

out_err:
    dev->sch = NULL;
    g_free(sch);
    return ret;
}