/* 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; }
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); }
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; }
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; }
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; }
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; }