提交 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 = {
.unmigratable = 1,
};
static struct USBDeviceInfo usb_audio_info = {
.product_desc = "QEMU USB Audio Interface",
.usbdevice_name = "audio",
.qdev.name = "usb-audio",
.qdev.size = sizeof(USBAudioState),
.qdev.vmsd = &vmstate_usb_audio,
.usb_desc = &desc_audio,
.init = usb_audio_initfn,
.handle_packet = usb_generic_handle_packet,
.handle_reset = usb_audio_handle_reset,
.handle_control = usb_audio_handle_control,
.handle_data = usb_audio_handle_data,
.handle_destroy = usb_audio_handle_destroy,
.set_interface = usb_audio_set_interface,
.qdev.props = (Property[]) {
static void usb_audio_class_init(ObjectClass *klass, void *data)
{
USBDeviceClass *k = USB_DEVICE_CLASS(klass);
k->product_desc = "QEMU USB Audio Interface";
k->usb_desc = &desc_audio;
k->init = usb_audio_initfn;
k->handle_packet = usb_generic_handle_packet;
k->handle_reset = usb_audio_handle_reset;
k->handle_control = usb_audio_handle_control;
k->handle_data = usb_audio_handle_data;
k->handle_destroy = usb_audio_handle_destroy;
k->set_interface = usb_audio_set_interface;
}
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("buffer", USBAudioState, buffer,
8 * USBAUDIO_PACKET_SIZE),
......@@ -698,7 +704,7 @@ static struct USBDeviceInfo usb_audio_info = {
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)
......@@ -527,22 +527,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)
......@@ -65,14 +65,104 @@ 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;
}
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)
{
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);
usb_ep_init(dev);
......@@ -80,7 +170,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
if (rc != 0) {
return rc;
}
rc = dev->info->init(dev);
rc = usb_device_init(dev);
if (rc != 0) {
usb_release_port(dev);
return rc;
......@@ -97,34 +187,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);
}
}
......@@ -144,7 +243,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)
......@@ -365,7 +464,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",
......@@ -377,13 +476,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;
......@@ -434,8 +533,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;
......@@ -452,17 +551,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);
......@@ -470,12 +565,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);
......@@ -1286,28 +1286,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)
......@@ -297,8 +297,8 @@ static int usb_desc_set_interface(USBDevice *dev, int index, int value)
dev->ifaces[index] = iface;
usb_desc_ep_init(dev);
if (dev->info->set_interface && old != value) {
dev->info->set_interface(dev, index, old, value);
if (old != value) {
usb_device_set_interface(dev, index, old, value);
}
return 0;
}
......@@ -338,7 +338,7 @@ static int usb_desc_set_config(USBDevice *dev, int value)
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) {
......@@ -355,7 +355,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;
......@@ -371,7 +371,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)) {
......@@ -380,7 +380,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);
......@@ -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);
if (str == NULL) {
str = dev->info->usb_desc->str[index];
str = usb_device_get_usb_desc(dev)->str[index];
if (str == NULL) {
return 0;
}
......@@ -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)
{
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;
......@@ -463,9 +463,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) {
......@@ -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 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;
assert(desc != NULL);
......
......@@ -553,53 +553,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)
......@@ -533,23 +533,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)
......@@ -636,23 +636,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),
......@@ -662,6 +667,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)
......@@ -1385,29 +1385,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)
......@@ -570,41 +570,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(),
},
......@@ -612,7 +622,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)
......@@ -349,24 +349,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)
......@@ -1458,7 +1458,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
if (!xfer->in_xfer) {
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,
wValue, wIndex, wLength, xfer->data);
......@@ -1767,7 +1767,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
slot->devaddr = xhci->devaddr++;
slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | 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,
slot->devaddr, 0, 0, NULL);
}
......
......@@ -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 = usb_ep_get(dev, p->pid, p->devep);
......@@ -357,7 +353,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
void usb_cancel_packet(USBPacket * p)
{
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;
}
......
#ifndef QEMU_USB_H
#define QEMU_USB_H
/*
* QEMU USB API
*
......@@ -150,7 +153,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 USBEndpoint USBEndpoint;
......@@ -183,7 +185,6 @@ struct USBEndpoint {
/* definition of a USB device */
struct USBDevice {
DeviceState qdev;
USBDeviceInfo *info;
USBPort *port;
char *port_path;
void *opaque;
......@@ -219,8 +220,17 @@ struct USBDevice {
const USBDescIface *ifaces[USB_MAX_INTERFACES];
};
struct USBDeviceInfo {
DeviceInfo qdev;
#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)
typedef struct USBDeviceClass {
DeviceClass parent_class;
int (*init)(USBDevice *dev);
/*
......@@ -274,11 +284,7 @@ struct USBDeviceInfo {
const char *product_desc;
const USBDesc *usb_desc;
/* handle legacy -usbdevice command line options */
const char *usbdevice_name;
USBDevice *(*usbdevice_init)(const char *params);
};
} USBDeviceClass;
typedef struct USBPortOps {
void (*attach)(USBPort *port);
......@@ -412,8 +418,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);
......@@ -445,4 +452,25 @@ extern const VMStateDescription vmstate_usb_device;
.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:
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)
......
......@@ -1402,21 +1402,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),
......@@ -1429,7 +1434,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)
......
......@@ -1315,18 +1315,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(),
......@@ -1335,6 +1342,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);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册