提交 62aed765 编写于 作者: A Anthony Liguori

usb: convert to QEMU Object Model

Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>
上级 8f04ee08
...@@ -674,21 +674,27 @@ static const VMStateDescription vmstate_usb_audio = { ...@@ -674,21 +674,27 @@ static const VMStateDescription vmstate_usb_audio = {
.unmigratable = 1, .unmigratable = 1,
}; };
static struct USBDeviceInfo usb_audio_info = { static void usb_audio_class_init(ObjectClass *klass, void *data)
.product_desc = "QEMU USB Audio Interface", {
.usbdevice_name = "audio", USBDeviceClass *k = USB_DEVICE_CLASS(klass);
.qdev.name = "usb-audio",
.qdev.size = sizeof(USBAudioState), k->product_desc = "QEMU USB Audio Interface";
.qdev.vmsd = &vmstate_usb_audio, k->usb_desc = &desc_audio;
.usb_desc = &desc_audio, k->init = usb_audio_initfn;
.init = usb_audio_initfn, k->handle_packet = usb_generic_handle_packet;
.handle_packet = usb_generic_handle_packet, k->handle_reset = usb_audio_handle_reset;
.handle_reset = usb_audio_handle_reset, k->handle_control = usb_audio_handle_control;
.handle_control = usb_audio_handle_control, k->handle_data = usb_audio_handle_data;
.handle_data = usb_audio_handle_data, k->handle_destroy = usb_audio_handle_destroy;
.handle_destroy = usb_audio_handle_destroy, k->set_interface = usb_audio_set_interface;
.set_interface = usb_audio_set_interface, }
.qdev.props = (Property[]) {
static struct DeviceInfo usb_audio_info = {
.name = "usb-audio",
.size = sizeof(USBAudioState),
.vmsd = &vmstate_usb_audio,
.class_init = usb_audio_class_init,
.props = (Property[]) {
DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0), DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0),
DEFINE_PROP_UINT32("buffer", USBAudioState, buffer, DEFINE_PROP_UINT32("buffer", USBAudioState, buffer,
8 * USBAUDIO_PACKET_SIZE), 8 * USBAUDIO_PACKET_SIZE),
...@@ -698,7 +704,7 @@ static struct USBDeviceInfo usb_audio_info = { ...@@ -698,7 +704,7 @@ static struct USBDeviceInfo usb_audio_info = {
static void usb_audio_register_devices(void) static void usb_audio_register_devices(void)
{ {
usb_qdev_register(&usb_audio_info); usb_qdev_register(&usb_audio_info, "audio", NULL);
} }
device_init(usb_audio_register_devices) device_init(usb_audio_register_devices)
...@@ -527,22 +527,29 @@ static const VMStateDescription vmstate_usb_bt = { ...@@ -527,22 +527,29 @@ static const VMStateDescription vmstate_usb_bt = {
.unmigratable = 1, .unmigratable = 1,
}; };
static struct USBDeviceInfo bt_info = { static void usb_bt_class_initfn(ObjectClass *klass, void *data)
.product_desc = "QEMU BT dongle", {
.qdev.name = "usb-bt-dongle", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.size = sizeof(struct USBBtState),
.qdev.vmsd = &vmstate_usb_bt, uc->init = usb_bt_initfn;
.usb_desc = &desc_bluetooth, uc->product_desc = "QEMU BT dongle";
.init = usb_bt_initfn, uc->usb_desc = &desc_bluetooth;
.handle_packet = usb_generic_handle_packet, uc->handle_packet = usb_generic_handle_packet;
.handle_reset = usb_bt_handle_reset, uc->handle_reset = usb_bt_handle_reset;
.handle_control = usb_bt_handle_control, uc->handle_control = usb_bt_handle_control;
.handle_data = usb_bt_handle_data, uc->handle_data = usb_bt_handle_data;
.handle_destroy = usb_bt_handle_destroy, 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) 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) device_init(usb_bt_register_devices)
...@@ -65,14 +65,104 @@ USBBus *usb_bus_find(int busnr) ...@@ -65,14 +65,104 @@ USBBus *usb_bus_find(int busnr)
return NULL; 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;
}
void usb_device_set_interface(USBDevice *dev, int interface,
int alt_old, int alt_new)
{
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
if (klass->set_interface) {
klass->set_interface(dev, interface, alt_old, alt_new);
}
}
static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base) static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
{ {
USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev); USBDevice *dev = USB_DEVICE(qdev);
USBDeviceInfo *info = DO_UPCAST(USBDeviceInfo, qdev, base);
int rc; int rc;
pstrcpy(dev->product_desc, sizeof(dev->product_desc), info->product_desc); pstrcpy(dev->product_desc, sizeof(dev->product_desc),
dev->info = info; usb_device_get_product_desc(dev));
dev->auto_attach = 1; dev->auto_attach = 1;
QLIST_INIT(&dev->strings); QLIST_INIT(&dev->strings);
usb_ep_init(dev); usb_ep_init(dev);
...@@ -80,7 +170,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base) ...@@ -80,7 +170,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
if (rc != 0) { if (rc != 0) {
return rc; return rc;
} }
rc = dev->info->init(dev); rc = usb_device_init(dev);
if (rc != 0) { if (rc != 0) {
usb_release_port(dev); usb_release_port(dev);
return rc; return rc;
...@@ -97,34 +187,43 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base) ...@@ -97,34 +187,43 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
static int usb_qdev_exit(DeviceState *qdev) static int usb_qdev_exit(DeviceState *qdev)
{ {
USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev); USBDevice *dev = USB_DEVICE(qdev);
if (dev->attached) { if (dev->attached) {
usb_device_detach(dev); usb_device_detach(dev);
} }
if (dev->info->handle_destroy) { usb_device_handle_destroy(dev);
dev->info->handle_destroy(dev);
}
if (dev->port) { if (dev->port) {
usb_release_port(dev); usb_release_port(dev);
} }
return 0; return 0;
} }
void usb_qdev_register(USBDeviceInfo *info) typedef struct LegacyUSBFactory
{ {
info->qdev.bus_info = &usb_bus_info; const char *name;
info->qdev.init = usb_qdev_init; const char *usbdevice_name;
info->qdev.unplug = qdev_simple_unplug_cb; USBDevice *(*usbdevice_init)(const char *params);
info->qdev.exit = usb_qdev_exit; } LegacyUSBFactory;
qdev_register(&info->qdev);
}
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) { info->bus_info = &usb_bus_info;
usb_qdev_register(info); info->init = usb_qdev_init;
info++; 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);
} }
} }
...@@ -144,7 +243,7 @@ USBDevice *usb_create(USBBus *bus, const char *name) ...@@ -144,7 +243,7 @@ USBDevice *usb_create(USBBus *bus, const char *name)
#endif #endif
dev = qdev_create(&bus->qbus, name); 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) USBDevice *usb_create_simple(USBBus *bus, const char *name)
...@@ -365,7 +464,7 @@ static const char *usb_speed(unsigned int speed) ...@@ -365,7 +464,7 @@ static const char *usb_speed(unsigned int speed)
static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent) 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); USBBus *bus = usb_bus_from_device(dev);
monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n", monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
...@@ -377,13 +476,13 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent) ...@@ -377,13 +476,13 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
static char *usb_get_dev_path(DeviceState *qdev) 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); return g_strdup(dev->port->path);
} }
static char *usb_get_fw_dev_path(DeviceState *qdev) 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; char *fw_path, *in;
ssize_t pos = 0, fw_len; ssize_t pos = 0, fw_len;
long nr; long nr;
...@@ -434,8 +533,8 @@ void usb_info(Monitor *mon) ...@@ -434,8 +533,8 @@ void usb_info(Monitor *mon)
USBDevice *usbdevice_create(const char *cmdline) USBDevice *usbdevice_create(const char *cmdline)
{ {
USBBus *bus = usb_bus_find(-1 /* any */); USBBus *bus = usb_bus_find(-1 /* any */);
DeviceInfo *info; LegacyUSBFactory *f = NULL;
USBDeviceInfo *usb; GSList *i;
char driver[32]; char driver[32];
const char *params; const char *params;
int len; int len;
...@@ -452,17 +551,13 @@ USBDevice *usbdevice_create(const char *cmdline) ...@@ -452,17 +551,13 @@ USBDevice *usbdevice_create(const char *cmdline)
pstrcpy(driver, sizeof(driver), cmdline); pstrcpy(driver, sizeof(driver), cmdline);
} }
for (info = device_info_list; info != NULL; info = info->next) { for (i = legacy_usb_factory; i; i = i->next) {
if (info->bus_info != &usb_bus_info) f = i->data;
continue; if (strcmp(f->usbdevice_name, driver) == 0) {
usb = DO_UPCAST(USBDeviceInfo, qdev, info); break;
if (usb->usbdevice_name == NULL) }
continue;
if (strcmp(usb->usbdevice_name, driver) != 0)
continue;
break;
} }
if (info == NULL) { if (i == NULL) {
#if 0 #if 0
/* no error because some drivers are not converted (yet) */ /* no error because some drivers are not converted (yet) */
error_report("usbdevice %s not found", driver); error_report("usbdevice %s not found", driver);
...@@ -470,12 +565,27 @@ USBDevice *usbdevice_create(const char *cmdline) ...@@ -470,12 +565,27 @@ USBDevice *usbdevice_create(const char *cmdline)
return NULL; return NULL;
} }
if (!usb->usbdevice_init) { if (!f->usbdevice_init) {
if (*params) { if (*params) {
error_report("usbdevice %s accepts no params", driver); error_report("usbdevice %s accepts no params", driver);
return NULL; 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);
...@@ -1286,28 +1286,34 @@ static VMStateDescription ccid_vmstate = { ...@@ -1286,28 +1286,34 @@ static VMStateDescription ccid_vmstate = {
} }
}; };
static struct USBDeviceInfo ccid_info = { static void ccid_class_initfn(ObjectClass *klass, void *data)
.product_desc = "QEMU USB CCID", {
.qdev.name = CCID_DEV_NAME, USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.desc = "CCID Rev 1.1 smartcard reader",
.qdev.size = sizeof(USBCCIDState), uc->init = ccid_initfn;
.init = ccid_initfn, uc->product_desc = "QEMU USB CCID";
.usb_desc = &desc_ccid, uc->usb_desc = &desc_ccid;
.handle_packet = usb_generic_handle_packet, uc->handle_packet = usb_generic_handle_packet;
.handle_reset = ccid_handle_reset, uc->handle_reset = ccid_handle_reset;
.handle_control = ccid_handle_control, uc->handle_control = ccid_handle_control;
.handle_data = ccid_handle_data, uc->handle_data = ccid_handle_data;
.handle_destroy = ccid_handle_destroy, uc->handle_destroy = ccid_handle_destroy;
.usbdevice_name = "ccid", }
.qdev.props = (Property[]) {
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_UINT8("debug", USBCCIDState, debug, 0),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}, },
.qdev.vmsd = &ccid_vmstate,
}; };
static void ccid_register_devices(void) static void ccid_register_devices(void)
{ {
usb_qdev_register(&ccid_info); usb_qdev_register(&ccid_info, "ccid", NULL);
} }
device_init(ccid_register_devices) device_init(ccid_register_devices)
...@@ -297,8 +297,8 @@ static int usb_desc_set_interface(USBDevice *dev, int index, int value) ...@@ -297,8 +297,8 @@ static int usb_desc_set_interface(USBDevice *dev, int index, int value)
dev->ifaces[index] = iface; dev->ifaces[index] = iface;
usb_desc_ep_init(dev); usb_desc_ep_init(dev);
if (dev->info->set_interface && old != value) { if (old != value) {
dev->info->set_interface(dev, index, old, value); usb_device_set_interface(dev, index, old, value);
} }
return 0; return 0;
} }
...@@ -338,7 +338,7 @@ static int usb_desc_set_config(USBDevice *dev, int value) ...@@ -338,7 +338,7 @@ static int usb_desc_set_config(USBDevice *dev, int value)
static void usb_desc_setdefaults(USBDevice *dev) 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); assert(desc != NULL);
switch (dev->speed) { switch (dev->speed) {
...@@ -355,7 +355,7 @@ static void usb_desc_setdefaults(USBDevice *dev) ...@@ -355,7 +355,7 @@ static void usb_desc_setdefaults(USBDevice *dev)
void usb_desc_init(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); assert(desc != NULL);
dev->speed = USB_SPEED_FULL; dev->speed = USB_SPEED_FULL;
...@@ -371,7 +371,7 @@ void usb_desc_init(USBDevice *dev) ...@@ -371,7 +371,7 @@ void usb_desc_init(USBDevice *dev)
void usb_desc_attach(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); assert(desc != NULL);
if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) { if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) {
...@@ -380,7 +380,7 @@ void usb_desc_attach(USBDevice *dev) ...@@ -380,7 +380,7 @@ void usb_desc_attach(USBDevice *dev)
dev->speed = USB_SPEED_FULL; dev->speed = USB_SPEED_FULL;
} else { } else {
fprintf(stderr, "usb: port/device speed mismatch for \"%s\"\n", fprintf(stderr, "usb: port/device speed mismatch for \"%s\"\n",
dev->info->product_desc); usb_device_get_product_desc(dev));
return; return;
} }
usb_desc_setdefaults(dev); usb_desc_setdefaults(dev);
...@@ -436,7 +436,7 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len) ...@@ -436,7 +436,7 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len)
str = usb_desc_get_string(dev, index); str = usb_desc_get_string(dev, index);
if (str == NULL) { if (str == NULL) {
str = dev->info->usb_desc->str[index]; str = usb_device_get_usb_desc(dev)->str[index];
if (str == NULL) { if (str == NULL) {
return 0; return 0;
} }
...@@ -455,7 +455,7 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len) ...@@ -455,7 +455,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) 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; const USBDescDevice *other_dev;
uint8_t buf[256]; uint8_t buf[256];
uint8_t type = value >> 8; uint8_t type = value >> 8;
...@@ -463,9 +463,9 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len ...@@ -463,9 +463,9 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len
int ret = -1; int ret = -1;
if (dev->speed == USB_SPEED_HIGH) { if (dev->speed == USB_SPEED_HIGH) {
other_dev = dev->info->usb_desc->full; other_dev = usb_device_get_usb_desc(dev)->full;
} else { } else {
other_dev = dev->info->usb_desc->high; other_dev = usb_device_get_usb_desc(dev)->high;
} }
switch(type) { switch(type) {
...@@ -520,7 +520,7 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len ...@@ -520,7 +520,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 usb_desc_handle_control(USBDevice *dev, USBPacket *p,
int request, int value, int index, int length, uint8_t *data) 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 ret = -1; int ret = -1;
assert(desc != NULL); assert(desc != NULL);
......
...@@ -553,53 +553,73 @@ static const VMStateDescription vmstate_usb_kbd = { ...@@ -553,53 +553,73 @@ static const VMStateDescription vmstate_usb_kbd = {
} }
}; };
static struct USBDeviceInfo hid_info[] = { static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
{ {
.product_desc = "QEMU USB Tablet", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.name = "usb-tablet",
.usbdevice_name = "tablet", uc->init = usb_tablet_initfn;
.qdev.size = sizeof(USBHIDState), uc->product_desc = "QEMU USB Tablet";
.qdev.vmsd = &vmstate_usb_ptr, uc->usb_desc = &desc_tablet;
.usb_desc = &desc_tablet, uc->handle_packet = usb_generic_handle_packet;
.init = usb_tablet_initfn, uc->handle_reset = usb_hid_handle_reset;
.handle_packet = usb_generic_handle_packet, uc->handle_control = usb_hid_handle_control;
.handle_reset = usb_hid_handle_reset, uc->handle_data = usb_hid_handle_data;
.handle_control = usb_hid_handle_control, uc->handle_destroy = usb_hid_handle_destroy;
.handle_data = usb_hid_handle_data, }
.handle_destroy = usb_hid_handle_destroy,
},{ static struct DeviceInfo usb_tablet_info = {
.product_desc = "QEMU USB Mouse", .name = "usb-tablet",
.qdev.name = "usb-mouse", .size = sizeof(USBHIDState),
.usbdevice_name = "mouse", .vmsd = &vmstate_usb_ptr,
.qdev.size = sizeof(USBHIDState), .class_init= usb_tablet_class_initfn,
.qdev.vmsd = &vmstate_usb_ptr, };
.usb_desc = &desc_mouse,
.init = usb_mouse_initfn, static void usb_mouse_class_initfn(ObjectClass *klass, void *data)
.handle_packet = usb_generic_handle_packet, {
.handle_reset = usb_hid_handle_reset, USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.handle_control = usb_hid_handle_control,
.handle_data = usb_hid_handle_data, uc->init = usb_mouse_initfn;
.handle_destroy = usb_hid_handle_destroy, uc->product_desc = "QEMU USB Mouse";
},{ uc->usb_desc = &desc_mouse;
.product_desc = "QEMU USB Keyboard", uc->handle_packet = usb_generic_handle_packet;
.qdev.name = "usb-kbd", uc->handle_reset = usb_hid_handle_reset;
.usbdevice_name = "keyboard", uc->handle_control = usb_hid_handle_control;
.qdev.size = sizeof(USBHIDState), uc->handle_data = usb_hid_handle_data;
.qdev.vmsd = &vmstate_usb_kbd, uc->handle_destroy = usb_hid_handle_destroy;
.usb_desc = &desc_keyboard, }
.init = usb_keyboard_initfn,
.handle_packet = usb_generic_handle_packet, static struct DeviceInfo usb_mouse_info = {
.handle_reset = usb_hid_handle_reset, .name = "usb-mouse",
.handle_control = usb_hid_handle_control, .size = sizeof(USBHIDState),
.handle_data = usb_hid_handle_data, .vmsd = &vmstate_usb_ptr,
.handle_destroy = usb_hid_handle_destroy, .class_init= usb_mouse_class_initfn,
},{ };
/* end of list */
} 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) 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) device_init(usb_hid_register_devices)
...@@ -533,23 +533,30 @@ static const VMStateDescription vmstate_usb_hub = { ...@@ -533,23 +533,30 @@ static const VMStateDescription vmstate_usb_hub = {
} }
}; };
static struct USBDeviceInfo hub_info = { static void usb_hub_class_initfn(ObjectClass *klass, void *data)
.product_desc = "QEMU USB Hub", {
.qdev.name = "usb-hub", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.fw_name = "hub",
.qdev.size = sizeof(USBHubState), uc->init = usb_hub_initfn;
.qdev.vmsd = &vmstate_usb_hub, uc->product_desc = "QEMU USB Hub";
.usb_desc = &desc_hub, uc->usb_desc = &desc_hub;
.init = usb_hub_initfn, uc->handle_packet = usb_hub_handle_packet;
.handle_packet = usb_hub_handle_packet, uc->handle_reset = usb_hub_handle_reset;
.handle_reset = usb_hub_handle_reset, uc->handle_control = usb_hub_handle_control;
.handle_control = usb_hub_handle_control, uc->handle_data = usb_hub_handle_data;
.handle_data = usb_hub_handle_data, uc->handle_destroy = usb_hub_handle_destroy;
.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) 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) device_init(usb_hub_register_devices)
...@@ -636,23 +636,28 @@ static const VMStateDescription vmstate_usb_msd = { ...@@ -636,23 +636,28 @@ static const VMStateDescription vmstate_usb_msd = {
} }
}; };
static struct USBDeviceInfo msd_info = { static void usb_msd_class_initfn(ObjectClass *klass, void *data)
.product_desc = "QEMU USB MSD", {
.qdev.name = "usb-storage", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.fw_name = "storage",
.qdev.size = sizeof(MSDState), uc->init = usb_msd_initfn;
.qdev.vmsd = &vmstate_usb_msd, uc->product_desc = "QEMU USB MSD";
.usb_desc = &desc, uc->usb_desc = &desc;
.init = usb_msd_initfn, uc->handle_packet = usb_generic_handle_packet;
.handle_packet = usb_generic_handle_packet, uc->cancel_packet = usb_msd_cancel_io;
.cancel_packet = usb_msd_cancel_io, uc->handle_attach = usb_desc_attach;
.handle_attach = usb_desc_attach, uc->handle_reset = usb_msd_handle_reset;
.handle_reset = usb_msd_handle_reset, uc->handle_control = usb_msd_handle_control;
.handle_control = usb_msd_handle_control, uc->handle_data = usb_msd_handle_data;
.handle_data = usb_msd_handle_data, }
.usbdevice_name = "disk",
.usbdevice_init = usb_msd_init, static struct DeviceInfo msd_info = {
.qdev.props = (Property[]) { .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_BLOCK_PROPERTIES(MSDState, conf),
DEFINE_PROP_STRING("serial", MSDState, serial), DEFINE_PROP_STRING("serial", MSDState, serial),
DEFINE_PROP_BIT("removable", MSDState, removable, 0, false), DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
...@@ -662,6 +667,6 @@ static struct USBDeviceInfo msd_info = { ...@@ -662,6 +667,6 @@ static struct USBDeviceInfo msd_info = {
static void usb_msd_register_devices(void) 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) device_init(usb_msd_register_devices)
...@@ -1385,29 +1385,34 @@ static const VMStateDescription vmstate_usb_net = { ...@@ -1385,29 +1385,34 @@ static const VMStateDescription vmstate_usb_net = {
.unmigratable = 1, .unmigratable = 1,
}; };
static struct USBDeviceInfo net_info = { static void usb_net_class_initfn(ObjectClass *klass, void *data)
.product_desc = "QEMU USB Network Interface", {
.qdev.name = "usb-net", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.fw_name = "network",
.qdev.size = sizeof(USBNetState), uc->init = usb_net_initfn;
.qdev.vmsd = &vmstate_usb_net, uc->product_desc = "QEMU USB Network Interface";
.usb_desc = &desc_net, uc->usb_desc = &desc_net;
.init = usb_net_initfn, uc->handle_packet = usb_generic_handle_packet;
.handle_packet = usb_generic_handle_packet, uc->handle_reset = usb_net_handle_reset;
.handle_reset = usb_net_handle_reset, uc->handle_control = usb_net_handle_control;
.handle_control = usb_net_handle_control, uc->handle_data = usb_net_handle_data;
.handle_data = usb_net_handle_data, uc->handle_destroy = usb_net_handle_destroy;
.handle_destroy = usb_net_handle_destroy, }
.usbdevice_name = "net",
.usbdevice_init = usb_net_init, static struct DeviceInfo net_info = {
.qdev.props = (Property[]) { .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_NIC_PROPERTIES(USBNetState, conf),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
} },
}; };
static void usb_net_register_devices(void) 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) device_init(usb_net_register_devices)
...@@ -570,41 +570,51 @@ static const VMStateDescription vmstate_usb_serial = { ...@@ -570,41 +570,51 @@ static const VMStateDescription vmstate_usb_serial = {
.unmigratable = 1, .unmigratable = 1,
}; };
static struct USBDeviceInfo serial_info = { static void usb_serial_class_initfn(ObjectClass *klass, void *data)
.product_desc = "QEMU USB Serial", {
.qdev.name = "usb-serial", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.size = sizeof(USBSerialState),
.qdev.vmsd = &vmstate_usb_serial, uc->init = usb_serial_initfn;
.usb_desc = &desc_serial, uc->product_desc = "QEMU USB Serial";
.init = usb_serial_initfn, uc->usb_desc = &desc_serial;
.handle_packet = usb_generic_handle_packet, uc->handle_packet = usb_generic_handle_packet;
.handle_reset = usb_serial_handle_reset, uc->handle_reset = usb_serial_handle_reset;
.handle_control = usb_serial_handle_control, uc->handle_control = usb_serial_handle_control;
.handle_data = usb_serial_handle_data, uc->handle_data = usb_serial_handle_data;
.handle_destroy = usb_serial_handle_destroy, uc->handle_destroy = usb_serial_handle_destroy;
.usbdevice_name = "serial", }
.usbdevice_init = usb_serial_init,
.qdev.props = (Property[]) { 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_CHR("chardev", USBSerialState, cs),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}, },
}; };
static struct USBDeviceInfo braille_info = { static void usb_braille_class_initfn(ObjectClass *klass, void *data)
.product_desc = "QEMU USB Braille", {
.qdev.name = "usb-braille", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.size = sizeof(USBSerialState),
.qdev.vmsd = &vmstate_usb_serial, uc->init = usb_serial_initfn;
.usb_desc = &desc_braille, uc->product_desc = "QEMU USB Braille";
.init = usb_serial_initfn, uc->usb_desc = &desc_braille;
.handle_packet = usb_generic_handle_packet, uc->handle_packet = usb_generic_handle_packet;
.handle_reset = usb_serial_handle_reset, uc->handle_reset = usb_serial_handle_reset;
.handle_control = usb_serial_handle_control, uc->handle_control = usb_serial_handle_control;
.handle_data = usb_serial_handle_data, uc->handle_data = usb_serial_handle_data;
.handle_destroy = usb_serial_handle_destroy, uc->handle_destroy = usb_serial_handle_destroy;
.usbdevice_name = "braille", }
.usbdevice_init = usb_braille_init,
.qdev.props = (Property[]) { 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_CHR("chardev", USBSerialState, cs),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}, },
...@@ -612,7 +622,7 @@ static struct USBDeviceInfo braille_info = { ...@@ -612,7 +622,7 @@ static struct USBDeviceInfo braille_info = {
static void usb_serial_register_devices(void) static void usb_serial_register_devices(void)
{ {
usb_qdev_register(&serial_info); usb_qdev_register(&serial_info, "serial", usb_serial_init);
usb_qdev_register(&braille_info); usb_qdev_register(&braille_info, "braille", usb_braille_init);
} }
device_init(usb_serial_register_devices) device_init(usb_serial_register_devices)
...@@ -349,24 +349,30 @@ static const VMStateDescription vmstate_usb_wacom = { ...@@ -349,24 +349,30 @@ static const VMStateDescription vmstate_usb_wacom = {
.unmigratable = 1, .unmigratable = 1,
}; };
static struct USBDeviceInfo wacom_info = { static void usb_wacom_class_init(ObjectClass *class, void *data)
.product_desc = "QEMU PenPartner Tablet", {
.qdev.name = "usb-wacom-tablet", USBDeviceClass *uc = USB_DEVICE_CLASS(class);
.qdev.desc = "QEMU PenPartner Tablet",
.usbdevice_name = "wacom-tablet", uc->product_desc = "QEMU PenPartner Tablet";
.usb_desc = &desc_wacom, uc->usb_desc = &desc_wacom;
.qdev.size = sizeof(USBWacomState), uc->init = usb_wacom_initfn;
.qdev.vmsd = &vmstate_usb_wacom, uc->handle_packet = usb_generic_handle_packet;
.init = usb_wacom_initfn, uc->handle_reset = usb_wacom_handle_reset;
.handle_packet = usb_generic_handle_packet, uc->handle_control = usb_wacom_handle_control;
.handle_reset = usb_wacom_handle_reset, uc->handle_data = usb_wacom_handle_data;
.handle_control = usb_wacom_handle_control, uc->handle_destroy = usb_wacom_handle_destroy;
.handle_data = usb_wacom_handle_data, }
.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) 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) device_init(usb_wacom_register_devices)
...@@ -1458,7 +1458,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) ...@@ -1458,7 +1458,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
if (!xfer->in_xfer) { if (!xfer->in_xfer) {
xhci_xfer_data(xfer, xfer->data, wLength, 0, 1, 0); xhci_xfer_data(xfer, xfer->data, wLength, 0, 1, 0);
} }
ret = dev->info->handle_control(dev, &xfer->packet, ret = usb_device_handle_control(dev, &xfer->packet,
(bmRequestType << 8) | bRequest, (bmRequestType << 8) | bRequest,
wValue, wIndex, wLength, xfer->data); wValue, wIndex, wLength, xfer->data);
...@@ -1767,7 +1767,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid, ...@@ -1767,7 +1767,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
slot->devaddr = xhci->devaddr++; slot->devaddr = xhci->devaddr++;
slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slot->devaddr; slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slot->devaddr;
DPRINTF("xhci: device address is %d\n", slot->devaddr); DPRINTF("xhci: device address is %d\n", slot->devaddr);
dev->info->handle_control(dev, NULL, usb_device_handle_control(dev, NULL,
DeviceOutRequest | USB_REQ_SET_ADDRESS, DeviceOutRequest | USB_REQ_SET_ADDRESS,
slot->devaddr, 0, 0, NULL); slot->devaddr, 0, 0, NULL);
} }
......
...@@ -95,8 +95,8 @@ static int do_token_setup(USBDevice *s, USBPacket *p) ...@@ -95,8 +95,8 @@ static int do_token_setup(USBDevice *s, USBPacket *p)
index = (s->setup_buf[5] << 8) | s->setup_buf[4]; index = (s->setup_buf[5] << 8) | s->setup_buf[4];
if (s->setup_buf[0] & USB_DIR_IN) { if (s->setup_buf[0] & USB_DIR_IN) {
ret = s->info->handle_control(s, p, request, value, index, ret = usb_device_handle_control(s, p, request, value, index,
s->setup_len, s->data_buf); s->setup_len, s->data_buf);
if (ret == USB_RET_ASYNC) { if (ret == USB_RET_ASYNC) {
s->setup_state = SETUP_STATE_SETUP; s->setup_state = SETUP_STATE_SETUP;
return USB_RET_ASYNC; return USB_RET_ASYNC;
...@@ -129,7 +129,7 @@ static int do_token_in(USBDevice *s, USBPacket *p) ...@@ -129,7 +129,7 @@ static int do_token_in(USBDevice *s, USBPacket *p)
int ret = 0; int ret = 0;
if (p->devep != 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]; request = (s->setup_buf[0] << 8) | s->setup_buf[1];
value = (s->setup_buf[3] << 8) | s->setup_buf[2]; value = (s->setup_buf[3] << 8) | s->setup_buf[2];
...@@ -138,8 +138,8 @@ static int do_token_in(USBDevice *s, USBPacket *p) ...@@ -138,8 +138,8 @@ static int do_token_in(USBDevice *s, USBPacket *p)
switch(s->setup_state) { switch(s->setup_state) {
case SETUP_STATE_ACK: case SETUP_STATE_ACK:
if (!(s->setup_buf[0] & USB_DIR_IN)) { if (!(s->setup_buf[0] & USB_DIR_IN)) {
ret = s->info->handle_control(s, p, request, value, index, ret = usb_device_handle_control(s, p, request, value, index,
s->setup_len, s->data_buf); s->setup_len, s->data_buf);
if (ret == USB_RET_ASYNC) { if (ret == USB_RET_ASYNC) {
return USB_RET_ASYNC; return USB_RET_ASYNC;
} }
...@@ -176,7 +176,7 @@ static int do_token_in(USBDevice *s, USBPacket *p) ...@@ -176,7 +176,7 @@ static int do_token_in(USBDevice *s, USBPacket *p)
static int do_token_out(USBDevice *s, USBPacket *p) static int do_token_out(USBDevice *s, USBPacket *p)
{ {
if (p->devep != 0) if (p->devep != 0)
return s->info->handle_data(s, p); return usb_device_handle_data(s, p);
switch(s->setup_state) { switch(s->setup_state) {
case SETUP_STATE_ACK: case SETUP_STATE_ACK:
...@@ -220,9 +220,7 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p) ...@@ -220,9 +220,7 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
switch(p->pid) { switch(p->pid) {
case USB_MSG_ATTACH: case USB_MSG_ATTACH:
s->state = USB_STATE_ATTACHED; s->state = USB_STATE_ATTACHED;
if (s->info->handle_attach) { usb_device_handle_attach(s);
s->info->handle_attach(s);
}
return 0; return 0;
case USB_MSG_DETACH: case USB_MSG_DETACH:
...@@ -233,9 +231,7 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p) ...@@ -233,9 +231,7 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
s->remote_wakeup = 0; s->remote_wakeup = 0;
s->addr = 0; s->addr = 0;
s->state = USB_STATE_DEFAULT; s->state = USB_STATE_DEFAULT;
if (s->info->handle_reset) { usb_device_handle_reset(s);
s->info->handle_reset(s);
}
return 0; return 0;
} }
...@@ -326,7 +322,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p) ...@@ -326,7 +322,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
int ret; int ret;
assert(p->owner == NULL); assert(p->owner == NULL);
ret = dev->info->handle_packet(dev, p); ret = usb_device_handle_packet(dev, p);
if (ret == USB_RET_ASYNC) { if (ret == USB_RET_ASYNC) {
if (p->owner == NULL) { if (p->owner == NULL) {
p->owner = usb_ep_get(dev, p->pid, p->devep); p->owner = usb_ep_get(dev, p->pid, p->devep);
...@@ -357,7 +353,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p) ...@@ -357,7 +353,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
void usb_cancel_packet(USBPacket * p) void usb_cancel_packet(USBPacket * p)
{ {
assert(p->owner != NULL); assert(p->owner != NULL);
p->owner->dev->info->cancel_packet(p->owner->dev, p); usb_device_cancel_packet(p->owner->dev, p);
p->owner = NULL; p->owner = NULL;
} }
......
#ifndef QEMU_USB_H
#define QEMU_USB_H
/* /*
* QEMU USB API * QEMU USB API
* *
...@@ -150,7 +153,6 @@ typedef struct USBBus USBBus; ...@@ -150,7 +153,6 @@ typedef struct USBBus USBBus;
typedef struct USBBusOps USBBusOps; typedef struct USBBusOps USBBusOps;
typedef struct USBPort USBPort; typedef struct USBPort USBPort;
typedef struct USBDevice USBDevice; typedef struct USBDevice USBDevice;
typedef struct USBDeviceInfo USBDeviceInfo;
typedef struct USBPacket USBPacket; typedef struct USBPacket USBPacket;
typedef struct USBEndpoint USBEndpoint; typedef struct USBEndpoint USBEndpoint;
...@@ -183,7 +185,6 @@ struct USBEndpoint { ...@@ -183,7 +185,6 @@ struct USBEndpoint {
/* definition of a USB device */ /* definition of a USB device */
struct USBDevice { struct USBDevice {
DeviceState qdev; DeviceState qdev;
USBDeviceInfo *info;
USBPort *port; USBPort *port;
char *port_path; char *port_path;
void *opaque; void *opaque;
...@@ -219,8 +220,17 @@ struct USBDevice { ...@@ -219,8 +220,17 @@ struct USBDevice {
const USBDescIface *ifaces[USB_MAX_INTERFACES]; const USBDescIface *ifaces[USB_MAX_INTERFACES];
}; };
struct USBDeviceInfo { #define TYPE_USB_DEVICE "usb-device"
DeviceInfo qdev; #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)
typedef struct USBDeviceClass {
DeviceClass parent_class;
int (*init)(USBDevice *dev); int (*init)(USBDevice *dev);
/* /*
...@@ -274,11 +284,7 @@ struct USBDeviceInfo { ...@@ -274,11 +284,7 @@ struct USBDeviceInfo {
const char *product_desc; const char *product_desc;
const USBDesc *usb_desc; const USBDesc *usb_desc;
} USBDeviceClass;
/* handle legacy -usbdevice command line options */
const char *usbdevice_name;
USBDevice *(*usbdevice_init)(const char *params);
};
typedef struct USBPortOps { typedef struct USBPortOps {
void (*attach)(USBPort *port); void (*attach)(USBPort *port);
...@@ -412,8 +418,9 @@ struct USBBusOps { ...@@ -412,8 +418,9 @@ struct USBBusOps {
void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host); void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host);
USBBus *usb_bus_find(int busnr); USBBus *usb_bus_find(int busnr);
void usb_qdev_register(USBDeviceInfo *info); void usb_qdev_register(DeviceInfo *info,
void usb_qdev_register_many(USBDeviceInfo *info); const char *usbdevice_name,
USBDevice *(*usbdevice_init)(const char *params));
USBDevice *usb_create(USBBus *bus, const char *name); USBDevice *usb_create(USBBus *bus, const char *name);
USBDevice *usb_create_simple(USBBus *bus, const char *name); USBDevice *usb_create_simple(USBBus *bus, const char *name);
USBDevice *usbdevice_create(const char *cmdline); USBDevice *usbdevice_create(const char *cmdline);
...@@ -445,4 +452,25 @@ extern const VMStateDescription vmstate_usb_device; ...@@ -445,4 +452,25 @@ extern const VMStateDescription vmstate_usb_device;
.offset = vmstate_offset_value(_state, _field, USBDevice), \ .offset = vmstate_offset_value(_state, _field, USBDevice), \
} }
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);
void usb_device_set_interface(USBDevice *dev, int interface,
int alt_old, int alt_new);
const char *usb_device_get_product_desc(USBDevice *dev);
const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
#endif
...@@ -397,21 +397,28 @@ fail: ...@@ -397,21 +397,28 @@ fail:
return ret; return ret;
} }
static struct USBDeviceInfo usb_host_dev_info = { static void usb_host_class_initfn(ObjectClass *klass, void *data)
.product_desc = "USB Host Device", {
.qdev.name = "usb-host", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.size = sizeof(USBHostDevice),
.init = usb_host_initfn, uc->product_desc = "USB Host Device";
.handle_packet = usb_generic_handle_packet, uc->init = usb_host_initfn;
.handle_reset = usb_host_handle_reset, uc->handle_packet = usb_generic_handle_packet;
.handle_control = usb_host_handle_control, uc->handle_reset = usb_host_handle_reset;
.handle_data = usb_host_handle_data, uc->handle_control = usb_host_handle_control;
.handle_destroy = usb_host_handle_destroy, 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) 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) device_init(usb_host_register_devices)
......
...@@ -1402,21 +1402,26 @@ static const VMStateDescription vmstate_usb_host = { ...@@ -1402,21 +1402,26 @@ static const VMStateDescription vmstate_usb_host = {
.unmigratable = 1, .unmigratable = 1,
}; };
static struct USBDeviceInfo usb_host_dev_info = { static void usb_host_class_initfn(ObjectClass *klass, void *data)
.product_desc = "USB Host Device", {
.qdev.name = "usb-host", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.size = sizeof(USBHostDevice),
.qdev.vmsd = &vmstate_usb_host, uc->init = usb_host_initfn;
.init = usb_host_initfn, uc->product_desc = "USB Host Device";
.handle_packet = usb_generic_handle_packet, uc->handle_packet = usb_generic_handle_packet;
.cancel_packet = usb_host_async_cancel, uc->cancel_packet = usb_host_async_cancel;
.handle_data = usb_host_handle_data, uc->handle_data = usb_host_handle_data;
.handle_control = usb_host_handle_control, uc->handle_control = usb_host_handle_control;
.handle_reset = usb_host_handle_reset, uc->handle_reset = usb_host_handle_reset;
.handle_destroy = usb_host_handle_destroy, uc->handle_destroy = usb_host_handle_destroy;
.usbdevice_name = "host", }
.usbdevice_init = usb_host_device_open,
.qdev.props = (Property[]) { 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("hostbus", USBHostDevice, match.bus_num, 0),
DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr, 0), DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr, 0),
DEFINE_PROP_STRING("hostport", USBHostDevice, match.port), DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
...@@ -1429,7 +1434,7 @@ static struct USBDeviceInfo usb_host_dev_info = { ...@@ -1429,7 +1434,7 @@ static struct USBDeviceInfo usb_host_dev_info = {
static void usb_host_register_devices(void) 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) device_init(usb_host_register_devices)
......
...@@ -1315,18 +1315,25 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id, ...@@ -1315,18 +1315,25 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
} }
} }
static struct USBDeviceInfo usbredir_dev_info = { static void usbredir_class_initfn(ObjectClass *klass, void *data)
.product_desc = "USB Redirection Device", {
.qdev.name = "usb-redir", USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
.qdev.size = sizeof(USBRedirDevice),
.init = usbredir_initfn, uc->init = usbredir_initfn;
.handle_destroy = usbredir_handle_destroy, uc->product_desc = "USB Redirection Device";
.handle_packet = usb_generic_handle_packet, uc->handle_destroy = usbredir_handle_destroy;
.cancel_packet = usbredir_cancel_packet, uc->handle_packet = usb_generic_handle_packet;
.handle_reset = usbredir_handle_reset, uc->cancel_packet = usbredir_cancel_packet;
.handle_data = usbredir_handle_data, uc->handle_reset = usbredir_handle_reset;
.handle_control = usbredir_handle_control, uc->handle_data = usbredir_handle_data;
.qdev.props = (Property[]) { 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_CHR("chardev", USBRedirDevice, cs),
DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0), DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
...@@ -1335,6 +1342,6 @@ static struct USBDeviceInfo usbredir_dev_info = { ...@@ -1335,6 +1342,6 @@ static struct USBDeviceInfo usbredir_dev_info = {
static void usbredir_register_devices(void) 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); device_init(usbredir_register_devices);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册