bus->dev_offs += dev_len;
- virtio_bind_device(vdev, &virtio_s390_bindings, dev);
+ virtio_bind_device(vdev, &virtio_s390_bindings, DEVICE(dev));
dev->host_features = vdev->get_features(vdev, dev->host_features);
s390_virtio_device_sync(dev);
s390_virtio_reset_idx(dev);
return NULL;
}
-static void virtio_s390_notify(void *opaque, uint16_t vector)
+/* DeviceState to VirtIOS390Device. Note: used on datapath,
+ * be careful and test performance if you change this.
+ */
+static inline VirtIOS390Device *to_virtio_s390_device_fast(DeviceState *d)
+{
+ return container_of(d, VirtIOS390Device, qdev);
+}
+
+/* DeviceState to VirtIOS390Device. TODO: use QOM. */
+static inline VirtIOS390Device *to_virtio_s390_device(DeviceState *d)
+{
+ return container_of(d, VirtIOS390Device, qdev);
+}
+
+static void virtio_s390_notify(DeviceState *d, uint16_t vector)
{
- VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
+ VirtIOS390Device *dev = to_virtio_s390_device_fast(d);
uint64_t token = s390_virtio_device_vq_token(dev, vector);
S390CPU *cpu = s390_cpu_addr2state(0);
CPUS390XState *env = &cpu->env;
s390_virtio_irq(env, 0, token);
}
-static unsigned virtio_s390_get_features(void *opaque)
+static unsigned virtio_s390_get_features(DeviceState *d)
{
- VirtIOS390Device *dev = (VirtIOS390Device*)opaque;
+ VirtIOS390Device *dev = to_virtio_s390_device(d);
return dev->host_features;
}
bool virtio_is_big_endian(void);
/* virtio device */
+/* DeviceState to VirtIOPCIProxy. For use off data-path. TODO: use QOM. */
+static inline VirtIOPCIProxy *to_virtio_pci_proxy(DeviceState *d)
+{
+ return container_of(d, VirtIOPCIProxy, pci_dev.qdev);
+}
-static void virtio_pci_notify(void *opaque, uint16_t vector)
+/* DeviceState to VirtIOPCIProxy. Note: used on datapath,
+ * be careful and test performance if you change this.
+ */
+static inline VirtIOPCIProxy *to_virtio_pci_proxy_fast(DeviceState *d)
{
- VirtIOPCIProxy *proxy = opaque;
+ return container_of(d, VirtIOPCIProxy, pci_dev.qdev);
+}
+
+static void virtio_pci_notify(DeviceState *d, uint16_t vector)
+{
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d);
if (msix_enabled(&proxy->pci_dev))
msix_notify(&proxy->pci_dev, vector);
else
qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
}
-static void virtio_pci_save_config(void * opaque, QEMUFile *f)
+static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
pci_device_save(&proxy->pci_dev, f);
msix_save(&proxy->pci_dev, f);
if (msix_present(&proxy->pci_dev))
qemu_put_be16(f, proxy->vdev->config_vector);
}
-static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
+static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
if (msix_present(&proxy->pci_dev))
qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
}
-static int virtio_pci_load_config(void * opaque, QEMUFile *f)
+static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
int ret;
ret = pci_device_load(&proxy->pci_dev, f);
if (ret) {
return 0;
}
-static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
+static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
uint16_t vector;
if (msix_present(&proxy->pci_dev)) {
qemu_get_be16s(f, &vector);
void virtio_pci_reset(DeviceState *d)
{
- VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
virtio_pci_stop_ioeventfd(proxy);
virtio_reset(proxy->vdev);
msix_unuse_all_vectors(&proxy->pci_dev);
}
}
-static unsigned virtio_pci_get_features(void *opaque)
+static unsigned virtio_pci_get_features(DeviceState *d)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
return proxy->host_features;
}
}
}
-static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
+static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
return 0;
}
-static bool virtio_pci_query_guest_notifiers(void *opaque)
+static bool virtio_pci_query_guest_notifiers(DeviceState *d)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
return msix_enabled(&proxy->pci_dev);
}
-static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
+static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
VirtIODevice *vdev = proxy->vdev;
int r, n;
break;
}
- r = virtio_pci_set_guest_notifier(opaque, n, assign);
+ r = virtio_pci_set_guest_notifier(d, n, assign);
if (r < 0) {
goto assign_error;
}
/* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
assert(assign);
while (--n >= 0) {
- virtio_pci_set_guest_notifier(opaque, n, !assign);
+ virtio_pci_set_guest_notifier(d, n, !assign);
}
return r;
}
-static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
+static int virtio_pci_set_host_notifier(DeviceState *d, int n, bool assign)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
/* Stop using ioeventfd for virtqueue kick if the device starts using host
* notifiers. This makes it easy to avoid stepping on each others' toes.
return virtio_pci_set_host_notifier_internal(proxy, n, assign, false);
}
-static void virtio_pci_vmstate_change(void *opaque, bool running)
+static void virtio_pci_vmstate_change(DeviceState *d, bool running)
{
- VirtIOPCIProxy *proxy = opaque;
+ VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
if (running) {
/* Try to find out if the guest has bus master disabled, but is
proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
}
- virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
+ virtio_bind_device(vdev, &virtio_pci_bindings, DEVICE(proxy));
proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
proxy->host_features = vdev->get_features(vdev, proxy->host_features);
} VirtQueueElement;
typedef struct {
- void (*notify)(void * opaque, uint16_t vector);
- void (*save_config)(void * opaque, QEMUFile *f);
- void (*save_queue)(void * opaque, int n, QEMUFile *f);
- int (*load_config)(void * opaque, QEMUFile *f);
- int (*load_queue)(void * opaque, int n, QEMUFile *f);
- int (*load_done)(void * opaque, QEMUFile *f);
- unsigned (*get_features)(void * opaque);
- bool (*query_guest_notifiers)(void * opaque);
- int (*set_guest_notifiers)(void * opaque, bool assigned);
- int (*set_host_notifier)(void * opaque, int n, bool assigned);
- void (*vmstate_change)(void * opaque, bool running);
+ void (*notify)(DeviceState *d, uint16_t vector);
+ void (*save_config)(DeviceState *d, QEMUFile *f);
+ void (*save_queue)(DeviceState *d, int n, QEMUFile *f);
+ int (*load_config)(DeviceState *d, QEMUFile *f);
+ int (*load_queue)(DeviceState *d, int n, QEMUFile *f);
+ int (*load_done)(DeviceState *d, QEMUFile *f);
+ unsigned (*get_features)(DeviceState *d);
+ bool (*query_guest_notifiers)(DeviceState *d);
+ int (*set_guest_notifiers)(DeviceState *d, bool assigned);
+ int (*set_host_notifier)(DeviceState *d, int n, bool assigned);
+ void (*vmstate_change)(DeviceState *d, bool running);
} VirtIOBindings;
#define VIRTIO_PCI_QUEUE_MAX 64
void (*set_status)(VirtIODevice *vdev, uint8_t val);
VirtQueue *vq;
const VirtIOBindings *binding;
- void *binding_opaque;
+ DeviceState *binding_opaque;
uint16_t device_id;
bool vm_running;
VMChangeStateEntry *vmstate;
int virtio_set_features(VirtIODevice *vdev, uint32_t val);
void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
- void *opaque);
+ DeviceState *opaque);
/* Base devices. */
typedef struct VirtIOBlkConf VirtIOBlkConf;