All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <aliguori@us.ibm.com>
To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Anthony Liguori <aliguori@us.ibm.com>,
	Markus Armbruster <armbru@redhat.com>
Subject: [Qemu-devel] [PATCH 12/27] usb: convert to QEMU Object Model
Date: Tue, 20 Dec 2011 10:51:41 -0600	[thread overview]
Message-ID: <1324399916-21315-13-git-send-email-aliguori@us.ibm.com> (raw)
In-Reply-To: <1324399916-21315-1-git-send-email-aliguori@us.ibm.com>

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/usb-bt.c     |   33 ++++++----
 hw/usb-bus.c    |  179 +++++++++++++++++++++++++++++++++++++++++++------------
 hw/usb-ccid.c   |   38 +++++++-----
 hw/usb-desc.c   |   18 +++---
 hw/usb-hid.c    |  108 ++++++++++++++++++++--------------
 hw/usb-hub.c    |   35 +++++++----
 hw/usb-msd.c    |   41 +++++++------
 hw/usb-net.c    |   41 +++++++------
 hw/usb-serial.c |   74 +++++++++++++----------
 hw/usb-wacom.c  |   36 +++++++-----
 hw/usb.c        |   24 +++----
 hw/usb.h        |   98 +++++++++++++++++++-----------
 usb-bsd.c       |   29 ++++++----
 usb-linux.c     |   37 +++++++-----
 usb-redir.c     |   33 ++++++----
 15 files changed, 516 insertions(+), 308 deletions(-)

diff --git a/hw/usb-bt.c b/hw/usb-bt.c
index f30eec1..6e210ac 100644
--- a/hw/usb-bt.c
+++ b/hw/usb-bt.c
@@ -549,22 +549,29 @@ static const VMStateDescription vmstate_usb_bt = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo bt_info = {
-    .product_desc   = "QEMU BT dongle",
-    .qdev.name      = "usb-bt-dongle",
-    .qdev.size      = sizeof(struct USBBtState),
-    .qdev.vmsd      = &vmstate_usb_bt,
-    .usb_desc       = &desc_bluetooth,
-    .init           = usb_bt_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_bt_handle_reset,
-    .handle_control = usb_bt_handle_control,
-    .handle_data    = usb_bt_handle_data,
-    .handle_destroy = usb_bt_handle_destroy,
+static void usb_bt_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_bt_initfn;
+    uc->product_desc   = "QEMU BT dongle";
+    uc->usb_desc       = &desc_bluetooth;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_bt_handle_reset;
+    uc->handle_control = usb_bt_handle_control;
+    uc->handle_data    = usb_bt_handle_data;
+    uc->handle_destroy = usb_bt_handle_destroy;
+}
+
+static struct DeviceInfo bt_info = {
+    .name      = "usb-bt-dongle",
+    .size      = sizeof(struct USBBtState),
+    .vmsd      = &vmstate_usb_bt,
+    .class_init= usb_bt_class_initfn,
 };
 
 static void usb_bt_register_devices(void)
 {
-    usb_qdev_register(&bt_info);
+    usb_qdev_register(&bt_info, NULL, NULL);
 }
 device_init(usb_bt_register_devices)
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 23691be..6d5ef3f 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -65,21 +65,102 @@ USBBus *usb_bus_find(int busnr)
     return NULL;
 }
 
+static int usb_device_init(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->init) {
+        return klass->init(dev);
+    }
+    return 0;
+}
+
+static void usb_device_handle_destroy(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_destroy) {
+        klass->handle_destroy(dev);
+    }
+}
+
+int usb_device_handle_packet(USBDevice *dev, USBPacket *p)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_packet) {
+        return klass->handle_packet(dev, p);
+    }
+    return -ENOSYS;
+}
+
+void usb_device_cancel_packet(USBDevice *dev, USBPacket *p)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->cancel_packet) {
+        klass->cancel_packet(dev, p);
+    }
+}
+
+void usb_device_handle_attach(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_attach) {
+        klass->handle_attach(dev);
+    }
+}
+
+void usb_device_handle_reset(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_reset) {
+        klass->handle_reset(dev);
+    }
+}
+
+int usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
+                              int value, int index, int length, uint8_t *data)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_control) {
+        return klass->handle_control(dev, p, request, value, index, length,
+                                         data);
+    }
+    return -ENOSYS;
+}
+
+int usb_device_handle_data(USBDevice *dev, USBPacket *p)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_data) {
+        return klass->handle_data(dev, p);
+    }
+    return -ENOSYS;
+}
+
+const char *usb_device_get_product_desc(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    return klass->product_desc;
+}
+
+const USBDesc *usb_device_get_usb_desc(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    return klass->usb_desc;
+}
+
 static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
-    USBDeviceInfo *info = DO_UPCAST(USBDeviceInfo, qdev, base);
+    USBDevice *dev = USB_DEVICE(qdev);
     int rc;
 
-    pstrcpy(dev->product_desc, sizeof(dev->product_desc), info->product_desc);
-    dev->info = info;
+    pstrcpy(dev->product_desc, sizeof(dev->product_desc),
+            usb_device_get_product_desc(dev));
     dev->auto_attach = 1;
     QLIST_INIT(&dev->strings);
     rc = usb_claim_port(dev);
     if (rc != 0) {
         return rc;
     }
-    rc = dev->info->init(dev);
+    rc = usb_device_init(dev);
     if (rc != 0) {
         usb_release_port(dev);
         return rc;
@@ -96,34 +177,43 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
 
 static int usb_qdev_exit(DeviceState *qdev)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+    USBDevice *dev = USB_DEVICE(qdev);
 
     if (dev->attached) {
         usb_device_detach(dev);
     }
-    if (dev->info->handle_destroy) {
-        dev->info->handle_destroy(dev);
-    }
+    usb_device_handle_destroy(dev);
     if (dev->port) {
         usb_release_port(dev);
     }
     return 0;
 }
 
-void usb_qdev_register(USBDeviceInfo *info)
+typedef struct LegacyUSBFactory
 {
-    info->qdev.bus_info = &usb_bus_info;
-    info->qdev.init     = usb_qdev_init;
-    info->qdev.unplug   = qdev_simple_unplug_cb;
-    info->qdev.exit     = usb_qdev_exit;
-    qdev_register(&info->qdev);
-}
+    const char *name;
+    const char *usbdevice_name;
+    USBDevice *(*usbdevice_init)(const char *params);
+} LegacyUSBFactory;
 
-void usb_qdev_register_many(USBDeviceInfo *info)
+static GSList *legacy_usb_factory;
+
+void usb_qdev_register(DeviceInfo *info,
+                       const char *usbdevice_name,
+                       USBDevice *(*usbdevice_init)(const char *params))
 {
-    while (info->qdev.name) {
-        usb_qdev_register(info);
-        info++;
+    info->bus_info = &usb_bus_info;
+    info->init     = usb_qdev_init;
+    info->unplug   = qdev_simple_unplug_cb;
+    info->exit     = usb_qdev_exit;
+    qdev_register_subclass(info, TYPE_USB_DEVICE);
+
+    if (usbdevice_name) {
+        LegacyUSBFactory *f = g_malloc0(sizeof(*f));
+        f->name = info->name;
+        f->usbdevice_name = usbdevice_name;
+        f->usbdevice_init = usbdevice_init;
+        legacy_usb_factory = g_slist_append(legacy_usb_factory, f);
     }
 }
 
@@ -143,7 +233,7 @@ USBDevice *usb_create(USBBus *bus, const char *name)
 #endif
 
     dev = qdev_create(&bus->qbus, name);
-    return DO_UPCAST(USBDevice, qdev, dev);
+    return USB_DEVICE(dev);
 }
 
 USBDevice *usb_create_simple(USBBus *bus, const char *name)
@@ -364,7 +454,7 @@ static const char *usb_speed(unsigned int speed)
 
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+    USBDevice *dev = USB_DEVICE(qdev);
     USBBus *bus = usb_bus_from_device(dev);
 
     monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
@@ -376,13 +466,13 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 
 static char *usb_get_dev_path(DeviceState *qdev)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+    USBDevice *dev = USB_DEVICE(qdev);
     return g_strdup(dev->port->path);
 }
 
 static char *usb_get_fw_dev_path(DeviceState *qdev)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+    USBDevice *dev = USB_DEVICE(qdev);
     char *fw_path, *in;
     ssize_t pos = 0, fw_len;
     long nr;
@@ -433,8 +523,8 @@ void usb_info(Monitor *mon)
 USBDevice *usbdevice_create(const char *cmdline)
 {
     USBBus *bus = usb_bus_find(-1 /* any */);
-    DeviceInfo *info;
-    USBDeviceInfo *usb;
+    LegacyUSBFactory *f = NULL;
+    GSList *i;
     char driver[32];
     const char *params;
     int len;
@@ -451,17 +541,13 @@ USBDevice *usbdevice_create(const char *cmdline)
         pstrcpy(driver, sizeof(driver), cmdline);
     }
 
-    for (info = device_info_list; info != NULL; info = info->next) {
-        if (info->bus_info != &usb_bus_info)
-            continue;
-        usb = DO_UPCAST(USBDeviceInfo, qdev, info);
-        if (usb->usbdevice_name == NULL)
-            continue;
-        if (strcmp(usb->usbdevice_name, driver) != 0)
-            continue;
-        break;
+    for (i = legacy_usb_factory; i; i = i->next) {
+        f = i->data;
+        if (strcmp(f->usbdevice_name, driver) == 0) {
+            break;
+        }
     }
-    if (info == NULL) {
+    if (i == NULL) {
 #if 0
         /* no error because some drivers are not converted (yet) */
         error_report("usbdevice %s not found", driver);
@@ -469,12 +555,27 @@ USBDevice *usbdevice_create(const char *cmdline)
         return NULL;
     }
 
-    if (!usb->usbdevice_init) {
+    if (!f->usbdevice_init) {
         if (*params) {
             error_report("usbdevice %s accepts no params", driver);
             return NULL;
         }
-        return usb_create_simple(bus, usb->qdev.name);
+        return usb_create_simple(bus, f->name);
     }
-    return usb->usbdevice_init(params);
+    return f->usbdevice_init(params);
 }
+
+static TypeInfo usb_device_type_info = {
+    .name = TYPE_USB_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(USBDevice),
+    .abstract = true,
+    .class_size = sizeof(USBDeviceClass),
+};
+
+static void usb_register_devices(void)
+{
+    type_register_static(&usb_device_type_info);
+}
+
+device_init(usb_register_devices);
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 8a79729..47b1120 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1294,28 +1294,34 @@ static VMStateDescription ccid_vmstate = {
     }
 };
 
-static struct USBDeviceInfo ccid_info = {
-    .product_desc   = "QEMU USB CCID",
-    .qdev.name      = CCID_DEV_NAME,
-    .qdev.desc      = "CCID Rev 1.1 smartcard reader",
-    .qdev.size      = sizeof(USBCCIDState),
-    .init           = ccid_initfn,
-    .usb_desc       = &desc_ccid,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = ccid_handle_reset,
-    .handle_control = ccid_handle_control,
-    .handle_data    = ccid_handle_data,
-    .handle_destroy = ccid_handle_destroy,
-    .usbdevice_name = "ccid",
-    .qdev.props     = (Property[]) {
+static void ccid_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = ccid_initfn;
+    uc->product_desc   = "QEMU USB CCID";
+    uc->usb_desc       = &desc_ccid;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = ccid_handle_reset;
+    uc->handle_control = ccid_handle_control;
+    uc->handle_data    = ccid_handle_data;
+    uc->handle_destroy = ccid_handle_destroy;
+}
+
+static struct DeviceInfo ccid_info = {
+    .name      = CCID_DEV_NAME,
+    .desc      = "CCID Rev 1.1 smartcard reader",
+    .size      = sizeof(USBCCIDState),
+    .class_init= ccid_class_initfn,
+    .vmsd      = &ccid_vmstate,
+    .props     = (Property[]) {
         DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0),
         DEFINE_PROP_END_OF_LIST(),
     },
-    .qdev.vmsd      = &ccid_vmstate,
 };
 
 static void ccid_register_devices(void)
 {
-    usb_qdev_register(&ccid_info);
+    usb_qdev_register(&ccid_info, "ccid", NULL);
 }
 device_init(ccid_register_devices)
diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index ae2d384..1f5fc7a 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -225,7 +225,7 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len)
 
 static void usb_desc_setdefaults(USBDevice *dev)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
 
     assert(desc != NULL);
     switch (dev->speed) {
@@ -242,7 +242,7 @@ static void usb_desc_setdefaults(USBDevice *dev)
 
 void usb_desc_init(USBDevice *dev)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
 
     assert(desc != NULL);
     dev->speed = USB_SPEED_FULL;
@@ -258,7 +258,7 @@ void usb_desc_init(USBDevice *dev)
 
 void usb_desc_attach(USBDevice *dev)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
 
     assert(desc != NULL);
     if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) {
@@ -267,7 +267,7 @@ void usb_desc_attach(USBDevice *dev)
         dev->speed = USB_SPEED_FULL;
     } else {
         fprintf(stderr, "usb: port/device speed mismatch for \"%s\"\n",
-                dev->info->product_desc);
+                usb_device_get_product_desc(dev));
         return;
     }
     usb_desc_setdefaults(dev);
@@ -323,7 +323,7 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len)
 
     str = usb_desc_get_string(dev, index);
     if (str == NULL) {
-        str = dev->info->usb_desc->str[index];
+        str = usb_device_get_usb_desc(dev)->str[index];
         if (str == NULL) {
             return 0;
         }
@@ -342,7 +342,7 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len)
 
 int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
     const USBDescDevice *other_dev;
     uint8_t buf[256];
     uint8_t type = value >> 8;
@@ -350,9 +350,9 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len
     int ret = -1;
 
     if (dev->speed == USB_SPEED_HIGH) {
-        other_dev = dev->info->usb_desc->full;
+        other_dev = usb_device_get_usb_desc(dev)->full;
     } else {
-        other_dev = dev->info->usb_desc->high;
+        other_dev = usb_device_get_usb_desc(dev)->high;
     }
 
     switch(type) {
@@ -407,7 +407,7 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len
 int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
         int request, int value, int index, int length, uint8_t *data)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
     int i, ret = -1;
 
     assert(desc != NULL);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index a110c74..2538b9c 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -560,53 +560,73 @@ static const VMStateDescription vmstate_usb_kbd = {
     }
 };
 
-static struct USBDeviceInfo hid_info[] = {
-    {
-        .product_desc   = "QEMU USB Tablet",
-        .qdev.name      = "usb-tablet",
-        .usbdevice_name = "tablet",
-        .qdev.size      = sizeof(USBHIDState),
-        .qdev.vmsd      = &vmstate_usb_ptr,
-        .usb_desc       = &desc_tablet,
-        .init           = usb_tablet_initfn,
-        .handle_packet  = usb_generic_handle_packet,
-        .handle_reset   = usb_hid_handle_reset,
-        .handle_control = usb_hid_handle_control,
-        .handle_data    = usb_hid_handle_data,
-        .handle_destroy = usb_hid_handle_destroy,
-    },{
-        .product_desc   = "QEMU USB Mouse",
-        .qdev.name      = "usb-mouse",
-        .usbdevice_name = "mouse",
-        .qdev.size      = sizeof(USBHIDState),
-        .qdev.vmsd      = &vmstate_usb_ptr,
-        .usb_desc       = &desc_mouse,
-        .init           = usb_mouse_initfn,
-        .handle_packet  = usb_generic_handle_packet,
-        .handle_reset   = usb_hid_handle_reset,
-        .handle_control = usb_hid_handle_control,
-        .handle_data    = usb_hid_handle_data,
-        .handle_destroy = usb_hid_handle_destroy,
-    },{
-        .product_desc   = "QEMU USB Keyboard",
-        .qdev.name      = "usb-kbd",
-        .usbdevice_name = "keyboard",
-        .qdev.size      = sizeof(USBHIDState),
-        .qdev.vmsd      = &vmstate_usb_kbd,
-        .usb_desc       = &desc_keyboard,
-        .init           = usb_keyboard_initfn,
-        .handle_packet  = usb_generic_handle_packet,
-        .handle_reset   = usb_hid_handle_reset,
-        .handle_control = usb_hid_handle_control,
-        .handle_data    = usb_hid_handle_data,
-        .handle_destroy = usb_hid_handle_destroy,
-    },{
-        /* end of list */
-    }
+static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_tablet_initfn;
+    uc->product_desc   = "QEMU USB Tablet";
+    uc->usb_desc       = &desc_tablet;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_hid_handle_reset;
+    uc->handle_control = usb_hid_handle_control;
+    uc->handle_data    = usb_hid_handle_data;
+    uc->handle_destroy = usb_hid_handle_destroy;
+}
+
+static struct DeviceInfo usb_tablet_info = {
+    .name      = "usb-tablet",
+    .size      = sizeof(USBHIDState),
+    .vmsd      = &vmstate_usb_ptr,
+    .class_init= usb_tablet_class_initfn,
+};
+
+static void usb_mouse_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_mouse_initfn;
+    uc->product_desc   = "QEMU USB Mouse";
+    uc->usb_desc       = &desc_mouse;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_hid_handle_reset;
+    uc->handle_control = usb_hid_handle_control;
+    uc->handle_data    = usb_hid_handle_data;
+    uc->handle_destroy = usb_hid_handle_destroy;
+}
+
+static struct DeviceInfo usb_mouse_info = {
+    .name      = "usb-mouse",
+    .size      = sizeof(USBHIDState),
+    .vmsd      = &vmstate_usb_ptr,
+    .class_init= usb_mouse_class_initfn,
+};
+
+static void usb_keyboard_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_keyboard_initfn;
+    uc->product_desc   = "QEMU USB Keyboard";
+    uc->usb_desc       = &desc_keyboard;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_hid_handle_reset;
+    uc->handle_control = usb_hid_handle_control;
+    uc->handle_data    = usb_hid_handle_data;
+    uc->handle_destroy = usb_hid_handle_destroy;
+}
+
+static struct DeviceInfo usb_keyboard_info = {
+    .name      = "usb-kbd",
+    .size      = sizeof(USBHIDState),
+    .vmsd      = &vmstate_usb_kbd,
+    .class_init= usb_keyboard_class_initfn,
 };
 
 static void usb_hid_register_devices(void)
 {
-    usb_qdev_register_many(hid_info);
+    usb_qdev_register(&usb_tablet_info, "tablet", NULL);
+    usb_qdev_register(&usb_mouse_info, "mouse", NULL);
+    usb_qdev_register(&usb_keyboard_info, "keyboard", NULL);
 }
 device_init(usb_hid_register_devices)
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index e195937..f997152 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -540,23 +540,30 @@ static const VMStateDescription vmstate_usb_hub = {
     }
 };
 
-static struct USBDeviceInfo hub_info = {
-    .product_desc   = "QEMU USB Hub",
-    .qdev.name      = "usb-hub",
-    .qdev.fw_name    = "hub",
-    .qdev.size      = sizeof(USBHubState),
-    .qdev.vmsd      = &vmstate_usb_hub,
-    .usb_desc       = &desc_hub,
-    .init           = usb_hub_initfn,
-    .handle_packet  = usb_hub_handle_packet,
-    .handle_reset   = usb_hub_handle_reset,
-    .handle_control = usb_hub_handle_control,
-    .handle_data    = usb_hub_handle_data,
-    .handle_destroy = usb_hub_handle_destroy,
+static void  usb_hub_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_hub_initfn;
+    uc->product_desc   = "QEMU USB Hub";
+    uc->usb_desc       = &desc_hub;
+    uc->handle_packet  = usb_hub_handle_packet;
+    uc->handle_reset   = usb_hub_handle_reset;
+    uc->handle_control = usb_hub_handle_control;
+    uc->handle_data    = usb_hub_handle_data;
+    uc->handle_destroy = usb_hub_handle_destroy;
+}
+
+static struct DeviceInfo hub_info = {
+    .name      = "usb-hub",
+    .fw_name   = "hub",
+    .size      = sizeof(USBHubState),
+    .vmsd      = &vmstate_usb_hub,
+    .class_init= usb_hub_class_initfn,
 };
 
 static void usb_hub_register_devices(void)
 {
-    usb_qdev_register(&hub_info);
+    usb_qdev_register(&hub_info, NULL, NULL);
 }
 device_init(usb_hub_register_devices)
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 4c06950..e4a1e4e 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -634,23 +634,28 @@ static const VMStateDescription vmstate_usb_msd = {
     }
 };
 
-static struct USBDeviceInfo msd_info = {
-    .product_desc   = "QEMU USB MSD",
-    .qdev.name      = "usb-storage",
-    .qdev.fw_name      = "storage",
-    .qdev.size      = sizeof(MSDState),
-    .qdev.vmsd      = &vmstate_usb_msd,
-    .usb_desc       = &desc,
-    .init           = usb_msd_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .cancel_packet  = usb_msd_cancel_io,
-    .handle_attach  = usb_desc_attach,
-    .handle_reset   = usb_msd_handle_reset,
-    .handle_control = usb_msd_handle_control,
-    .handle_data    = usb_msd_handle_data,
-    .usbdevice_name = "disk",
-    .usbdevice_init = usb_msd_init,
-    .qdev.props     = (Property[]) {
+static void usb_msd_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_msd_initfn;
+    uc->product_desc   = "QEMU USB MSD";
+    uc->usb_desc       = &desc;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->cancel_packet  = usb_msd_cancel_io;
+    uc->handle_attach  = usb_desc_attach;
+    uc->handle_reset   = usb_msd_handle_reset;
+    uc->handle_control = usb_msd_handle_control;
+    uc->handle_data    = usb_msd_handle_data;
+}
+
+static struct DeviceInfo msd_info = {
+    .name      = "usb-storage",
+    .fw_name   = "storage",
+    .size      = sizeof(MSDState),
+    .vmsd      = &vmstate_usb_msd,
+    .class_init= usb_msd_class_initfn,
+    .props     = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(MSDState, conf),
         DEFINE_PROP_STRING("serial", MSDState, serial),
         DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
@@ -660,6 +665,6 @@ static struct USBDeviceInfo msd_info = {
 
 static void usb_msd_register_devices(void)
 {
-    usb_qdev_register(&msd_info);
+    usb_qdev_register(&msd_info, "disk", usb_msd_init);
 }
 device_init(usb_msd_register_devices)
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 9969598..7155f88 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1399,29 +1399,34 @@ static const VMStateDescription vmstate_usb_net = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo net_info = {
-    .product_desc   = "QEMU USB Network Interface",
-    .qdev.name      = "usb-net",
-    .qdev.fw_name    = "network",
-    .qdev.size      = sizeof(USBNetState),
-    .qdev.vmsd      = &vmstate_usb_net,
-    .usb_desc       = &desc_net,
-    .init           = usb_net_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_net_handle_reset,
-    .handle_control = usb_net_handle_control,
-    .handle_data    = usb_net_handle_data,
-    .handle_destroy = usb_net_handle_destroy,
-    .usbdevice_name = "net",
-    .usbdevice_init = usb_net_init,
-    .qdev.props     = (Property[]) {
+static void usb_net_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_net_initfn;
+    uc->product_desc   = "QEMU USB Network Interface";
+    uc->usb_desc       = &desc_net;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_net_handle_reset;
+    uc->handle_control = usb_net_handle_control;
+    uc->handle_data    = usb_net_handle_data;
+    uc->handle_destroy = usb_net_handle_destroy;
+}
+
+static struct DeviceInfo net_info = {
+    .name      = "usb-net",
+    .fw_name   = "network",
+    .size      = sizeof(USBNetState),
+    .vmsd      = &vmstate_usb_net,
+    .class_init= usb_net_class_initfn,
+    .props     = (Property[]) {
         DEFINE_NIC_PROPERTIES(USBNetState, conf),
         DEFINE_PROP_END_OF_LIST(),
-    }
+    },
 };
 
 static void usb_net_register_devices(void)
 {
-    usb_qdev_register(&net_info);
+    usb_qdev_register(&net_info, "net", usb_net_init);
 }
 device_init(usb_net_register_devices)
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index 7dbf6df..73bb80b 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -577,41 +577,51 @@ static const VMStateDescription vmstate_usb_serial = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo serial_info = {
-    .product_desc   = "QEMU USB Serial",
-    .qdev.name      = "usb-serial",
-    .qdev.size      = sizeof(USBSerialState),
-    .qdev.vmsd      = &vmstate_usb_serial,
-    .usb_desc       = &desc_serial,
-    .init           = usb_serial_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_serial_handle_reset,
-    .handle_control = usb_serial_handle_control,
-    .handle_data    = usb_serial_handle_data,
-    .handle_destroy = usb_serial_handle_destroy,
-    .usbdevice_name = "serial",
-    .usbdevice_init = usb_serial_init,
-    .qdev.props     = (Property[]) {
+static void usb_serial_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init = usb_serial_initfn;
+    uc->product_desc   = "QEMU USB Serial";
+    uc->usb_desc       = &desc_serial;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_serial_handle_reset;
+    uc->handle_control = usb_serial_handle_control;
+    uc->handle_data    = usb_serial_handle_data;
+    uc->handle_destroy = usb_serial_handle_destroy;
+}
+
+static struct DeviceInfo serial_info = {
+    .name      = "usb-serial",
+    .size      = sizeof(USBSerialState),
+    .vmsd      = &vmstate_usb_serial,
+    .class_init= usb_serial_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_CHR("chardev", USBSerialState, cs),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
 
-static struct USBDeviceInfo braille_info = {
-    .product_desc   = "QEMU USB Braille",
-    .qdev.name      = "usb-braille",
-    .qdev.size      = sizeof(USBSerialState),
-    .qdev.vmsd      = &vmstate_usb_serial,
-    .usb_desc       = &desc_braille,
-    .init           = usb_serial_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_serial_handle_reset,
-    .handle_control = usb_serial_handle_control,
-    .handle_data    = usb_serial_handle_data,
-    .handle_destroy = usb_serial_handle_destroy,
-    .usbdevice_name = "braille",
-    .usbdevice_init = usb_braille_init,
-    .qdev.props     = (Property[]) {
+static void usb_braille_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_serial_initfn;
+    uc->product_desc   = "QEMU USB Braille";
+    uc->usb_desc       = &desc_braille;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_serial_handle_reset;
+    uc->handle_control = usb_serial_handle_control;
+    uc->handle_data    = usb_serial_handle_data;
+    uc->handle_destroy = usb_serial_handle_destroy;
+}
+
+static struct DeviceInfo braille_info = {
+    .name      = "usb-braille",
+    .size      = sizeof(USBSerialState),
+    .vmsd      = &vmstate_usb_serial,
+    .class_init= usb_braille_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_CHR("chardev", USBSerialState, cs),
         DEFINE_PROP_END_OF_LIST(),
     },
@@ -619,7 +629,7 @@ static struct USBDeviceInfo braille_info = {
 
 static void usb_serial_register_devices(void)
 {
-    usb_qdev_register(&serial_info);
-    usb_qdev_register(&braille_info);
+    usb_qdev_register(&serial_info, "serial", usb_serial_init);
+    usb_qdev_register(&braille_info, "braille", usb_braille_init);
 }
 device_init(usb_serial_register_devices)
diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c
index 2558006..12c949f 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb-wacom.c
@@ -356,24 +356,30 @@ static const VMStateDescription vmstate_usb_wacom = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo wacom_info = {
-    .product_desc   = "QEMU PenPartner Tablet",
-    .qdev.name      = "usb-wacom-tablet",
-    .qdev.desc      = "QEMU PenPartner Tablet",
-    .usbdevice_name = "wacom-tablet",
-    .usb_desc       = &desc_wacom,
-    .qdev.size      = sizeof(USBWacomState),
-    .qdev.vmsd      = &vmstate_usb_wacom,
-    .init           = usb_wacom_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_wacom_handle_reset,
-    .handle_control = usb_wacom_handle_control,
-    .handle_data    = usb_wacom_handle_data,
-    .handle_destroy = usb_wacom_handle_destroy,
+static void usb_wacom_class_init(ObjectClass *class, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(class);
+
+    uc->product_desc   = "QEMU PenPartner Tablet";
+    uc->usb_desc       = &desc_wacom;
+    uc->init           = usb_wacom_initfn;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_wacom_handle_reset;
+    uc->handle_control = usb_wacom_handle_control;
+    uc->handle_data    = usb_wacom_handle_data;
+    uc->handle_destroy = usb_wacom_handle_destroy;
+}
+
+static struct DeviceInfo wacom_info = {
+    .name      = "usb-wacom-tablet",
+    .desc      = "QEMU PenPartner Tablet",
+    .size      = sizeof(USBWacomState),
+    .vmsd      = &vmstate_usb_wacom,
+    .class_init= usb_wacom_class_init,
 };
 
 static void usb_wacom_register_devices(void)
 {
-    usb_qdev_register(&wacom_info);
+    usb_qdev_register(&wacom_info, "wacom-tablet", NULL);
 }
 device_init(usb_wacom_register_devices)
diff --git a/hw/usb.c b/hw/usb.c
index 2216efe..e1cbfec 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -95,8 +95,8 @@ static int do_token_setup(USBDevice *s, USBPacket *p)
     index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
 
     if (s->setup_buf[0] & USB_DIR_IN) {
-        ret = s->info->handle_control(s, p, request, value, index,
-                                      s->setup_len, s->data_buf);
+        ret = usb_device_handle_control(s, p, request, value, index,
+                                        s->setup_len, s->data_buf);
         if (ret == USB_RET_ASYNC) {
              s->setup_state = SETUP_STATE_SETUP;
              return USB_RET_ASYNC;
@@ -129,7 +129,7 @@ static int do_token_in(USBDevice *s, USBPacket *p)
     int ret = 0;
 
     if (p->devep != 0)
-        return s->info->handle_data(s, p);
+        return usb_device_handle_data(s, p);
 
     request = (s->setup_buf[0] << 8) | s->setup_buf[1];
     value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
@@ -138,8 +138,8 @@ static int do_token_in(USBDevice *s, USBPacket *p)
     switch(s->setup_state) {
     case SETUP_STATE_ACK:
         if (!(s->setup_buf[0] & USB_DIR_IN)) {
-            ret = s->info->handle_control(s, p, request, value, index,
-                                          s->setup_len, s->data_buf);
+            ret = usb_device_handle_control(s, p, request, value, index,
+                                            s->setup_len, s->data_buf);
             if (ret == USB_RET_ASYNC) {
                 return USB_RET_ASYNC;
             }
@@ -176,7 +176,7 @@ static int do_token_in(USBDevice *s, USBPacket *p)
 static int do_token_out(USBDevice *s, USBPacket *p)
 {
     if (p->devep != 0)
-        return s->info->handle_data(s, p);
+        return usb_device_handle_data(s, p);
 
     switch(s->setup_state) {
     case SETUP_STATE_ACK:
@@ -220,9 +220,7 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
     switch(p->pid) {
     case USB_MSG_ATTACH:
         s->state = USB_STATE_ATTACHED;
-        if (s->info->handle_attach) {
-            s->info->handle_attach(s);
-        }
+        usb_device_handle_attach(s);
         return 0;
 
     case USB_MSG_DETACH:
@@ -233,9 +231,7 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
         s->remote_wakeup = 0;
         s->addr = 0;
         s->state = USB_STATE_DEFAULT;
-        if (s->info->handle_reset) {
-            s->info->handle_reset(s);
-        }
+        usb_device_handle_reset(s);
         return 0;
     }
 
@@ -326,7 +322,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
     int ret;
 
     assert(p->owner == NULL);
-    ret = dev->info->handle_packet(dev, p);
+    ret = usb_device_handle_packet(dev, p);
     if (ret == USB_RET_ASYNC) {
         if (p->owner == NULL) {
             p->owner = dev;
@@ -357,7 +353,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
 void usb_cancel_packet(USBPacket * p)
 {
     assert(p->owner != NULL);
-    p->owner->info->cancel_packet(p->owner, p);
+    usb_device_cancel_packet(p->owner, p);
     p->owner = NULL;
 }
 
diff --git a/hw/usb.h b/hw/usb.h
index c6e1870..2bbfb0a 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -1,3 +1,6 @@
+#ifndef QEMU_USB_H
+#define QEMU_USB_H
+
 /*
  * QEMU USB API
  *
@@ -142,7 +145,6 @@ typedef struct USBBus USBBus;
 typedef struct USBBusOps USBBusOps;
 typedef struct USBPort USBPort;
 typedef struct USBDevice USBDevice;
-typedef struct USBDeviceInfo USBDeviceInfo;
 typedef struct USBPacket USBPacket;
 
 typedef struct USBDesc USBDesc;
@@ -161,38 +163,17 @@ struct USBDescString {
     QLIST_ENTRY(USBDescString) next;
 };
 
-/* definition of a USB device */
-struct USBDevice {
-    DeviceState qdev;
-    USBDeviceInfo *info;
-    USBPort *port;
-    char *port_path;
-    void *opaque;
-
-    /* Actual connected speed */
-    int speed;
-    /* Supported speeds, not in info because it may be variable (hostdevs) */
-    int speedmask;
-    uint8_t addr;
-    char product_desc[32];
-    int auto_attach;
-    int attached;
-
-    int32_t state;
-    uint8_t setup_buf[8];
-    uint8_t data_buf[4096];
-    int32_t remote_wakeup;
-    int32_t setup_state;
-    int32_t setup_len;
-    int32_t setup_index;
+#define TYPE_USB_DEVICE "usb-device"
+#define USB_DEVICE(obj) \
+     OBJECT_CHECK(USBDevice, (obj), TYPE_USB_DEVICE)
+#define USB_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(USBDeviceClass, (klass), TYPE_USB_DEVICE)
+#define USB_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(USBDeviceClass, (obj), TYPE_USB_DEVICE)
 
-    QLIST_HEAD(, USBDescString) strings;
-    const USBDescDevice *device;
-    const USBDescConfig *config;
-};
+typedef struct USBDeviceClass {
+    DeviceClass parent_class;
 
-struct USBDeviceInfo {
-    DeviceInfo qdev;
     int (*init)(USBDevice *dev);
 
     /*
@@ -243,10 +224,35 @@ struct USBDeviceInfo {
 
     const char *product_desc;
     const USBDesc *usb_desc;
+} USBDeviceClass;
+
+/* definition of a USB device */
+struct USBDevice {
+    DeviceState qdev;
+    USBPort *port;
+    char *port_path;
+    void *opaque;
+
+    /* Actual connected speed */
+    int speed;
+    /* Supported speeds, not in info because it may be variable (hostdevs) */
+    int speedmask;
+    uint8_t addr;
+    char product_desc[32];
+    int auto_attach;
+    int attached;
+
+    int32_t state;
+    uint8_t setup_buf[8];
+    uint8_t data_buf[4096];
+    int32_t remote_wakeup;
+    int32_t setup_state;
+    int32_t setup_len;
+    int32_t setup_index;
 
-    /* handle legacy -usbdevice command line options */
-    const char *usbdevice_name;
-    USBDevice *(*usbdevice_init)(const char *params);
+    QLIST_HEAD(, USBDescString) strings;
+    const USBDescDevice *device;
+    const USBDescConfig *config;
 };
 
 typedef struct USBPortOps {
@@ -370,8 +376,9 @@ struct USBBusOps {
 
 void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host);
 USBBus *usb_bus_find(int busnr);
-void usb_qdev_register(USBDeviceInfo *info);
-void usb_qdev_register_many(USBDeviceInfo *info);
+void usb_qdev_register(DeviceInfo *info,
+                       const char *usbdevice_name,
+                       USBDevice *(*usbdevice_init)(const char *params));
 USBDevice *usb_create(USBBus *bus, const char *name);
 USBDevice *usb_create_simple(USBBus *bus, const char *name);
 USBDevice *usbdevice_create(const char *cmdline);
@@ -392,3 +399,22 @@ static inline USBBus *usb_bus_from_device(USBDevice *d)
 {
     return DO_UPCAST(USBBus, qbus, d->qdev.parent_bus);
 }
+
+int usb_device_handle_packet(USBDevice *dev, USBPacket *p);
+
+void usb_device_cancel_packet(USBDevice *dev, USBPacket *p);
+
+void usb_device_handle_attach(USBDevice *dev);
+
+void usb_device_handle_reset(USBDevice *dev);
+
+int usb_device_handle_control(USBDevice *dev, USBPacket *p, int request, int value,
+                              int index, int length, uint8_t *data);
+
+int usb_device_handle_data(USBDevice *dev, USBPacket *p);
+
+const char *usb_device_get_product_desc(USBDevice *dev);
+
+const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
+
+#endif
diff --git a/usb-bsd.c b/usb-bsd.c
index 1187552..2c6afc8 100644
--- a/usb-bsd.c
+++ b/usb-bsd.c
@@ -397,21 +397,28 @@ fail:
     return ret;
 }
 
-static struct USBDeviceInfo usb_host_dev_info = {
-    .product_desc   = "USB Host Device",
-    .qdev.name      = "usb-host",
-    .qdev.size      = sizeof(USBHostDevice),
-    .init           = usb_host_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_host_handle_reset,
-    .handle_control = usb_host_handle_control,
-    .handle_data    = usb_host_handle_data,
-    .handle_destroy = usb_host_handle_destroy,
+static void usb_host_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->product_desc   = "USB Host Device";
+    uc->init           = usb_host_initfn;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_host_handle_reset;
+    uc->handle_control = usb_host_handle_control;
+    uc->handle_data    = usb_host_handle_data;
+    uc->handle_destroy = usb_host_handle_destroy;
+}
+
+static struct DeviceInfo usb_host_dev_info = {
+    .name      = "usb-host",
+    .size      = sizeof(USBHostDevice),
+    .class_init= usb_host_initfn,
 };
 
 static void usb_host_register_devices(void)
 {
-    usb_qdev_register(&usb_host_dev_info);
+    usb_qdev_register(&usb_host_dev_info, NULL, NULL);
 }
 device_init(usb_host_register_devices)
 
diff --git a/usb-linux.c b/usb-linux.c
index ab4c693..82d7e7e 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1428,21 +1428,26 @@ static const VMStateDescription vmstate_usb_host = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo usb_host_dev_info = {
-    .product_desc   = "USB Host Device",
-    .qdev.name      = "usb-host",
-    .qdev.size      = sizeof(USBHostDevice),
-    .qdev.vmsd      = &vmstate_usb_host,
-    .init           = usb_host_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .cancel_packet  = usb_host_async_cancel,
-    .handle_data    = usb_host_handle_data,
-    .handle_control = usb_host_handle_control,
-    .handle_reset   = usb_host_handle_reset,
-    .handle_destroy = usb_host_handle_destroy,
-    .usbdevice_name = "host",
-    .usbdevice_init = usb_host_device_open,
-    .qdev.props     = (Property[]) {
+static void usb_host_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_host_initfn;
+    uc->product_desc   = "USB Host Device";
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->cancel_packet  = usb_host_async_cancel;
+    uc->handle_data    = usb_host_handle_data;
+    uc->handle_control = usb_host_handle_control;
+    uc->handle_reset   = usb_host_handle_reset;
+    uc->handle_destroy = usb_host_handle_destroy;
+}
+
+static struct DeviceInfo usb_host_dev_info = {
+    .name      = "usb-host",
+    .size      = sizeof(USBHostDevice),
+    .vmsd      = &vmstate_usb_host,
+    .class_init= usb_host_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_UINT32("hostbus",  USBHostDevice, match.bus_num,    0),
         DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr,       0),
         DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
@@ -1455,7 +1460,7 @@ static struct USBDeviceInfo usb_host_dev_info = {
 
 static void usb_host_register_devices(void)
 {
-    usb_qdev_register(&usb_host_dev_info);
+    usb_qdev_register(&usb_host_dev_info, "host", usb_host_device_open);
 }
 device_init(usb_host_register_devices)
 
diff --git a/usb-redir.c b/usb-redir.c
index a36f2a7..26a9ba3 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -1227,18 +1227,25 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
     }
 }
 
-static struct USBDeviceInfo usbredir_dev_info = {
-    .product_desc   = "USB Redirection Device",
-    .qdev.name      = "usb-redir",
-    .qdev.size      = sizeof(USBRedirDevice),
-    .init           = usbredir_initfn,
-    .handle_destroy = usbredir_handle_destroy,
-    .handle_packet  = usb_generic_handle_packet,
-    .cancel_packet  = usbredir_cancel_packet,
-    .handle_reset   = usbredir_handle_reset,
-    .handle_data    = usbredir_handle_data,
-    .handle_control = usbredir_handle_control,
-    .qdev.props     = (Property[]) {
+static void usbredir_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usbredir_initfn;
+    uc->product_desc   = "USB Redirection Device";
+    uc->handle_destroy = usbredir_handle_destroy;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->cancel_packet  = usbredir_cancel_packet;
+    uc->handle_reset   = usbredir_handle_reset;
+    uc->handle_data    = usbredir_handle_data;
+    uc->handle_control = usbredir_handle_control;
+}
+
+static struct DeviceInfo usbredir_dev_info = {
+    .name      = "usb-redir",
+    .size      = sizeof(USBRedirDevice),
+    .class_init= usbredir_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
         DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
         DEFINE_PROP_END_OF_LIST(),
@@ -1247,6 +1254,6 @@ static struct USBDeviceInfo usbredir_dev_info = {
 
 static void usbredir_register_devices(void)
 {
-    usb_qdev_register(&usbredir_dev_info);
+    usb_qdev_register(&usbredir_dev_info, NULL, NULL);
 }
 device_init(usbredir_register_devices);
-- 
1.7.4.1

  parent reply	other threads:[~2011-12-20 16:52 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-20 16:51 [Qemu-devel] [PATCH 00/27] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 01/27] qom: add the base Object class Anthony Liguori
2011-12-21 13:35   ` Paolo Bonzini
2011-12-21 14:35     ` Anthony Liguori
2011-12-21 15:28       ` Paolo Bonzini
2011-12-22 17:25       ` Kevin O'Connor
2011-12-22 17:41         ` Anthony Liguori
2011-12-22 18:00           ` Kevin O'Connor
2011-12-22 19:57             ` Anthony Liguori
2012-01-02 23:01               ` Andreas Färber
2012-01-03  0:56                 ` Anthony Liguori
2011-12-22 20:25         ` Paolo Bonzini
2012-01-02 17:59   ` Paolo Bonzini
2012-01-03  1:18     ` Anthony Liguori
2012-01-03  8:57       ` Paolo Bonzini
2011-12-20 16:51 ` [Qemu-devel] [PATCH 02/27] qdev: integrate with QEMU Object Model Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 03/27] qdev: move qdev->info to class Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 04/27] qdev: don't access name through info Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 05/27] qdev: use a wrapper to access reset and promote reset to a class method Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 06/27] pci: check for an initialized QOM object instead of looking for an info link Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 07/27] qdev: add a interface to register subclasses Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 08/27] qdev: add class_init to DeviceInfo Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 09/27] qdev: prepare source tree for code conversion Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 10/27] not-for-upstream: disable non-qdev pci devices Anthony Liguori
2012-01-02 22:55   ` Andreas Färber
2012-01-03  0:55     ` Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 11/27] isa: convert to QEMU Object Model Anthony Liguori
2011-12-20 16:51 ` Anthony Liguori [this message]
2011-12-20 16:51 ` [Qemu-devel] [PATCH 13/27] ccid: " Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 14/27] ssi: " Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 15/27] i2c: rename i2c_slave -> I2CSlave Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 16/27] i2c: smbus: convert to QEMU Object Model Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 17/27] hda-codec: " Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 18/27] ide: " Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 19/27] scsi: " Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 20/27] not-for-upstream: spapr: break default console Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 21/27] spapr: convert to QEMU Object Model Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 22/27] not-for-upstream: virtio-serial: stub out a strange hack Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 23/27] virtio-serial: convert to QEMU Object Model Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 24/27] grackle: remove broken pci device Anthony Liguori
2012-01-02 22:41   ` Andreas Färber
2012-01-03  0:53     ` Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 25/27] unin_pci: remove phantom qdev devices in unin_pci Anthony Liguori
2012-01-02 22:44   ` Andreas Färber
2011-12-20 16:51 ` [Qemu-devel] [PATCH 26/27] pci: convert to QEMU Object Model Anthony Liguori
2011-12-20 16:51 ` [Qemu-devel] [PATCH 27/27] sysbus: " Anthony Liguori
2011-12-20 16:55 ` [Qemu-devel] [PATCH 00/27] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1324399916-21315-13-git-send-email-aliguori@us.ibm.com \
    --to=aliguori@us.ibm.com \
    --cc=armbru@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.