diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index 67deffebcf..f092bb8496 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -361,6 +361,9 @@ typedef struct USBAudioState { uint32_t buffer; } USBAudioState; +#define TYPE_USB_AUDIO "usb-audio" +#define USB_AUDIO(obj) OBJECT_CHECK(USBAudioState, (obj), TYPE_USB_AUDIO) + static void output_callback(void *opaque, int avail) { USBAudioState *s = opaque; @@ -506,7 +509,7 @@ static void usb_audio_handle_control(USBDevice *dev, USBPacket *p, int request, int value, int index, int length, uint8_t *data) { - USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev); + USBAudioState *s = USB_AUDIO(dev); int ret = 0; if (s->debug) { @@ -565,7 +568,7 @@ fail: static void usb_audio_set_interface(USBDevice *dev, int iface, int old, int value) { - USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev); + USBAudioState *s = USB_AUDIO(dev); if (iface == 1) { usb_audio_set_output_altset(s, value); @@ -574,7 +577,7 @@ static void usb_audio_set_interface(USBDevice *dev, int iface, static void usb_audio_handle_reset(USBDevice *dev) { - USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev); + USBAudioState *s = USB_AUDIO(dev); if (s->debug) { fprintf(stderr, "usb-audio: reset\n"); @@ -615,7 +618,7 @@ static void usb_audio_handle_data(USBDevice *dev, USBPacket *p) static void usb_audio_handle_destroy(USBDevice *dev) { - USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev); + USBAudioState *s = USB_AUDIO(dev); if (s->debug) { fprintf(stderr, "usb-audio: destroy\n"); @@ -630,12 +633,12 @@ static void usb_audio_handle_destroy(USBDevice *dev) static void usb_audio_realize(USBDevice *dev, Error **errp) { - USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev); + USBAudioState *s = USB_AUDIO(dev); usb_desc_create_serial(dev); usb_desc_init(dev); s->dev.opaque = s; - AUD_register_card("usb-audio", &s->card); + AUD_register_card(TYPE_USB_AUDIO, &s->card); s->out.altset = ALTSET_OFF; s->out.mute = false; @@ -647,14 +650,14 @@ static void usb_audio_realize(USBDevice *dev, Error **errp) s->out.as.endianness = 0; streambuf_init(&s->out.buf, s->buffer); - s->out.voice = AUD_open_out(&s->card, s->out.voice, "usb-audio", + s->out.voice = AUD_open_out(&s->card, s->out.voice, TYPE_USB_AUDIO, s, output_callback, &s->out.as); AUD_set_volume_out(s->out.voice, s->out.mute, s->out.vol[0], s->out.vol[1]); AUD_set_active_out(s->out.voice, 0); } static const VMStateDescription vmstate_usb_audio = { - .name = "usb-audio", + .name = TYPE_USB_AUDIO, .unmigratable = 1, }; @@ -684,7 +687,7 @@ static void usb_audio_class_init(ObjectClass *klass, void *data) } static const TypeInfo usb_audio_info = { - .name = "usb-audio", + .name = TYPE_USB_AUDIO, .parent = TYPE_USB_DEVICE, .instance_size = sizeof(USBAudioState), .class_init = usb_audio_class_init, @@ -693,7 +696,7 @@ static const TypeInfo usb_audio_info = { static void usb_audio_register_types(void) { type_register_static(&usb_audio_info); - usb_legacy_register("usb-audio", "audio", NULL); + usb_legacy_register(TYPE_USB_AUDIO, "audio", NULL); } type_init(usb_audio_register_types) diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c index 9bf673057a..b19ec76b00 100644 --- a/hw/usb/dev-bluetooth.c +++ b/hw/usb/dev-bluetooth.c @@ -49,6 +49,9 @@ struct USBBtState { } outcmd, outacl, outsco; }; +#define TYPE_USB_BT "usb-bt-dongle" +#define USB_BT(obj) OBJECT_CHECK(struct USBBtState, (obj), TYPE_USB_BT) + #define USB_EVT_EP 1 #define USB_ACL_EP 2 #define USB_SCO_EP 3 @@ -503,7 +506,7 @@ static void usb_bt_handle_destroy(USBDevice *dev) static void usb_bt_realize(USBDevice *dev, Error **errp) { - struct USBBtState *s = DO_UPCAST(struct USBBtState, dev, dev); + struct USBBtState *s = USB_BT(dev); usb_desc_create_serial(dev); usb_desc_init(dev); @@ -523,7 +526,7 @@ static USBDevice *usb_bt_init(USBBus *bus, const char *cmdline) USBDevice *dev; struct USBBtState *s; HCIInfo *hci; - const char *name = "usb-bt-dongle"; + const char *name = TYPE_USB_BT; if (*cmdline) { hci = hci_init(cmdline); @@ -534,7 +537,7 @@ static USBDevice *usb_bt_init(USBBus *bus, const char *cmdline) return NULL; dev = usb_create(bus, name); - s = DO_UPCAST(struct USBBtState, dev, dev); + s = USB_BT(dev); s->hci = hci; return dev; } @@ -561,7 +564,7 @@ static void usb_bt_class_initfn(ObjectClass *klass, void *data) } static const TypeInfo bt_info = { - .name = "usb-bt-dongle", + .name = TYPE_USB_BT, .parent = TYPE_USB_DEVICE, .instance_size = sizeof(struct USBBtState), .class_init = usb_bt_class_initfn, @@ -570,7 +573,7 @@ static const TypeInfo bt_info = { static void usb_bt_register_types(void) { type_register_static(&bt_info); - usb_legacy_register("usb-bt-dongle", "bt", usb_bt_init); + usb_legacy_register(TYPE_USB_BT, "bt", usb_bt_init); } type_init(usb_bt_register_types) diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c index 507c9663c5..2e7dcd96cb 100644 --- a/hw/usb/dev-hid.c +++ b/hw/usb/dev-hid.c @@ -51,6 +51,9 @@ typedef struct USBHIDState { uint32_t head; } USBHIDState; +#define TYPE_USB_HID "usb-hid" +#define USB_HID(obj) OBJECT_CHECK(USBHIDState, (obj), TYPE_USB_HID) + enum { STR_MANUFACTURER = 1, STR_PRODUCT_MOUSE, @@ -564,7 +567,7 @@ static void usb_hid_changed(HIDState *hs) static void usb_hid_handle_reset(USBDevice *dev) { - USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + USBHIDState *us = USB_HID(dev); hid_reset(&us->hid); } @@ -572,7 +575,7 @@ static void usb_hid_handle_reset(USBDevice *dev) static void usb_hid_handle_control(USBDevice *dev, USBPacket *p, int request, int value, int index, int length, uint8_t *data) { - USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + USBHIDState *us = USB_HID(dev); HIDState *hs = &us->hid; int ret; @@ -651,7 +654,7 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p, static void usb_hid_handle_data(USBDevice *dev, USBPacket *p) { - USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + USBHIDState *us = USB_HID(dev); HIDState *hs = &us->hid; uint8_t buf[p->iov.size]; int len = 0; @@ -687,7 +690,7 @@ static void usb_hid_handle_data(USBDevice *dev, USBPacket *p) static void usb_hid_handle_destroy(USBDevice *dev) { - USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + USBHIDState *us = USB_HID(dev); hid_free(&us->hid); } @@ -696,7 +699,7 @@ static void usb_hid_initfn(USBDevice *dev, int kind, const USBDesc *usb1, const USBDesc *usb2, Error **errp) { - USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + USBHIDState *us = USB_HID(dev); switch (us->usb_version) { case 1: dev->usb_desc = usb1; @@ -784,6 +787,14 @@ static void usb_hid_class_initfn(ObjectClass *klass, void *data) uc->handle_attach = usb_desc_attach; } +static const TypeInfo usb_hid_type_info = { + .name = TYPE_USB_HID, + .parent = TYPE_USB_DEVICE, + .instance_size = sizeof(USBHIDState), + .abstract = true, + .class_init = usb_hid_class_initfn, +}; + static Property usb_tablet_properties[] = { DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2), DEFINE_PROP_STRING("display", USBHIDState, display), @@ -796,7 +807,6 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); - usb_hid_class_initfn(klass, data); uc->realize = usb_tablet_realize; uc->product_desc = "QEMU USB Tablet"; dc->vmsd = &vmstate_usb_ptr; @@ -806,8 +816,7 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data) static const TypeInfo usb_tablet_info = { .name = "usb-tablet", - .parent = TYPE_USB_DEVICE, - .instance_size = sizeof(USBHIDState), + .parent = TYPE_USB_HID, .class_init = usb_tablet_class_initfn, }; @@ -821,7 +830,6 @@ static void usb_mouse_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); - usb_hid_class_initfn(klass, data); uc->realize = usb_mouse_realize; uc->product_desc = "QEMU USB Mouse"; dc->vmsd = &vmstate_usb_ptr; @@ -831,8 +839,7 @@ static void usb_mouse_class_initfn(ObjectClass *klass, void *data) static const TypeInfo usb_mouse_info = { .name = "usb-mouse", - .parent = TYPE_USB_DEVICE, - .instance_size = sizeof(USBHIDState), + .parent = TYPE_USB_HID, .class_init = usb_mouse_class_initfn, }; @@ -847,7 +854,6 @@ static void usb_keyboard_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); - usb_hid_class_initfn(klass, data); uc->realize = usb_keyboard_realize; uc->product_desc = "QEMU USB Keyboard"; dc->vmsd = &vmstate_usb_kbd; @@ -857,13 +863,13 @@ static void usb_keyboard_class_initfn(ObjectClass *klass, void *data) static const TypeInfo usb_keyboard_info = { .name = "usb-kbd", - .parent = TYPE_USB_DEVICE, - .instance_size = sizeof(USBHIDState), + .parent = TYPE_USB_HID, .class_init = usb_keyboard_class_initfn, }; static void usb_hid_register_types(void) { + type_register_static(&usb_hid_type_info); type_register_static(&usb_tablet_info); usb_legacy_register("usb-tablet", "tablet", NULL); type_register_static(&usb_mouse_info); diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c index 0482f58719..c8c6855505 100644 --- a/hw/usb/dev-hub.c +++ b/hw/usb/dev-hub.c @@ -41,6 +41,9 @@ typedef struct USBHubState { USBHubPort ports[NUM_PORTS]; } USBHubState; +#define TYPE_USB_HUB "usb-hub" +#define USB_HUB(obj) OBJECT_CHECK(USBHubState, (obj), TYPE_USB_HUB) + #define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE) #define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE) #define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR) @@ -227,7 +230,7 @@ static void usb_hub_complete(USBPort *port, USBPacket *packet) static USBDevice *usb_hub_find_device(USBDevice *dev, uint8_t addr) { - USBHubState *s = DO_UPCAST(USBHubState, dev, dev); + USBHubState *s = USB_HUB(dev); USBHubPort *port; USBDevice *downstream; int i; @@ -247,7 +250,7 @@ static USBDevice *usb_hub_find_device(USBDevice *dev, uint8_t addr) static void usb_hub_handle_reset(USBDevice *dev) { - USBHubState *s = DO_UPCAST(USBHubState, dev, dev); + USBHubState *s = USB_HUB(dev); USBHubPort *port; int i; @@ -513,7 +516,7 @@ static USBPortOps usb_hub_port_ops = { static void usb_hub_realize(USBDevice *dev, Error **errp) { - USBHubState *s = DO_UPCAST(USBHubState, dev, dev); + USBHubState *s = USB_HUB(dev); USBHubPort *port; int i; @@ -577,7 +580,7 @@ static void usb_hub_class_initfn(ObjectClass *klass, void *data) } static const TypeInfo hub_info = { - .name = "usb-hub", + .name = TYPE_USB_HUB, .parent = TYPE_USB_DEVICE, .instance_size = sizeof(USBHubState), .class_init = usb_hub_class_initfn, diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 108ece8190..809b1cb118 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -130,6 +130,9 @@ struct MTPState { QTAILQ_HEAD(, MTPObject) objects; }; +#define TYPE_USB_MTP "usb-mtp" +#define USB_MTP(obj) OBJECT_CHECK(MTPState, (obj), TYPE_USB_MTP) + #define QEMU_STORAGE_ID 0x00010001 #define MTP_FLAG_WRITABLE 0 @@ -878,7 +881,7 @@ static void usb_mtp_command(MTPState *s, MTPControl *c) static void usb_mtp_handle_reset(USBDevice *dev) { - MTPState *s = DO_UPCAST(MTPState, dev, dev); + MTPState *s = USB_MTP(dev); trace_usb_mtp_reset(s->dev.addr); @@ -914,7 +917,7 @@ static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p) static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p) { - MTPState *s = DO_UPCAST(MTPState, dev, dev); + MTPState *s = USB_MTP(dev); MTPControl cmd; mtp_container container; uint32_t params[5]; @@ -1062,12 +1065,16 @@ static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p) static void usb_mtp_realize(USBDevice *dev, Error **errp) { - MTPState *s = DO_UPCAST(MTPState, dev, dev); + MTPState *s = USB_MTP(dev); usb_desc_create_serial(dev); usb_desc_init(dev); QTAILQ_INIT(&s->objects); if (s->desc == NULL) { + if (s->root == NULL) { + error_setg(errp, "usb-mtp: x-root property must be configured"); + return; + } s->desc = strrchr(s->root, '/'); if (s->desc && s->desc[0]) { s->desc = g_strdup(s->desc + 1); @@ -1113,7 +1120,7 @@ static void usb_mtp_class_initfn(ObjectClass *klass, void *data) } static TypeInfo mtp_info = { - .name = "usb-mtp", + .name = TYPE_USB_MTP, .parent = TYPE_USB_DEVICE, .instance_size = sizeof(MTPState), .class_init = usb_mtp_class_initfn, diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c index 18669917f5..743c231d6b 100644 --- a/hw/usb/dev-network.c +++ b/hw/usb/dev-network.c @@ -648,6 +648,9 @@ typedef struct USBNetState { QTAILQ_HEAD(rndis_resp_head, rndis_response) rndis_resp; } USBNetState; +#define TYPE_USB_NET "usb-net" +#define USB_NET(obj) OBJECT_CHECK(USBNetState, (obj), TYPE_USB_NET) + static int is_rndis(USBNetState *s) { return s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE; @@ -1310,6 +1313,10 @@ static int usbnet_can_receive(NetClientState *nc) { USBNetState *s = qemu_get_nic_opaque(nc); + if (!s->dev.config) { + return 0; + } + if (is_rndis(s) && s->rndis_state != RNDIS_DATA_INITIALIZED) { return 1; } @@ -1343,7 +1350,7 @@ static NetClientInfo net_usbnet_info = { static void usb_net_realize(USBDevice *dev, Error **errrp) { - USBNetState *s = DO_UPCAST(USBNetState, dev, dev); + USBNetState *s = USB_NET(dev); usb_desc_create_serial(dev); usb_desc_init(dev); @@ -1376,7 +1383,7 @@ static void usb_net_realize(USBDevice *dev, Error **errrp) static void usb_net_instance_init(Object *obj) { USBDevice *dev = USB_DEVICE(obj); - USBNetState *s = DO_UPCAST(USBNetState, dev, dev); + USBNetState *s = USB_NET(dev); device_add_bootindex_property(obj, &s->conf.bootindex, "bootindex", "/ethernet-phy@0", @@ -1437,7 +1444,7 @@ static void usb_net_class_initfn(ObjectClass *klass, void *data) } static const TypeInfo net_info = { - .name = "usb-net", + .name = TYPE_USB_NET, .parent = TYPE_USB_DEVICE, .instance_size = sizeof(USBNetState), .class_init = usb_net_class_initfn, @@ -1447,7 +1454,7 @@ static const TypeInfo net_info = { static void usb_net_register_types(void) { type_register_static(&net_info); - usb_legacy_register("usb-net", "net", usb_net_init); + usb_legacy_register(TYPE_USB_NET, "net", usb_net_init); } type_init(usb_net_register_types) diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index 67c2072ce7..6ca3da9727 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -103,6 +103,9 @@ typedef struct { CharDriverState *cs; } USBSerialState; +#define TYPE_USB_SERIAL "usb-serial-dev" +#define USB_SERIAL_DEV(obj) OBJECT_CHECK(USBSerialState, (obj), TYPE_USB_SERIAL) + enum { STR_MANUFACTURER = 1, STR_PRODUCT_SERIAL, @@ -473,7 +476,7 @@ static void usb_serial_event(void *opaque, int event) static void usb_serial_realize(USBDevice *dev, Error **errp) { - USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev); + USBSerialState *s = USB_SERIAL_DEV(dev); Error *local_err = NULL; usb_desc_create_serial(dev); @@ -576,26 +579,40 @@ static Property serial_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void usb_serial_dev_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + USBDeviceClass *uc = USB_DEVICE_CLASS(klass); + + uc->realize = usb_serial_realize; + uc->handle_reset = usb_serial_handle_reset; + uc->handle_control = usb_serial_handle_control; + uc->handle_data = usb_serial_handle_data; + dc->vmsd = &vmstate_usb_serial; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + +static const TypeInfo usb_serial_dev_type_info = { + .name = TYPE_USB_SERIAL, + .parent = TYPE_USB_DEVICE, + .instance_size = sizeof(USBSerialState), + .abstract = true, + .class_init = usb_serial_dev_class_init, +}; + static void usb_serial_class_initfn(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); - uc->realize = usb_serial_realize; uc->product_desc = "QEMU USB Serial"; uc->usb_desc = &desc_serial; - uc->handle_reset = usb_serial_handle_reset; - uc->handle_control = usb_serial_handle_control; - uc->handle_data = usb_serial_handle_data; - dc->vmsd = &vmstate_usb_serial; dc->props = serial_properties; - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } static const TypeInfo serial_info = { .name = "usb-serial", - .parent = TYPE_USB_DEVICE, - .instance_size = sizeof(USBSerialState), + .parent = TYPE_USB_SERIAL, .class_init = usb_serial_class_initfn, }; @@ -609,26 +626,20 @@ static void usb_braille_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); - uc->realize = usb_serial_realize; uc->product_desc = "QEMU USB Braille"; uc->usb_desc = &desc_braille; - uc->handle_reset = usb_serial_handle_reset; - uc->handle_control = usb_serial_handle_control; - uc->handle_data = usb_serial_handle_data; - dc->vmsd = &vmstate_usb_serial; dc->props = braille_properties; - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } static const TypeInfo braille_info = { .name = "usb-braille", - .parent = TYPE_USB_DEVICE, - .instance_size = sizeof(USBSerialState), + .parent = TYPE_USB_SERIAL, .class_init = usb_braille_class_initfn, }; static void usb_serial_register_types(void) { + type_register_static(&usb_serial_dev_type_info); type_register_static(&serial_info); usb_legacy_register("usb-serial", "serial", usb_serial_init); type_register_static(&braille_info); diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c index 78ce681671..2d29367ae7 100644 --- a/hw/usb/dev-smartcard-reader.c +++ b/hw/usb/dev-smartcard-reader.c @@ -55,7 +55,7 @@ do { \ #define D_VERBOSE 4 #define CCID_DEV_NAME "usb-ccid" - +#define USB_CCID_DEV(obj) OBJECT_CHECK(USBCCIDState, (obj), CCID_DEV_NAME) /* * The two options for variable sized buffers: * make them constant size, for large enough constant, @@ -649,7 +649,7 @@ static void ccid_detach(USBCCIDState *s) static void ccid_handle_reset(USBDevice *dev) { - USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev); + USBCCIDState *s = USB_CCID_DEV(dev); DPRINTF(s, 1, "Reset\n"); @@ -692,7 +692,7 @@ static const char *ccid_control_to_str(USBCCIDState *s, int request) static void ccid_handle_control(USBDevice *dev, USBPacket *p, int request, int value, int index, int length, uint8_t *data) { - USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev); + USBCCIDState *s = USB_CCID_DEV(dev); int ret; DPRINTF(s, 1, "%s: got control %s (%x), value %x\n", __func__, @@ -1104,7 +1104,7 @@ static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p) static void ccid_handle_data(USBDevice *dev, USBPacket *p) { - USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev); + USBCCIDState *s = USB_CCID_DEV(dev); uint8_t buf[2]; switch (p->pid) { @@ -1148,7 +1148,7 @@ static void ccid_handle_data(USBDevice *dev, USBPacket *p) static void ccid_handle_destroy(USBDevice *dev) { - USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev); + USBCCIDState *s = USB_CCID_DEV(dev); ccid_bulk_in_clear(s); } @@ -1184,8 +1184,9 @@ static const TypeInfo ccid_bus_info = { void ccid_card_send_apdu_to_guest(CCIDCardState *card, uint8_t *apdu, uint32_t len) { - USBCCIDState *s = DO_UPCAST(USBCCIDState, dev.qdev, - card->qdev.parent_bus->parent); + DeviceState *qdev = DEVICE(card); + USBDevice *dev = USB_DEVICE(qdev); + USBCCIDState *s = USB_CCID_DEV(dev); Answer *answer; if (!ccid_has_pending_answers(s)) { @@ -1206,8 +1207,9 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card, void ccid_card_card_removed(CCIDCardState *card) { - USBCCIDState *s = - DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent); + DeviceState *qdev = DEVICE(card); + USBDevice *dev = USB_DEVICE(qdev); + USBCCIDState *s = USB_CCID_DEV(dev); ccid_on_slot_change(s, false); ccid_flush_pending_answers(s); @@ -1216,8 +1218,9 @@ void ccid_card_card_removed(CCIDCardState *card) int ccid_card_ccid_attach(CCIDCardState *card) { - USBCCIDState *s = - DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent); + DeviceState *qdev = DEVICE(card); + USBDevice *dev = USB_DEVICE(qdev); + USBCCIDState *s = USB_CCID_DEV(dev); DPRINTF(s, 1, "CCID Attach\n"); if (s->migration_state == MIGRATION_MIGRATED) { @@ -1228,8 +1231,9 @@ int ccid_card_ccid_attach(CCIDCardState *card) void ccid_card_ccid_detach(CCIDCardState *card) { - USBCCIDState *s = - DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent); + DeviceState *qdev = DEVICE(card); + USBDevice *dev = USB_DEVICE(qdev); + USBCCIDState *s = USB_CCID_DEV(dev); DPRINTF(s, 1, "CCID Detach\n"); if (ccid_card_inserted(s)) { @@ -1240,8 +1244,9 @@ void ccid_card_ccid_detach(CCIDCardState *card) void ccid_card_card_error(CCIDCardState *card, uint64_t error) { - USBCCIDState *s = - DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent); + DeviceState *qdev = DEVICE(card); + USBDevice *dev = USB_DEVICE(qdev); + USBCCIDState *s = USB_CCID_DEV(dev); s->bmCommandStatus = COMMAND_STATUS_FAILED; s->last_answer_error = error; @@ -1258,8 +1263,9 @@ void ccid_card_card_error(CCIDCardState *card, uint64_t error) void ccid_card_card_inserted(CCIDCardState *card) { - USBCCIDState *s = - DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent); + DeviceState *qdev = DEVICE(card); + USBDevice *dev = USB_DEVICE(qdev); + USBCCIDState *s = USB_CCID_DEV(dev); s->bmCommandStatus = COMMAND_STATUS_NO_ERROR; ccid_flush_pending_answers(s); @@ -1270,8 +1276,8 @@ static int ccid_card_exit(DeviceState *qdev) { int ret = 0; CCIDCardState *card = CCID_CARD(qdev); - USBCCIDState *s = - DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent); + USBDevice *dev = USB_DEVICE(qdev); + USBCCIDState *s = USB_CCID_DEV(dev); if (ccid_card_inserted(s)) { ccid_card_card_removed(card); @@ -1284,8 +1290,8 @@ static int ccid_card_exit(DeviceState *qdev) static int ccid_card_init(DeviceState *qdev) { CCIDCardState *card = CCID_CARD(qdev); - USBCCIDState *s = - DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent); + USBDevice *dev = USB_DEVICE(qdev); + USBCCIDState *s = USB_CCID_DEV(dev); int ret = 0; if (card->slot != 0) { @@ -1306,7 +1312,7 @@ static int ccid_card_init(DeviceState *qdev) static void ccid_realize(USBDevice *dev, Error **errp) { - USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev); + USBCCIDState *s = USB_CCID_DEV(dev); usb_desc_create_serial(dev); usb_desc_init(dev); diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index ae8d40dc77..abe0e1d6a1 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -64,6 +64,9 @@ typedef struct { SCSIDevice *scsi_dev; } MSDState; +#define TYPE_USB_STORAGE "usb-storage-dev" +#define USB_STORAGE_DEV(obj) OBJECT_CHECK(MSDState, (obj), TYPE_USB_STORAGE) + struct usb_msd_cbw { uint32_t sig; uint32_t tag; @@ -385,7 +388,7 @@ static void usb_msd_handle_control(USBDevice *dev, USBPacket *p, static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p) { - MSDState *s = DO_UPCAST(MSDState, dev, dev); + MSDState *s = USB_STORAGE_DEV(dev); assert(s->packet == p); s->packet = NULL; @@ -599,7 +602,7 @@ static const struct SCSIBusInfo usb_msd_scsi_info_bot = { static void usb_msd_realize_storage(USBDevice *dev, Error **errp) { - MSDState *s = DO_UPCAST(MSDState, dev, dev); + MSDState *s = USB_STORAGE_DEV(dev); BlockBackend *blk = s->conf.blk; SCSIDevice *scsi_dev; Error *err = NULL; @@ -658,7 +661,7 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp) static void usb_msd_realize_bot(USBDevice *dev, Error **errp) { - MSDState *s = DO_UPCAST(MSDState, dev, dev); + MSDState *s = USB_STORAGE_DEV(dev); usb_desc_create_serial(dev); usb_desc_init(dev); @@ -748,7 +751,7 @@ static Property msd_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void usb_msd_class_initfn_common(ObjectClass *klass) +static void usb_msd_class_initfn_common(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); @@ -772,14 +775,13 @@ static void usb_msd_class_initfn_storage(ObjectClass *klass, void *data) uc->realize = usb_msd_realize_storage; dc->props = msd_properties; - usb_msd_class_initfn_common(klass); } static void usb_msd_get_bootindex(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { USBDevice *dev = USB_DEVICE(obj); - MSDState *s = DO_UPCAST(MSDState, dev, dev); + MSDState *s = USB_STORAGE_DEV(dev); visit_type_int32(v, &s->conf.bootindex, name, errp); } @@ -788,7 +790,7 @@ static void usb_msd_set_bootindex(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { USBDevice *dev = USB_DEVICE(obj); - MSDState *s = DO_UPCAST(MSDState, dev, dev); + MSDState *s = USB_STORAGE_DEV(dev); int32_t boot_index; Error *local_err = NULL; @@ -815,6 +817,14 @@ out: } } +static const TypeInfo usb_storage_dev_type_info = { + .name = TYPE_USB_STORAGE, + .parent = TYPE_USB_DEVICE, + .instance_size = sizeof(MSDState), + .abstract = true, + .class_init = usb_msd_class_initfn_common, +}; + static void usb_msd_instance_init(Object *obj) { object_property_add(obj, "bootindex", "int32", @@ -829,27 +839,25 @@ static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); uc->realize = usb_msd_realize_bot; - usb_msd_class_initfn_common(klass); dc->hotpluggable = false; } static const TypeInfo msd_info = { .name = "usb-storage", - .parent = TYPE_USB_DEVICE, - .instance_size = sizeof(MSDState), + .parent = TYPE_USB_STORAGE, .class_init = usb_msd_class_initfn_storage, .instance_init = usb_msd_instance_init, }; static const TypeInfo bot_info = { .name = "usb-bot", - .parent = TYPE_USB_DEVICE, - .instance_size = sizeof(MSDState), + .parent = TYPE_USB_STORAGE, .class_init = usb_msd_class_initfn_bot, }; static void usb_msd_register_types(void) { + type_register_static(&usb_storage_dev_type_info); type_register_static(&msd_info); type_register_static(&bot_info); usb_legacy_register("usb-storage", "disk", usb_msd_init); diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c index 04fc515dbe..38b26c586d 100644 --- a/hw/usb/dev-uas.c +++ b/hw/usb/dev-uas.c @@ -127,6 +127,9 @@ struct UASDevice { USBPacket *status3[UAS_MAX_STREAMS + 1]; }; +#define TYPE_USB_UAS "usb-uas" +#define USB_UAS(obj) OBJECT_CHECK(UASDevice, (obj), TYPE_USB_UAS) + struct UASRequest { uint16_t tag; uint64_t lun; @@ -626,7 +629,7 @@ static const struct SCSIBusInfo usb_uas_scsi_info = { static void usb_uas_handle_reset(USBDevice *dev) { - UASDevice *uas = DO_UPCAST(UASDevice, dev, dev); + UASDevice *uas = USB_UAS(dev); UASRequest *req, *nreq; UASStatus *st, *nst; @@ -655,7 +658,7 @@ static void usb_uas_handle_control(USBDevice *dev, USBPacket *p, static void usb_uas_cancel_io(USBDevice *dev, USBPacket *p) { - UASDevice *uas = DO_UPCAST(UASDevice, dev, dev); + UASDevice *uas = USB_UAS(dev); UASRequest *req, *nreq; int i; @@ -797,7 +800,7 @@ incorrect_lun: static void usb_uas_handle_data(USBDevice *dev, USBPacket *p) { - UASDevice *uas = DO_UPCAST(UASDevice, dev, dev); + UASDevice *uas = USB_UAS(dev); uas_iu iu; UASStatus *st; UASRequest *req; @@ -888,14 +891,14 @@ static void usb_uas_handle_data(USBDevice *dev, USBPacket *p) static void usb_uas_handle_destroy(USBDevice *dev) { - UASDevice *uas = DO_UPCAST(UASDevice, dev, dev); + UASDevice *uas = USB_UAS(dev); qemu_bh_delete(uas->status_bh); } static void usb_uas_realize(USBDevice *dev, Error **errp) { - UASDevice *uas = DO_UPCAST(UASDevice, dev, dev); + UASDevice *uas = USB_UAS(dev); usb_desc_create_serial(dev); usb_desc_init(dev); @@ -943,7 +946,7 @@ static void usb_uas_class_initfn(ObjectClass *klass, void *data) } static const TypeInfo uas_info = { - .name = "usb-uas", + .name = TYPE_USB_UAS, .parent = TYPE_USB_DEVICE, .instance_size = sizeof(UASDevice), .class_init = usb_uas_class_initfn, diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c index 844eafadf7..c2450e7297 100644 --- a/hw/usb/dev-wacom.c +++ b/hw/usb/dev-wacom.c @@ -56,6 +56,9 @@ typedef struct USBWacomState { int changed; } USBWacomState; +#define TYPE_USB_WACOM "usb-wacom-tablet" +#define USB_WACOM(obj) OBJECT_CHECK(USBWacomState, (obj), TYPE_USB_WACOM) + enum { STR_MANUFACTURER = 1, STR_PRODUCT, @@ -337,7 +340,7 @@ static void usb_wacom_handle_destroy(USBDevice *dev) static void usb_wacom_realize(USBDevice *dev, Error **errp) { - USBWacomState *s = DO_UPCAST(USBWacomState, dev, dev); + USBWacomState *s = USB_WACOM(dev); usb_desc_create_serial(dev); usb_desc_init(dev); s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); @@ -367,7 +370,7 @@ static void usb_wacom_class_init(ObjectClass *klass, void *data) } static const TypeInfo wacom_info = { - .name = "usb-wacom-tablet", + .name = TYPE_USB_WACOM, .parent = TYPE_USB_DEVICE, .instance_size = sizeof(USBWacomState), .class_init = usb_wacom_class_init, @@ -376,7 +379,7 @@ static const TypeInfo wacom_info = { static void usb_wacom_register_types(void) { type_register_static(&wacom_info); - usb_legacy_register("usb-wacom-tablet", "wacom-tablet", NULL); + usb_legacy_register(TYPE_USB_WACOM, "wacom-tablet", NULL); } type_init(usb_wacom_register_types) diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 327f26da70..3f0ed62689 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -154,6 +154,9 @@ static void uhci_async_cancel(UHCIAsync *async); static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td); static void uhci_resume(void *opaque); +#define TYPE_UHCI "pci-uhci-usb" +#define UHCI(obj) OBJECT_CHECK(UHCIState, (obj), TYPE_UHCI) + static inline int32_t uhci_queue_token(UHCI_TD *td) { if ((td->token & (0xf << 15)) == 0) { @@ -351,7 +354,7 @@ static void uhci_update_irq(UHCIState *s) static void uhci_reset(DeviceState *dev) { PCIDevice *d = PCI_DEVICE(dev); - UHCIState *s = DO_UPCAST(UHCIState, dev, d); + UHCIState *s = UHCI(d); uint8_t *pci_conf; int i; UHCIPort *port; @@ -363,7 +366,7 @@ static void uhci_reset(DeviceState *dev) pci_conf[0x6a] = 0x01; /* usb clock */ pci_conf[0x6b] = 0x00; s->cmd = 0; - s->status = 0; + s->status = UHCI_STS_HCHALTED; s->status2 = 0; s->intr = 0; s->fl_base_addr = 0; @@ -1196,7 +1199,7 @@ static void usb_uhci_common_realize(PCIDevice *dev, Error **errp) Error *err = NULL; PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); UHCIPCIDeviceClass *u = container_of(pc, UHCIPCIDeviceClass, parent_class); - UHCIState *s = DO_UPCAST(UHCIState, dev, dev); + UHCIState *s = UHCI(dev); uint8_t *pci_conf = s->dev.config; int i; @@ -1241,7 +1244,7 @@ static void usb_uhci_common_realize(PCIDevice *dev, Error **errp) static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp) { - UHCIState *s = DO_UPCAST(UHCIState, dev, dev); + UHCIState *s = UHCI(dev); uint8_t *pci_conf = s->dev.config; /* USB misc control 1/2 */ @@ -1256,7 +1259,7 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp) static void usb_uhci_exit(PCIDevice *dev) { - UHCIState *s = DO_UPCAST(UHCIState, dev, dev); + UHCIState *s = UHCI(dev); trace_usb_uhci_exit(); @@ -1294,6 +1297,26 @@ static void uhci_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->class_id = PCI_CLASS_SERIAL_USB; + dc->vmsd = &vmstate_uhci; + dc->reset = uhci_reset; + set_bit(DEVICE_CATEGORY_USB, dc->categories); +} + +static const TypeInfo uhci_pci_type_info = { + .name = TYPE_UHCI, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(UHCIState), + .class_size = sizeof(UHCIPCIDeviceClass), + .abstract = true, + .class_init = uhci_class_init, +}; + +static void uhci_data_class_init(ObjectClass *klass, void *data) +{ + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); UHCIPCIDeviceClass *u = container_of(k, UHCIPCIDeviceClass, parent_class); UHCIInfo *info = data; @@ -1302,9 +1325,6 @@ static void uhci_class_init(ObjectClass *klass, void *data) k->vendor_id = info->vendor_id; k->device_id = info->device_id; k->revision = info->revision; - k->class_id = PCI_CLASS_SERIAL_USB; - dc->vmsd = &vmstate_uhci; - dc->reset = uhci_reset; if (!info->unplug) { /* uhci controllers in companion setups can't be hotplugged */ dc->hotpluggable = false; @@ -1312,7 +1332,6 @@ static void uhci_class_init(ObjectClass *klass, void *data) } else { dc->props = uhci_properties_standalone; } - set_bit(DEVICE_CATEGORY_USB, dc->categories); u->info = *info; } @@ -1387,13 +1406,13 @@ static UHCIInfo uhci_info[] = { static void uhci_register_types(void) { TypeInfo uhci_type_info = { - .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(UHCIState), - .class_size = sizeof(UHCIPCIDeviceClass), - .class_init = uhci_class_init, + .parent = TYPE_UHCI, + .class_init = uhci_data_class_init, }; int i; + type_register_static(&uhci_pci_type_info); + for (i = 0; i < ARRAY_SIZE(uhci_info); i++) { uhci_type_info.name = uhci_info[i].name; uhci_type_info.class_data = uhci_info + i; diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index ba15ae0019..927dc3652f 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1767,18 +1767,9 @@ static void xhci_xfer_report(XHCITransfer *xfer) break; } - /* - * XHCI 1.1, 4.11.3.1 Transfer Event TRB -- "each Transfer TRB - * encountered with its IOC flag set to '1' shall generate a Transfer - * Event." - * - * Otherwise, longer transfers can have multiple data TRBs (for scatter - * gather). Short transfers and errors should be reported once per - * transfer only. - */ - if ((trb->control & TRB_TR_IOC) || - (!reported && ((shortpkt && (trb->control & TRB_TR_ISP)) || - (xfer->status != CC_SUCCESS && left == 0)))) { + if (!reported && ((trb->control & TRB_TR_IOC) || + (shortpkt && (trb->control & TRB_TR_ISP)) || + (xfer->status != CC_SUCCESS && left == 0))) { event.slotid = xfer->slotid; event.epid = xfer->epid; event.length = (trb->status & 0x1ffff) - chunk; @@ -1802,6 +1793,14 @@ static void xhci_xfer_report(XHCITransfer *xfer) return; } } + + switch (TRB_TYPE(*trb)) { + case TR_SETUP: + reported = 0; + shortpkt = 0; + break; + } + } } @@ -2224,6 +2223,8 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, if (xfer->running_retry) { DPRINTF("xhci: xfer nacked, stopping schedule\n"); epctx->retry = xfer; + timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + epctx->interval * 125000); break; } } diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 2416de83e9..242a654583 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -130,6 +130,9 @@ struct USBRedirDevice { int compatible_speedmask; }; +#define TYPE_USB_REDIR "usb-redir" +#define USB_REDIRECT(obj) OBJECT_CHECK(USBRedirDevice, (obj), TYPE_USB_REDIR) + static void usbredir_hello(void *priv, struct usb_redir_hello_header *h); static void usbredir_device_connect(void *priv, struct usb_redir_device_connect_header *device_connect); @@ -360,7 +363,7 @@ static void packet_id_queue_empty(struct PacketIdQueue *q) static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p) { - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); int i = USBEP2I(p->ep); if (p->combined) { @@ -500,7 +503,7 @@ static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep) static void usbredir_handle_reset(USBDevice *udev) { - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); DPRINTF("reset device\n"); usbredirparser_send_reset(dev->parser); @@ -907,7 +910,7 @@ static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev, static void usbredir_handle_data(USBDevice *udev, USBPacket *p) { - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); uint8_t ep; ep = p->ep->nr; @@ -976,7 +979,7 @@ static void usbredir_stop_ep(USBRedirDevice *dev, int i) static void usbredir_ep_stopped(USBDevice *udev, USBEndpoint *uep) { - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); usbredir_stop_ep(dev, USBEP2I(uep)); usbredirparser_do_write(dev->parser); @@ -1046,7 +1049,7 @@ static void usbredir_get_interface(USBRedirDevice *dev, USBPacket *p, static void usbredir_handle_control(USBDevice *udev, USBPacket *p, int request, int value, int index, int length, uint8_t *data) { - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); struct usb_redir_control_packet_header control_packet; if (usbredir_already_in_flight(dev, p->id)) { @@ -1101,7 +1104,7 @@ static void usbredir_handle_control(USBDevice *udev, USBPacket *p, static int usbredir_alloc_streams(USBDevice *udev, USBEndpoint **eps, int nr_eps, int streams) { - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); #if USBREDIR_VERSION >= 0x000700 struct usb_redir_alloc_bulk_streams_header alloc_streams; int i; @@ -1140,7 +1143,7 @@ static void usbredir_free_streams(USBDevice *udev, USBEndpoint **eps, int nr_eps) { #if USBREDIR_VERSION >= 0x000700 - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); struct usb_redir_free_bulk_streams_header free_streams; int i; @@ -1362,7 +1365,7 @@ static void usbredir_init_endpoints(USBRedirDevice *dev) static void usbredir_realize(USBDevice *udev, Error **errp) { - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); int i; if (dev->cs == NULL) { @@ -1415,7 +1418,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev) static void usbredir_handle_destroy(USBDevice *udev) { - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); qemu_chr_delete(dev->cs); dev->cs = NULL; @@ -2496,7 +2499,7 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data) static void usbredir_instance_init(Object *obj) { USBDevice *udev = USB_DEVICE(obj); - USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + USBRedirDevice *dev = USB_REDIRECT(udev); device_add_bootindex_property(obj, &dev->bootindex, "bootindex", NULL, @@ -2504,7 +2507,7 @@ static void usbredir_instance_init(Object *obj) } static const TypeInfo usbredir_dev_info = { - .name = "usb-redir", + .name = TYPE_USB_REDIR, .parent = TYPE_USB_DEVICE, .instance_size = sizeof(USBRedirDevice), .class_init = usbredir_class_initfn,